diff --git a/core/modules/node/src/Plugin/views/wizard/NodeRevision.php b/core/modules/node/src/Plugin/views/wizard/NodeRevision.php index d7088eb7b4ef5248794179440a2e09ee43b764fb..14119d4fb56587c2f289bd1f60127caf5a26be7d 100644 --- a/core/modules/node/src/Plugin/views/wizard/NodeRevision.php +++ b/core/modules/node/src/Plugin/views/wizard/NodeRevision.php @@ -2,6 +2,7 @@ namespace Drupal\node\Plugin\views\wizard; +use Drupal\Core\Form\FormStateInterface; use Drupal\views\Plugin\views\wizard\WizardPluginBase; /** @@ -95,4 +96,48 @@ protected function defaultDisplayOptions() { return $display_options; } + /** + * {@inheritdoc} + */ + protected function defaultDisplayFiltersUser(array $form, FormStateInterface $form_state) { + $filters = []; + + $type = $form_state->getValue(['show', 'type']); + if ($type && $type != 'all') { + $filters['type'] = [ + 'id' => 'type', + 'table' => 'node_field_data', + 'field' => 'type', + 'relationship' => 'nid', + 'value' => [$type => $type], + 'entity_type' => 'node', + 'entity_field' => 'type', + 'plugin_id' => 'bundle', + ]; + } + return $filters; + } + + /** + * {@inheritdoc} + */ + protected function buildDisplayOptions($form, FormStateInterface $form_state) { + $display_options = parent::buildDisplayOptions($form, $form_state); + if (isset($display_options['default']['filters']['type'])) { + $display_options['default']['relationships']['nid'] = [ + 'id' => 'nid', + 'table' => 'node_field_revision', + 'field' => 'nid', + 'relationship' => 'none', + 'group_type' => 'group', + 'admin_label' => 'Get the actual content from a content revision.', + 'required' => 'true', + 'entity_type' => 'node', + 'entity_field' => 'nid', + 'plugin_id' => 'standard', + ]; + } + return $display_options; + } + } diff --git a/core/modules/node/tests/src/Functional/Views/NodeRevisionWizardTest.php b/core/modules/node/tests/src/Functional/Views/NodeRevisionWizardTest.php index 4cbecf314eee0d0782a9b205e9d06f1d150347c9..3a3c5723a68d36f0e89ff83521649488e8a01a15 100644 --- a/core/modules/node/tests/src/Functional/Views/NodeRevisionWizardTest.php +++ b/core/modules/node/tests/src/Functional/Views/NodeRevisionWizardTest.php @@ -21,44 +21,94 @@ public function testViewAdd() { // Create two nodes with two revision. $node_storage = \Drupal::entityManager()->getStorage('node'); /** @var \Drupal\node\NodeInterface $node */ - $node = $node_storage->create(['title' => $this->randomString(), 'type' => 'article', 'created' => REQUEST_TIME + 40]); + $node = $node_storage->create(['title' => $this->randomString(), 'type' => 'article', 'changed' => REQUEST_TIME + 40]); $node->save(); $node = $node->createDuplicate(); $node->setNewRevision(); - $node->created->value = REQUEST_TIME + 20; + $node->changed->value = REQUEST_TIME + 20; $node->save(); - $node = $node_storage->create(['title' => $this->randomString(), 'type' => 'article', 'created' => REQUEST_TIME + 30]); + $node = $node_storage->create(['title' => $this->randomString(), 'type' => 'article', 'changed' => REQUEST_TIME + 30]); $node->save(); $node = $node->createDuplicate(); $node->setNewRevision(); - $node->created->value = REQUEST_TIME + 10; + $node->changed->value = REQUEST_TIME + 10; $node->save(); + $this->drupalCreateContentType(['type' => 'not-article']); + $node = $node_storage->create(['title' => $this->randomString(), 'type' => 'not-article', 'changed' => REQUEST_TIME + 80]); + $node->save(); + + $type = [ + 'show[wizard_key]' => 'node_revision', + ]; + $this->drupalPostForm('admin/structure/views/add', $type, t('Update "Show" choice')); + $view = []; $view['label'] = $this->randomMachineName(16); $view['id'] = strtolower($this->randomMachineName(16)); $view['description'] = $this->randomMachineName(16); $view['page[create]'] = FALSE; - $view['show[wizard_key]'] = 'node_revision'; - $this->drupalPostForm('admin/structure/views/add', $view, t('Save and edit')); + $view['show[type]'] = 'article'; + $view['show[sort]'] = 'changed:DESC'; + $this->drupalPostForm(NULL, $view, t('Save and edit')); $view = Views::getView($view['id']); $view->initHandlers(); - $this->assertEqual($view->getBaseTables(), ['node_field_revision' => TRUE, '#global' => TRUE]); + $this->assertEqual($view->getBaseTables(), [ + 'node_field_revision' => TRUE, + '#global' => TRUE, + 'node_field_data' => TRUE, + ] + ); // Check for the default filters. $this->assertEqual($view->filter['status']->table, 'node_field_revision'); $this->assertEqual($view->filter['status']->field, 'status'); $this->assertTrue($view->filter['status']->value); + $this->assertEquals('node_field_data', $view->filter['type']->table); $this->executeView($view); $this->assertIdenticalResultset($view, [['vid' => 1], ['vid' => 3], ['vid' => 2], ['vid' => 4]], ['vid' => 'vid']); + + // Create a new view with no filter on type. + $type = [ + 'show[wizard_key]' => 'node_revision', + ]; + $this->drupalPostForm('admin/structure/views/add', $type, t('Update "Show" choice')); + $view = []; + $view['label'] = $this->randomMachineName(16); + $view['id'] = strtolower($this->randomMachineName(16)); + $view['description'] = $this->randomMachineName(16); + $view['page[create]'] = FALSE; + $view['show[type]'] = 'all'; + $view['show[sort]'] = 'changed:DESC'; + $this->drupalPostForm(NULL, $view, t('Save and edit')); + + $view = Views::getView($view['id']); + $view->initHandlers(); + + $this->assertEqual($view->getBaseTables(), [ + 'node_field_revision' => TRUE, + '#global' => TRUE, + ] + ); + + // Check for the default filters. + $this->assertEqual($view->filter['status']->table, 'node_field_revision'); + $this->assertEqual($view->filter['status']->field, 'status'); + $this->assertTrue($view->filter['status']->value); + $this->assertTrue(empty($view->filter['type'])); + + $this->executeView($view); + + $this->assertIdenticalResultset($view, [['vid' => 5], ['vid' => 1], ['vid' => 3], ['vid' => 2], ['vid' => 4]], + ['vid' => 'vid']); } } diff --git a/core/modules/views/src/Plugin/views/wizard/WizardPluginBase.php b/core/modules/views/src/Plugin/views/wizard/WizardPluginBase.php index badfdbe3d27b02d0a86e9832e62f023cda36528e..20ff84dad7ba2d0ee9ef51b258b7d166bc53fbcf 100644 --- a/core/modules/views/src/Plugin/views/wizard/WizardPluginBase.php +++ b/core/modules/views/src/Plugin/views/wizard/WizardPluginBase.php @@ -928,6 +928,7 @@ protected function defaultDisplayFiltersUser(array $form, FormStateInterface $fo // example, is stored in taxonomy_vocabulary, not taxonomy_term_data. module_load_include('inc', 'views_ui', 'admin'); $fields = Views::viewsDataHelper()->fetchFields($this->base_table, 'filter'); + $table = FALSE; if (isset($fields[$this->base_table . '.' . $bundle_key])) { $table = $this->base_table; } @@ -939,27 +940,34 @@ protected function defaultDisplayFiltersUser(array $form, FormStateInterface $fo } } } - $table_data = Views::viewsData()->get($table); - // If the 'in' operator is being used, map the values to an array. - $handler = $table_data[$bundle_key]['filter']['id']; - $handler_definition = Views::pluginManager('filter')->getDefinition($handler); - if ($handler == 'in_operator' || is_subclass_of($handler_definition['class'], 'Drupal\\views\\Plugin\\views\\filter\\InOperator')) { - $value = [$type => $type]; - } - // Otherwise, use just a single value. - else { - $value = $type; - } + // Some entities have bundles but don't provide their bundle data on the + // base table. In this case the entities wizard should provide a + // relationship to the relevant data. + // @see \Drupal\node\Plugin\views\wizard\NodeRevision + if (!empty($table)) { + $table_data = Views::viewsData()->get($table); + // If the 'in' operator is being used, map the values to an array. + $handler = $table_data[$bundle_key]['filter']['id']; + $handler_definition = Views::pluginManager('filter') + ->getDefinition($handler); + if ($handler == 'in_operator' || is_subclass_of($handler_definition['class'], 'Drupal\\views\\Plugin\\views\\filter\\InOperator')) { + $value = [$type => $type]; + } + // Otherwise, use just a single value. + else { + $value = $type; + } - $filters[$bundle_key] = [ - 'id' => $bundle_key, - 'table' => $table, - 'field' => $bundle_key, - 'value' => $value, - 'entity_type' => isset($table_data['table']['entity type']) ? $table_data['table']['entity type'] : NULL, - 'entity_field' => isset($table_data[$bundle_key]['entity field']) ? $table_data[$bundle_key]['entity field'] : NULL, - 'plugin_id' => $handler, - ]; + $filters[$bundle_key] = [ + 'id' => $bundle_key, + 'table' => $table, + 'field' => $bundle_key, + 'value' => $value, + 'entity_type' => isset($table_data['table']['entity type']) ? $table_data['table']['entity type'] : NULL, + 'entity_field' => isset($table_data[$bundle_key]['entity field']) ? $table_data[$bundle_key]['entity field'] : NULL, + 'plugin_id' => $handler, + ]; + } } return $filters; diff --git a/core/modules/views/tests/src/Functional/Wizard/EntityTestRevisionTest.php b/core/modules/views/tests/src/Functional/Wizard/EntityTestRevisionTest.php new file mode 100644 index 0000000000000000000000000000000000000000..2c5f52fcae312c03850158f2903f979c5e38549c --- /dev/null +++ b/core/modules/views/tests/src/Functional/Wizard/EntityTestRevisionTest.php @@ -0,0 +1,43 @@ +<?php + +namespace Drupal\Tests\views\Functional\Wizard; + +/** + * Tests wizard for generic revisionable entities. + * + * @group Views + */ +class EntityTestRevisionTest extends WizardTestBase { + + /** + * {@inheritdoc} + */ + public static $modules = ['entity_test']; + + /** + * Tests creating a view of revisions where the type is not on the base table. + */ + public function testRevisionsViewWithNoTypeOnBaseTable() { + $type = [ + 'show[wizard_key]' => 'standard:entity_test_rev_revision', + ]; + $this->drupalPostForm('admin/structure/views/add', $type, t('Update "Show" choice')); + $view = []; + $view['label'] = $this->randomMachineName(16); + $view['id'] = strtolower($this->randomMachineName(16)); + $view['description'] = $this->randomMachineName(16); + $view['page[create]'] = FALSE; + $view['show[type]'] = 'entity_test_rev'; + $this->drupalPostForm(NULL, $view, t('Save and edit')); + + $view_storage_controller = \Drupal::entityTypeManager()->getStorage('view'); + /** @var \Drupal\views\Entity\View $view */ + $view = $view_storage_controller->load($view['id']); + + $display_options = $view->getDisplay('default')['display_options']; + // Ensure that no filters exist on 'type' since that data is not available + // on the base table. + $this->assertEmpty($display_options['filters']); + } + +}