diff --git a/core/modules/views/lib/Drupal/views/Plugin/Derivative/ViewsEntityArgumentValidator.php b/core/modules/views/lib/Drupal/views/Plugin/Derivative/ViewsEntityArgumentValidator.php new file mode 100644 index 0000000..48eb9a9 --- /dev/null +++ b/core/modules/views/lib/Drupal/views/Plugin/Derivative/ViewsEntityArgumentValidator.php @@ -0,0 +1,57 @@ +derivatives) && !empty($this->derivatives[$derivative_id])) { + return $this->derivatives[$derivative_id]; + } + $this->getDerivativeDefinitions($base_plugin_definition); + return $this->derivatives[$derivative_id]; + } + + /** + * {@inheritdoc} + */ + public function getDerivativeDefinitions(array $base_plugin_definition) { + $entity_info = \Drupal::entityManager()->getDefinitions(); + foreach ($entity_info as $entity_type => $entity_info) { + $this->derivatives[$entity_type] = array( + 'id' => 'entity:' . $entity_type, + 'module' => 'views', + 'title' => $entity_info['label'], + 'help' => t('Validate @label', array('@label' => $entity_info['label'])), + 'entity_type' => $entity_type, + 'class' => $base_plugin_definition['class'], + ); + } + + return $this->derivatives; + } +} diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/argument/ArgumentPluginBase.php b/core/modules/views/lib/Drupal/views/Plugin/views/argument/ArgumentPluginBase.php index 862a847..e33aa2d 100644 --- a/core/modules/views/lib/Drupal/views/Plugin/views/argument/ArgumentPluginBase.php +++ b/core/modules/views/lib/Drupal/views/Plugin/views/argument/ArgumentPluginBase.php @@ -294,7 +294,7 @@ public function buildOptionsForm(&$form, &$form_state) { $form['validate']['type'] = array( '#type' => 'select', '#title' => t('Validator'), - '#default_value' => $this->options['validate']['type'], + '#default_value' => str_replace(':', '-', $this->options['validate']['type']), '#states' => array( 'visible' => array( ':input[name="options[specify_validation]"]' => array('checked' => TRUE), @@ -327,8 +327,9 @@ public function buildOptionsForm(&$form, &$form_state) { $plugin = $this->getPlugin('argument_validator', $id); if ($plugin) { if ($plugin->access() || $this->options['validate']['type'] == $id) { - $form['validate']['options'][$id] = array( - '#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..323e60d --- /dev/null +++ b/core/modules/views/lib/Drupal/views/Plugin/views/argument_validator/Entity.php @@ -0,0 +1,153 @@ +entityManager = $entity_manager; + } + + /** + * {@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'); + + return $options; + } + + /** + * {@inheritdoc} + */ + public function buildOptionsForm(&$form, &$form_state) { + parent::buildOptionsForm($form, $form_state); + + $entity_type = $this->definition['entity_type']; + $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($this->definition['entity_type']); + $bundle_options = array(); + foreach ($bundles as $bundle_id => $bundle_info) { + $bundle_options[$bundle_id] = $bundle_info['label']; + } + $storage_controller = $this->entityManager->getStorageController($this->definition['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][' . 'entity-' . $entity_type . '][access]"]' => array('checked' => TRUE), + ), + ), + ); + } + + /** + * {@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']; + + $entity = entity_load($entity_type, $argument); + if (! $entity) { + return FALSE; + } + // 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; + } +}