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:

  1. Create a custom plugin using the default selection plugin provided by the core Drupal Entity Component using the following annotation for my plugin definition
  2. /**
     * Custom plugin implementation of the Entity Reference Selection plugin.
     *
     * @EntityReferenceSelection(
     *   id = "news",
     *   label = @Translation("Related News"),
     *   group = "custom",
     *   weight = 0
     * )
     */
    
  3. Added a new field to the Basic Page Content Type
  4. Looked for my plugin "Related News" in the "Reference Type" select list

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

aczietlow created an issue. See original summary.

aczietlow’s picture

Issue summary: View changes

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.0-beta1 was released on August 3, 2016, which means new developments and disruptive changes should now be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

tacituseu’s picture

Judging 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 (see core\lib\Drupal\Core\Entity\Plugin\EntityReferenceSelection\DefaultSelection.php) and expects the definition to be derived by core\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.