Issue #2787873 by claudiu.cristea, amateescu, jibran, dawehner, catch: Add a base class for entity reference selection handlers and fix the structure of their configuration
parent
3225473ddd
commit
b0900c73b1
|
|
@ -780,11 +780,24 @@ text_format:
|
|||
# The text format should not be translated as part of the string
|
||||
# translation system, so this is not marked as translatable.
|
||||
|
||||
# Schema for the configuration of the Entity reference selection plugins.
|
||||
|
||||
# Base schema for all entity reference selection handler schemas.
|
||||
entity_reference_selection:
|
||||
type: mapping
|
||||
label: 'Entity reference selection plugin configuration'
|
||||
label: 'Entity reference selection handler settings'
|
||||
mapping:
|
||||
target_type:
|
||||
type: string
|
||||
label: 'Type of item to reference'
|
||||
|
||||
# Schema for all entity reference selection handlers that are not providing a
|
||||
# specific schema.
|
||||
entity_reference_selection.*:
|
||||
type: entity_reference_selection
|
||||
|
||||
# Schema for the entity reference 'default' selection handler settings.
|
||||
entity_reference_selection.default:
|
||||
type: entity_reference_selection
|
||||
label: 'Default selection handler settings'
|
||||
mapping:
|
||||
target_bundles:
|
||||
type: sequence
|
||||
|
|
@ -792,7 +805,7 @@ entity_reference_selection:
|
|||
nullable: true
|
||||
sequence:
|
||||
type: string
|
||||
label: 'Type'
|
||||
label: 'Bundle'
|
||||
sort:
|
||||
type: mapping
|
||||
label: 'Sort settings'
|
||||
|
|
@ -810,5 +823,7 @@ entity_reference_selection:
|
|||
type: string
|
||||
label: 'Bundle assigned to the auto-created entities.'
|
||||
|
||||
entity_reference_selection.*:
|
||||
type: entity_reference_selection
|
||||
# Schema for all entity reference 'default:*' selection handlers that are not
|
||||
# providing a specific schema.
|
||||
entity_reference_selection.default:*:
|
||||
type: entity_reference_selection.default
|
||||
|
|
|
|||
|
|
@ -152,10 +152,9 @@ class EntityAutocomplete extends Textfield {
|
|||
$value = NULL;
|
||||
|
||||
if (!empty($element['#value'])) {
|
||||
$options = [
|
||||
$options = $element['#selection_settings'] + [
|
||||
'target_type' => $element['#target_type'],
|
||||
'handler' => $element['#selection_handler'],
|
||||
'handler_settings' => $element['#selection_settings'],
|
||||
];
|
||||
/** @var /Drupal\Core\Entity\EntityReferenceSelection\SelectionInterface $handler */
|
||||
$handler = \Drupal::service('plugin.manager.entity_reference_selection')->getInstance($options);
|
||||
|
|
|
|||
|
|
@ -52,10 +52,9 @@ class EntityAutocompleteMatcher {
|
|||
public function getMatches($target_type, $selection_handler, $selection_settings, $string = '') {
|
||||
$matches = [];
|
||||
|
||||
$options = [
|
||||
$options = $selection_settings + [
|
||||
'target_type' => $target_type,
|
||||
'handler' => $selection_handler,
|
||||
'handler_settings' => $selection_settings,
|
||||
];
|
||||
$handler = $this->selectionManager->getInstance($options);
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,160 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Core\Entity\EntityReferenceSelection;
|
||||
|
||||
use Drupal\Component\Plugin\ConfigurablePluginInterface;
|
||||
use Drupal\Component\Utility\NestedArray;
|
||||
use Drupal\Core\Database\Query\SelectInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Plugin\PluginBase;
|
||||
|
||||
/**
|
||||
* Provides a base class for configurable selection handlers.
|
||||
*/
|
||||
abstract class SelectionPluginBase extends PluginBase implements SelectionInterface, ConfigurablePluginInterface {
|
||||
|
||||
/**
|
||||
* Constructs a new selection 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.
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition) {
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition);
|
||||
$this->setConfiguration($configuration);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function defaultConfiguration() {
|
||||
return [
|
||||
'target_type' => NULL,
|
||||
// @todo Remove this key in Drupal 9.0.x.
|
||||
'handler' => $this->getPluginId(),
|
||||
'entity' => NULL,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getConfiguration() {
|
||||
return $this->configuration;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setConfiguration(array $configuration) {
|
||||
// Resolve backward compatibility level configurations, if any.
|
||||
$this->resolveBackwardCompatibilityConfiguration($configuration);
|
||||
|
||||
// Merge in defaults.
|
||||
$this->configuration = NestedArray::mergeDeep(
|
||||
$this->defaultConfiguration(),
|
||||
$configuration
|
||||
);
|
||||
|
||||
// Ensure a backward compatibility level configuration.
|
||||
$this->ensureBackwardCompatibilityConfiguration();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function calculateDependencies() {
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function validateConfigurationForm(array &$form, FormStateInterface $form_state) { }
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitConfigurationForm(array &$form, FormStateInterface $form_state) { }
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function entityQueryAlter(SelectInterface $query) { }
|
||||
|
||||
/**
|
||||
* Moves the backward compatibility level configurations in the right place.
|
||||
*
|
||||
* In order to keep backward compatibility, we copy all settings, except
|
||||
* 'target_type', 'handler' and 'entity' under 'handler_settings', following
|
||||
* the structure from the field config. If the plugin was instantiated using
|
||||
* the 'handler_settings' level, those values will be used. In case of
|
||||
* conflict, the root level settings will take precedence. The backward
|
||||
* compatibility aware configuration will have the next structure:
|
||||
* - target_type
|
||||
* - handler (will be removed in Drupal 9.0.x, it's the plugin id)
|
||||
* - entity
|
||||
* - setting_1
|
||||
* - setting_2
|
||||
* ...
|
||||
* - setting_N
|
||||
* - handler_settings: (will be removed in Drupal 9.0.x)
|
||||
* - setting_1
|
||||
* - setting_2
|
||||
* ...
|
||||
* - setting_N
|
||||
*
|
||||
* @param array $configuration
|
||||
* The configuration array to be altered.
|
||||
*
|
||||
* @deprecated Scheduled for removal in Drupal 9.0.x.
|
||||
*
|
||||
* @see https://www.drupal.org/node/2870971
|
||||
*/
|
||||
protected function resolveBackwardCompatibilityConfiguration(array &$configuration) {
|
||||
if (isset($this->defaultConfiguration()['handler_settings'])) {
|
||||
throw new \InvalidArgumentException("{$this->getPluginDefinition()['class']}::defaultConfiguration() should not contain a 'handler_settings' key. All settings should be placed in the root level.");
|
||||
}
|
||||
|
||||
// Extract the BC level from the passed configuration, if any.
|
||||
if (array_key_exists('handler_settings', $configuration)) {
|
||||
if (!is_array($configuration['handler_settings'])) {
|
||||
throw new \InvalidArgumentException("The setting 'handler_settings' is reserved and cannot be used.");
|
||||
}
|
||||
@trigger_error("Providing settings under 'handler_settings' is deprecated and will be removed before 9.0.0. Move the settings in the root of the configuration array. See https://www.drupal.org/node/2870971.", E_USER_DEPRECATED);
|
||||
|
||||
// Settings passed in the root level take precedence over BC settings.
|
||||
$configuration += $configuration['handler_settings'];
|
||||
unset($configuration['handler_settings']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures a backward compatibility level configuration.
|
||||
*
|
||||
* @deprecated Scheduled for removal in Drupal 9.0.x.
|
||||
*
|
||||
* @see https://www.drupal.org/node/2870971
|
||||
*/
|
||||
protected function ensureBackwardCompatibilityConfiguration() {
|
||||
// Synchronize back 'handler_settings'.
|
||||
foreach ($this->configuration as $key => $value) {
|
||||
// Filter out keys that belong strictly to the root level.
|
||||
if (!in_array($key, ['handler', 'target_type', 'entity', 'handler_settings'])) {
|
||||
$this->configuration['handler_settings'][$key] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -39,7 +39,6 @@ class SelectionPluginManager extends DefaultPluginManager implements SelectionPl
|
|||
// Initialize default options.
|
||||
$options += [
|
||||
'handler' => $this->getPluginId($options['target_type'], 'default'),
|
||||
'handler_settings' => [],
|
||||
];
|
||||
|
||||
// A specific selection plugin ID was already specified.
|
||||
|
|
@ -50,6 +49,7 @@ class SelectionPluginManager extends DefaultPluginManager implements SelectionPl
|
|||
else {
|
||||
$plugin_id = $this->getPluginId($options['target_type'], $options['handler']);
|
||||
}
|
||||
unset($options['handler']);
|
||||
|
||||
return $this->createInstance($plugin_id, $options);
|
||||
}
|
||||
|
|
@ -92,10 +92,10 @@ class SelectionPluginManager extends DefaultPluginManager implements SelectionPl
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function getSelectionHandler(FieldDefinitionInterface $field_definition, EntityInterface $entity = NULL) {
|
||||
$options = [
|
||||
$options = $field_definition->getSetting('handler_settings') ?: [];
|
||||
$options += [
|
||||
'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);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,74 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Core\Entity\EntityReferenceSelection;
|
||||
|
||||
use Drupal\Core\Entity\EntityManagerInterface;
|
||||
use Drupal\Core\Extension\ModuleHandlerInterface;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Provides common methods and injects services for core selection handlers.
|
||||
*/
|
||||
trait SelectionTrait {
|
||||
|
||||
/**
|
||||
* The entity manager service.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityManagerInterface
|
||||
*/
|
||||
protected $entityManager;
|
||||
|
||||
/**
|
||||
* The module handler service.
|
||||
*
|
||||
* @var \Drupal\Core\Extension\ModuleHandlerInterface
|
||||
*/
|
||||
protected $moduleHandler;
|
||||
|
||||
/**
|
||||
* The current user.
|
||||
*
|
||||
* @var \Drupal\Core\Session\AccountInterface
|
||||
*/
|
||||
protected $currentUser;
|
||||
|
||||
/**
|
||||
* Constructs a new selection 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 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')
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -2,8 +2,7 @@
|
|||
|
||||
namespace Drupal\Core\Entity\Plugin\EntityReferenceSelection;
|
||||
|
||||
use Drupal\Core\Database\Query\SelectInterface;
|
||||
use Drupal\Core\Entity\EntityReferenceSelection\SelectionInterface;
|
||||
use Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginBase;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
|
||||
/**
|
||||
|
|
@ -14,28 +13,19 @@ use Drupal\Core\Form\FormStateInterface;
|
|||
* label = @Translation("Broken/Missing")
|
||||
* )
|
||||
*/
|
||||
class Broken implements SelectionInterface {
|
||||
class Broken extends SelectionPluginBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
|
||||
$form = parent::buildConfigurationForm($form, $form_state);
|
||||
$form['selection_handler'] = [
|
||||
'#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}
|
||||
*/
|
||||
|
|
@ -57,9 +47,4 @@ class Broken implements SelectionInterface {
|
|||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function entityQueryAlter(SelectInterface $query) { }
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,19 +4,14 @@ namespace Drupal\Core\Entity\Plugin\EntityReferenceSelection;
|
|||
|
||||
use Drupal\Component\Utility\Html;
|
||||
use Drupal\Core\Database\Query\AlterableInterface;
|
||||
use Drupal\Core\Database\Query\SelectInterface;
|
||||
use Drupal\Core\Entity\EntityManagerInterface;
|
||||
use Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginBase;
|
||||
use Drupal\Core\Entity\EntityReferenceSelection\SelectionTrait;
|
||||
use Drupal\Core\Entity\EntityReferenceSelection\SelectionWithAutocreateInterface;
|
||||
use Drupal\Core\Entity\FieldableEntityInterface;
|
||||
use Drupal\Core\Extension\ModuleHandlerInterface;
|
||||
use Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Entity\EntityReferenceSelection\SelectionInterface;
|
||||
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
|
||||
use Drupal\Core\Plugin\PluginBase;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Drupal\user\EntityOwnerInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Default plugin implementation of the Entity Reference Selection plugin.
|
||||
|
|
@ -38,88 +33,38 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
|
|||
* deriver = "Drupal\Core\Entity\Plugin\Derivative\DefaultSelectionDeriver"
|
||||
* )
|
||||
*/
|
||||
class DefaultSelection extends PluginBase implements SelectionInterface, SelectionWithAutocreateInterface, ContainerFactoryPluginInterface {
|
||||
class DefaultSelection extends SelectionPluginBase implements ContainerFactoryPluginInterface, SelectionWithAutocreateInterface {
|
||||
|
||||
/**
|
||||
* The entity manager.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityManagerInterface
|
||||
*/
|
||||
protected $entityManager;
|
||||
|
||||
/**
|
||||
* The module handler service.
|
||||
*
|
||||
* @var \Drupal\Core\Extension\ModuleHandlerInterface
|
||||
*/
|
||||
protected $moduleHandler;
|
||||
|
||||
/**
|
||||
* The current user.
|
||||
*
|
||||
* @var \Drupal\Core\Session\AccountInterface
|
||||
*/
|
||||
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;
|
||||
}
|
||||
use SelectionTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
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 += [
|
||||
public function defaultConfiguration() {
|
||||
return [
|
||||
// For the 'target_bundles' setting, a NULL value is equivalent to "allow
|
||||
// entities from any bundle to be referenced" and an empty array value is
|
||||
// equivalent to "no entities from any bundle can be referenced".
|
||||
'target_bundles' => NULL,
|
||||
'sort' => [
|
||||
'field' => '_none',
|
||||
'direction' => 'ASC',
|
||||
],
|
||||
'auto_create' => FALSE,
|
||||
'auto_create_bundle' => NULL,
|
||||
];
|
||||
] + parent::defaultConfiguration();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
|
||||
$form = parent::buildConfigurationForm($form, $form_state);
|
||||
|
||||
$configuration = $this->getConfiguration();
|
||||
$entity_type_id = $configuration['target_type'];
|
||||
$entity_type = $this->entityManager->getDefinition($entity_type_id);
|
||||
$bundles = $this->entityManager->getBundleInfo($entity_type_id);
|
||||
|
||||
if ($entity_type->hasKey('bundle')) {
|
||||
$bundle_options = [];
|
||||
|
|
@ -132,7 +77,7 @@ class DefaultSelection extends PluginBase implements SelectionInterface, Selecti
|
|||
'#type' => 'checkboxes',
|
||||
'#title' => $this->t('Bundles'),
|
||||
'#options' => $bundle_options,
|
||||
'#default_value' => (array) $selection_handler_settings['target_bundles'],
|
||||
'#default_value' => (array) $configuration['target_bundles'],
|
||||
'#required' => TRUE,
|
||||
'#size' => 6,
|
||||
'#multiple' => TRUE,
|
||||
|
|
@ -189,7 +134,7 @@ class DefaultSelection extends PluginBase implements SelectionInterface, Selecti
|
|||
] + $fields,
|
||||
'#ajax' => TRUE,
|
||||
'#limit_validation_errors' => [],
|
||||
'#default_value' => $selection_handler_settings['sort']['field'],
|
||||
'#default_value' => $configuration['sort']['field'],
|
||||
];
|
||||
|
||||
$form['sort']['settings'] = [
|
||||
|
|
@ -198,12 +143,7 @@ class DefaultSelection extends PluginBase implements SelectionInterface, Selecti
|
|||
'#process' => [[EntityReferenceItem::class, 'formProcessMergeParent']],
|
||||
];
|
||||
|
||||
if ($selection_handler_settings['sort']['field'] != '_none') {
|
||||
// Merge-in default values.
|
||||
$selection_handler_settings['sort'] += [
|
||||
'direction' => 'ASC',
|
||||
];
|
||||
|
||||
if ($configuration['sort']['field'] != '_none') {
|
||||
$form['sort']['settings']['direction'] = [
|
||||
'#type' => 'select',
|
||||
'#title' => $this->t('Sort direction'),
|
||||
|
|
@ -212,7 +152,7 @@ class DefaultSelection extends PluginBase implements SelectionInterface, Selecti
|
|||
'ASC' => $this->t('Ascending'),
|
||||
'DESC' => $this->t('Descending'),
|
||||
],
|
||||
'#default_value' => $selection_handler_settings['sort']['direction'],
|
||||
'#default_value' => $configuration['sort']['direction'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -220,17 +160,17 @@ class DefaultSelection extends PluginBase implements SelectionInterface, Selecti
|
|||
$form['auto_create'] = [
|
||||
'#type' => 'checkbox',
|
||||
'#title' => $this->t("Create referenced entities if they don't already exist"),
|
||||
'#default_value' => $selection_handler_settings['auto_create'],
|
||||
'#default_value' => $configuration['auto_create'],
|
||||
'#weight' => -2,
|
||||
];
|
||||
|
||||
if ($entity_type->hasKey('bundle')) {
|
||||
$bundles = array_intersect_key($bundle_options, array_filter((array) $selection_handler_settings['target_bundles']));
|
||||
$bundles = array_intersect_key($bundle_options, array_filter((array) $configuration['target_bundles']));
|
||||
$form['auto_create_bundle'] = [
|
||||
'#type' => 'select',
|
||||
'#title' => $this->t('Store new items in'),
|
||||
'#options' => $bundles,
|
||||
'#default_value' => $selection_handler_settings['auto_create_bundle'],
|
||||
'#default_value' => $configuration['auto_create_bundle'],
|
||||
'#access' => count($bundles) > 1,
|
||||
'#states' => [
|
||||
'visible' => [
|
||||
|
|
@ -248,6 +188,8 @@ class DefaultSelection extends PluginBase implements SelectionInterface, Selecti
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
|
||||
parent::validateConfigurationForm($form, $form_state);
|
||||
|
||||
// If no checkboxes were checked for 'target_bundles', store NULL ("all
|
||||
// bundles are referenceable") rather than empty array ("no bundle is
|
||||
// referenceable" - typically happens when all referenceable bundles have
|
||||
|
|
@ -261,11 +203,6 @@ class DefaultSelection extends PluginBase implements SelectionInterface, Selecti
|
|||
$form_state->unsetValue(['settings', 'handler_settings', 'target_bundles_update']);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitConfigurationForm(array &$form, FormStateInterface $form_state) { }
|
||||
|
||||
/**
|
||||
* Form element validation handler; Filters the #value property of an element.
|
||||
*/
|
||||
|
|
@ -278,7 +215,7 @@ class DefaultSelection extends PluginBase implements SelectionInterface, Selecti
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function getReferenceableEntities($match = NULL, $match_operator = 'CONTAINS', $limit = 0) {
|
||||
$target_type = $this->configuration['target_type'];
|
||||
$target_type = $this->getConfiguration()['target_type'];
|
||||
|
||||
$query = $this->buildEntityQuery($match, $match_operator);
|
||||
if ($limit > 0) {
|
||||
|
|
@ -353,8 +290,9 @@ class DefaultSelection extends PluginBase implements SelectionInterface, Selecti
|
|||
*/
|
||||
public function validateReferenceableNewEntities(array $entities) {
|
||||
return array_filter($entities, function ($entity) {
|
||||
if (isset($this->configuration['handler_settings']['target_bundles'])) {
|
||||
return in_array($entity->bundle(), $this->configuration['handler_settings']['target_bundles']);
|
||||
$target_bundles = $this->getConfiguration()['target_bundles'];
|
||||
if (isset($target_bundles)) {
|
||||
return in_array($entity->bundle(), $target_bundles);
|
||||
}
|
||||
return TRUE;
|
||||
});
|
||||
|
|
@ -374,23 +312,23 @@ class DefaultSelection extends PluginBase implements SelectionInterface, Selecti
|
|||
* it.
|
||||
*/
|
||||
protected function buildEntityQuery($match = NULL, $match_operator = 'CONTAINS') {
|
||||
$target_type = $this->configuration['target_type'];
|
||||
$handler_settings = $this->configuration['handler_settings'];
|
||||
$configuration = $this->getConfiguration();
|
||||
$target_type = $configuration['target_type'];
|
||||
$entity_type = $this->entityManager->getDefinition($target_type);
|
||||
|
||||
$query = $this->entityManager->getStorage($target_type)->getQuery();
|
||||
|
||||
// If 'target_bundles' is NULL, all bundles are referenceable, no further
|
||||
// conditions are needed.
|
||||
if (isset($handler_settings['target_bundles']) && is_array($handler_settings['target_bundles'])) {
|
||||
if (is_array($configuration['target_bundles'])) {
|
||||
// If 'target_bundles' is an empty array, no bundle is referenceable,
|
||||
// force the query to never return anything and bail out early.
|
||||
if ($handler_settings['target_bundles'] === []) {
|
||||
if ($configuration['target_bundles'] === []) {
|
||||
$query->condition($entity_type->getKey('id'), NULL, '=');
|
||||
return $query;
|
||||
}
|
||||
else {
|
||||
$query->condition($entity_type->getKey('bundle'), $handler_settings['target_bundles'], 'IN');
|
||||
$query->condition($entity_type->getKey('bundle'), $configuration['target_bundles'], 'IN');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -406,21 +344,13 @@ class DefaultSelection extends PluginBase implements SelectionInterface, Selecti
|
|||
$query->addMetaData('entity_reference_selection_handler', $this);
|
||||
|
||||
// Add the sort option.
|
||||
if (!empty($handler_settings['sort'])) {
|
||||
$sort_settings = $handler_settings['sort'];
|
||||
if ($sort_settings['field'] != '_none') {
|
||||
$query->sort($sort_settings['field'], $sort_settings['direction']);
|
||||
}
|
||||
if ($configuration['sort']['field'] !== '_none') {
|
||||
$query->sort($configuration['sort']['field'], $configuration['sort']['direction']);
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function entityQueryAlter(SelectInterface $query) { }
|
||||
|
||||
/**
|
||||
* Helper method: Passes a query to the alteration system again.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -66,6 +66,8 @@ class CommentSelection extends DefaultSelection {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function entityQueryAlter(SelectInterface $query) {
|
||||
parent::entityQueryAlter($query);
|
||||
|
||||
$tables = $query->getTables();
|
||||
$data_table = 'comment_field_data';
|
||||
if (!isset($tables['comment_field_data']['alias'])) {
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ base_file_field_field_settings:
|
|||
label: 'Reference method'
|
||||
handler_settings:
|
||||
type: entity_reference_selection.[%parent.handler]
|
||||
label: 'Entity reference selection settings'
|
||||
label: 'File selection handler settings'
|
||||
file_directory:
|
||||
type: string
|
||||
label: 'File directory'
|
||||
|
|
|
|||
|
|
@ -74,9 +74,7 @@ class EntityReferenceSelectionAccessTest extends BrowserTestBase {
|
|||
$selection_options = [
|
||||
'target_type' => 'node',
|
||||
'handler' => 'default',
|
||||
'handler_settings' => [
|
||||
'target_bundles' => NULL,
|
||||
],
|
||||
];
|
||||
|
||||
// Build a set of test data.
|
||||
|
|
@ -200,10 +198,8 @@ class EntityReferenceSelectionAccessTest extends BrowserTestBase {
|
|||
$selection_options = [
|
||||
'target_type' => 'user',
|
||||
'handler' => 'default',
|
||||
'handler_settings' => [
|
||||
'target_bundles' => NULL,
|
||||
'include_anonymous' => TRUE,
|
||||
],
|
||||
];
|
||||
|
||||
// Build a set of test data.
|
||||
|
|
@ -322,7 +318,7 @@ class EntityReferenceSelectionAccessTest extends BrowserTestBase {
|
|||
$this->assertReferenceable($selection_options, $referenceable_tests, 'User handler (admin)');
|
||||
|
||||
// Test the 'include_anonymous' option.
|
||||
$selection_options['handler_settings']['include_anonymous'] = FALSE;
|
||||
$selection_options['include_anonymous'] = FALSE;
|
||||
$referenceable_tests = [
|
||||
[
|
||||
'arguments' => [
|
||||
|
|
@ -361,9 +357,7 @@ class EntityReferenceSelectionAccessTest extends BrowserTestBase {
|
|||
$selection_options = [
|
||||
'target_type' => 'comment',
|
||||
'handler' => 'default',
|
||||
'handler_settings' => [
|
||||
'target_bundles' => NULL,
|
||||
],
|
||||
];
|
||||
|
||||
// Build a set of test data.
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
namespace Drupal\taxonomy\Plugin\EntityReferenceSelection;
|
||||
|
||||
use Drupal\Component\Utility\Html;
|
||||
use Drupal\Core\Database\Query\SelectInterface;
|
||||
use Drupal\Core\Entity\Plugin\EntityReferenceSelection\DefaultSelection;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\taxonomy\Entity\Vocabulary;
|
||||
|
|
@ -24,8 +23,13 @@ class TermSelection extends DefaultSelection {
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function entityQueryAlter(SelectInterface $query) {
|
||||
// @todo: How to set access, as vocabulary is now config?
|
||||
public function defaultConfiguration() {
|
||||
return [
|
||||
'sort' => [
|
||||
'field' => 'name',
|
||||
'direction' => 'asc',
|
||||
]
|
||||
] + parent::defaultConfiguration();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -49,15 +53,13 @@ class TermSelection extends DefaultSelection {
|
|||
*/
|
||||
public function getReferenceableEntities($match = NULL, $match_operator = 'CONTAINS', $limit = 0) {
|
||||
if ($match || $limit) {
|
||||
$this->configuration['handler_settings']['sort'] = ['field' => 'name', 'direction' => 'asc'];
|
||||
return parent::getReferenceableEntities($match, $match_operator, $limit);
|
||||
}
|
||||
|
||||
$options = [];
|
||||
|
||||
$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);
|
||||
$bundle_names = $this->getConfiguration()['target_bundles'] ?: array_keys($bundles);
|
||||
|
||||
foreach ($bundle_names as $bundle) {
|
||||
if ($vocabulary = Vocabulary::load($bundle)) {
|
||||
|
|
|
|||
|
|
@ -166,8 +166,10 @@ condition.plugin.user_role:
|
|||
sequence:
|
||||
type: string
|
||||
|
||||
# Schema for the entity reference 'default:user' selection handler settings.
|
||||
entity_reference_selection.default:user:
|
||||
type: entity_reference_selection
|
||||
type: entity_reference_selection.default
|
||||
label: 'User selection handler settings'
|
||||
mapping:
|
||||
filter:
|
||||
type: mapping
|
||||
|
|
|
|||
|
|
@ -83,21 +83,26 @@ class UserSelection extends DefaultSelection {
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
|
||||
$selection_handler_settings = $this->configuration['handler_settings'];
|
||||
|
||||
// Merge in default values.
|
||||
$selection_handler_settings += [
|
||||
public function defaultConfiguration() {
|
||||
return [
|
||||
'filter' => [
|
||||
'type' => '_none',
|
||||
'role' => NULL,
|
||||
],
|
||||
'include_anonymous' => TRUE,
|
||||
];
|
||||
] + parent::defaultConfiguration();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
|
||||
$configuration = $this->getConfiguration();
|
||||
|
||||
$form['include_anonymous'] = [
|
||||
'#type' => 'checkbox',
|
||||
'#title' => $this->t('Include the anonymous user.'),
|
||||
'#default_value' => $selection_handler_settings['include_anonymous'],
|
||||
'#default_value' => $configuration['include_anonymous'],
|
||||
];
|
||||
|
||||
// Add user specific filter options.
|
||||
|
|
@ -110,7 +115,7 @@ class UserSelection extends DefaultSelection {
|
|||
],
|
||||
'#ajax' => TRUE,
|
||||
'#limit_validation_errors' => [],
|
||||
'#default_value' => $selection_handler_settings['filter']['type'],
|
||||
'#default_value' => $configuration['filter']['type'],
|
||||
];
|
||||
|
||||
$form['filter']['settings'] = [
|
||||
|
|
@ -119,18 +124,13 @@ class UserSelection extends DefaultSelection {
|
|||
'#process' => [['\Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem', 'formProcessMergeParent']],
|
||||
];
|
||||
|
||||
if ($selection_handler_settings['filter']['type'] == 'role') {
|
||||
// Merge in default values.
|
||||
$selection_handler_settings['filter'] += [
|
||||
'role' => NULL,
|
||||
];
|
||||
|
||||
if ($configuration['filter']['type'] == 'role') {
|
||||
$form['filter']['settings']['role'] = [
|
||||
'#type' => 'checkboxes',
|
||||
'#title' => $this->t('Restrict to the selected roles'),
|
||||
'#required' => TRUE,
|
||||
'#options' => array_diff_key(user_role_names(TRUE), [RoleInterface::AUTHENTICATED_ID => RoleInterface::AUTHENTICATED_ID]),
|
||||
'#default_value' => $selection_handler_settings['filter']['role'],
|
||||
'#default_value' => $configuration['filter']['role'],
|
||||
];
|
||||
}
|
||||
|
||||
|
|
@ -144,11 +144,12 @@ class UserSelection extends DefaultSelection {
|
|||
*/
|
||||
protected function buildEntityQuery($match = NULL, $match_operator = 'CONTAINS') {
|
||||
$query = parent::buildEntityQuery($match, $match_operator);
|
||||
$handler_settings = $this->configuration['handler_settings'];
|
||||
|
||||
$configuration = $this->getConfiguration();
|
||||
|
||||
// Filter out the Anonymous user if the selection handler is configured to
|
||||
// exclude it.
|
||||
if (isset($handler_settings['include_anonymous']) && !$handler_settings['include_anonymous']) {
|
||||
if (!$configuration['include_anonymous']) {
|
||||
$query->condition('uid', 0, '<>');
|
||||
}
|
||||
|
||||
|
|
@ -158,8 +159,8 @@ class UserSelection extends DefaultSelection {
|
|||
}
|
||||
|
||||
// Filter by role.
|
||||
if (!empty($handler_settings['filter']['role'])) {
|
||||
$query->condition('roles', $handler_settings['filter']['role'], 'IN');
|
||||
if (!empty($configuration['filter']['role'])) {
|
||||
$query->condition('roles', $configuration['filter']['role'], 'IN');
|
||||
}
|
||||
|
||||
// Adding the permission check is sadly insufficient for users: core
|
||||
|
|
@ -191,10 +192,10 @@ class UserSelection extends DefaultSelection {
|
|||
public function validateReferenceableNewEntities(array $entities) {
|
||||
$entities = parent::validateReferenceableNewEntities($entities);
|
||||
// Mirror the conditions checked in buildEntityQuery().
|
||||
if (!empty($this->configuration['handler_settings']['filter']['role'])) {
|
||||
$entities = array_filter($entities, function ($user) {
|
||||
if ($role = $this->getConfiguration()['filter']['role']) {
|
||||
$entities = array_filter($entities, function ($user) use ($role) {
|
||||
/** @var \Drupal\user\UserInterface $user */
|
||||
return !empty(array_intersect($user->getRoles(), $this->configuration['handler_settings']['filter']['role']));
|
||||
return !empty(array_intersect($user->getRoles(), $role));
|
||||
});
|
||||
}
|
||||
if (!$this->currentUser->hasPermission('administer users')) {
|
||||
|
|
@ -210,9 +211,10 @@ class UserSelection extends DefaultSelection {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function entityQueryAlter(SelectInterface $query) {
|
||||
parent::entityQueryAlter($query);
|
||||
|
||||
// Bail out early if we do not need to match the Anonymous user.
|
||||
$handler_settings = $this->configuration['handler_settings'];
|
||||
if (isset($handler_settings['include_anonymous']) && !$handler_settings['include_anonymous']) {
|
||||
if (!$this->getConfiguration()['include_anonymous']) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
# Schema for the views entity reference selection plugins.
|
||||
# Schema for the entity reference 'views' selection handler settings.
|
||||
|
||||
entity_reference_selection.views:
|
||||
type: mapping
|
||||
label: 'View handler settings'
|
||||
type: entity_reference_selection
|
||||
label: 'Views selection handler settings'
|
||||
mapping:
|
||||
view:
|
||||
type: mapping
|
||||
|
|
|
|||
|
|
@ -2,17 +2,12 @@
|
|||
|
||||
namespace Drupal\views\Plugin\EntityReferenceSelection;
|
||||
|
||||
use Drupal\Core\Database\Query\SelectInterface;
|
||||
use Drupal\Core\Entity\EntityManagerInterface;
|
||||
use Drupal\Core\Entity\EntityReferenceSelection\SelectionInterface;
|
||||
use Drupal\Core\Extension\ModuleHandlerInterface;
|
||||
use Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginBase;
|
||||
use Drupal\Core\Entity\EntityReferenceSelection\SelectionTrait;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
|
||||
use Drupal\Core\Plugin\PluginBase;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\views\Views;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Plugin implementation of the 'selection' entity_reference.
|
||||
|
|
@ -24,66 +19,9 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
|
|||
* weight = 0
|
||||
* )
|
||||
*/
|
||||
class ViewsSelection extends PluginBase implements SelectionInterface, ContainerFactoryPluginInterface {
|
||||
class ViewsSelection extends SelectionPluginBase implements ContainerFactoryPluginInterface {
|
||||
|
||||
/**
|
||||
* The entity manager.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityManagerInterface
|
||||
*/
|
||||
protected $entityManager;
|
||||
|
||||
/**
|
||||
* The module handler service.
|
||||
*
|
||||
* @var \Drupal\Core\Extension\ModuleHandlerInterface
|
||||
*/
|
||||
protected $moduleHandler;
|
||||
|
||||
/**
|
||||
* The current user.
|
||||
*
|
||||
* @var \Drupal\Core\Session\AccountInterface
|
||||
*/
|
||||
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 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')
|
||||
);
|
||||
}
|
||||
use SelectionTrait;
|
||||
|
||||
/**
|
||||
* The loaded View object.
|
||||
|
|
@ -92,12 +30,26 @@ class ViewsSelection extends PluginBase implements SelectionInterface, Container
|
|||
*/
|
||||
protected $view;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function defaultConfiguration() {
|
||||
return [
|
||||
'view' => [
|
||||
'view_name' => NULL,
|
||||
'display_name' => NULL,
|
||||
'arguments' => [],
|
||||
],
|
||||
] + parent::defaultConfiguration();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@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'] : [];
|
||||
$form = parent::buildConfigurationForm($form, $form_state);
|
||||
|
||||
$view_settings = $this->getConfiguration()['view'];
|
||||
$displays = Views::getApplicableViews('entity_reference_display');
|
||||
// Filter views that list the entity type we want, and group the separate
|
||||
// displays by view.
|
||||
|
|
@ -156,16 +108,6 @@ class ViewsSelection extends PluginBase implements SelectionInterface, Container
|
|||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function validateConfigurationForm(array &$form, FormStateInterface $form_state) { }
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitConfigurationForm(array &$form, FormStateInterface $form_state) { }
|
||||
|
||||
/**
|
||||
* Initializes a view.
|
||||
*
|
||||
|
|
@ -184,9 +126,8 @@ class ViewsSelection extends PluginBase implements SelectionInterface, Container
|
|||
* Return TRUE if the view was initialized, FALSE otherwise.
|
||||
*/
|
||||
protected function initializeView($match = NULL, $match_operator = 'CONTAINS', $limit = 0, $ids = NULL) {
|
||||
$handler_settings = $this->configuration['handler_settings'];
|
||||
$view_name = $handler_settings['view']['view_name'];
|
||||
$display_name = $handler_settings['view']['display_name'];
|
||||
$view_name = $this->getConfiguration()['view']['view_name'];
|
||||
$display_name = $this->getConfiguration()['view']['display_name'];
|
||||
|
||||
// Check that the view is valid and the display still exists.
|
||||
$this->view = Views::getView($view_name);
|
||||
|
|
@ -211,9 +152,8 @@ class ViewsSelection extends PluginBase implements SelectionInterface, Container
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function getReferenceableEntities($match = NULL, $match_operator = 'CONTAINS', $limit = 0) {
|
||||
$handler_settings = $this->configuration['handler_settings'];
|
||||
$display_name = $handler_settings['view']['display_name'];
|
||||
$arguments = $handler_settings['view']['arguments'];
|
||||
$display_name = $this->getConfiguration()['view']['display_name'];
|
||||
$arguments = $this->getConfiguration()['view']['arguments'];
|
||||
$result = [];
|
||||
if ($this->initializeView($match, $match_operator, $limit)) {
|
||||
// Get the results.
|
||||
|
|
@ -242,9 +182,8 @@ class ViewsSelection extends PluginBase implements SelectionInterface, Container
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function validateReferenceableEntities(array $ids) {
|
||||
$handler_settings = $this->configuration['handler_settings'];
|
||||
$display_name = $handler_settings['view']['display_name'];
|
||||
$arguments = $handler_settings['view']['arguments'];
|
||||
$display_name = $this->getConfiguration()['view']['display_name'];
|
||||
$arguments = $this->getConfiguration()['view']['arguments'];
|
||||
$result = [];
|
||||
if ($this->initializeView(NULL, 'CONTAINS', 0, $ids)) {
|
||||
// Get the results.
|
||||
|
|
@ -283,9 +222,4 @@ class ViewsSelection extends PluginBase implements SelectionInterface, Container
|
|||
$form_state->setValueForElement($element, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function entityQueryAlter(SelectInterface $query) { }
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -96,14 +96,12 @@ class EntityReferenceSelectionSortTest extends EntityKernelTestBase {
|
|||
$selection_options = [
|
||||
'target_type' => 'node',
|
||||
'handler' => 'default',
|
||||
'handler_settings' => [
|
||||
'target_bundles' => NULL,
|
||||
// Add sorting.
|
||||
'sort' => [
|
||||
'field' => 'field_text.value',
|
||||
'direction' => 'DESC',
|
||||
],
|
||||
],
|
||||
];
|
||||
$handler = $this->container->get('plugin.manager.entity_reference_selection')->getInstance($selection_options);
|
||||
|
||||
|
|
@ -117,7 +115,7 @@ class EntityReferenceSelectionSortTest extends EntityKernelTestBase {
|
|||
$this->assertIdentical($result['article'], $expected_result, 'Query sorted by field returned expected values.');
|
||||
|
||||
// Assert sort by base field.
|
||||
$selection_options['handler_settings']['sort'] = [
|
||||
$selection_options['sort'] = [
|
||||
'field' => 'nid',
|
||||
'direction' => 'ASC',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -0,0 +1,235 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\Core\EntityReferenceSelection;
|
||||
|
||||
use Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginBase;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
|
||||
/**
|
||||
* Provides unit testing for selection handlers.
|
||||
*
|
||||
* @coversDefaultClass \Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginBase
|
||||
*
|
||||
* @group entity_reference
|
||||
* @group legacy
|
||||
*/
|
||||
class EntityReferenceSelectionUnitTest extends UnitTestCase {
|
||||
|
||||
/**
|
||||
* Tests invalid default configuration.
|
||||
*
|
||||
* @covers ::defaultConfiguration
|
||||
* @covers ::resolveBackwardCompatibilityConfiguration
|
||||
*/
|
||||
public function testInvalidDefaultConfiguration() {
|
||||
$this->setExpectedException(\InvalidArgumentException::class, "TestSelectionWithInvalidDefaultConfiguration::defaultConfiguration() should not contain a 'handler_settings' key. All settings should be placed in the root level.");
|
||||
new TestSelectionWithInvalidDefaultConfiguration(
|
||||
[],
|
||||
'test_selector',
|
||||
['class' => 'TestSelectionWithInvalidDefaultConfiguration']
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the selection handler with malformed 'handler_settings' value.
|
||||
*
|
||||
* @covers ::setConfiguration
|
||||
* @covers ::resolveBackwardCompatibilityConfiguration
|
||||
*/
|
||||
public function testMalformedHandlerSettingsValue() {
|
||||
$this->setExpectedException(\InvalidArgumentException::class, "The setting 'handler_settings' is reserved and cannot be used.");
|
||||
new TestSelection(
|
||||
// The deprecated 'handler_setting' should be an array.
|
||||
['handler_settings' => FALSE],
|
||||
'test_selector',
|
||||
['class' => 'TestSelectionWithInvalidDefaultConfiguration']
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides test data for ::testSetConfiguration()
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @see \Drupal\Tests\Core\EntityReferenceSelection\testSetConfiguration
|
||||
*/
|
||||
public function providerTestSetConfiguration() {
|
||||
return [
|
||||
[
|
||||
[
|
||||
'setting1' => 'foo',
|
||||
'setting2' => [
|
||||
'bar' => 'bar value',
|
||||
'baz' => 'baz value',
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
[
|
||||
'handler_settings' => [
|
||||
'setting1' => 'foo',
|
||||
'setting2' => [
|
||||
'bar' => 'bar value',
|
||||
'baz' => 'baz value',
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
[
|
||||
'setting1' => 'foo',
|
||||
'handler_settings' => [
|
||||
'setting2' => [
|
||||
'bar' => 'bar value',
|
||||
'baz' => 'baz value',
|
||||
],
|
||||
]
|
||||
],
|
||||
],
|
||||
[
|
||||
[
|
||||
'setting1' => 'foo',
|
||||
'setting2' => [
|
||||
'bar' => 'bar value',
|
||||
'baz' => 'baz value',
|
||||
],
|
||||
'handler_settings' => [
|
||||
// Same setting from root level takes precedence.
|
||||
'setting2' => 'this will be overwritten',
|
||||
]
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests selection handler plugin configuration set.
|
||||
*
|
||||
* @dataProvider providerTestSetConfiguration
|
||||
* @covers ::setConfiguration
|
||||
* @covers ::resolveBackwardCompatibilityConfiguration
|
||||
* @covers ::ensureBackwardCompatibilityConfiguration
|
||||
*
|
||||
* @param array $options
|
||||
* The configuration passed to the plugin.
|
||||
*/
|
||||
public function testSetConfiguration($options) {
|
||||
$selection = new TestSelection($options, 'test_selector', []);
|
||||
|
||||
$expected = [
|
||||
'target_type' => NULL,
|
||||
'handler' => 'test_selector',
|
||||
'entity' => NULL,
|
||||
'setting1' => 'foo',
|
||||
'setting2' => [
|
||||
'qux' => 'qux value',
|
||||
'bar' => 'bar value',
|
||||
'baz' => 'baz value',
|
||||
],
|
||||
'setting3' => 'foobar',
|
||||
'handler_settings' => [
|
||||
'setting1' => 'foo',
|
||||
'setting2' => [
|
||||
'qux' => 'qux value',
|
||||
'bar' => 'bar value',
|
||||
'baz' => 'baz value',
|
||||
],
|
||||
'setting3' => 'foobar',
|
||||
],
|
||||
];
|
||||
|
||||
$this->assertArrayEquals($expected, $selection->getConfiguration());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the selection handler plugin BC structure.
|
||||
*
|
||||
* @covers ::setConfiguration
|
||||
* @covers ::resolveBackwardCompatibilityConfiguration
|
||||
* @covers ::ensureBackwardCompatibilityConfiguration
|
||||
*/
|
||||
public function testSetConfigurationBcLevel() {
|
||||
$config = [
|
||||
'target_type' => 'some_entity_type_id',
|
||||
'handler' => 'test_selector',
|
||||
'setting1' => 'foo',
|
||||
];
|
||||
$selection = new TestSelection($config, 'test_selector', []);
|
||||
|
||||
$expected = [
|
||||
'target_type' => 'some_entity_type_id',
|
||||
'handler' => 'test_selector',
|
||||
'entity' => NULL,
|
||||
'setting1' => 'foo',
|
||||
'setting2' => ['qux' => 'qux value'],
|
||||
'setting3' => 'foobar',
|
||||
'handler_settings' => [
|
||||
'setting1' => 'foo',
|
||||
'setting2' => ['qux' => 'qux value'],
|
||||
'setting3' => 'foobar',
|
||||
],
|
||||
];
|
||||
|
||||
$this->assertArrayEquals($expected, $selection->getConfiguration());
|
||||
|
||||
// Read the stored values and override a setting.
|
||||
$config = $selection->getConfiguration();
|
||||
$config['setting1'] = 'bar';
|
||||
$selection->setConfiguration($config);
|
||||
$expected['setting1'] = 'bar';
|
||||
$expected['handler_settings']['setting1'] = 'bar';
|
||||
|
||||
$this->assertArrayEquals($expected, $selection->getConfiguration());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests deprecation error triggering.
|
||||
*
|
||||
* @covers ::setConfiguration
|
||||
* @covers ::resolveBackwardCompatibilityConfiguration
|
||||
* @expectedDeprecation Providing settings under 'handler_settings' is deprecated and will be removed before 9.0.0. Move the settings in the root of the configuration array. See https://www.drupal.org/node/2870971.
|
||||
*/
|
||||
public function testDeprecationErrorTriggering() {
|
||||
// Configuration with BC level.
|
||||
$config = ['handler_settings' => ['setting1' => TRUE]];
|
||||
new TestSelection($config, 'test_selector', []);
|
||||
// Ensure at least one assertion.
|
||||
$this->assertTrue(TRUE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a testing plugin.
|
||||
*/
|
||||
class TestSelection extends SelectionPluginBase {
|
||||
|
||||
public function defaultConfiguration() {
|
||||
return [
|
||||
'setting2' => [
|
||||
'qux' => 'qux value',
|
||||
],
|
||||
'setting3' => 'foobar',
|
||||
] + parent::defaultConfiguration();
|
||||
}
|
||||
|
||||
public function getReferenceableEntities($match = NULL, $match_operator = 'CONTAINS', $limit = 0) { }
|
||||
|
||||
public function validateReferenceableEntities(array $ids) { }
|
||||
|
||||
public function countReferenceableEntities($match = NULL, $match_operator = 'CONTAINS') { }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a testing plugin with invalid default configuration.
|
||||
*/
|
||||
class TestSelectionWithInvalidDefaultConfiguration extends TestSelection {
|
||||
|
||||
public function defaultConfiguration() {
|
||||
return [
|
||||
'handler_settings' => ['foo' => 'bar'],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue