Issue #2107243 by amateescu, jibran, larowlan, Xano: Decouple entity reference selection plugins from field definitions
parent
c0b346b75c
commit
5d20c57be1
|
@ -348,6 +348,9 @@ services:
|
|||
arguments: ['@config.manager', '@entity.manager']
|
||||
tags:
|
||||
- { name: event_subscriber }
|
||||
plugin.manager.entity_reference_selection:
|
||||
class: Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginManager
|
||||
parent: default_plugin_manager
|
||||
plugin.manager.block:
|
||||
class: Drupal\Core\Block\BlockManager
|
||||
parent: default_plugin_manager
|
||||
|
|
|
@ -2,25 +2,25 @@
|
|||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\entity_reference\Annotation\EntityReferenceSelection.
|
||||
* Contains \Drupal\Core\Entity\Annotation\EntityReferenceSelection.
|
||||
*/
|
||||
|
||||
namespace Drupal\entity_reference\Annotation;
|
||||
namespace Drupal\Core\Entity\Annotation;
|
||||
|
||||
use Drupal\Component\Annotation\Plugin;
|
||||
|
||||
/**
|
||||
* Defines an EntityReferenceSelection plugin annotation object.
|
||||
*
|
||||
* Plugin Namespace: Plugin\entity_reference\selection
|
||||
* Plugin Namespace: Plugin\EntityReferenceSelection
|
||||
*
|
||||
* For a working example, see
|
||||
* \Drupal\comment\Plugin\entity_reference\selection\CommentSelection
|
||||
* \Drupal\comment\Plugin\EntityReferenceSelection\CommentSelection
|
||||
*
|
||||
* @see \Drupal\entity_reference\Plugin\Type\SelectionPluginManager
|
||||
* @see \Drupal\entity_reference\Plugin\Type\Selection\SelectionInterface
|
||||
* @see \Drupal\entity_reference\Plugin\entity_reference\selection\SelectionBase
|
||||
* @see \Drupal\entity_reference\Plugin\Derivative\SelectionBase
|
||||
* @see \Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginManager
|
||||
* @see \Drupal\Core\Entity\EntityReferenceSelection\SelectionInterface
|
||||
* @see \Drupal\Core\Entity\Plugin\EntityReferenceSelection\SelectionBase
|
||||
* @see \Drupal\Core\Entity\Plugin\Derivative\SelectionBase
|
||||
* @see plugin_api
|
||||
*
|
||||
* @Annotation
|
|
@ -2,25 +2,25 @@
|
|||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\entity_reference\Plugin\Type\Selection\SelectionInterface.
|
||||
* Contains \Drupal\Core\Entity\EntityReferenceSelection\SelectionInterface.
|
||||
*/
|
||||
|
||||
namespace Drupal\entity_reference\Plugin\Type\Selection;
|
||||
namespace Drupal\Core\Entity\EntityReferenceSelection;
|
||||
|
||||
use Drupal\Core\Database\Query\SelectInterface;
|
||||
use Drupal\Core\Field\FieldDefinitionInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Plugin\PluginFormInterface;
|
||||
|
||||
/**
|
||||
* Interface definition for Entity Reference Selection plugins.
|
||||
*
|
||||
* @see \Drupal\entity_reference\Plugin\entity_reference\selection\SelectionBase
|
||||
* @see \Drupal\entity_reference\Plugin\Type\SelectionPluginManager
|
||||
* @see \Drupal\entity_reference\Annotation\EntityReferenceSelection
|
||||
* @see \Drupal\entity_reference\Plugin\Derivative\SelectionBase
|
||||
* @see \Drupal\Core\Entity\Plugin\EntityReferenceSelection\SelectionBase
|
||||
* @see \Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginManager
|
||||
* @see \Drupal\Core\Entity\Annotation\EntityReferenceSelection
|
||||
* @see \Drupal\Core\Entity\Plugin\Derivative\SelectionBase
|
||||
* @see plugin_api
|
||||
*/
|
||||
interface SelectionInterface {
|
||||
interface SelectionInterface extends PluginFormInterface {
|
||||
|
||||
/**
|
||||
* Returns a list of referenceable entities.
|
||||
|
@ -78,15 +78,4 @@ interface SelectionInterface {
|
|||
*/
|
||||
public function entityQueryAlter(SelectInterface $query);
|
||||
|
||||
/**
|
||||
* Generates the settings form for this selection.
|
||||
*
|
||||
* @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
|
||||
* The definition of the field to which the selection is associated.
|
||||
*
|
||||
* @return array
|
||||
* A Form API array.
|
||||
*/
|
||||
public static function settingsForm(FieldDefinitionInterface $field_definition);
|
||||
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginManager.
|
||||
*/
|
||||
|
||||
namespace Drupal\Core\Entity\EntityReferenceSelection;
|
||||
|
||||
use Drupal\Component\Plugin\FallbackPluginManagerInterface;
|
||||
use Drupal\Core\Cache\CacheBackendInterface;
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\Core\Field\FieldDefinitionInterface;
|
||||
use Drupal\Core\Extension\ModuleHandlerInterface;
|
||||
use Drupal\Core\Plugin\DefaultPluginManager;
|
||||
|
||||
/**
|
||||
* Plugin type manager for Entity Reference Selection plugins.
|
||||
*
|
||||
* @see \Drupal\Core\Entity\Annotation\EntityReferenceSelection
|
||||
* @see \Drupal\Core\Entity\EntityReferenceSelection\SelectionInterface
|
||||
* @see \Drupal\Core\Entity\Plugin\EntityReferenceSelection\SelectionBase
|
||||
* @see \Drupal\Core\Entity\Plugin\Derivative\SelectionBase
|
||||
* @see plugin_api
|
||||
*/
|
||||
class SelectionPluginManager extends DefaultPluginManager implements SelectionPluginManagerInterface, FallbackPluginManagerInterface {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) {
|
||||
$this->alterInfo('entity_reference_selection');
|
||||
$this->setCacheBackend($cache_backend, 'entity_reference_selection_plugins');
|
||||
|
||||
parent::__construct('Plugin/EntityReferenceSelection', $namespaces, $module_handler, 'Drupal\Core\Entity\EntityReferenceSelection\SelectionInterface', 'Drupal\Core\Entity\Annotation\EntityReferenceSelection');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getInstance(array $options) {
|
||||
if (!isset($options['target_type'])) {
|
||||
throw new \InvalidArgumentException("Missing required 'target_type' property for a EntityReferenceSelection plugin.");
|
||||
}
|
||||
|
||||
// Initialize default options.
|
||||
$options += array(
|
||||
'handler' => 'default',
|
||||
'handler_settings' => array(),
|
||||
);
|
||||
|
||||
// Get all available selection plugins for this entity type.
|
||||
$selection_handler_groups = $this->getSelectionGroups($options['target_type']);
|
||||
|
||||
// Sort the selection plugins by weight and select the best match.
|
||||
uasort($selection_handler_groups[$options['handler']], array('Drupal\Component\Utility\SortArray', 'sortByWeightElement'));
|
||||
end($selection_handler_groups[$options['handler']]);
|
||||
$plugin_id = key($selection_handler_groups[$options['handler']]);
|
||||
|
||||
return $this->createInstance($plugin_id, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getSelectionGroups($entity_type_id) {
|
||||
$plugins = array();
|
||||
$definitions = $this->getDefinitions();
|
||||
|
||||
// Do not display the 'broken' plugin in the UI.
|
||||
unset($definitions['broken']);
|
||||
|
||||
foreach ($definitions as $plugin_id => $plugin) {
|
||||
if (empty($plugin['entity_types']) || in_array($entity_type_id, $plugin['entity_types'])) {
|
||||
$plugins[$plugin['group']][$plugin_id] = $plugin;
|
||||
}
|
||||
}
|
||||
|
||||
return $plugins;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getSelectionHandler(FieldDefinitionInterface $field_definition, EntityInterface $entity = NULL) {
|
||||
$options = array(
|
||||
'target_type' => $field_definition->getFieldStorageDefinition()->getSetting('target_type'),
|
||||
'handler' => $field_definition->getSetting('handler'),
|
||||
'handler_settings' => $field_definition->getSetting('handler_settings'),
|
||||
'entity' => $entity,
|
||||
);
|
||||
return $this->getInstance($options);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFallbackPluginId($plugin_id, array $configuration = array()) {
|
||||
return 'broken';
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginManagerInterface.
|
||||
*/
|
||||
|
||||
namespace Drupal\Core\Entity\EntityReferenceSelection;
|
||||
|
||||
use Drupal\Component\Plugin\PluginManagerInterface;
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\Core\Field\FieldDefinitionInterface;
|
||||
|
||||
/**
|
||||
* Defines an interface for the entity reference selection plugin manager.
|
||||
*/
|
||||
interface SelectionPluginManagerInterface extends PluginManagerInterface {
|
||||
|
||||
/**
|
||||
* Returns selection plugins that can reference a specific entity type.
|
||||
*
|
||||
* @param string $entity_type_id
|
||||
* A Drupal entity type ID.
|
||||
*
|
||||
* @return array
|
||||
* An array of selection plugins grouped by selection group.
|
||||
*/
|
||||
public function getSelectionGroups($entity_type_id);
|
||||
|
||||
/**
|
||||
* Gets the selection handler for a given entity_reference field.
|
||||
*
|
||||
* @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
|
||||
* The field definition for the operation.
|
||||
* @param \Drupal\Core\Entity\EntityInterface $entity
|
||||
* (optional) The entity for the operation. Defaults to NULL.
|
||||
*
|
||||
* @return \Drupal\Core\Entity\EntityReferenceSelection\SelectionInterface
|
||||
* The selection plugin.
|
||||
*/
|
||||
public function getSelectionHandler(FieldDefinitionInterface $field_definition, EntityInterface $entity = NULL);
|
||||
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Core\Entity\Plugin\Derivative\SelectionBase.
|
||||
*/
|
||||
|
||||
namespace Drupal\Core\Entity\Plugin\Derivative;
|
||||
|
||||
use Drupal\Component\Plugin\Derivative\DeriverBase;
|
||||
use Drupal\Core\Entity\EntityManagerInterface;
|
||||
use Drupal\Core\Plugin\Discovery\ContainerDeriverInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Provides derivative plugins for Entity Reference Selection plugins.
|
||||
*
|
||||
* @see \Drupal\Core\Entity\Plugin\EntityReferenceSelection\SelectionBase
|
||||
* @see \Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginManager
|
||||
* @see \Drupal\Core\Entity\Annotation\EntityReferenceSelection
|
||||
* @see \Drupal\Core\Entity\EntityReferenceSelection\SelectionInterface
|
||||
* @see plugin_api
|
||||
*/
|
||||
class SelectionBase extends DeriverBase implements ContainerDeriverInterface {
|
||||
|
||||
/**
|
||||
* The entity manager
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityManagerInterface
|
||||
*/
|
||||
protected $entityManager;
|
||||
|
||||
/**
|
||||
* Creates an SelectionBase object.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
|
||||
* The entity manager.
|
||||
*/
|
||||
public function __construct(EntityManagerInterface $entity_manager) {
|
||||
$this->entityManager = $entity_manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container, $base_plugin_id) {
|
||||
return new static(
|
||||
$container->get('entity.manager')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDerivativeDefinitions($base_plugin_definition) {
|
||||
foreach ($this->entityManager->getDefinitions() as $entity_type_id => $entity_type) {
|
||||
$this->derivatives[$entity_type_id] = $base_plugin_definition;
|
||||
$this->derivatives[$entity_type_id]['entity_types'] = array($entity_type_id);
|
||||
$this->derivatives[$entity_type_id]['label'] = t('@entity_type selection', array('@entity_type' => $entity_type->getLabel()));
|
||||
$this->derivatives[$entity_type_id]['base_plugin_label'] = (string) $base_plugin_definition['label'];
|
||||
}
|
||||
return parent::getDerivativeDefinitions($base_plugin_definition);
|
||||
}
|
||||
|
||||
}
|
|
@ -2,12 +2,13 @@
|
|||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\entity_reference\Plugin\Type\Selection\SelectionBroken.
|
||||
* Contains \Drupal\Core\Entity\Plugin\EntityReferenceSelection\SelectionBroken.
|
||||
*/
|
||||
|
||||
namespace Drupal\entity_reference\Plugin\Type\Selection;
|
||||
namespace Drupal\Core\Entity\Plugin\EntityReferenceSelection;
|
||||
|
||||
use Drupal\Core\Database\Query\SelectInterface;
|
||||
use Drupal\Core\Entity\EntityReferenceSelection\SelectionInterface;
|
||||
use Drupal\Core\Field\FieldDefinitionInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
|
||||
|
@ -19,18 +20,28 @@ use Drupal\Core\Form\FormStateInterface;
|
|||
* label = @Translation("Broken/Missing")
|
||||
* )
|
||||
*/
|
||||
class SelectionBroken implements SelectionInterface {
|
||||
class Broken implements SelectionInterface {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function settingsForm(FieldDefinitionInterface $field_definition) {
|
||||
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
|
||||
$form['selection_handler'] = array(
|
||||
'#markup' => t('The selected selection handler is broken.'),
|
||||
);
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function validateConfigurationForm(array &$form, FormStateInterface $form_state) { }
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitConfigurationForm(array &$form, FormStateInterface $form_state) { }
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
|
@ -2,18 +2,22 @@
|
|||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\entity_reference\Plugin\entity_reference\selection\SelectionBase.
|
||||
* Contains \Drupal\Core\Entity\Plugin\EntityReferenceSelection\SelectionBase.
|
||||
*/
|
||||
|
||||
namespace Drupal\entity_reference\Plugin\entity_reference\selection;
|
||||
namespace Drupal\Core\Entity\Plugin\EntityReferenceSelection;
|
||||
|
||||
use Drupal\Component\Utility\String;
|
||||
use Drupal\Core\Database\Query\AlterableInterface;
|
||||
use Drupal\Core\Database\Query\SelectInterface;
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\Core\Field\FieldDefinitionInterface;
|
||||
use Drupal\Core\Entity\EntityManagerInterface;
|
||||
use Drupal\Core\Extension\ModuleHandlerInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\entity_reference\Plugin\Type\Selection\SelectionInterface;
|
||||
use Drupal\Core\Entity\EntityReferenceSelection\SelectionInterface;
|
||||
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
|
||||
use Drupal\Core\Plugin\PluginBase;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Default plugin implementation of the Entity Reference Selection plugin.
|
||||
|
@ -21,10 +25,10 @@ use Drupal\entity_reference\Plugin\Type\Selection\SelectionInterface;
|
|||
* Also serves as a base class for specific types of Entity Reference
|
||||
* Selection plugins.
|
||||
*
|
||||
* @see \Drupal\entity_reference\Plugin\Type\SelectionPluginManager
|
||||
* @see \Drupal\entity_reference\Annotation\EntityReferenceSelection
|
||||
* @see \Drupal\entity_reference\Plugin\Type\Selection\SelectionInterface
|
||||
* @see \Drupal\entity_reference\Plugin\Derivative\SelectionBase
|
||||
* @see \Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginManager
|
||||
* @see \Drupal\Core\Entity\Annotation\EntityReferenceSelection
|
||||
* @see \Drupal\Core\Entity\EntityReferenceSelection\SelectionInterface
|
||||
* @see \Drupal\Core\Entity\Plugin\Derivative\SelectionBase
|
||||
* @see plugin_api
|
||||
*
|
||||
* @EntityReferenceSelection(
|
||||
|
@ -32,42 +36,78 @@ use Drupal\entity_reference\Plugin\Type\Selection\SelectionInterface;
|
|||
* label = @Translation("Default"),
|
||||
* group = "default",
|
||||
* weight = 0,
|
||||
* deriver = "Drupal\entity_reference\Plugin\Derivative\SelectionBase"
|
||||
* deriver = "Drupal\Core\Entity\Plugin\Derivative\SelectionBase"
|
||||
* )
|
||||
*/
|
||||
class SelectionBase implements SelectionInterface {
|
||||
class SelectionBase extends PluginBase implements SelectionInterface, ContainerFactoryPluginInterface {
|
||||
|
||||
/**
|
||||
* The field definition.
|
||||
* The entity manager.
|
||||
*
|
||||
* @var \Drupal\Core\Field\FieldDefinitionInterface
|
||||
* @var \Drupal\Core\Entity\EntityManagerInterface
|
||||
*/
|
||||
protected $fieldDefinition;
|
||||
protected $entityManager;
|
||||
|
||||
/**
|
||||
* The entity object, or NULL
|
||||
* The module handler service.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityInterface|null
|
||||
* @var \Drupal\Core\Extension\ModuleHandlerInterface
|
||||
*/
|
||||
protected $entity;
|
||||
protected $moduleHandler;
|
||||
|
||||
/**
|
||||
* Constructs a SelectionBase object.
|
||||
* The current user.
|
||||
*
|
||||
* @var \Drupal\Core\Session\AccountInterface
|
||||
*/
|
||||
public function __construct(FieldDefinitionInterface $field_definition, EntityInterface $entity = NULL) {
|
||||
$this->fieldDefinition = $field_definition;
|
||||
$this->entity = $entity;
|
||||
protected $currentUser;
|
||||
|
||||
/**
|
||||
* Constructs a new SelectionBase object.
|
||||
*
|
||||
* @param array $configuration
|
||||
* A configuration array containing information about the plugin instance.
|
||||
* @param string $plugin_id
|
||||
* The plugin_id for the plugin instance.
|
||||
* @param mixed $plugin_definition
|
||||
* The plugin implementation definition.
|
||||
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
|
||||
* The entity manager service.
|
||||
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
|
||||
* The module handler service.
|
||||
* @param \Drupal\Core\Session\AccountInterface $current_user
|
||||
* The current user.
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityManagerInterface $entity_manager, ModuleHandlerInterface $module_handler, AccountInterface $current_user) {
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition);
|
||||
|
||||
$this->entityManager = $entity_manager;
|
||||
$this->moduleHandler = $module_handler;
|
||||
$this->currentUser = $current_user;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function settingsForm(FieldDefinitionInterface $field_definition) {
|
||||
$entity_manager = \Drupal::entityManager();
|
||||
$entity_type_id = $field_definition->getSetting('target_type');
|
||||
$selection_handler_settings = $field_definition->getSetting('handler_settings') ?: array();
|
||||
$entity_type = $entity_manager->getDefinition($entity_type_id);
|
||||
$bundles = $entity_manager->getBundleInfo($entity_type_id);
|
||||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
|
||||
return new static(
|
||||
$configuration,
|
||||
$plugin_id,
|
||||
$plugin_definition,
|
||||
$container->get('entity.manager'),
|
||||
$container->get('module_handler'),
|
||||
$container->get('current_user')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
|
||||
$entity_type_id = $this->configuration['target_type'];
|
||||
$selection_handler_settings = $this->configuration['handler_settings'];
|
||||
$entity_type = $this->entityManager->getDefinition($entity_type_id);
|
||||
$bundles = $this->entityManager->getBundleInfo($entity_type_id);
|
||||
|
||||
// Merge-in default values.
|
||||
$selection_handler_settings += array(
|
||||
|
@ -84,13 +124,13 @@ class SelectionBase implements SelectionInterface {
|
|||
$bundle_options[$bundle_name] = $bundle_info['label'];
|
||||
}
|
||||
|
||||
$target_bundles_title = t('Bundles');
|
||||
$target_bundles_title = $this->t('Bundles');
|
||||
// Default core entity types with sensible labels.
|
||||
if ($entity_type_id == 'node') {
|
||||
$target_bundles_title = t('Content types');
|
||||
$target_bundles_title = $this->t('Content types');
|
||||
}
|
||||
elseif ($entity_type_id == 'taxonomy_term') {
|
||||
$target_bundles_title = t('Vocabularies');
|
||||
$target_bundles_title = $this->t('Vocabularies');
|
||||
}
|
||||
|
||||
$form['target_bundles'] = array(
|
||||
|
@ -114,7 +154,7 @@ class SelectionBase implements SelectionInterface {
|
|||
if ($entity_type->isSubclassOf('\Drupal\Core\Entity\FieldableEntityInterface')) {
|
||||
$fields = array();
|
||||
foreach (array_keys($bundles) as $bundle) {
|
||||
$bundle_fields = array_filter($entity_manager->getFieldDefinitions($entity_type_id, $bundle), function ($field_definition) {
|
||||
$bundle_fields = array_filter($this->entityManager->getFieldDefinitions($entity_type_id, $bundle), function ($field_definition) {
|
||||
return !$field_definition->isComputed();
|
||||
});
|
||||
foreach ($bundle_fields as $field_name => $field_definition) {
|
||||
|
@ -125,20 +165,20 @@ class SelectionBase implements SelectionInterface {
|
|||
// @todo: Use property labels instead of the column name.
|
||||
if (count($columns) > 1) {
|
||||
foreach ($columns as $column_name => $column_info) {
|
||||
$fields[$field_name . '.' . $column_name] = t('@label (@column)', array('@label' => $field_definition->getLabel(), '@column' => $column_name));
|
||||
$fields[$field_name . '.' . $column_name] = $this->t('@label (@column)', array('@label' => $field_definition->getLabel(), '@column' => $column_name));
|
||||
}
|
||||
}
|
||||
else {
|
||||
$fields[$field_name] = t('@label', array('@label' => $field_definition->getLabel()));
|
||||
$fields[$field_name] = $this->t('@label', array('@label' => $field_definition->getLabel()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$form['sort']['field'] = array(
|
||||
'#type' => 'select',
|
||||
'#title' => t('Sort by'),
|
||||
'#title' => $this->t('Sort by'),
|
||||
'#options' => array(
|
||||
'_none' => t('- None -'),
|
||||
'_none' => $this->t('- None -'),
|
||||
) + $fields,
|
||||
'#ajax' => TRUE,
|
||||
'#limit_validation_errors' => array(),
|
||||
|
@ -159,11 +199,11 @@ class SelectionBase implements SelectionInterface {
|
|||
|
||||
$form['sort']['settings']['direction'] = array(
|
||||
'#type' => 'select',
|
||||
'#title' => t('Sort direction'),
|
||||
'#title' => $this->t('Sort direction'),
|
||||
'#required' => TRUE,
|
||||
'#options' => array(
|
||||
'ASC' => t('Ascending'),
|
||||
'DESC' => t('Descending'),
|
||||
'ASC' => $this->t('Ascending'),
|
||||
'DESC' => $this->t('Descending'),
|
||||
),
|
||||
'#default_value' => $selection_handler_settings['sort']['direction'],
|
||||
);
|
||||
|
@ -173,11 +213,21 @@ class SelectionBase implements SelectionInterface {
|
|||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function validateConfigurationForm(array &$form, FormStateInterface $form_state) { }
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitConfigurationForm(array &$form, FormStateInterface $form_state) { }
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getReferenceableEntities($match = NULL, $match_operator = 'CONTAINS', $limit = 0) {
|
||||
$target_type = $this->fieldDefinition->getSetting('target_type');
|
||||
$target_type = $this->configuration['target_type'];
|
||||
|
||||
$query = $this->buildEntityQuery($match, $match_operator);
|
||||
if ($limit > 0) {
|
||||
|
@ -216,8 +266,8 @@ class SelectionBase implements SelectionInterface {
|
|||
public function validateReferenceableEntities(array $ids) {
|
||||
$result = array();
|
||||
if ($ids) {
|
||||
$target_type = $this->fieldDefinition->getSetting('target_type');
|
||||
$entity_type = \Drupal::entityManager()->getDefinition($target_type);
|
||||
$target_type = $this->configuration['target_type'];
|
||||
$entity_type = $this->entityManager->getDefinition($target_type);
|
||||
$query = $this->buildEntityQuery();
|
||||
$result = $query
|
||||
->condition($entity_type->getKey('id'), $ids, 'IN')
|
||||
|
@ -243,13 +293,13 @@ class SelectionBase implements SelectionInterface {
|
|||
if (empty($entities)) {
|
||||
if ($strict) {
|
||||
// Error if there are no entities available for a required field.
|
||||
$form_state->setError($element, t('There are no entities matching "%value".', $params));
|
||||
$form_state->setError($element, $this->t('There are no entities matching "%value".', $params));
|
||||
}
|
||||
}
|
||||
elseif (count($entities) > 5) {
|
||||
$params['@id'] = key($entities);
|
||||
// Error if there are more than 5 matching entities.
|
||||
$form_state->setError($element, t('Many entities are called %value. Specify the one you want by appending the id in parentheses, like "@value (@id)".', $params));
|
||||
$form_state->setError($element, $this->t('Many entities are called %value. Specify the one you want by appending the id in parentheses, like "@value (@id)".', $params));
|
||||
}
|
||||
elseif (count($entities) > 1) {
|
||||
// More helpful error if there are only a few matching entities.
|
||||
|
@ -258,7 +308,7 @@ class SelectionBase implements SelectionInterface {
|
|||
$multiples[] = $name . ' (' . $id . ')';
|
||||
}
|
||||
$params['@id'] = $id;
|
||||
$form_state->setError($element, t('Multiple entities match this reference; "%multiple". Specify the one you want by appending the id in parentheses, like "@value (@id)".', array('%multiple' => implode('", "', $multiples))));
|
||||
$form_state->setError($element, $this->t('Multiple entities match this reference; "%multiple". Specify the one you want by appending the id in parentheses, like "@value (@id)".', array('%multiple' => implode('", "', $multiples))));
|
||||
}
|
||||
else {
|
||||
// Take the one and only matching entity.
|
||||
|
@ -280,11 +330,11 @@ class SelectionBase implements SelectionInterface {
|
|||
* it.
|
||||
*/
|
||||
public function buildEntityQuery($match = NULL, $match_operator = 'CONTAINS') {
|
||||
$target_type = $this->fieldDefinition->getSetting('target_type');
|
||||
$handler_settings = $this->fieldDefinition->getSetting('handler_settings');
|
||||
$entity_type = \Drupal::entityManager()->getDefinition($target_type);
|
||||
$target_type = $this->configuration['target_type'];
|
||||
$handler_settings = $this->configuration['handler_settings'];
|
||||
$entity_type = $this->entityManager->getDefinition($target_type);
|
||||
|
||||
$query = \Drupal::entityQuery($target_type);
|
||||
$query = $this->entityManager->getStorage($target_type)->getQuery();
|
||||
if (!empty($handler_settings['target_bundles'])) {
|
||||
$query->condition($entity_type->getKey('bundle'), $handler_settings['target_bundles'], 'IN');
|
||||
}
|
||||
|
@ -294,16 +344,14 @@ class SelectionBase implements SelectionInterface {
|
|||
}
|
||||
|
||||
// Add entity-access tag.
|
||||
$query->addTag($this->fieldDefinition->getSetting('target_type') . '_access');
|
||||
$query->addTag($target_type . '_access');
|
||||
|
||||
// Add the Selection handler for
|
||||
// entity_reference_query_entity_reference_alter().
|
||||
$query->addTag('entity_reference');
|
||||
$query->addMetaData('field_definition', $this->fieldDefinition);
|
||||
$query->addMetaData('entity_reference_selection_handler', $this);
|
||||
|
||||
// Add the sort option.
|
||||
$handler_settings = $this->fieldDefinition->getSetting('handler_settings');
|
||||
if (!empty($handler_settings['sort'])) {
|
||||
$sort_settings = $handler_settings['sort'];
|
||||
if ($sort_settings['field'] != '_none') {
|
||||
|
@ -333,10 +381,11 @@ class SelectionBase implements SelectionInterface {
|
|||
|
||||
$query->alterTags = array($tag => TRUE);
|
||||
$query->alterMetaData['base_table'] = $base_table;
|
||||
\Drupal::moduleHandler()->alter(array('query', 'query_' . $tag), $query);
|
||||
$this->moduleHandler->alter(array('query', 'query_' . $tag), $query);
|
||||
|
||||
// Restore the tags and metadata.
|
||||
$query->alterTags = $old_tags;
|
||||
$query->alterMetaData = $old_metadata;
|
||||
}
|
||||
|
||||
}
|
|
@ -243,7 +243,7 @@ class EntityReferenceItem extends FieldItemBase {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public static function generateSampleValue(FieldDefinitionInterface $field_definition) {
|
||||
$manager = \Drupal::service('plugin.manager.entity_reference.selection');
|
||||
$manager = \Drupal::service('plugin.manager.entity_reference_selection');
|
||||
if ($referenceable = $manager->getSelectionHandler($field_definition)->getReferenceableEntities()) {
|
||||
$group = array_rand($referenceable);
|
||||
$values['target_id'] = array_rand($referenceable[$group]);
|
||||
|
|
|
@ -2,20 +2,20 @@
|
|||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\comment\Plugin\entity_reference\selection\CommentSelection.
|
||||
* Contains \Drupal\comment\Plugin\EntityReferenceSelection\CommentSelection.
|
||||
*/
|
||||
|
||||
namespace Drupal\comment\Plugin\entity_reference\selection;
|
||||
namespace Drupal\comment\Plugin\EntityReferenceSelection;
|
||||
|
||||
use Drupal\Core\Database\Query\SelectInterface;
|
||||
use Drupal\Core\Entity\Plugin\EntityReferenceSelection\SelectionBase;
|
||||
use Drupal\comment\CommentInterface;
|
||||
use Drupal\entity_reference\Plugin\entity_reference\selection\SelectionBase;
|
||||
|
||||
/**
|
||||
* Provides specific access control for the comment entity type.
|
||||
*
|
||||
* @EntityReferenceSelection(
|
||||
* id = "comment_default",
|
||||
* id = "default:comment",
|
||||
* label = @Translation("Comment selection"),
|
||||
* entity_types = {"comment"},
|
||||
* group = "default",
|
||||
|
@ -33,7 +33,7 @@ class CommentSelection extends SelectionBase {
|
|||
// Adding the 'comment_access' tag is sadly insufficient for comments:
|
||||
// core requires us to also know about the concept of 'published' and
|
||||
// 'unpublished'.
|
||||
if (!\Drupal::currentUser()->hasPermission('administer comments')) {
|
||||
if (!$this->currentUser->hasPermission('administer comments')) {
|
||||
$query->condition('status', CommentInterface::PUBLISHED);
|
||||
}
|
||||
return $query;
|
||||
|
@ -61,8 +61,9 @@ class CommentSelection extends SelectionBase {
|
|||
// Passing the query to node_query_node_access_alter() is sadly
|
||||
// insufficient for nodes.
|
||||
// @see SelectionEntityTypeNode::entityQueryAlter()
|
||||
if (!\Drupal::currentUser()->hasPermission('bypass node access') && !count(\Drupal::moduleHandler()->getImplementations('node_grants'))) {
|
||||
if (!$this->currentUser->hasPermission('bypass node access') && !count($this->moduleHandler->getImplementations('node_grants'))) {
|
||||
$query->condition($node_alias . '.status', 1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -201,7 +201,7 @@ function entity_reference_query_entity_reference_alter(AlterableInterface $query
|
|||
* @param int $cardinality
|
||||
* The cardinality of the field.
|
||||
*
|
||||
* @see \Drupal\entity_reference\Plugin\entity_reference\selection\SelectionBase::settingsForm()
|
||||
* @see \Drupal\Core\Entity\Plugin\EntityReferenceSelection\SelectionBase::buildConfigurationForm()
|
||||
*/
|
||||
function entity_reference_create_field($entity_type, $bundle, $field_name, $field_label, $target_entity_type, $selection_handler = 'default', $selection_handler_settings = array(), $cardinality = 1) {
|
||||
// Look for or add the specified field to the requested entity bundle.
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
services:
|
||||
plugin.manager.entity_reference.selection:
|
||||
class: Drupal\entity_reference\Plugin\Type\SelectionPluginManager
|
||||
parent: default_plugin_manager
|
||||
entity_reference.autocomplete:
|
||||
class: Drupal\entity_reference\EntityReferenceAutocomplete
|
||||
arguments: ['@entity.manager', '@plugin.manager.entity_reference.selection']
|
||||
arguments: ['@entity.manager', '@plugin.manager.entity_reference_selection']
|
||||
|
|
|
@ -80,7 +80,7 @@ class ConfigurableEntityReferenceItem extends EntityReferenceItem implements Opt
|
|||
*/
|
||||
public function getSettableOptions(AccountInterface $account = NULL) {
|
||||
$field_definition = $this->getFieldDefinition();
|
||||
if (!$options = \Drupal::service('plugin.manager.entity_reference.selection')->getSelectionHandler($field_definition, $this->getEntity())->getReferenceableEntities()) {
|
||||
if (!$options = \Drupal::service('plugin.manager.entity_reference_selection')->getSelectionHandler($field_definition, $this->getEntity())->getReferenceableEntities()) {
|
||||
return array();
|
||||
}
|
||||
|
||||
|
@ -138,17 +138,18 @@ class ConfigurableEntityReferenceItem extends EntityReferenceItem implements Opt
|
|||
$field = $form_state->get('field');
|
||||
|
||||
// Get all selection plugins for this entity type.
|
||||
$selection_plugins = \Drupal::service('plugin.manager.entity_reference.selection')->getSelectionGroups($this->getSetting('target_type'));
|
||||
$handler_groups = array_keys($selection_plugins);
|
||||
|
||||
$handlers = \Drupal::service('plugin.manager.entity_reference.selection')->getDefinitions();
|
||||
$selection_plugins = \Drupal::service('plugin.manager.entity_reference_selection')->getSelectionGroups($this->getSetting('target_type'));
|
||||
$handlers_options = array();
|
||||
foreach ($handlers as $plugin_id => $plugin) {
|
||||
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',
|
||||
// entity type specific plugins (e.g. 'default:node', 'default:user',
|
||||
// ...).
|
||||
if (in_array($plugin_id, $handler_groups)) {
|
||||
$handlers_options[$plugin_id] = String::checkPlain($plugin['label']);
|
||||
if (array_key_exists($selection_group_id, $selection_plugins[$selection_group_id])) {
|
||||
$handlers_options[$selection_group_id] = String::checkPlain($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_id] = String::checkPlain($selection_plugins[$selection_group_id][$selection_group_plugin]['base_plugin_label']);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -191,8 +192,8 @@ class ConfigurableEntityReferenceItem extends EntityReferenceItem implements Opt
|
|||
'#attributes' => array('class' => array('entity_reference-settings')),
|
||||
);
|
||||
|
||||
$handler = \Drupal::service('plugin.manager.entity_reference.selection')->getSelectionHandler($field);
|
||||
$form['handler']['handler_settings'] += $handler->settingsForm($field);
|
||||
$handler = \Drupal::service('plugin.manager.entity_reference_selection')->getSelectionHandler($field);
|
||||
$form['handler']['handler_settings'] += $handler->buildConfigurationForm(array(), $form_state);
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
@ -209,6 +210,9 @@ class ConfigurableEntityReferenceItem extends EntityReferenceItem implements Opt
|
|||
if ($form_state->hasValue('field')) {
|
||||
$form_state->unsetValue(array('field', 'settings', 'handler_submit'));
|
||||
$form_state->get('field')->settings = $form_state->getValue(['field', 'settings']);
|
||||
|
||||
$handler = \Drupal::service('plugin.manager.entity_reference_selection')->getSelectionHandler($form_state->get('field'));
|
||||
$handler->validateConfigurationForm($form, $form_state);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,9 +10,8 @@ namespace Drupal\entity_reference;
|
|||
use Drupal\Component\Utility\String;
|
||||
use Drupal\Component\Utility\Tags;
|
||||
use Drupal\Core\Entity\EntityManagerInterface;
|
||||
use Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginManagerInterface;
|
||||
use Drupal\Core\Field\FieldDefinitionInterface;
|
||||
use Drupal\entity_reference\Plugin\Type\SelectionPluginManager;
|
||||
use Drupal\field\FieldConfigInterface;
|
||||
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
||||
|
||||
/**
|
||||
|
@ -30,7 +29,7 @@ class EntityReferenceAutocomplete {
|
|||
/**
|
||||
* The Entity reference selection handler plugin manager.
|
||||
*
|
||||
* @var \Drupal\entity_reference\Plugin\Type\SelectionPluginManager
|
||||
* @var \Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginManagerInterface
|
||||
*/
|
||||
protected $selectionHandlerManager;
|
||||
|
||||
|
@ -39,10 +38,10 @@ class EntityReferenceAutocomplete {
|
|||
*
|
||||
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
|
||||
* The entity manager.
|
||||
* @param \Drupal\entity_reference\Plugin\Type\SelectionPluginManager $selection_manager
|
||||
* @param \Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginManagerInterface $selection_manager
|
||||
* The Entity reference selection handler plugin manager.
|
||||
*/
|
||||
public function __construct(EntityManagerInterface $entity_manager, SelectionPluginManager $selection_manager) {
|
||||
public function __construct(EntityManagerInterface $entity_manager, SelectionPluginManagerInterface $selection_manager) {
|
||||
$this->entityManager = $entity_manager;
|
||||
$this->selectionHandlerManager = $selection_manager;
|
||||
}
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\entity_reference\Plugin\Derivative\SelectionBase.
|
||||
*/
|
||||
|
||||
namespace Drupal\entity_reference\Plugin\Derivative;
|
||||
|
||||
use Drupal\Component\Plugin\Derivative\DeriverBase;
|
||||
|
||||
/**
|
||||
* Provides derivative plugins for Entity Reference Selection plugins.
|
||||
*
|
||||
* @see \Drupal\entity_reference\Plugin\entity_reference\selection\SelectionBase
|
||||
* @see \Drupal\entity_reference\Plugin\Type\SelectionPluginManager
|
||||
* @see \Drupal\entity_reference\Annotation\EntityReferenceSelection
|
||||
* @see \Drupal\entity_reference\Plugin\Type\Selection\SelectionInterface
|
||||
* @see plugin_api
|
||||
*/
|
||||
class SelectionBase extends DeriverBase {
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDerivativeDefinitions($base_plugin_definition) {
|
||||
$supported_entities = array(
|
||||
'comment',
|
||||
'file',
|
||||
'node',
|
||||
'taxonomy_term',
|
||||
'user'
|
||||
);
|
||||
foreach (\Drupal::entityManager()->getDefinitions() as $entity_type_id => $entity_type) {
|
||||
if (!in_array($entity_type_id, $supported_entities)) {
|
||||
$this->derivatives[$entity_type_id] = $base_plugin_definition;
|
||||
$this->derivatives[$entity_type_id]['label'] = t('@entity_type selection', array('@entity_type' => $entity_type->getLabel()));
|
||||
}
|
||||
}
|
||||
return parent::getDerivativeDefinitions($base_plugin_definition);
|
||||
}
|
||||
}
|
|
@ -44,7 +44,7 @@ class AutocompleteTagsWidget extends AutocompleteWidgetBase {
|
|||
public function elementValidate($element, FormStateInterface $form_state, $form) {
|
||||
$value = array();
|
||||
// If a value was entered into the autocomplete.
|
||||
$handler = \Drupal::service('plugin.manager.entity_reference.selection')->getSelectionHandler($this->fieldDefinition);
|
||||
$handler = \Drupal::service('plugin.manager.entity_reference_selection')->getSelectionHandler($this->fieldDefinition);
|
||||
$bundles = entity_get_bundles($this->getFieldSetting('target_type'));
|
||||
$auto_create = $this->getSelectionHandlerSetting('auto_create');
|
||||
|
||||
|
|
|
@ -64,7 +64,7 @@ class AutocompleteWidget extends AutocompleteWidgetBase {
|
|||
if ($value === NULL) {
|
||||
// Try to get a match from the input string when the user didn't use the
|
||||
// autocomplete but filled in a value manually.
|
||||
$handler = \Drupal::service('plugin.manager.entity_reference.selection')->getSelectionHandler($this->fieldDefinition);
|
||||
$handler = \Drupal::service('plugin.manager.entity_reference_selection')->getSelectionHandler($this->fieldDefinition);
|
||||
$value = $handler->validateAutocompleteInput($element['#value'], $element, $form_state, $form, !$auto_create);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,115 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\entity_reference\Plugin\Type\SelectionPluginManager.
|
||||
*/
|
||||
|
||||
namespace Drupal\entity_reference\Plugin\Type;
|
||||
|
||||
use Drupal\Component\Plugin\Factory\ReflectionFactory;
|
||||
use Drupal\Component\Plugin\FallbackPluginManagerInterface;
|
||||
use Drupal\Core\Cache\CacheBackendInterface;
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\Core\Field\FieldDefinitionInterface;
|
||||
use Drupal\Core\Extension\ModuleHandlerInterface;
|
||||
use Drupal\Core\Plugin\DefaultPluginManager;
|
||||
use Drupal\Core\Plugin\Discovery\AnnotatedClassDiscovery;
|
||||
|
||||
/**
|
||||
* Plugin type manager for Entity Reference Selection plugins.
|
||||
*
|
||||
* @see \Drupal\entity_reference\Annotation\EntityReferenceSelection
|
||||
* @see \Drupal\entity_reference\Plugin\Type\Selection\SelectionInterface
|
||||
* @see \Drupal\entity_reference\Plugin\entity_reference\selection\SelectionBase
|
||||
* @see \Drupal\entity_reference\Plugin\Derivative\SelectionBase
|
||||
* @see plugin_api
|
||||
*/
|
||||
class SelectionPluginManager extends DefaultPluginManager implements FallbackPluginManagerInterface {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) {
|
||||
$this->discovery = new AnnotatedClassDiscovery('Plugin/entity_reference/selection', $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, '\Drupal\entity_reference\Plugin\Type\Selection\SelectionInterface');
|
||||
|
||||
$this->moduleHandler = $module_handler;
|
||||
$this->alterInfo('entity_reference_selection');
|
||||
$this->setCacheBackend($cache_backend, 'entity_reference_selection_plugins');
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides \Drupal\Component\Plugin\PluginManagerBase::getInstance().
|
||||
*/
|
||||
public function getInstance(array $options) {
|
||||
$selection_handler = $options['field_definition']->getSetting('handler');
|
||||
$target_entity_type = $options['field_definition']->getSetting('target_type');
|
||||
|
||||
// Get all available selection plugins for this entity type.
|
||||
$selection_handler_groups = $this->getSelectionGroups($target_entity_type);
|
||||
|
||||
// Sort the selection plugins by weight and select the best match.
|
||||
uasort($selection_handler_groups[$selection_handler], array('Drupal\Component\Utility\SortArray', 'sortByWeightElement'));
|
||||
end($selection_handler_groups[$selection_handler]);
|
||||
$plugin_id = key($selection_handler_groups[$selection_handler]);
|
||||
|
||||
return $this->createInstance($plugin_id, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of selection plugins that can reference a specific entity
|
||||
* type.
|
||||
*
|
||||
* @param string $entity_type
|
||||
* A Drupal entity type.
|
||||
*
|
||||
* @return array
|
||||
* An array of selection plugins grouped by selection group.
|
||||
*/
|
||||
public function getSelectionGroups($entity_type) {
|
||||
$plugins = array();
|
||||
$definitions = $this->getDefinitions();
|
||||
|
||||
// Do not display the 'broken' plugin in the UI.
|
||||
unset($definitions['broken']);
|
||||
|
||||
foreach ($definitions as $plugin_id => $plugin) {
|
||||
if (empty($plugin['entity_types']) || in_array($entity_type, $plugin['entity_types'])) {
|
||||
$plugins[$plugin['group']][$plugin_id] = $plugin;
|
||||
}
|
||||
}
|
||||
|
||||
return $plugins;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the selection handler for a given entity_reference field.
|
||||
*
|
||||
* @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
|
||||
* The field definition for the operation.
|
||||
* @param \Drupal\Core\Entity\EntityInterface $entity
|
||||
* The entity for the operation.
|
||||
*
|
||||
* @return \Drupal\entity_reference\Plugin\Type\Selection\SelectionInterface
|
||||
* The selection plugin.
|
||||
*/
|
||||
public function getSelectionHandler(FieldDefinitionInterface $field_definition, EntityInterface $entity = NULL) {
|
||||
$options = array(
|
||||
'field_definition' => $field_definition,
|
||||
'entity' => $entity,
|
||||
);
|
||||
return $this->getInstance($options);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFallbackPluginId($plugin_id, array $configuration = array()) {
|
||||
return 'broken';
|
||||
}
|
||||
|
||||
}
|
|
@ -118,6 +118,26 @@ class EntityReferenceAdminTest extends WebTestBase {
|
|||
// The first 'Edit' link is for the Body field.
|
||||
$this->clickLink(t('Edit'), 1);
|
||||
$this->drupalPostForm(NULL, array(), t('Save settings'));
|
||||
|
||||
// Switch the target type to 'taxonomy_term' and check that the settings
|
||||
// specific to its selection handler are displayed.
|
||||
$field_name = 'node.' . $this->type . '.field_test';
|
||||
$edit = array(
|
||||
'field_storage[settings][target_type]' => 'taxonomy_term',
|
||||
);
|
||||
$this->drupalPostForm($bundle_path . '/fields/' . $field_name . '/storage', $edit, t('Save field settings'));
|
||||
$this->drupalGet($bundle_path . '/fields/' . $field_name);
|
||||
$this->assertFieldByName('field[settings][handler_settings][auto_create]');
|
||||
|
||||
// Switch the target type to 'user' and check that the settings specific to
|
||||
// its selection handler are displayed.
|
||||
$field_name = 'node.' . $this->type . '.field_test';
|
||||
$edit = array(
|
||||
'field_storage[settings][target_type]' => 'user',
|
||||
);
|
||||
$this->drupalPostForm($bundle_path . '/fields/' . $field_name . '/storage', $edit, t('Save field settings'));
|
||||
$this->drupalGet($bundle_path . '/fields/' . $field_name);
|
||||
$this->assertFieldByName('field[settings][handler_settings][filter][type]', '_none');
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -103,7 +103,7 @@ class SelectionTest extends WebTestBase {
|
|||
*/
|
||||
public function testSelectionHandler() {
|
||||
// Get values from selection handler.
|
||||
$handler = $this->container->get('plugin.manager.entity_reference.selection')->getSelectionHandler($this->field);
|
||||
$handler = $this->container->get('plugin.manager.entity_reference_selection')->getSelectionHandler($this->field);
|
||||
$result = $handler->getReferenceableEntities();
|
||||
$this->assertResults($result);
|
||||
}
|
||||
|
@ -140,7 +140,7 @@ class SelectionTest extends WebTestBase {
|
|||
$view->save();
|
||||
|
||||
// Get values from the selection handler.
|
||||
$handler = $this->container->get('plugin.manager.entity_reference.selection')->getSelectionHandler($this->field);
|
||||
$handler = $this->container->get('plugin.manager.entity_reference_selection')->getSelectionHandler($this->field);
|
||||
$result = $handler->getReferenceableEntities();
|
||||
$this->assertResults($result);
|
||||
}
|
||||
|
|
|
@ -2,18 +2,18 @@
|
|||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\file\Plugin\Type\selection\FileSelection.
|
||||
* Contains \Drupal\file\Plugin\EntityReferenceSelection\FileSelection.
|
||||
*/
|
||||
|
||||
namespace Drupal\file\Plugin\entity_reference\selection;
|
||||
namespace Drupal\file\Plugin\EntityReferenceSelection;
|
||||
|
||||
use Drupal\entity_reference\Plugin\entity_reference\selection\SelectionBase;
|
||||
use Drupal\Core\Entity\Plugin\EntityReferenceSelection\SelectionBase;
|
||||
|
||||
/**
|
||||
* Provides specific access control for the file entity type.
|
||||
*
|
||||
* @EntityReferenceSelection(
|
||||
* id = "file_default",
|
||||
* id = "default:file",
|
||||
* label = @Translation("File selection"),
|
||||
* entity_types = {"file"},
|
||||
* group = "default",
|
||||
|
@ -30,4 +30,5 @@ class FileSelection extends SelectionBase {
|
|||
$query->condition('status', FILE_STATUS_PERMANENT);
|
||||
return $query;
|
||||
}
|
||||
|
||||
}
|
|
@ -2,18 +2,18 @@
|
|||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\node\Plugin\Type\selection\NodeSelection.
|
||||
* Contains \Drupal\node\Plugin\EntityReferenceSelection\NodeSelection.
|
||||
*/
|
||||
|
||||
namespace Drupal\node\Plugin\entity_reference\selection;
|
||||
namespace Drupal\node\Plugin\EntityReferenceSelection;
|
||||
|
||||
use Drupal\entity_reference\Plugin\entity_reference\selection\SelectionBase;
|
||||
use Drupal\Core\Entity\Plugin\EntityReferenceSelection\SelectionBase;
|
||||
|
||||
/**
|
||||
* Provides specific access control for the node entity type.
|
||||
*
|
||||
* @EntityReferenceSelection(
|
||||
* id = "node_default",
|
||||
* id = "default:node",
|
||||
* label = @Translation("Node selection"),
|
||||
* entity_types = {"node"},
|
||||
* group = "default",
|
||||
|
@ -32,9 +32,10 @@ class NodeSelection extends SelectionBase {
|
|||
// 'unpublished'. We need to do that as long as there are no access control
|
||||
// modules in use on the site. As long as one access control module is there,
|
||||
// it is supposed to handle this check.
|
||||
if (!\Drupal::currentUser()->hasPermission('bypass node access') && !count(\Drupal::moduleHandler()->getImplementations('node_grants'))) {
|
||||
if (!$this->currentUser->hasPermission('bypass node access') && !count($this->moduleHandler->getImplementations('node_grants'))) {
|
||||
$query->condition('status', NODE_PUBLISHED);
|
||||
}
|
||||
return $query;
|
||||
}
|
||||
|
||||
}
|
|
@ -2,13 +2,12 @@
|
|||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\entity_reference\Tests\EntityReferenceSelectionAccessTest.
|
||||
* Contains \Drupal\system\Tests\Entity\EntityReferenceSelection\EntityReferenceSelectionAccessTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\entity_reference\Tests;
|
||||
namespace Drupal\system\Tests\Entity\EntityReferenceSelection;
|
||||
|
||||
use Drupal\Component\Utility\String;
|
||||
use Drupal\Core\Field\FieldDefinitionInterface;
|
||||
use Drupal\Core\Language\LanguageInterface;
|
||||
use Drupal\comment\CommentInterface;
|
||||
use Drupal\simpletest\WebTestBase;
|
||||
|
@ -20,7 +19,12 @@ use Drupal\simpletest\WebTestBase;
|
|||
*/
|
||||
class EntityReferenceSelectionAccessTest extends WebTestBase {
|
||||
|
||||
public static $modules = array('node', 'comment', 'entity_reference', 'entity_test');
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('node', 'comment');
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
@ -29,8 +33,18 @@ class EntityReferenceSelectionAccessTest extends WebTestBase {
|
|||
$this->drupalCreateContentType(array('type' => 'article', 'name' => 'Article'));
|
||||
}
|
||||
|
||||
protected function assertReferenceable(FieldDefinitionInterface $field_definition, $tests, $handler_name) {
|
||||
$handler = \Drupal::service('plugin.manager.entity_reference.selection')->getSelectionHandler($field_definition);
|
||||
/**
|
||||
* Checks that a selection plugin returns the expected results.
|
||||
*
|
||||
* @param array $selection_options
|
||||
* An array of options as required by entity reference selection plugins.
|
||||
* @param array $tests
|
||||
* An array of tests to run.
|
||||
* @param string $handler_name
|
||||
* The name of the entity type selection handler being tested.
|
||||
*/
|
||||
protected function assertReferenceable(array $selection_options, $tests, $handler_name) {
|
||||
$handler = \Drupal::service('plugin.manager.entity_reference_selection')->getInstance($selection_options);
|
||||
|
||||
foreach ($tests as $test) {
|
||||
foreach ($test['arguments'] as $arguments) {
|
||||
|
@ -55,30 +69,13 @@ class EntityReferenceSelectionAccessTest extends WebTestBase {
|
|||
* Test the node-specific overrides of the entity handler.
|
||||
*/
|
||||
public function testNodeHandler() {
|
||||
// Create a field.
|
||||
$field_storage = entity_create('field_storage_config', array(
|
||||
'field_name' => 'test_field',
|
||||
'entity_type' => 'entity_test',
|
||||
'translatable' => FALSE,
|
||||
'entity_types' => array(),
|
||||
'settings' => array(
|
||||
'target_type' => 'node',
|
||||
$selection_options = array(
|
||||
'target_type' => 'node',
|
||||
'handler' => 'default',
|
||||
'handler_settings' => array(
|
||||
'target_bundles' => array(),
|
||||
),
|
||||
'type' => 'entity_reference',
|
||||
'cardinality' => '1',
|
||||
));
|
||||
$field_storage->save();
|
||||
$field = entity_create('field_config', array(
|
||||
'field_storage' => $field_storage,
|
||||
'bundle' => 'test_bundle',
|
||||
'settings' => array(
|
||||
'handler' => 'default',
|
||||
'handler_settings' => array(
|
||||
'target_bundles' => array(),
|
||||
),
|
||||
),
|
||||
));
|
||||
$field->save();
|
||||
);
|
||||
|
||||
// Build a set of test data.
|
||||
// Titles contain HTML-special characters to test escaping.
|
||||
|
@ -162,7 +159,7 @@ class EntityReferenceSelectionAccessTest extends WebTestBase {
|
|||
'result' => array(),
|
||||
),
|
||||
);
|
||||
$this->assertReferenceable($field, $referenceable_tests, 'Node handler');
|
||||
$this->assertReferenceable($selection_options, $referenceable_tests, 'Node handler');
|
||||
|
||||
// Test as an admin.
|
||||
$admin_user = $this->drupalCreateUser(array('access content', 'bypass node access'));
|
||||
|
@ -191,36 +188,20 @@ class EntityReferenceSelectionAccessTest extends WebTestBase {
|
|||
),
|
||||
),
|
||||
);
|
||||
$this->assertReferenceable($field, $referenceable_tests, 'Node handler (admin)');
|
||||
$this->assertReferenceable($selection_options, $referenceable_tests, 'Node handler (admin)');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the user-specific overrides of the entity handler.
|
||||
*/
|
||||
public function testUserHandler() {
|
||||
// Create a field.
|
||||
$field_storage = entity_create('field_storage_config', array(
|
||||
'field_name' => 'test_field',
|
||||
'entity_type' => 'entity_test',
|
||||
'translatable' => FALSE,
|
||||
'settings' => array(
|
||||
'target_type' => 'user',
|
||||
$selection_options = array(
|
||||
'target_type' => 'user',
|
||||
'handler' => 'default',
|
||||
'handler_settings' => array(
|
||||
'target_bundles' => array(),
|
||||
),
|
||||
'type' => 'entity_reference',
|
||||
'cardinality' => '1',
|
||||
));
|
||||
$field_storage->save();
|
||||
$field = entity_create('field_config', array(
|
||||
'field_storage' => $field_storage,
|
||||
'bundle' => 'test_bundle',
|
||||
'settings' => array(
|
||||
'handler' => 'default',
|
||||
'handler_settings' => array(
|
||||
'target_bundles' => array(),
|
||||
),
|
||||
),
|
||||
));
|
||||
$field->save();
|
||||
);
|
||||
|
||||
// Build a set of test data.
|
||||
$user_values = array(
|
||||
|
@ -296,7 +277,7 @@ class EntityReferenceSelectionAccessTest extends WebTestBase {
|
|||
'result' => array(),
|
||||
),
|
||||
);
|
||||
$this->assertReferenceable($field, $referenceable_tests, 'User handler');
|
||||
$this->assertReferenceable($selection_options, $referenceable_tests, 'User handler');
|
||||
|
||||
\Drupal::currentUser()->setAccount($users['admin']);
|
||||
$referenceable_tests = array(
|
||||
|
@ -335,37 +316,20 @@ class EntityReferenceSelectionAccessTest extends WebTestBase {
|
|||
),
|
||||
),
|
||||
);
|
||||
$this->assertReferenceable($field, $referenceable_tests, 'User handler (admin)');
|
||||
$this->assertReferenceable($selection_options, $referenceable_tests, 'User handler (admin)');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the comment-specific overrides of the entity handler.
|
||||
*/
|
||||
public function testCommentHandler() {
|
||||
// Create a field.
|
||||
$field_storage = entity_create('field_storage_config', array(
|
||||
'field_name' => 'test_field',
|
||||
'entity_type' => 'entity_test',
|
||||
'translatable' => FALSE,
|
||||
'entity_types' => array(),
|
||||
'settings' => array(
|
||||
'target_type' => 'comment',
|
||||
$selection_options = array(
|
||||
'target_type' => 'comment',
|
||||
'handler' => 'default',
|
||||
'handler_settings' => array(
|
||||
'target_bundles' => array(),
|
||||
),
|
||||
'type' => 'entity_reference',
|
||||
'cardinality' => '1',
|
||||
));
|
||||
$field_storage->save();
|
||||
$field = entity_create('field_config', array(
|
||||
'field_storage' => $field_storage,
|
||||
'bundle' => 'test_bundle',
|
||||
'settings' => array(
|
||||
'handler' => 'default',
|
||||
'handler_settings' => array(
|
||||
'target_bundles' => array(),
|
||||
),
|
||||
),
|
||||
));
|
||||
$field->save();
|
||||
);
|
||||
|
||||
// Build a set of test data.
|
||||
$node_values = array(
|
||||
|
@ -474,7 +438,7 @@ class EntityReferenceSelectionAccessTest extends WebTestBase {
|
|||
'result' => array(),
|
||||
),
|
||||
);
|
||||
$this->assertReferenceable($field, $referenceable_tests, 'Comment handler');
|
||||
$this->assertReferenceable($selection_options, $referenceable_tests, 'Comment handler');
|
||||
|
||||
// Test as a comment admin.
|
||||
$admin_user = $this->drupalCreateUser(array('access content', 'access comments', 'administer comments'));
|
||||
|
@ -492,7 +456,7 @@ class EntityReferenceSelectionAccessTest extends WebTestBase {
|
|||
),
|
||||
),
|
||||
);
|
||||
$this->assertReferenceable($field, $referenceable_tests, 'Comment handler (comment admin)');
|
||||
$this->assertReferenceable($selection_options, $referenceable_tests, 'Comment handler (comment admin)');
|
||||
|
||||
// Test as a node and comment admin.
|
||||
$admin_user = $this->drupalCreateUser(array('access content', 'access comments', 'administer comments', 'bypass node access'));
|
||||
|
@ -511,6 +475,7 @@ class EntityReferenceSelectionAccessTest extends WebTestBase {
|
|||
),
|
||||
),
|
||||
);
|
||||
$this->assertReferenceable($field, $referenceable_tests, 'Comment handler (comment + node admin)');
|
||||
$this->assertReferenceable($selection_options, $referenceable_tests, 'Comment handler (comment + node admin)');
|
||||
}
|
||||
|
||||
}
|
|
@ -2,28 +2,42 @@
|
|||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\entity_reference\Tests\EntityReferenceSelectionSortTest.
|
||||
* Contains \Drupal\system\Tests\Entity\EntityReferenceSelection\EntityReferenceSelectionSortTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\entity_reference\Tests;
|
||||
namespace Drupal\system\Tests\Entity\EntityReferenceSelection;
|
||||
|
||||
use Drupal\Component\Utility\String;
|
||||
use Drupal\simpletest\WebTestBase;
|
||||
use Drupal\node\Entity\Node;
|
||||
use Drupal\node\Entity\NodeType;
|
||||
use Drupal\system\Tests\Entity\EntityUnitTestBase;
|
||||
|
||||
/**
|
||||
* Tests sorting referenced items.
|
||||
*
|
||||
* @group entity_reference
|
||||
*/
|
||||
class EntityReferenceSelectionSortTest extends WebTestBase {
|
||||
class EntityReferenceSelectionSortTest extends EntityUnitTestBase {
|
||||
|
||||
public static $modules = array('node', 'entity_reference', 'entity_test');
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('node');
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Create an Article node type.
|
||||
$this->drupalCreateContentType(array('type' => 'article', 'name' => 'Article'));
|
||||
$article = NodeType::create(array(
|
||||
'type' => 'article',
|
||||
));
|
||||
$article->save();
|
||||
|
||||
// Test as a non-admin.
|
||||
$normal_user = $this->createUser(array(), array('access content'));
|
||||
\Drupal::currentUser()->setAccount($normal_user);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -47,37 +61,6 @@ class EntityReferenceSelectionSortTest extends WebTestBase {
|
|||
'required' => FALSE,
|
||||
))->save();
|
||||
|
||||
|
||||
// Create a field.
|
||||
$field_storage = entity_create('field_storage_config', array(
|
||||
'field_name' => 'test_field',
|
||||
'entity_type' => 'entity_test',
|
||||
'translatable' => FALSE,
|
||||
'settings' => array(
|
||||
'target_type' => 'node',
|
||||
),
|
||||
'type' => 'entity_reference',
|
||||
'cardinality' => 1,
|
||||
));
|
||||
$field_storage->save();
|
||||
$field = entity_create('field_config', array(
|
||||
'field_storage' => $field_storage,
|
||||
'entity_type' => 'entity_test',
|
||||
'bundle' => 'test_bundle',
|
||||
'settings' => array(
|
||||
'handler' => 'default',
|
||||
'handler_settings' => array(
|
||||
'target_bundles' => array(),
|
||||
// Add sorting.
|
||||
'sort' => array(
|
||||
'field' => 'field_text.value',
|
||||
'direction' => 'DESC',
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
$field->save();
|
||||
|
||||
// Build a set of test data.
|
||||
$node_values = array(
|
||||
'published1' => array(
|
||||
|
@ -107,17 +90,25 @@ class EntityReferenceSelectionSortTest extends WebTestBase {
|
|||
$nodes = array();
|
||||
$node_labels = array();
|
||||
foreach ($node_values as $key => $values) {
|
||||
$node = entity_create('node', $values);
|
||||
$node = Node::create($values);
|
||||
$node->save();
|
||||
$nodes[$key] = $node;
|
||||
$node_labels[$key] = String::checkPlain($node->label());
|
||||
}
|
||||
|
||||
// Test as a non-admin.
|
||||
$normal_user = $this->drupalCreateUser(array('access content'));
|
||||
\Drupal::currentUser()->setAccount($normal_user);
|
||||
|
||||
$handler = $this->container->get('plugin.manager.entity_reference.selection')->getSelectionHandler($field);
|
||||
$selection_options = array(
|
||||
'target_type' => 'node',
|
||||
'handler' => 'default',
|
||||
'handler_settings' => array(
|
||||
'target_bundles' => array(),
|
||||
// Add sorting.
|
||||
'sort' => array(
|
||||
'field' => 'field_text.value',
|
||||
'direction' => 'DESC',
|
||||
),
|
||||
),
|
||||
);
|
||||
$handler = $this->container->get('plugin.manager.entity_reference_selection')->getInstance($selection_options);
|
||||
|
||||
// Not only assert the result, but make sure the keys are sorted as
|
||||
// expected.
|
||||
|
@ -128,12 +119,12 @@ class EntityReferenceSelectionSortTest extends WebTestBase {
|
|||
);
|
||||
$this->assertIdentical($result['article'], $expected_result, 'Query sorted by field returned expected values.');
|
||||
|
||||
// Assert sort by property.
|
||||
$field->settings['handler_settings']['sort'] = array(
|
||||
// Assert sort by base field.
|
||||
$selection_options['handler_settings']['sort'] = array(
|
||||
'field' => 'nid',
|
||||
'direction' => 'ASC',
|
||||
);
|
||||
$handler = $this->container->get('plugin.manager.entity_reference.selection')->getSelectionHandler($field);
|
||||
$handler = $this->container->get('plugin.manager.entity_reference_selection')->getInstance($selection_options);
|
||||
$result = $handler->getReferenceableEntities();
|
||||
$expected_result = array(
|
||||
$nodes['published1']->id() => $node_labels['published1'],
|
||||
|
@ -141,4 +132,5 @@ class EntityReferenceSelectionSortTest extends WebTestBase {
|
|||
);
|
||||
$this->assertIdentical($result['article'], $expected_result, 'Query sorted by property returned expected values.');
|
||||
}
|
||||
|
||||
}
|
|
@ -2,22 +2,22 @@
|
|||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\taxonomy\Plugin\entity_reference\selection\TermSelection.
|
||||
* Contains \Drupal\taxonomy\Plugin\EntityReferenceSelection\TermSelection.
|
||||
*/
|
||||
|
||||
namespace Drupal\taxonomy\Plugin\entity_reference\selection;
|
||||
namespace Drupal\taxonomy\Plugin\EntityReferenceSelection;
|
||||
|
||||
use Drupal\Component\Utility\String;
|
||||
use Drupal\Core\Database\Query\SelectInterface;
|
||||
use Drupal\Core\Field\FieldDefinitionInterface;
|
||||
use Drupal\entity_reference\Plugin\entity_reference\selection\SelectionBase;
|
||||
use Drupal\Core\Entity\Plugin\EntityReferenceSelection\SelectionBase;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\taxonomy\Entity\Vocabulary;
|
||||
|
||||
/**
|
||||
* Provides specific access control for the taxonomy_term entity type.
|
||||
*
|
||||
* @EntityReferenceSelection(
|
||||
* id = "taxonomy_term_default",
|
||||
* id = "default:taxonomy_term",
|
||||
* label = @Translation("Taxonomy Term selection"),
|
||||
* entity_types = {"taxonomy_term"},
|
||||
* group = "default",
|
||||
|
@ -36,15 +36,14 @@ class TermSelection extends SelectionBase {
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function settingsForm(FieldDefinitionInterface $field_definition) {
|
||||
$form = parent::settingsForm($field_definition);
|
||||
$selection_handler_settings = $field_definition->getSetting('handler_settings');
|
||||
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
|
||||
$form = parent::buildConfigurationForm($form, $form_state);
|
||||
|
||||
// @todo: Currently allow auto-create only on taxonomy terms.
|
||||
$form['auto_create'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t("Create referenced entities if they don't already exist"),
|
||||
'#default_value' => isset($selection_handler_settings['auto_create']) ? $selection_handler_settings['auto_create'] : FALSE,
|
||||
'#title' => $this->t("Create referenced entities if they don't already exist"),
|
||||
'#default_value' => isset($this->configuration['handler_settings']['auto_create']) ? $this->configuration['handler_settings']['auto_create'] : FALSE,
|
||||
);
|
||||
return $form;
|
||||
|
||||
|
@ -60,13 +59,13 @@ class TermSelection extends SelectionBase {
|
|||
|
||||
$options = array();
|
||||
|
||||
$bundles = entity_get_bundles('taxonomy_term');
|
||||
$handler_settings = $this->fieldDefinition->getSetting('handler_settings');
|
||||
$bundles = $this->entityManager->getBundleInfo('taxonomy_term');
|
||||
$handler_settings = $this->configuration['handler_settings'];
|
||||
$bundle_names = !empty($handler_settings['target_bundles']) ? $handler_settings['target_bundles'] : array_keys($bundles);
|
||||
|
||||
foreach ($bundle_names as $bundle) {
|
||||
if ($vocabulary = Vocabulary::load($bundle)) {
|
||||
if ($terms = taxonomy_get_tree($vocabulary->id(), 0, NULL, TRUE)) {
|
||||
if ($terms = $this->entityManager->getStorage('taxonomy_term')->loadTree($vocabulary->id(), 0, NULL, TRUE)) {
|
||||
foreach ($terms as $term) {
|
||||
$options[$vocabulary->id()][$term->id()] = str_repeat('-', $term->depth) . String::checkPlain($term->getName());
|
||||
}
|
||||
|
@ -76,4 +75,5 @@ class TermSelection extends SelectionBase {
|
|||
|
||||
return $options;
|
||||
}
|
||||
|
||||
}
|
|
@ -69,7 +69,7 @@ class TermEntityReferenceTest extends TaxonomyTestBase {
|
|||
));
|
||||
$field->save();
|
||||
|
||||
$handler = $this->container->get('plugin.manager.entity_reference.selection')->getSelectionHandler($field);
|
||||
$handler = $this->container->get('plugin.manager.entity_reference_selection')->getSelectionHandler($field);
|
||||
$result = $handler->getReferenceableEntities();
|
||||
|
||||
$expected_result = array(
|
||||
|
|
|
@ -2,21 +2,25 @@
|
|||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\user\Plugin\entity_reference\selection\UserSelection.
|
||||
* Contains \Drupal\user\Plugin\EntityReferenceSelection\UserSelection.
|
||||
*/
|
||||
|
||||
namespace Drupal\user\Plugin\entity_reference\selection;
|
||||
namespace Drupal\user\Plugin\EntityReferenceSelection;
|
||||
|
||||
use Drupal\Core\Database\Database;
|
||||
use Drupal\Core\Database\Connection;
|
||||
use Drupal\Core\Database\Query\SelectInterface;
|
||||
use Drupal\Core\Field\FieldDefinitionInterface;
|
||||
use Drupal\entity_reference\Plugin\entity_reference\selection\SelectionBase;
|
||||
use Drupal\Core\Entity\EntityManagerInterface;
|
||||
use Drupal\Core\Entity\Plugin\EntityReferenceSelection\SelectionBase;
|
||||
use Drupal\Core\Extension\ModuleHandlerInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Provides specific access control for the user entity type.
|
||||
*
|
||||
* @EntityReferenceSelection(
|
||||
* id = "user_default",
|
||||
* id = "default:user",
|
||||
* label = @Translation("User selection"),
|
||||
* entity_types = {"user"},
|
||||
* group = "default",
|
||||
|
@ -25,11 +29,57 @@ use Drupal\entity_reference\Plugin\entity_reference\selection\SelectionBase;
|
|||
*/
|
||||
class UserSelection extends SelectionBase {
|
||||
|
||||
/**
|
||||
* The database connection.
|
||||
*
|
||||
* @var \Drupal\Core\Database\Connection
|
||||
*/
|
||||
protected $connection;
|
||||
|
||||
/**
|
||||
* Constructs a new UserSelection object.
|
||||
*
|
||||
* @param array $configuration
|
||||
* A configuration array containing information about the plugin instance.
|
||||
* @param string $plugin_id
|
||||
* The plugin_id for the plugin instance.
|
||||
* @param mixed $plugin_definition
|
||||
* The plugin implementation definition.
|
||||
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
|
||||
* The entity manager service.
|
||||
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
|
||||
* The module handler service.
|
||||
* @param \Drupal\Core\Session\AccountInterface $current_user
|
||||
* The current user.
|
||||
* @param \Drupal\Core\Database\Connection $connection
|
||||
* The database connection.
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityManagerInterface $entity_manager, ModuleHandlerInterface $module_handler, AccountInterface $current_user, Connection $connection) {
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition, $entity_manager, $module_handler, $current_user);
|
||||
|
||||
$this->connection = $connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function settingsForm(FieldDefinitionInterface $field_definition) {
|
||||
$selection_handler_settings = $field_definition->getSetting('handler_settings');
|
||||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
|
||||
return new static(
|
||||
$configuration,
|
||||
$plugin_id,
|
||||
$plugin_definition,
|
||||
$container->get('entity.manager'),
|
||||
$container->get('module_handler'),
|
||||
$container->get('current_user'),
|
||||
$container->get('database')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
|
||||
$selection_handler_settings = $this->configuration['handler_settings'];
|
||||
|
||||
// Merge in default values.
|
||||
$selection_handler_settings += array(
|
||||
|
@ -41,10 +91,10 @@ class UserSelection extends SelectionBase {
|
|||
// Add user specific filter options.
|
||||
$form['filter']['type'] = array(
|
||||
'#type' => 'select',
|
||||
'#title' => t('Filter by'),
|
||||
'#title' => $this->t('Filter by'),
|
||||
'#options' => array(
|
||||
'_none' => t('- None -'),
|
||||
'role' => t('User role'),
|
||||
'_none' => $this->t('- None -'),
|
||||
'role' => $this->t('User role'),
|
||||
),
|
||||
'#ajax' => TRUE,
|
||||
'#limit_validation_errors' => array(),
|
||||
|
@ -65,14 +115,14 @@ class UserSelection extends SelectionBase {
|
|||
|
||||
$form['filter']['settings']['role'] = array(
|
||||
'#type' => 'checkboxes',
|
||||
'#title' => t('Restrict to the selected roles'),
|
||||
'#title' => $this->t('Restrict to the selected roles'),
|
||||
'#required' => TRUE,
|
||||
'#options' => array_diff_key(user_role_names(TRUE), array(DRUPAL_AUTHENTICATED_RID => DRUPAL_AUTHENTICATED_RID)),
|
||||
'#default_value' => $selection_handler_settings['filter']['role'],
|
||||
);
|
||||
}
|
||||
|
||||
$form += parent::settingsForm($field_definition);
|
||||
$form += parent::buildConfigurationForm($form, $form_state);
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
@ -89,14 +139,14 @@ class UserSelection extends SelectionBase {
|
|||
}
|
||||
|
||||
// Filter by role.
|
||||
$handler_settings = $this->fieldDefinition->getSetting('handler_settings');
|
||||
$handler_settings = $this->configuration['handler_settings'];
|
||||
if (!empty($handler_settings['filter']['role'])) {
|
||||
$query->condition('roles', $handler_settings['filter']['role'], 'IN');
|
||||
}
|
||||
|
||||
// Adding the permission check is sadly insufficient for users: core
|
||||
// requires us to also know about the concept of 'blocked' and 'active'.
|
||||
if (!\Drupal::currentUser()->hasPermission('administer users')) {
|
||||
if (!$this->currentUser->hasPermission('administer users')) {
|
||||
$query->condition('status', 1);
|
||||
}
|
||||
return $query;
|
||||
|
@ -106,7 +156,7 @@ class UserSelection extends SelectionBase {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function entityQueryAlter(SelectInterface $query) {
|
||||
if (\Drupal::currentUser()->hasPermission('administer users')) {
|
||||
if ($this->currentUser->hasPermission('administer users')) {
|
||||
// In addition, if the user is administrator, we need to make sure to
|
||||
// match the anonymous user, that doesn't actually have a name in the
|
||||
// database.
|
||||
|
@ -128,7 +178,7 @@ class UserSelection extends SelectionBase {
|
|||
// field, and concatenate the field and the condition separately.
|
||||
$value_part = db_and();
|
||||
$value_part->condition('anonymous_name', $condition['value'], $condition['operator']);
|
||||
$value_part->compile(Database::getConnection(), $query);
|
||||
$value_part->compile($this->connection, $query);
|
||||
$or->condition(db_and()
|
||||
->where(str_replace('anonymous_name', ':anonymous_name', (string) $value_part), $value_part->arguments() + array(':anonymous_name' => user_format_name(user_load(0))))
|
||||
->condition('base_table.uid', 0)
|
||||
|
@ -138,4 +188,5 @@ class UserSelection extends SelectionBase {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -2,17 +2,20 @@
|
|||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\views\Plugin\entity_reference\selection\ViewsSelection.
|
||||
* Contains \Drupal\views\Plugin\EntityReferenceSelection\ViewsSelection.
|
||||
*/
|
||||
|
||||
namespace Drupal\views\Plugin\entity_reference\selection;
|
||||
namespace Drupal\views\Plugin\EntityReferenceSelection;
|
||||
|
||||
use Drupal\Core\Database\Query\SelectInterface;
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\Core\Field\FieldDefinitionInterface;
|
||||
use Drupal\Core\Entity\EntityManagerInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\entity_reference\Plugin\Type\Selection\SelectionInterface;
|
||||
use Drupal\Core\Entity\EntityReferenceSelection\SelectionInterface;
|
||||
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
|
||||
use Drupal\Core\Plugin\PluginBase;
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\views\Views;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Plugin implementation of the 'selection' entity_reference.
|
||||
|
@ -24,21 +27,14 @@ use Drupal\views\Views;
|
|||
* weight = 0
|
||||
* )
|
||||
*/
|
||||
class ViewsSelection implements SelectionInterface {
|
||||
class ViewsSelection extends PluginBase implements SelectionInterface, ContainerFactoryPluginInterface {
|
||||
|
||||
/**
|
||||
* The field definition.
|
||||
* The entity manager.
|
||||
*
|
||||
* @var \Drupal\Core\Field\FieldDefinitionInterface
|
||||
* @var \Drupal\Core\Entity\EntityManagerInterface
|
||||
*/
|
||||
protected $fieldDefinition;
|
||||
|
||||
/**
|
||||
* The entity object, or NULL
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityInterface|null
|
||||
*/
|
||||
protected $entity;
|
||||
protected $entityManager;
|
||||
|
||||
/**
|
||||
* The loaded View object.
|
||||
|
@ -48,23 +44,45 @@ class ViewsSelection implements SelectionInterface {
|
|||
protected $view;
|
||||
|
||||
/**
|
||||
* Constructs a View selection handler.
|
||||
* Constructs a new ViewsSelection object.
|
||||
*
|
||||
* @param array $configuration
|
||||
* A configuration array containing information about the plugin instance.
|
||||
* @param string $plugin_id
|
||||
* The plugin_id for the plugin instance.
|
||||
* @param mixed $plugin_definition
|
||||
* The plugin implementation definition.
|
||||
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
|
||||
* The entity manager service.
|
||||
*/
|
||||
public function __construct(FieldDefinitionInterface $field_definition, EntityInterface $entity = NULL) {
|
||||
$this->fieldDefinition = $field_definition;
|
||||
$this->entity = $entity;
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityManagerInterface $entity_manager) {
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition);
|
||||
|
||||
$this->entityManager = $entity_manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function settingsForm(FieldDefinitionInterface $field_definition) {
|
||||
$selection_handler_settings = $field_definition->getSetting('handler_settings') ?: array();
|
||||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
|
||||
return new static(
|
||||
$configuration,
|
||||
$plugin_id,
|
||||
$plugin_definition,
|
||||
$container->get('entity.manager')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
|
||||
$selection_handler_settings = $this->configuration['handler_settings'];
|
||||
$view_settings = !empty($selection_handler_settings['view']) ? $selection_handler_settings['view'] : array();
|
||||
$displays = Views::getApplicableViews('entity_reference_display');
|
||||
// Filter views that list the entity type we want, and group the separate
|
||||
// displays by view.
|
||||
$entity_type = \Drupal::entityManager()->getDefinition($field_definition->getSetting('target_type'));
|
||||
$entity_type = $this->entityManager->getDefinition($this->configuration['target_type']);
|
||||
$options = array();
|
||||
foreach ($displays as $data) {
|
||||
list($view, $display_id) = $data;
|
||||
|
@ -79,40 +97,49 @@ class ViewsSelection implements SelectionInterface {
|
|||
// into 'view_name' and 'view_display' in the final submitted values, so
|
||||
// we massage the data at validate time on the wrapping element (not
|
||||
// ideal).
|
||||
$plugin = new static($field_definition);
|
||||
$form['view']['#element_validate'] = array(array($plugin, 'settingsFormValidate'));
|
||||
$form['view']['#element_validate'] = array(array(get_called_class(), 'settingsFormValidate'));
|
||||
|
||||
if ($options) {
|
||||
$default = !empty($view_settings['view_name']) ? $view_settings['view_name'] . ':' . $view_settings['display_name'] : NULL;
|
||||
$form['view']['view_and_display'] = array(
|
||||
'#type' => 'select',
|
||||
'#title' => t('View used to select the entities'),
|
||||
'#title' => $this->t('View used to select the entities'),
|
||||
'#required' => TRUE,
|
||||
'#options' => $options,
|
||||
'#default_value' => $default,
|
||||
'#description' => '<p>' . t('Choose the view and display that select the entities that can be referenced.<br />Only views with a display of type "Entity Reference" are eligible.') . '</p>',
|
||||
'#description' => '<p>' . $this->t('Choose the view and display that select the entities that can be referenced.<br />Only views with a display of type "Entity Reference" are eligible.') . '</p>',
|
||||
);
|
||||
|
||||
$default = !empty($view_settings['arguments']) ? implode(', ', $view_settings['arguments']) : '';
|
||||
$form['view']['arguments'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#title' => t('View arguments'),
|
||||
'#title' => $this->t('View arguments'),
|
||||
'#default_value' => $default,
|
||||
'#required' => FALSE,
|
||||
'#description' => t('Provide a comma separated list of arguments to pass to the view.'),
|
||||
'#description' => $this->t('Provide a comma separated list of arguments to pass to the view.'),
|
||||
);
|
||||
}
|
||||
else {
|
||||
$form['view']['no_view_help'] = array(
|
||||
'#markup' => '<p>' . t('No eligible views were found. <a href="@create">Create a view</a> with an <em>Entity Reference</em> display, or add such a display to an <a href="@existing">existing view</a>.', array(
|
||||
'@create' => \Drupal::url('views_ui.add'),
|
||||
'@existing' => \Drupal::url('entity.view.collection'),
|
||||
'#markup' => '<p>' . $this->t('No eligible views were found. <a href="@create">Create a view</a> with an <em>Entity Reference</em> display, or add such a display to an <a href="@existing">existing view</a>.', array(
|
||||
'@create' => Url::fromRoute('views_ui.add'),
|
||||
'@existing' => Url::fromRoute('entity.view.collection'),
|
||||
)) . '</p>',
|
||||
);
|
||||
}
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function validateConfigurationForm(array &$form, FormStateInterface $form_state) { }
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitConfigurationForm(array &$form, FormStateInterface $form_state) { }
|
||||
|
||||
/**
|
||||
* Initializes a view.
|
||||
*
|
||||
|
@ -131,14 +158,14 @@ class ViewsSelection implements SelectionInterface {
|
|||
* Return TRUE if the view was initialized, FALSE otherwise.
|
||||
*/
|
||||
protected function initializeView($match = NULL, $match_operator = 'CONTAINS', $limit = 0, $ids = NULL) {
|
||||
$handler_settings = $this->fieldDefinition->getSetting('handler_settings');
|
||||
$handler_settings = $this->configuration['handler_settings'];
|
||||
$view_name = $handler_settings['view']['view_name'];
|
||||
$display_name = $handler_settings['view']['display_name'];
|
||||
|
||||
// Check that the view is valid and the display still exists.
|
||||
$this->view = Views::getView($view_name);
|
||||
if (!$this->view || !$this->view->access($display_name)) {
|
||||
drupal_set_message(t('The reference view %view_name used in the %field_name field cannot be found.', array('%view_name' => $view_name, '%field_name' => $this->fieldDefinition->getLabel())), 'warning');
|
||||
drupal_set_message(t('The reference view %view_name cannot be found.', array('%view_name' => $view_name)), 'warning');
|
||||
return FALSE;
|
||||
}
|
||||
$this->view->setDisplay($display_name);
|
||||
|
@ -158,7 +185,7 @@ class ViewsSelection implements SelectionInterface {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function getReferenceableEntities($match = NULL, $match_operator = 'CONTAINS', $limit = 0) {
|
||||
$handler_settings = $this->fieldDefinition->getSetting('handler_settings');
|
||||
$handler_settings = $this->configuration['handler_settings'];
|
||||
$display_name = $handler_settings['view']['display_name'];
|
||||
$arguments = $handler_settings['view']['arguments'];
|
||||
$result = array();
|
||||
|
@ -189,7 +216,7 @@ class ViewsSelection implements SelectionInterface {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function validateReferenceableEntities(array $ids) {
|
||||
$handler_settings = $this->fieldDefinition->getSetting('handler_settings');
|
||||
$handler_settings = $this->configuration['handler_settings'];
|
||||
$display_name = $handler_settings['view']['display_name'];
|
||||
$arguments = $handler_settings['view']['arguments'];
|
||||
$result = array();
|
||||
|
@ -222,7 +249,7 @@ class ViewsSelection implements SelectionInterface {
|
|||
list($view, $display) = explode(':', $element['view_and_display']['#value']);
|
||||
}
|
||||
else {
|
||||
$form_state->setError($element, t('The views entity selection mode requires a view.'));
|
||||
$form_state->setError($element, $this->t('The views entity selection mode requires a view.'));
|
||||
return;
|
||||
}
|
||||
|
Loading…
Reference in New Issue