When creating new EntityReferenceSelection plugins they are not available for selection in the Entity Reference Field settings form. To recreate this bug I did the following:
- Create a custom plugin using the default selection plugin provided by the core Drupal Entity Component using the following annotation for my plugin definition
- Added a new field to the Basic Page Content Type
- Looked for my plugin "Related News" in the "Reference Type" select list
/**
* Custom plugin implementation of the Entity Reference Selection plugin.
*
* @EntityReferenceSelection(
* id = "news",
* label = @Translation("Related News"),
* group = "custom",
* weight = 0
* )
*/
I was expecting to see my plugin in the select list of available EntityReferenceSelection plugins but instead did not. Debugging verified that my plugin was discoverable to the SelectionPluginManager. If I use the the same string for 'id' and 'group' in the plugin definition e.g. 'news' and 'news, and clear the cache it's available as an option from the select list.
I believe the issue is in Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem::fieldSettingsForm; specifically:
// Get all selection plugins for this entity type.
$selection_plugins = \Drupal::service('plugin.manager.entity_reference_selection')->getSelectionGroups($this->getSetting('target_type'));
$handlers_options = array();
foreach (array_keys($selection_plugins) as $selection_group_id) {
// We only display base plugins (e.g. 'default', 'views', ...) and not
// entity type specific plugins (e.g. 'default:node', 'default:user',
// ...).
if (array_key_exists($selection_group_id, $selection_plugins[$selection_group_id])) {
$handlers_options[$selection_group_id] = Html::escape($selection_plugins[$selection_group_id][$selection_group_id]['label']);
}
elseif (array_key_exists($selection_group_id . ':' . $this->getSetting('target_type'), $selection_plugins[$selection_group_id])) {
$selection_group_plugin = $selection_group_id . ':' . $this->getSetting('target_type');
$handlers_options[$selection_group_plugin] = Html::escape($selection_plugins[$selection_group_id][$selection_group_plugin]['base_plugin_label']);
}
}
I don't fully understand what the if statement is checking her. This logic will only add plugins that have identical groups and ids to the select options. I couldn't find any documentation support this. I would think all plugin ids from all groups should be available as options (excluding default:node, default:user which is checked for in the elseif conditional.
This is a simple enough fix that I'd love to do, if someone can elaborate on the intended behavior of these plugin definitions and if my assumptions above are correct.
Comments
Comment #2
aczietlow CreditAttribution: aczietlow commentedComment #4
tacituseu CreditAttribution: tacituseu commentedJudging by the code, for most custom cases id should be equal to group (e.g.
core\modules\views\src\Plugin\EntityReferenceSelection\ViewsSelection.php
)The other case seems to be a way of minimizing boilerplate for
DefaultSelection
plugin (seecore\lib\Drupal\Core\Entity\Plugin\EntityReferenceSelection\DefaultSelection.php
) and expects the definition to be derived bycore\lib\Drupal\Core\Entity\Plugin\Derivative\DefaultSelectionDeriver.php
.Closing as duplicate of #2649712: Entity reference selection plugins break when not following a weird ID pattern.