Issue #2016589 by amateescu, tim.plunkett: Add a dedicated @EntityReferenceSelection annotation.

8.0.x
Alex Pott 2013-07-09 15:29:25 +01:00
parent 45a9e859d6
commit c250f7354d
11 changed files with 128 additions and 63 deletions

View File

@ -7,17 +7,16 @@
namespace Drupal\comment\Plugin\entity_reference\selection;
use Drupal\Component\Annotation\Plugin;
use Drupal\Core\Annotation\Translation;
use Drupal\Core\Database\Query\SelectInterface;
use Drupal\entity_reference\Annotation\EntityReferenceSelection;
use Drupal\entity_reference\Plugin\entity_reference\selection\SelectionBase;
/**
* Provides specific access control for the comment entity type.
*
* @Plugin(
* @EntityReferenceSelection(
* id = "comment_default",
* module = "comment",
* label = @Translation("Comment selection"),
* entity_types = {"comment"},
* group = "default",
@ -27,7 +26,7 @@ use Drupal\entity_reference\Plugin\entity_reference\selection\SelectionBase;
class CommentSelection extends SelectionBase {
/**
* Overrides SelectionBase::buildEntityQuery().
* {@inheritdoc}
*/
public function buildEntityQuery($match = NULL, $match_operator = 'CONTAINS') {
$query = parent::buildEntityQuery($match, $match_operator);
@ -42,7 +41,7 @@ class CommentSelection extends SelectionBase {
}
/**
* Overrides SelectionBase::entityQueryAlter().
* {@inheritdoc}
*/
public function entityQueryAlter(SelectInterface $query) {
$tables = $query->getTables();

View File

@ -139,7 +139,7 @@ function entity_reference_field_settings_form($field, $instance) {
// @todo As the database schema can currently only store numeric IDs of
// referenced entities and configuration entities have string IDs, prevent
// configuration entities from being referenced.
if (!in_array('\Drupal\Core\Config\Entity\ConfigEntityInterface', class_implements($entity_info['class']))) {
if (!is_subclass_of($entity_info['class'], '\Drupal\Core\Config\Entity\ConfigEntityInterface')) {
$entity_type_options[$entity_type] = $entity_info['label'];
}
}
@ -206,8 +206,8 @@ function entity_reference_field_instance_settings_form($field, $instance, $form_
$handlers = Drupal::service('plugin.manager.entity_reference.selection')->getDefinitions();
$handlers_options = array();
foreach ($handlers as $plugin_id => $plugin) {
// We only display base plugins (e.g. 'base', 'views', ..) and not entity
// type specific plugins (e.g. 'base_node', 'base_user', ...).
// We only display base plugins (e.g. 'default', 'views', ..) and not entity
// type specific plugins (e.g. 'default_node', 'default_user', ...).
if (in_array($plugin_id, $handler_groups)) {
$handlers_options[$plugin_id] = check_plain($plugin['label']);
}

View File

@ -1,7 +1,7 @@
services:
plugin.manager.entity_reference.selection:
class: Drupal\entity_reference\Plugin\Type\SelectionPluginManager
arguments: ['@container.namespaces']
arguments: ['@container.namespaces', '@cache.cache', '@language_manager', '@module_handler']
entity_reference.autocomplete:
class: Drupal\entity_reference\EntityReferenceAutocomplete
arguments: ['@plugin.manager.entity']

View File

@ -0,0 +1,68 @@
<?php
/**
* @file
* Contains \Drupal\entity_reference\Annotation\EntityReferenceSelection.
*/
namespace Drupal\entity_reference\Annotation;
use Drupal\Component\Annotation\Plugin;
/**
* Defines a EntityReferenceSelection annotation object.
*
* @Annotation
*/
class EntityReferenceSelection extends Plugin {
/**
* The plugin ID.
*
* @var string
*/
public $id;
/**
* The human-readable name of the selection plugin.
*
* @ingroup plugin_translatable
*
* @var \Drupal\Core\Annotation\Translation
*/
public $label;
/**
* The selection plugin group.
*
* This property is used to allow selection plugins to target a specific
* entity type while also inheriting the code of an existing selection plugin.
* For example, if we want to override the NodeSelection from the 'default'
* selection type, we can define the annotation of a new plugin as follows:
* @code
* id = "node_advanced",
* entity_types = {"node"},
* group = "default",
* weight = 5
* @endcode
*
* @var string
*/
public $group;
/**
* An array of entity types that can be referenced by this plugin. Defaults to
* all entity types.
*
* @var array (optional)
*/
public $entity_types = array();
/**
* The weight of the plugin in it's group.
*
* @var int
*/
public $weight;
}

View File

@ -9,28 +9,34 @@ namespace Drupal\entity_reference\Plugin\Type;
use Drupal\Component\Plugin\Exception\PluginException;
use Drupal\Component\Plugin\Factory\ReflectionFactory;
use Drupal\Component\Plugin\PluginManagerBase;
use Drupal\Core\Plugin\Discovery\AlterDecorator;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Language\LanguageManager;
use Drupal\Core\Plugin\DefaultPluginManager;
use Drupal\Core\Plugin\Discovery\AnnotatedClassDiscovery;
use Drupal\Core\Plugin\Discovery\CacheDecorator;
use Drupal\entity_reference\Plugin\Type\Selection\SelectionBroken;
/**
* Plugin type manager for the Entity Reference Selection plugin.
*/
class SelectionPluginManager extends PluginManagerBase {
class SelectionPluginManager extends DefaultPluginManager {
/**
* Constructs a SelectionPluginManager object.
*
* @param \Traversable $namespaces
* An object that implements \Traversable which contains the root paths
* keyed by the corresponding namespace to look for plugin implementations,
* {@inheritdoc}
*/
public function __construct(\Traversable $namespaces) {
$this->baseDiscovery = new AlterDecorator(new AnnotatedClassDiscovery('entity_reference/selection', $namespaces), 'entity_reference_selection');
$this->discovery = new CacheDecorator($this->baseDiscovery, 'entity_reference_selection');
public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, LanguageManager $language_manager, ModuleHandlerInterface $module_handler) {
$this->subdir = 'entity_reference/selection';
$annotation_namespaces = array(
'Drupal\entity_reference\Annotation' => $namespaces['Drupal\entity_reference']
);
$this->discovery = new AnnotatedClassDiscovery($this->subdir, $namespaces, $annotation_namespaces, 'Drupal\entity_reference\Annotation\EntityReferenceSelection');
// We're not using the parent constructor because we use a different factory
// method and don't need the derivative discovery decorator.
$this->factory = new ReflectionFactory($this);
$this->alterInfo($module_handler, 'entity_reference_selection');
$this->setCacheBackend($cache_backend, $language_manager, 'entity_reference_selection');
}
/**
@ -78,7 +84,7 @@ class SelectionPluginManager extends PluginManagerBase {
$plugins = array();
foreach ($this->getDefinitions() as $plugin_id => $plugin) {
if (!isset($plugin['entity_types']) || in_array($entity_type, $plugin['entity_types'])) {
if (empty($plugin['entity_types']) || in_array($entity_type, $plugin['entity_types'])) {
$plugins[$plugin['group']][$plugin_id] = $plugin;
}
}

View File

@ -7,21 +7,20 @@
namespace Drupal\entity_reference\Plugin\entity_reference\selection;
use Drupal\Component\Annotation\Plugin;
use Drupal\Core\Annotation\Translation;
use Drupal\Core\Database\Query\AlterableInterface;
use Drupal\Core\Database\Query\SelectInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\Field\FieldDefinitionInterface;
use Drupal\Component\Utility\NestedArray;
use Drupal\entity_reference\Annotation\EntityReferenceSelection;
use Drupal\entity_reference\Plugin\Type\Selection\SelectionInterface;
/**
* Plugin implementation of the 'selection' entity_reference.
*
* @Plugin(
* @EntityReferenceSelection(
* id = "default",
* module = "entity_reference",
* label = @Translation("Default"),
* group = "default",
* weight = 0,
@ -53,7 +52,7 @@ class SelectionBase implements SelectionInterface {
}
/**
* Implements SelectionInterface::settingsForm().
* {@inheritdoc}
*/
public static function settingsForm(&$field, &$instance) {
$entity_info = entity_get_info($field['settings']['target_type']);
@ -155,7 +154,7 @@ class SelectionBase implements SelectionInterface {
}
/**
* Implements SelectionInterface::getReferenceableEntities().
* {@inheritdoc}
*/
public function getReferenceableEntities($match = NULL, $match_operator = 'CONTAINS', $limit = 0) {
$target_type = $this->fieldDefinition->getFieldSetting('target_type');
@ -182,7 +181,7 @@ class SelectionBase implements SelectionInterface {
}
/**
* Implements SelectionInterface::countReferenceableEntities().
* {@inheritdoc}
*/
public function countReferenceableEntities($match = NULL, $match_operator = 'CONTAINS') {
$query = $this->buildEntityQuery($match, $match_operator);
@ -192,7 +191,7 @@ class SelectionBase implements SelectionInterface {
}
/**
* Implements SelectionInterface::validateReferenceableEntities().
* {@inheritdoc}
*/
public function validateReferenceableEntities(array $ids) {
$result = array();
@ -209,7 +208,7 @@ class SelectionBase implements SelectionInterface {
}
/**
* Implements SelectionInterface::validateAutocompleteInput().
* {@inheritdoc}
*/
public function validateAutocompleteInput($input, &$element, &$form_state, $form, $strict = TRUE) {
$entities = $this->getReferenceableEntities($input, '=', 6);
@ -292,7 +291,7 @@ class SelectionBase implements SelectionInterface {
}
/**
* Implements SelectionInterface::entityQueryAlter().
* {@inheritdoc}
*/
public function entityQueryAlter(SelectInterface $query) { }

View File

@ -7,17 +7,15 @@
namespace Drupal\file\Plugin\entity_reference\selection;
use Drupal\Component\Annotation\Plugin;
use Drupal\Core\Annotation\Translation;
use Drupal\Core\Database\Query\SelectInterface;
use Drupal\entity_reference\Annotation\EntityReferenceSelection;
use Drupal\entity_reference\Plugin\entity_reference\selection\SelectionBase;
/**
* Provides specific access control for the file entity type.
*
* @Plugin(
* @EntityReferenceSelection(
* id = "file_default",
* module = "file",
* label = @Translation("File selection"),
* entity_types = {"file"},
* group = "default",
@ -27,7 +25,7 @@ use Drupal\entity_reference\Plugin\entity_reference\selection\SelectionBase;
class FileSelection extends SelectionBase {
/**
* Overrides SelectionBase::buildEntityQuery().
* {@inheritdoc}
*/
public function buildEntityQuery($match = NULL, $match_operator = 'CONTAINS') {
$query = parent::buildEntityQuery($match, $match_operator);

View File

@ -7,17 +7,15 @@
namespace Drupal\node\Plugin\entity_reference\selection;
use Drupal\Component\Annotation\Plugin;
use Drupal\Core\Annotation\Translation;
use Drupal\Core\Database\Query\SelectInterface;
use Drupal\entity_reference\Annotation\EntityReferenceSelection;
use Drupal\entity_reference\Plugin\entity_reference\selection\SelectionBase;
/**
* Provides specific access control for the node entity type.
*
* @Plugin(
* @EntityReferenceSelection(
* id = "node_default",
* module = "node",
* label = @Translation("Node selection"),
* entity_types = {"node"},
* group = "default",
@ -27,7 +25,7 @@ use Drupal\entity_reference\Plugin\entity_reference\selection\SelectionBase;
class NodeSelection extends SelectionBase {
/**
* Overrides SelectionBase::buildEntityQuery().
* {@inheritdoc}
*/
public function buildEntityQuery($match = NULL, $match_operator = 'CONTAINS') {
$query = parent::buildEntityQuery($match, $match_operator);

View File

@ -7,17 +7,16 @@
namespace Drupal\taxonomy\Plugin\entity_reference\selection;
use Drupal\Component\Annotation\Plugin;
use Drupal\Core\Annotation\Translation;
use Drupal\Core\Database\Query\SelectInterface;
use Drupal\entity_reference\Annotation\EntityReferenceSelection;
use Drupal\entity_reference\Plugin\entity_reference\selection\SelectionBase;
/**
* Provides specific access control for the taxonomy_term entity type.
*
* @Plugin(
* @EntityReferenceSelection(
* id = "taxonomy_term_default",
* module = "taxonomy",
* label = @Translation("Taxonomy Term selection"),
* entity_types = {"taxonomy_term"},
* group = "default",
@ -27,14 +26,14 @@ use Drupal\entity_reference\Plugin\entity_reference\selection\SelectionBase;
class TermSelection extends SelectionBase {
/**
* Overrides SelectionBase::entityQueryAlter().
* {@inheritdoc}
*/
public function entityQueryAlter(SelectInterface $query) {
// @todo: How to set access, as vocabulary is now config?
}
/**
* Overrides SelectionBase::settingsForm().
* {@inheritdoc}
*/
public static function settingsForm(&$field, &$instance) {
$form = parent::settingsForm($field, $instance);
@ -49,9 +48,8 @@ class TermSelection extends SelectionBase {
}
/**
* Overrides SelectionBase::getReferenceableEntities().
* {@inheritdoc}
*/
public function getReferenceableEntities($match = NULL, $match_operator = 'CONTAINS', $limit = 0) {
if ($match || $limit) {

View File

@ -7,18 +7,17 @@
namespace Drupal\user\Plugin\entity_reference\selection;
use Drupal\Component\Annotation\Plugin;
use Drupal\Core\Annotation\Translation;
use Drupal\Core\Database\Database;
use Drupal\Core\Database\Query\SelectInterface;
use Drupal\entity_reference\Annotation\EntityReferenceSelection;
use Drupal\entity_reference\Plugin\entity_reference\selection\SelectionBase;
/**
* Provides specific access control for the user entity type.
*
* @Plugin(
* @EntityReferenceSelection(
* id = "user_default",
* module = "user",
* label = @Translation("User selection"),
* entity_types = {"user"},
* group = "default",
@ -28,7 +27,7 @@ use Drupal\entity_reference\Plugin\entity_reference\selection\SelectionBase;
class UserSelection extends SelectionBase {
/**
* Overrides SelectionBase::settingsForm().
* {@inheritdoc}
*/
public static function settingsForm(&$field, &$instance) {
// Merge in default values.
@ -78,7 +77,7 @@ class UserSelection extends SelectionBase {
}
/**
* Overrides SelectionBase::buildEntityQuery().
* {@inheritdoc}
*/
public function buildEntityQuery($match = NULL, $match_operator = 'CONTAINS') {
$query = parent::buildEntityQuery($match, $match_operator);
@ -97,7 +96,7 @@ class UserSelection extends SelectionBase {
}
/**
* Overrides SelectionBase::entityQueryAlter().
* {@inheritdoc}
*/
public function entityQueryAlter(SelectInterface $query) {
if (user_access('administer users')) {

View File

@ -7,19 +7,18 @@
namespace Drupal\views\Plugin\entity_reference\selection;
use Drupal\Component\Annotation\Plugin;
use Drupal\Core\Annotation\Translation;
use Drupal\Core\Database\Query\SelectInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\Field\FieldDefinitionInterface;
use Drupal\entity_reference\Annotation\EntityReferenceSelection;
use Drupal\entity_reference\Plugin\Type\Selection\SelectionInterface;
/**
* Plugin implementation of the 'selection' entity_reference.
*
* @Plugin(
* @EntityReferenceSelection(
* id = "views",
* module = "views",
* label = @Translation("Views: Filter by an entity reference view"),
* group = "views",
* weight = 0
@ -57,7 +56,7 @@ class ViewsSelection implements SelectionInterface {
}
/**
* Implements \Drupal\entity_reference\Plugin\Type\Selection\SelectionInterface::settingsForm().
* {@inheritdoc}
*/
public static function settingsForm(&$field, &$instance) {
$view_settings = empty($instance['settings']['handler_settings']['view']) ? array() : $instance['settings']['handler_settings']['view'];
@ -155,7 +154,7 @@ class ViewsSelection implements SelectionInterface {
}
/**
* Implements \Drupal\entity_reference\Plugin\Type\Selection\SelectionInterface::getReferenceableEntities().
* {@inheritdoc}
*/
public function getReferenceableEntities($match = NULL, $match_operator = 'CONTAINS', $limit = 0) {
$handler_settings = $this->fieldDefinition->getFieldSetting('handler_settings');
@ -178,7 +177,7 @@ class ViewsSelection implements SelectionInterface {
}
/**
* Implements \Drupal\entity_reference\Plugin\Type\Selection\SelectionInterface::countReferenceableEntities().
* {@inheritdoc}
*/
public function countReferenceableEntities($match = NULL, $match_operator = 'CONTAINS') {
$this->getReferenceableEntities($match, $match_operator);
@ -186,7 +185,7 @@ class ViewsSelection implements SelectionInterface {
}
/**
* Implements \Drupal\entity_reference\Plugin\Type\Selection\SelectionInterface::validateReferenceableEntities().
* {@inheritdoc}
*/
public function validateReferenceableEntities(array $ids) {
$handler_settings = $this->fieldDefinition->getFieldSetting('handler_settings');
@ -202,14 +201,14 @@ class ViewsSelection implements SelectionInterface {
}
/**
* Implements \Drupal\entity_reference\Plugin\Type\Selection\SelectionInterface::validateAutocompleteInput().
* {@inheritdoc}
*/
public function validateAutocompleteInput($input, &$element, &$form_state, $form, $strict = TRUE) {
return NULL;
}
/**
* Implements \Drupal\entity_reference\Plugin\Type\Selection\SelectionInterface::entityQueryAlter().
* {@inheritdoc}
*/
public function entityQueryAlter(SelectInterface $query) {}
@ -241,4 +240,5 @@ class ViewsSelection implements SelectionInterface {
$value = array('view_name' => $view, 'display_name' => $display, 'arguments' => $arguments);
form_set_value($element, $value, $form_state);
}
}