diff --git a/core/modules/taxonomy/src/Plugin/views/argument_default/Tid.php b/core/modules/taxonomy/src/Plugin/views/argument_default/Tid.php index a1496c2..e1aae9d 100644 --- a/core/modules/taxonomy/src/Plugin/views/argument_default/Tid.php +++ b/core/modules/taxonomy/src/Plugin/views/argument_default/Tid.php @@ -234,4 +234,16 @@ public function getCacheContexts() { return ['cache.context.url']; } + /** + * {@inheritdoc} + */ + public function calculateDependencies() { + $dependencies = parent::calculateDependencies(); + + foreach ($this->vocabularyStorage->loadMultiple(array_keys($this->options['vids'])) as $vocabulary) { + $dependencies[$vocabulary->getConfigDependencyKey()][] = $vocabulary->getConfigDependencyName(); + } + return $dependencies; + } + } diff --git a/core/modules/user/src/Plugin/views/argument_validator/User.php b/core/modules/user/src/Plugin/views/argument_validator/User.php index 0cf7ad9..20b94f4 100644 --- a/core/modules/user/src/Plugin/views/argument_validator/User.php +++ b/core/modules/user/src/Plugin/views/argument_validator/User.php @@ -101,4 +101,18 @@ protected function validateEntity(EntityInterface $entity) { return $role_check_success && parent::validateEntity($entity); } + /** + * {@inheritdoc} + */ + public function calculateDependencies() { + $dependencies = parent::calculateDependencies(); + + foreach ($this->entityManager->getStorage('user_role')->loadMultiple(array_keys($this->options['roles'])) as $role) { + $dependencies[$role->getConfigDependencyKey()][] = $role->getConfigDependencyName(); + } + + return $dependencies; + } + + } diff --git a/core/modules/views/src/Entity/View.php b/core/modules/views/src/Entity/View.php index e42058e..472ce79 100644 --- a/core/modules/views/src/Entity/View.php +++ b/core/modules/views/src/Entity/View.php @@ -281,9 +281,6 @@ public function calculateDependencies() { // Collect all dependencies of plugins. foreach (Views::getPluginTypes('plugin') as $plugin_type) { - // Argument validator/default plugins do not return a plugin. - // @todo https://www.drupal.org/node/2368767 Calculate argument - // validator/default plugin dependencies. if (!$plugin = $display->getPlugin($plugin_type)) { continue; } diff --git a/core/modules/views/src/Plugin/views/argument/ArgumentPluginBase.php b/core/modules/views/src/Plugin/views/argument/ArgumentPluginBase.php index 785e024..698c786 100644 --- a/core/modules/views/src/Plugin/views/argument/ArgumentPluginBase.php +++ b/core/modules/views/src/Plugin/views/argument/ArgumentPluginBase.php @@ -7,6 +7,8 @@ namespace Drupal\views\Plugin\views\argument; +use Drupal\Component\Plugin\DependentPluginInterface; +use Drupal\Component\Utility\NestedArray; use Drupal\Component\Utility\String as UtilityString; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Render\Element; @@ -1223,6 +1225,24 @@ public function getCacheContexts() { return $contexts; } + /** + * {@inheritdoc} + */ + public function calculateDependencies() { + $dependencies = []; + if (($argument_default = $this->getPlugin('argument_default')) && $argument_default instanceof DependentPluginInterface) { + $dependencies = NestedArray::mergeDeep($dependencies, $argument_default->calculateDependencies()); + } + if (($argument_validator = $this->getPlugin('argument_validator')) && $argument_validator instanceof DependentPluginInterface) { + $dependencies = NestedArray::mergeDeep($dependencies, $argument_validator->calculateDependencies()); + } + if (($style = $this->getPlugin('style')) && $style instanceof DependentPluginInterface) { + $dependencies = NestedArray::mergeDeep($dependencies, $style->calculateDependencies()); + } + + return $dependencies; + } + } /** diff --git a/core/modules/views/src/Plugin/views/argument_validator/Entity.php b/core/modules/views/src/Plugin/views/argument_validator/Entity.php index 110b5bb..fe2175c 100644 --- a/core/modules/views/src/Plugin/views/argument_validator/Entity.php +++ b/core/modules/views/src/Plugin/views/argument_validator/Entity.php @@ -220,11 +220,16 @@ public function calculateDependencies() { $entity_type_id = $this->definition['entity_type']; $bundle_entity_type = $this->entityManager->getDefinition($entity_type_id)->getBundleEntityType(); - $bundle_entity_storage = $this->entityManager->getStorage($bundle_entity_type); - foreach (array_keys($this->options['bundles']) as $bundle) { - $bundle_entity = $bundle_entity_storage->load($bundle); - $dependencies[$bundle_entity->getConfigDependencyKey()][] = $bundle_entity->getConfigDependencyName(); + // The bundle entity type might not exist. For example, users do not have + // bundles. + if ($this->entityManager->hasHandler($bundle_entity_type, 'storage')) { + $bundle_entity_storage = $this->entityManager->getStorage($bundle_entity_type); + + $test = $bundle_entity_storage->loadMultiple(array_keys($this->options['bundles'])); + foreach ($bundle_entity_storage->loadMultiple(array_keys($this->options['bundles'])) as $bundle_entity) { + $dependencies[$bundle_entity->getConfigDependencyKey()][] = $bundle_entity->getConfigDependencyName(); + } } return $dependencies; diff --git a/core/modules/views/src/Tests/Entity/ViewEntityDependenciesTest.php b/core/modules/views/src/Tests/Entity/ViewEntityDependenciesTest.php index bc03cc0..cc750fa 100644 --- a/core/modules/views/src/Tests/Entity/ViewEntityDependenciesTest.php +++ b/core/modules/views/src/Tests/Entity/ViewEntityDependenciesTest.php @@ -23,14 +23,14 @@ class ViewEntityDependenciesTest extends ViewUnitTestBase { * * @var array */ - public static $testViews = ['test_field_get_entity', 'test_relationship_dependency', 'test_plugin_dependencies']; + public static $testViews = ['test_field_get_entity', 'test_relationship_dependency', 'test_plugin_dependencies', 'test_argument_dependency']; /** * Modules to enable. * * @var array */ - public static $modules = ['node', 'comment', 'user', 'field', 'text', 'entity_reference']; + public static $modules = ['node', 'comment', 'user', 'field', 'text', 'entity_reference', 'search']; /** * {@inheritdoc} @@ -39,7 +39,7 @@ protected function setUp() { parent::setUp(); // Install the necessary dependencies for node type creation to work. $this->installEntitySchema('node'); - $this->installConfig(array('field')); + $this->installConfig(array('field', 'node')); } /** @@ -96,7 +96,6 @@ public function testCalculateDependencies() { $expected['test_plugin_dependencies'] = [ 'module' => [ 'comment', - // The argument handler has an explicit dependency on views_test_data. 'views_test_data', ], 'content' => [ @@ -105,6 +104,23 @@ public function testCalculateDependencies() { 'StyleTest', ] ]; + + $expected['test_argument_dependency'] = [ + 'config' => [ + 'core.entity_view_mode.node.teaser' + ], + 'content' => [ + 'ArgumentDefaultTest', + 'ArgumentValidatorTest' + ], + 'module' => [ + 'node', + // The argument handler is provided by the search module. + 'search', + 'user' + ], + ]; + foreach ($this::$testViews as $view_id) { $view = Views::getView($view_id); diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_argument_dependency.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_argument_dependency.yml new file mode 100644 index 0000000..fce7f88 --- /dev/null +++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_argument_dependency.yml @@ -0,0 +1,220 @@ +langcode: en +status: true +dependencies: + config: + - core.entity_view_mode.node.teaser + content: + - ArgumentDefaultTest + - ArgumentValidatorTest + module: + - node + - search + - user +id: test_argument_dependency +label: test_argument_dependency +module: views +description: '' +tag: '' +base_table: node +base_field: nid +core: 8.x +display: + default: + display_plugin: default + id: default + display_title: Master + position: 0 + display_options: + access: + type: perm + options: + perm: 'access content' + cache: + type: none + options: { } + query: + type: views_query + options: + disable_sql_rewrite: false + distinct: false + replica: false + query_comment: false + query_tags: { } + exposed_form: + type: basic + options: + submit_button: Apply + reset_button: false + reset_button_label: Reset + exposed_sorts_label: 'Sort by' + expose_sort_order: true + sort_asc_label: Asc + sort_desc_label: Desc + pager: + type: full + options: + items_per_page: 10 + offset: 0 + id: 0 + total_pages: null + expose: + items_per_page: false + items_per_page_label: 'Items per page' + items_per_page_options: '5, 10, 25, 50' + items_per_page_options_all: false + items_per_page_options_all_label: '- All -' + offset: false + offset_label: Offset + tags: + previous: '‹ previous' + next: 'next ›' + first: '« first' + last: 'last »' + quantity: 9 + style: + type: default + row: + type: 'entity:node' + options: + view_mode: teaser + fields: + title: + id: title + table: node_field_data + field: title + entity_type: node + entity_field: title + label: '' + alter: + alter_text: false + make_link: false + absolute: false + trim: false + word_boundary: false + ellipsis: false + strip_tags: false + html: false + hide_empty: false + empty_zero: false + link_to_node: true + plugin_id: node + relationship: none + group_type: group + admin_label: '' + exclude: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_alter_empty: true + filters: + status: + value: true + table: node_field_data + field: status + plugin_id: boolean + entity_type: node + entity_field: status + id: status + expose: + operator: '' + group: 1 + sorts: + created: + id: created + table: node_field_data + field: created + order: DESC + entity_type: node + entity_field: created + plugin_id: date + relationship: none + group_type: group + admin_label: '' + exposed: false + expose: + label: '' + granularity: second + title: safa + header: { } + footer: { } + empty: { } + relationships: { } + arguments: + keys: + id: keys + table: node_search_index + field: keys + relationship: none + group_type: group + admin_label: '' + default_action: ignore + exception: + value: all + title_enable: false + title: All + title_enable: false + title: '' + default_argument_type: fixed + default_argument_options: + argument: '' + default_argument_skip_url: false + summary_options: + base_path: '' + count: true + items_per_page: 25 + override: false + summary: + sort_order: asc + number_of_records: 0 + format: default_summary + specify_validation: false + validate: + type: none + fail: 'not found' + validate_options: { } + plugin_id: search + uid: + id: uid + table: node_field_revision + field: uid + relationship: none + group_type: group + admin_label: '' + default_action: default + exception: + value: all + title_enable: false + title: All + title_enable: false + title: '' + default_argument_type: argument_default_test + default_argument_options: { } + default_argument_skip_url: false + summary_options: + base_path: '' + count: true + items_per_page: 25 + override: false + summary: + sort_order: asc + number_of_records: 0 + format: default_summary + specify_validation: false + validate: + type: argument_validator_test + fail: 'not found' + validate_options: { } + break_phrase: false + not: false + entity_type: node + entity_field: uid + plugin_id: numeric + display_extenders: { } + field_langcode: '***LANGUAGE_language_content***' + field_langcode_add_to_query: null diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_plugin_dependencies.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_plugin_dependencies.yml index 52edf70..acd118f 100644 --- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_plugin_dependencies.yml +++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_plugin_dependencies.yml @@ -21,15 +21,6 @@ display: display_options: access: type: test_static - arguments: - 'null': - default_action: default - default_argument_type: fixed - id: 'null' - must_not_be: false - table: views - field: null - plugin_id: 'null' cache: type: none exposed_form: diff --git a/core/modules/views/tests/modules/views_test_data/config/schema/views_test_data.views.schema.yml b/core/modules/views/tests/modules/views_test_data/config/schema/views_test_data.views.schema.yml index 74892c4..ffc5bd9 100644 --- a/core/modules/views/tests/modules/views_test_data/config/schema/views_test_data.views.schema.yml +++ b/core/modules/views/tests/modules/views_test_data/config/schema/views_test_data.views.schema.yml @@ -95,3 +95,10 @@ views.display_extender.display_extender_test: views.display_extender.display_extender_test2: type: views.display_extender.display_extender_test + +views.argument_default.argument_default_test: + type: ignore + +views.argument_validator.argument_validator_test: + type: ignore + diff --git a/core/modules/views/tests/modules/views_test_data/src/Plugin/views/argument_validator/ArgumentValidatorTest.php b/core/modules/views/tests/modules/views_test_data/src/Plugin/views/argument_validator/ArgumentValidatorTest.php new file mode 100644 index 0000000..9cc4081 --- /dev/null +++ b/core/modules/views/tests/modules/views_test_data/src/Plugin/views/argument_validator/ArgumentValidatorTest.php @@ -0,0 +1,30 @@ + ['ArgumentValidatorTest'], + ]; + } + +} diff --git a/core/modules/views/tests/src/Unit/Plugin/argument_validator/EntityTest.php b/core/modules/views/tests/src/Unit/Plugin/argument_validator/EntityTest.php index 250cc0e..0a00f8b 100644 --- a/core/modules/views/tests/src/Unit/Plugin/argument_validator/EntityTest.php +++ b/core/modules/views/tests/src/Unit/Plugin/argument_validator/EntityTest.php @@ -95,6 +95,7 @@ protected function setUp() { $this->entityManager->expects($this->any()) ->method('getStorage') + ->with('entity_test') ->will($this->returnValue($storage)); $this->executable = $this->getMockBuilder('Drupal\views\ViewExecutable') @@ -174,6 +175,54 @@ public function testValidateArgumentBundle() { } /** + * @covers ::calculateDependencies + */ + public function testCalculateDependencies() { + // Create an entity manager, storage, entity type, and entity to mock the + // loading of entities providing bundles. + $entityManager = $this->getMock('Drupal\Core\Entity\EntityManagerInterface'); + $storage = $this->getMock('Drupal\Core\Entity\EntityStorageInterface'); + $entity_type = $this->getMock('Drupal\Core\Entity\EntityTypeInterface'); + $mock_entity = $this->getMock('Drupal\Core\Entity\EntityInterface'); + + $mock_entity->expects($this->any()) + ->method('getConfigDependencyKey') + ->willReturn('config'); + $mock_entity->expects($this->any()) + ->method('getConfigDependencyName') + ->willReturn('test_bundle'); + $storage->expects($this->any()) + ->method('loadMultiple') + ->with(['test_bundle']) + ->willReturn(['test_bundle' => $mock_entity]); + + $entity_type->expects($this->any()) + ->method('getBundleEntityType') + ->willReturn('entity_test_bundle'); + $entityManager->expects($this->any()) + ->method('getDefinition') + ->with('entity_test') + ->willReturn($entity_type); + $entityManager->expects($this->any()) + ->method('hasHandler') + ->with('entity_test_bundle', 'storage') + ->willReturn(TRUE); + $entityManager->expects($this->any()) + ->method('getStorage') + ->with('entity_test_bundle') + ->willReturn($storage); + + // Set up the argument validator. + $argumentValidator = new Entity(array(), 'entity_test', ['entity_type' => 'entity_test'], $entityManager); + $options = array(); + $options['access'] = FALSE; + $options['bundles'] = array('test_bundle' => 1); + $argumentValidator->init($this->executable, $this->display, $options); + + $this->assertEquals(['config'=>['test_bundle']], $argumentValidator->calculateDependencies()); + } + + /** * Tests the validate argument method with multiple argument splitting. */ public function testValidateArgumentMultiple() {