diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/views/argument_validator/Term.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/views/argument_validator/Term.php
index 7491199..56a4701 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/views/argument_validator/Term.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/views/argument_validator/Term.php
@@ -9,20 +9,12 @@
use Drupal\views\ViewExecutable;
use Drupal\views\Plugin\views\display\DisplayPluginBase;
-use Drupal\Component\Annotation\Plugin;
-use Drupal\Core\Annotation\Translation;
-use Drupal\views\Plugin\views\argument_validator\ArgumentValidatorPluginBase;
+use Drupal\views\Plugin\views\argument_validator\Entity;
/**
- * Validate whether an argument is an acceptable node.
- *
- * @Plugin(
- * id = "taxonomy_term",
- * module = "taxonomy",
- * title = @Translation("Taxonomy term")
- * )
+ * Adds legacy vocabulary handling to standard Entity Argument validation..
*/
-class Term extends ArgumentValidatorPluginBase {
+class Term extends Entity {
/**
* Overrides \Drupal\views\Plugin\views\Plugin\views\PluginBase::init().
@@ -41,166 +33,4 @@ public function init(ViewExecutable $view, DisplayPluginBase $display, array &$o
}
}
}
-
- protected function defineOptions() {
- $options = parent::defineOptions();
- $options['vids'] = array('default' => array());
- $options['type'] = array('default' => 'tid');
- $options['transform'] = array('default' => FALSE, 'bool' => TRUE);
-
- return $options;
- }
-
- public function buildOptionsForm(&$form, &$form_state) {
- $vocabularies = entity_load_multiple('taxonomy_vocabulary');
- $options = array();
- foreach ($vocabularies as $voc) {
- $options[$voc->id()] = $voc->label();
- }
-
- $form['vids'] = array(
- '#type' => 'checkboxes',
- '#prefix' => '
',
+ $sanitized_id = str_replace(':', '-', $id);
+ $form['validate']['options'][$sanitized_id] = array(
+ '#prefix' => '
',
'#suffix' => '
',
'#type' => 'item',
// Even if the plugin has no options add the key to the form_state.
@@ -336,14 +337,14 @@ public function buildOptionsForm(&$form, &$form_state) {
'#states' => array(
'visible' => array(
':input[name="options[specify_validation]"]' => array('checked' => TRUE),
- ':input[name="options[validate][type]"]' => array('value' => $id),
+ ':input[name="options[validate][type]"]' => array('value' => $sanitized_id),
),
),
- '#id' => 'edit-options-validate-options-' . $id,
+ '#id' => 'edit-options-validate-options-' . $sanitized_id,
'#default_value' => array(),
);
- $plugin->buildOptionsForm($form['validate']['options'][$id], $form_state);
- $validate_types[$id] = $info['title'];
+ $plugin->buildOptionsForm($form['validate']['options'][$sanitized_id], $form_state);
+ $validate_types[$sanitized_id] = $info['title'];
}
}
}
@@ -385,10 +386,12 @@ public function validateOptionsForm(&$form, &$form_state) {
$plugin->validateOptionsForm($form['summary']['options'][$summary_id], $form_state, $form_state['values']['options']['summary']['options'][$summary_id]);
}
- $validate_id = $form_state['values']['options']['validate']['type'];
+ $sanitized_id = $form_state['values']['options']['validate']['type'];
+ // Correct ID for js sanitized version.
+ $validate_id = str_replace('-', ':', $sanitized_id);
$plugin = $this->getPlugin('argument_validator', $validate_id);
if ($plugin) {
- $plugin->validateOptionsForm($form['validate']['options'][$default_id], $form_state, $form_state['values']['options']['validate']['options'][$validate_id]);
+ $plugin->validateOptionsForm($form['validate']['options'][$default_id], $form_state, $form_state['values']['options']['validate']['options'][$sanitized_id]);
}
}
@@ -418,11 +421,13 @@ public function submitOptionsForm(&$form, &$form_state) {
$form_state['values']['options']['summary_options'] = $options;
}
- $validate_id = $form_state['values']['options']['validate']['type'];
+ $sanitized_id = $form_state['values']['options']['validate']['type'];
+ // Correct ID for js sanitized version.
+ $form_state['values']['options']['validate']['type'] = $validate_id = str_replace('-', ':', $sanitized_id);
$plugin = $this->getPlugin('argument_validator', $validate_id);
if ($plugin) {
- $options = &$form_state['values']['options']['validate']['options'][$validate_id];
- $plugin->submitOptionsForm($form['validate']['options'][$validate_id], $form_state, $options);
+ $options = &$form_state['values']['options']['validate']['options'][$sanitized_id];
+ $plugin->submitOptionsForm($form['validate']['options'][$sanitized_id], $form_state, $options);
// Copy the now submitted options to their final resting place so they get saved.
$form_state['values']['options']['validate_options'] = $options;
}
diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/argument_validator/Entity.php b/core/modules/views/lib/Drupal/views/Plugin/views/argument_validator/Entity.php
new file mode 100644
index 0000000..c087ec7
--- /dev/null
+++ b/core/modules/views/lib/Drupal/views/Plugin/views/argument_validator/Entity.php
@@ -0,0 +1,204 @@
+entityManager = $entity_manager;
+ $this->multipleCapable = TRUE;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function create(ContainerInterface $container, array $configuration, $plugin_id, array $plugin_definition) {
+ return new static(
+ $configuration,
+ $plugin_id,
+ $plugin_definition,
+ $container->get('plugin.manager.entity')
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function defineOptions() {
+ $options = parent::defineOptions();
+
+ $options['bundles'] = array('default' => array());
+ $options['access'] = array('default' => FALSE, 'bool' => TRUE);
+ $options['operation'] = array('default' => 'view');
+ $options['multiple'] = array('default' => FALSE, 'bool' => TRUE);
+
+ return $options;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildOptionsForm(&$form, &$form_state) {
+ parent::buildOptionsForm($form, $form_state);
+
+ $entity_type = $this->definition['entity_type'];
+ // Derivative id's are all entity:entity_type and converted back on
+ // submission. Other child classes can use another id.
+ $sanitized_id = str_replace(':', '-', $this->definition['id']);
+ $entity_definitions = $this->entityManager->getDefinitions();
+ $bundle_type = $entity_definitions[$entity_type]['entity_keys']['bundle'];
+
+ // If the entity has bundles, allow option to restrict to bundle(s).
+ if ($bundle_type) {
+ $bundles = entity_get_bundles($entity_type);
+ $bundle_options = array();
+ foreach ($bundles as $bundle_id => $bundle_info) {
+ $bundle_options[$bundle_id] = $bundle_info['label'];
+ }
+ $storage_controller = $this->entityManager->getStorageController($entity_type);
+ $fields = $storage_controller->baseFieldDefinitions();
+ $form['bundles'] = array(
+ '#title' => $entity_definitions[$entity_type]['bundle_label'],
+ '#default_value' => $this->options['bundles'],
+ '#type' => 'checkboxes',
+ '#options' => $bundle_options,
+ '#description' => t('Restrict to one or more %bundle_name. If none selected all are allowed.', array('%bundle_name' => $fields[$bundle_type]['label'])),
+ );
+ }
+
+ // Offer the option to filter by access to the entity in the argument.
+ $form['access'] = array(
+ '#type' => 'checkbox',
+ '#title' => t('Validate user has access to the %name', array('%name' => $entity_definitions[$entity_type]['label'])),
+ '#default_value' => $this->options['access'],
+ );
+ $form['operation'] = array(
+ '#type' => 'radios',
+ '#title' => t('Access operation to check'),
+ '#options' => array('view' => t('View'), 'update' => t('Edit'), 'delete' => t('Delete')),
+ '#default_value' => $this->options['operation'],
+ '#states' => array(
+ 'visible' => array(
+ ':input[name="options[validate][options][' . $sanitized_id . '][access]"]' => array('checked' => TRUE),
+ ),
+ ),
+ );
+
+ // If class is multiple capable give the option to validate single/multiple.
+ if ($this->multipleCapable) {
+ $form['multiple'] = array(
+ '#type' => 'radios',
+ '#title' => t('Multiple arguments'),
+ '#options' => array(
+ 0 => t('Single ID', array('%type' => $entity_definitions[$entity_type]['label'])),
+ 1 => t('One or more IDs separated by , or +', array('%type' => $entity_definitions[$entity_type]['label'])),
+ ),
+ '#default_value' => (string) $this->options['multiple'],
+ );
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function submitOptionsForm(&$form, &$form_state, &$options = array()) {
+ // Filter out unused options so we don't store giant unnecessary arrays.
+ $options['bundles'] = array_filter($options['bundles']);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function validateArgument($argument) {
+ $entity_type = $this->definition['entity_type'];
+
+ if ($this->options['multiple']) {
+ // At this point only interested in individual IDs no matter what type,
+ // just splitting by the allowed delimiters.
+ $ids = array_filter(preg_split('/[,+ ]/', $argument));
+ }
+ else {
+ $ids = array($argument);
+ }
+
+ $entities = entity_load_multiple($entity_type, $ids);
+ // Validate each id => entity. If any fails break out and return false.
+ foreach ($ids as $id) {
+ // There is no entity for this ID.
+ if (! isset($entities[$id])) {
+ return FALSE;
+ }
+ if (! $this->validateEntity($entities[$id])) {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+ }
+
+ /**
+ * Validate an individual entity against class access settings.
+ *
+ * @param Entity $entity
+ *
+ * @return bool
+ * True if validated.
+ */
+ protected function validateEntity(\Drupal\Core\Entity\Entity $entity) {
+ // If access restricted by entity operation.
+ if ($this->options['access'] && ! $entity->access($this->options['operation'])) {
+ return FALSE;
+ }
+ // If restricted by bundle.
+ $bundles = $this->options['bundles'];
+ if (count($bundles) && empty($bundles[$entity->bundle()])) {
+ return FALSE;
+ }
+
+ return TRUE;
+ }
+}