.../aggregator/src/Plugin/views/row/Rss.php | 30 +-------- core/modules/comment/src/Plugin/views/row/Rss.php | 41 +++--------- .../modules/field/src/Plugin/views/field/Field.php | 8 ++- core/modules/node/src/Plugin/views/row/Rss.php | 37 +++-------- .../src/Plugin/views/filter/TaxonomyIndexTid.php | 13 ++++ .../src/Plugin/views/relationship/NodeTermData.php | 16 +++++ core/modules/user/src/Plugin/views/access/Role.php | 16 +++++ core/modules/views/src/Entity/View.php | 3 +- core/modules/views/src/Plugin/views/area/View.php | 15 +++++ .../src/Plugin/views/argument_validator/Entity.php | 19 ++++++ .../views/src/Plugin/views/display/Page.php | 18 ++++- .../views/src/Plugin/views/filter/Bundle.php | 19 ++++++ .../views/src/Plugin/views/row/EntityRow.php | 16 +++++ .../views/src/Plugin/views/row/RssPluginBase.php | 77 ++++++++++++++++++++++ .../views/src/Tests/Handler/AreaViewTest.php | 2 +- core/modules/views/src/Tests/ViewTestData.php | 9 +-- core/modules/views/src/Tests/ViewUnitTestBase.php | 12 +++- .../views.view.test_page_display_menu.yml | 8 +-- .../test_views/views.view.test_tag_cache.yml | 39 ----------- .../modules/views_ui/src/Tests/DisplayPathTest.php | 1 + 20 files changed, 257 insertions(+), 142 deletions(-) diff --git a/core/modules/aggregator/src/Plugin/views/row/Rss.php b/core/modules/aggregator/src/Plugin/views/row/Rss.php index 2b6dba1..72410e5 100644 --- a/core/modules/aggregator/src/Plugin/views/row/Rss.php +++ b/core/modules/aggregator/src/Plugin/views/row/Rss.php @@ -7,8 +7,7 @@ namespace Drupal\aggregator\Plugin\views\row; -use Drupal\Core\Form\FormStateInterface; -use Drupal\views\Plugin\views\row\RowPluginBase; +use Drupal\views\Plugin\views\row\RssPluginBase; /** * Defines a row plugin which loads an aggregator item and renders as RSS. @@ -22,7 +21,7 @@ * display_types = {"feed"} * ) */ -class Rss extends RowPluginBase { +class Rss extends RssPluginBase { /** * The table the aggregator item is using for storage. @@ -41,30 +40,7 @@ class Rss extends RowPluginBase { /** * {@inheritdoc} */ - protected function defineOptions() { - $options = parent::defineOptions(); - - $options['view_mode'] = array('default' => 'default'); - - return $options; - } - - /** - * {@inheritdoc} - */ - public function buildOptionsForm(&$form, FormStateInterface $form_state) { - $form['view_mode'] = array( - '#type' => 'select', - '#title' => $this->t('Display type'), - '#options' => array( - 'fulltext' => $this->t('Full text'), - 'teaser' => $this->t('Title plus teaser'), - 'title' => $this->t('Title only'), - 'default' => $this->t('Use default RSS settings'), - ), - '#default_value' => $this->options['view_mode'], - ); - } + protected $entityTypeId = 'aggregator_item'; /** * {@inheritdoc} diff --git a/core/modules/comment/src/Plugin/views/row/Rss.php b/core/modules/comment/src/Plugin/views/row/Rss.php index 1dc6c8b..bbbce01 100644 --- a/core/modules/comment/src/Plugin/views/row/Rss.php +++ b/core/modules/comment/src/Plugin/views/row/Rss.php @@ -7,8 +7,7 @@ namespace Drupal\comment\Plugin\views\row; -use Drupal\Core\Form\FormStateInterface; -use Drupal\views\Plugin\views\row\RowPluginBase; +use Drupal\views\Plugin\views\row\RssPluginBase; /** * Plugin which formats the comments as RSS items. @@ -23,29 +22,15 @@ * display_types = {"feed"} * ) */ -class Rss extends RowPluginBase { +class Rss extends RssPluginBase { var $base_table = 'comment'; var $base_field = 'cid'; - protected function defineOptions() { - $options = parent::defineOptions(); - - $options['view_mode'] = array('default' => 'default'); - - return $options; - } - - public function buildOptionsForm(&$form, FormStateInterface $form_state) { - parent::buildOptionsForm($form, $form_state); - - $form['view_mode'] = array( - '#type' => 'select', - '#title' => $this->t('Display type'), - '#options' => $this->options_form_summary_options(), - '#default_value' => $this->options['view_mode'], - ); - } + /** + * {@inheritdoc} + */ + protected $entityTypeId = 'comment'; public function preRender($result) { $cids = array(); @@ -62,18 +47,10 @@ public function preRender($result) { } /** - * Return the main options, which are shown in the summary title - * - * @see views_plugin_row_node_rss::options_form_summary_options() - * @todo: Maybe provide a views_plugin_row_rss_entity and reuse this method - * in views_plugin_row_comment|node_rss.inc + * {@inheritdoc} */ - function options_form_summary_options() { - $view_modes = \Drupal::entityManager()->getViewModes('node'); - $options = array(); - foreach ($view_modes as $mode => $settings) { - $options[$mode] = $settings['label']; - } + public function buildOptionsForm_summary_options() { + $options = parent::buildOptionsForm_summary_options(); $options['title'] = $this->t('Title only'); $options['default'] = $this->t('Use site default RSS settings'); return $options; diff --git a/core/modules/field/src/Plugin/views/field/Field.php b/core/modules/field/src/Plugin/views/field/Field.php index 95dd59e..11ce27f 100644 --- a/core/modules/field/src/Plugin/views/field/Field.php +++ b/core/modules/field/src/Plugin/views/field/Field.php @@ -939,8 +939,14 @@ function field_langcode(EntityInterface $entity) { * {@inheritdoc} */ public function calculateDependencies() { + $dependencies = parent::calculateDependencies(); + // Add the module providing the configured field storage as a dependency. - return array('config' => array($this->getFieldStorageConfig()->getConfigDependencyName())); + $dependencies['config'][] = $this->getFieldStorageConfig()->getConfigDependencyName(); + // Add the module providing the formatter. + if ($this->options['type']) { + $dependencies['module'][] = $this->formatterPluginManager->getDefinition($this->options['type'])['provider']; + } } /** diff --git a/core/modules/node/src/Plugin/views/row/Rss.php b/core/modules/node/src/Plugin/views/row/Rss.php index 4ee566e..f2f5a50 100644 --- a/core/modules/node/src/Plugin/views/row/Rss.php +++ b/core/modules/node/src/Plugin/views/row/Rss.php @@ -9,8 +9,7 @@ use Drupal\Component\Utility\SafeMarkup; use Drupal\Component\Utility\String; -use Drupal\Core\Form\FormStateInterface; -use Drupal\views\Plugin\views\row\RowPluginBase; +use Drupal\views\Plugin\views\row\RssPluginBase; use Symfony\Component\DependencyInjection\ContainerInterface; use Drupal\node\NodeStorageInterface; @@ -28,7 +27,7 @@ * display_types = {"feed"} * ) */ -class Rss extends RowPluginBase { +class Rss extends RssPluginBase { // Basic properties that let the row style follow relationships. var $base_table = 'node'; @@ -39,6 +38,11 @@ class Rss extends RowPluginBase { var $nodes = array(); /** + * {@inheritdoc} + */ + protected $entityTypeId = 'node'; + + /** * The node storage * * @var \Drupal\node\NodeStorageInterface @@ -74,34 +78,11 @@ public static function create(ContainerInterface $container, array $configuratio ); } - protected function defineOptions() { - $options = parent::defineOptions(); - - $options['view_mode'] = array('default' => 'default'); - - return $options; - } - - public function buildOptionsForm(&$form, FormStateInterface $form_state) { - parent::buildOptionsForm($form, $form_state); - - $form['view_mode'] = array( - '#type' => 'select', - '#title' => $this->t('Display type'), - '#options' => $this->buildOptionsForm_summary_options(), - '#default_value' => $this->options['view_mode'], - ); - } - /** - * Return the main options, which are shown in the summary title. + * {@inheritdoc} */ public function buildOptionsForm_summary_options() { - $view_modes = \Drupal::entityManager()->getViewModes('node'); - $options = array(); - foreach ($view_modes as $mode => $settings) { - $options[$mode] = $settings['label']; - } + $options = parent::buildOptionsForm_summary_options(); $options['title'] = $this->t('Title only'); $options['default'] = $this->t('Use site default RSS settings'); return $options; diff --git a/core/modules/taxonomy/src/Plugin/views/filter/TaxonomyIndexTid.php b/core/modules/taxonomy/src/Plugin/views/filter/TaxonomyIndexTid.php index cf57b6f..9905272 100644 --- a/core/modules/taxonomy/src/Plugin/views/filter/TaxonomyIndexTid.php +++ b/core/modules/taxonomy/src/Plugin/views/filter/TaxonomyIndexTid.php @@ -374,4 +374,17 @@ public function getCacheContexts() { return $contexts; } + /** + * {@inheritdoc} + */ + public function calculateDependencies() { + $dependencies = parent::calculateDependencies(); + + $vocabulary = \Drupal::entityManager()->getStorage('taxonomy_vocabulary') + ->load($this->options['vid']); + $dependencies['config'][] = $vocabulary->getConfigDependencyName(); + + return $dependencies; + } + } diff --git a/core/modules/taxonomy/src/Plugin/views/relationship/NodeTermData.php b/core/modules/taxonomy/src/Plugin/views/relationship/NodeTermData.php index c0629c9..dc05411 100644 --- a/core/modules/taxonomy/src/Plugin/views/relationship/NodeTermData.php +++ b/core/modules/taxonomy/src/Plugin/views/relationship/NodeTermData.php @@ -103,4 +103,20 @@ public function query() { $this->alias = $this->query->addRelationship($alias, $join, 'taxonomy_term_data', $this->relationship); } + /** + * {@inheritdoc} + */ + public function calculateDependencies() { + $dependencies = parent::calculateDependencies(); + + $vocabulary_storage = \Drupal::entityManager()->getStorage('taxonomy_vocabulary'); + foreach (array_keys($this->options['vid']) as $vocabulary_id) { + if ($vocabulary = $vocabulary_storage->load($vocabulary_id)) { + $dependencies['config'][] = $vocabulary->getConfigDependencyName(); + } + } + + return $dependencies; + } + } diff --git a/core/modules/user/src/Plugin/views/access/Role.php b/core/modules/user/src/Plugin/views/access/Role.php index d821b11..a5bad55 100644 --- a/core/modules/user/src/Plugin/views/access/Role.php +++ b/core/modules/user/src/Plugin/views/access/Role.php @@ -92,4 +92,20 @@ public function validateOptionsForm(&$form, FormStateInterface $form_state) { $form_state->setValue(array('access_options', 'role'), $role); } + /** + * {@inheritdoc} + */ + public function calculateDependencies() { + $dependencies = parent::calculateDependencies(); + + $role_storage = \Drupal::entityManager()->getStorage('role'); + foreach (array_keys($this->options['role']) as $rid) { + if ($role = $role_storage->load($rid)) { + $dependencies['config'][] = $role->getConfigDependencyName(); + } + } + + return $dependencies; + } + } diff --git a/core/modules/views/src/Entity/View.php b/core/modules/views/src/Entity/View.php index 167f169..0f0543c 100644 --- a/core/modules/views/src/Entity/View.php +++ b/core/modules/views/src/Entity/View.php @@ -254,8 +254,7 @@ public function calculateDependencies() { foreach ($executable->displayHandlers as $display) { // Add dependency for the display itself. - /** @var \Drupal\views\Plugin\views\display\DisplayPluginBase $display */ - $this->addDependency('module', $display->getProvider()); + $this->calculatePluginDependencies($display); // Collect all dependencies of all handlers. foreach ($handler_types as $handler_type) { diff --git a/core/modules/views/src/Plugin/views/area/View.php b/core/modules/views/src/Plugin/views/area/View.php index 4e228bc..03f4ba5 100644 --- a/core/modules/views/src/Plugin/views/area/View.php +++ b/core/modules/views/src/Plugin/views/area/View.php @@ -151,4 +151,19 @@ public function isEmpty() { } } + /** + * {@inheritdoc} + */ + public function calculateDependencies() { + $dependencies = parent::calculateDependencies(); + + list($view_id, $display_id) = explode(':', $this->options['view_to_insert']); + if ($view_id) { + $view = \Drupal::entityManager()->getStorage('view')->load($view_id); + $dependencies['config'][] = $view->getConfigDependencyName(); + } + + 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 ee2ab8c..b84a2ce 100644 --- a/core/modules/views/src/Plugin/views/argument_validator/Entity.php +++ b/core/modules/views/src/Plugin/views/argument_validator/Entity.php @@ -7,6 +7,7 @@ namespace Drupal\views\Plugin\views\argument_validator; +use Drupal\Core\Config\Entity\ConfigEntityInterface; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityManagerInterface; use Drupal\Core\Form\FormStateInterface; @@ -211,4 +212,22 @@ protected function validateEntity(EntityInterface $entity) { return TRUE; } + /** + * {@inheritdoc} + */ + public function calculateDependencies() { + $dependencies = parent::calculateDependencies(); + + $entity_type_id = $this->definition['entity_type']; + $bundle_entity_type = \Drupal::entityManager()->getDefinition($entity_type_id)->getBundleEntityType(); + $bundle_entity_storage = \Drupal::entityManager()->getStorage($bundle_entity_type); + + foreach (array_keys($this->options['bundles']) as $bundle) { + $bundle_entity = $bundle_entity_storage->load($bundle); + $key = $bundle_entity instanceof ConfigEntityInterface ? 'config' : 'content'; + $dependencies[$key][] = $bundle_entity->getConfigDependencyName(); + } + + return $dependencies; + } } diff --git a/core/modules/views/src/Plugin/views/display/Page.php b/core/modules/views/src/Plugin/views/display/Page.php index 3dd9a3d..8837160 100644 --- a/core/modules/views/src/Plugin/views/display/Page.php +++ b/core/modules/views/src/Plugin/views/display/Page.php @@ -202,7 +202,8 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { // Only display the parent selector if Menu UI module is enabled. $menu_parent = $menu['menu_name'] . ':' . $menu['parent']; if (\Drupal::moduleHandler()->moduleExists('menu_ui')) { - $form['menu']['parent'] = \Drupal::service('menu.parent_form_selector')->parentSelectElement($menu_parent); + $menu_link = 'views_view:views.' . $form_state->get('view')->id() . '.' . $form_state->get('display_id'); + $form['menu']['parent'] = \Drupal::service('menu.parent_form_selector')->parentSelectElement($menu_parent, $menu_link); $form['menu']['parent'] += array( '#title' => $this->t('Parent'), '#description' => $this->t('The maximum depth for a link and all its children is fixed. Some menu links may not be available as parents if selecting them would exceed this limit.'), @@ -425,4 +426,19 @@ public function getPagerText() { ); } + /** + * {@inheritdoc} + */ + public function calculateDependencies() { + $dependencies = parent::calculateDependencies(); + + $menu = $this->getOption('menu'); + if ($menu['type'] === 'normal') { + $menu_entity = \Drupal::entityManager()->getStorage('menu')->load($menu['menu_name']); + $dependencies['config'][] = $menu_entity->getConfigDependencyName(); + } + + return $dependencies; + } + } diff --git a/core/modules/views/src/Plugin/views/filter/Bundle.php b/core/modules/views/src/Plugin/views/filter/Bundle.php index 614a75c..a2a6514 100644 --- a/core/modules/views/src/Plugin/views/filter/Bundle.php +++ b/core/modules/views/src/Plugin/views/filter/Bundle.php @@ -7,6 +7,7 @@ namespace Drupal\views\Plugin\views\filter; +use Drupal\Core\Config\Entity\ConfigEntityInterface; use Drupal\views\ViewExecutable; use Drupal\views\Plugin\views\display\DisplayPluginBase; @@ -73,4 +74,22 @@ public function query() { parent::query(); } + /** + * {@inheritdoc} + */ + public function calculateDependencies() { + $dependencies = parent::calculateDependencies(); + + $bundle_entity_type = $this->entityType->getBundleEntityType(); + $bundle_entity_storage = \Drupal::entityManager()->getStorage($bundle_entity_type); + + foreach (array_keys($this->value) as $bundle) { + $bundle_entity = $bundle_entity_storage->load($bundle); + $key = $bundle_entity instanceof ConfigEntityInterface ? 'config' : 'content'; + $dependencies[$key][] = $bundle_entity->getConfigDependencyName(); + } + + return $dependencies; + } + } diff --git a/core/modules/views/src/Plugin/views/row/EntityRow.php b/core/modules/views/src/Plugin/views/row/EntityRow.php index 77f8a85..f36cb10 100644 --- a/core/modules/views/src/Plugin/views/row/EntityRow.php +++ b/core/modules/views/src/Plugin/views/row/EntityRow.php @@ -213,4 +213,20 @@ public function render($row) { return $this->getRenderer()->render($row); } + /** + * {@inheritdoc} + */ + public function calculateDependencies() { + $dependencies = parent::calculateDependencies(); + + $view_mode = \Drupal::entityManager() + ->getStorage('entity_view_mode') + ->load($this->entityTypeId . '.' . $this->options['view_mode']); + if ($view_mode) { + $dependencies['config'][] = $view_mode->getConfigDependencyName(); + } + + return $dependencies; + } + } diff --git a/core/modules/views/src/Plugin/views/row/RssPluginBase.php b/core/modules/views/src/Plugin/views/row/RssPluginBase.php new file mode 100644 index 0000000..7ed7f7c --- /dev/null +++ b/core/modules/views/src/Plugin/views/row/RssPluginBase.php @@ -0,0 +1,77 @@ + 'default'); + + return $options; + } + + /** + * {@inheritdoc} + */ + public function buildOptionsForm(&$form, FormStateInterface $form_state) { + parent::buildOptionsForm($form, $form_state); + + $form['view_mode'] = array( + '#type' => 'select', + '#title' => $this->t('Display type'), + '#options' => $this->buildOptionsForm_summary_options(), + '#default_value' => $this->options['view_mode'], + ); + } + + /** + * Return the main options, which are shown in the summary title. + */ + public function buildOptionsForm_summary_options() { + $view_modes = \Drupal::entityManager()->getViewModes($this->entityTypeId); + $options = array(); + foreach ($view_modes as $mode => $settings) { + $options[$mode] = $settings['label']; + } + return $options; + } + + /** + * {@inheritdoc} + */ + public function calculateDependencies() { + $dependencies = parent::calculateDependencies(); + + $view_mode = \Drupal::entityManager() + ->getStorage('entity_view_mode') + ->load($this->entityTypeId . '.' . $this->options['view_mode']); + if ($view_mode) { + $dependencies['config'][] = $view_mode->getConfigDependencyName(); + } + + return $dependencies; + } + +} diff --git a/core/modules/views/src/Tests/Handler/AreaViewTest.php b/core/modules/views/src/Tests/Handler/AreaViewTest.php index 16bd12e..7f93855 100644 --- a/core/modules/views/src/Tests/Handler/AreaViewTest.php +++ b/core/modules/views/src/Tests/Handler/AreaViewTest.php @@ -30,7 +30,7 @@ class AreaViewTest extends ViewUnitTestBase { * * @var array */ - public static $testViews = array('test_area_view', 'test_simple_argument'); + public static $testViews = array('test_simple_argument', 'test_area_view'); /** * Tests the view area handler. diff --git a/core/modules/views/src/Tests/ViewTestData.php b/core/modules/views/src/Tests/ViewTestData.php index 97f2d66..03c4bae 100644 --- a/core/modules/views/src/Tests/ViewTestData.php +++ b/core/modules/views/src/Tests/ViewTestData.php @@ -23,7 +23,7 @@ class ViewTestData { * Create test views from config. * * @param string $class - * The name of the test class. + * The name of the test class. Installs the listed test views *in order*. * @param array $modules * The module directories to look in for test views. */ @@ -45,9 +45,10 @@ public static function createTestViews($class, array $modules) { } $file_storage = new FileStorage($config_dir); - foreach ($file_storage->listAll('views.view.') as $config_name) { - $id = str_replace('views.view.', '', $config_name); - if (in_array($id, $views)) { + $available_views = $file_storage->listAll('views.view.'); + foreach ($views as $id) { + $config_name = 'views.view.' . $id; + if (in_array($config_name, $available_views)) { $storage ->create($file_storage->read($config_name)) ->save(); diff --git a/core/modules/views/src/Tests/ViewUnitTestBase.php b/core/modules/views/src/Tests/ViewUnitTestBase.php index a5bdd3e..6bbd44f 100644 --- a/core/modules/views/src/Tests/ViewUnitTestBase.php +++ b/core/modules/views/src/Tests/ViewUnitTestBase.php @@ -53,6 +53,15 @@ protected function setUp() { * using it, it cannot be enabled normally. */ protected function setUpFixtures() { + // First install the system module first; many Views have Page displays that + // have associated menu links, for those to work, the system menus must + // already be present. + // @todo Get rid of ViewTestData::createTestViews, in favor of fixing the + // config dependencies in all tested view config entities, which will then + // allow us to use ConfigInstaller instead, which automatically handles + // dependencies. + $this->installConfig(array('system')); + // Define the schema and views data variable before enabling the test module. \Drupal::state()->set('views_test_data_schema', $this->schemaDefinition()); \Drupal::state()->set('views_test_data_views_data', $this->viewsData()); @@ -75,9 +84,6 @@ protected function setUpFixtures() { } $query->execute(); - // Tests implementing ViewUnitTestBase depend on the theme system being - // properly configured. - $this->installConfig(array('system')); ViewTestData::createTestViews(get_class($this), array('views_test_config')); } diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_page_display_menu.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_page_display_menu.yml index c9b40a5..7467d36 100644 --- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_page_display_menu.yml +++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_page_display_menu.yml @@ -97,7 +97,7 @@ display: title: 'Test page as child' menu: type: normal - title: 'Test child' + title: 'Test child (with parent)' parent: system.admin description: '' menu_name: tools @@ -117,10 +117,10 @@ display: title: 'Tests a menu with a non-existing parent' menu: type: normal - title: 'Test child' - parent: system.admin + title: 'Test child with non-existing parent' + parent: llamasarelame description: '' - menu_name: not-existing-menu-name + menu_name: tools weight: 0 context: '0' defaults: diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_tag_cache.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_tag_cache.yml index b83e7a8..ae2ccc5 100644 --- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_tag_cache.yml +++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_tag_cache.yml @@ -53,45 +53,6 @@ display: hide_alter_empty: true link_to_node: true plugin_id: node - filters: - type: - id: type - table: node_field_data - field: type - relationship: none - group_type: group - admin_label: '' - operator: in - value: - page: page - group: 1 - exposed: false - expose: - operator_id: '' - label: '' - description: '' - use_operator: false - operator: '' - identifier: '' - required: false - remember: false - multiple: false - remember_roles: - authenticated: authenticated - reduce: false - is_grouped: false - group_info: - label: '' - description: '' - identifier: '' - optional: true - widget: select - multiple: false - remember: false - default_group: All - default_group_multiple: { } - group_items: { } - plugin_id: bundle group_by: true pager: type: some diff --git a/core/modules/views_ui/src/Tests/DisplayPathTest.php b/core/modules/views_ui/src/Tests/DisplayPathTest.php index 71b2035..144813b 100644 --- a/core/modules/views_ui/src/Tests/DisplayPathTest.php +++ b/core/modules/views_ui/src/Tests/DisplayPathTest.php @@ -145,6 +145,7 @@ public function testMenuOptions() { '
', '', '-- Compose tips (disabled)', + '-- Test child (with parent)', '-- Test menu link', ], $menu_options); }