diff --git a/core/modules/field/config/schema/field.views.schema.yml b/core/modules/field/config/schema/field.views.schema.yml index 56d852d..fdaeedc 100644 --- a/core/modules/field/config/schema/field.views.schema.yml +++ b/core/modules/field/config/schema/field.views.schema.yml @@ -18,7 +18,7 @@ views.argument.field_list_string: views.field.field: type: views_field - label: 'Log event message' + label: 'Views field field handler' mapping: click_sort_column: type: string diff --git a/core/modules/field/src/Plugin/views/field/Field.php b/core/modules/field/src/Plugin/views/field/Field.php index f686371..eb6fe47 100644 --- a/core/modules/field/src/Plugin/views/field/Field.php +++ b/core/modules/field/src/Plugin/views/field/Field.php @@ -266,7 +266,6 @@ function get_base_table() { public function query($use_groupby = FALSE) { $this->get_base_table(); - $entity_type = $this->definition['entity_tables'][$this->base_table]; $fields = $this->additional_fields; // No need to add the entity type. $entity_type_key = array_search('entity_type', $fields); @@ -284,15 +283,11 @@ public function query($use_groupby = FALSE) { $options += is_array($this->options['group_columns']) ? $this->options['group_columns'] : array(); $fields = array(); - $rkey = $this->definition['is revision'] ? EntityStorageInterface::FIELD_LOAD_REVISION : EntityStorageInterface::FIELD_LOAD_CURRENT; + // @todo what we are doing here is right? + $rkey = !empty($this->definition['is revision']) ? EntityStorageInterface::FIELD_LOAD_REVISION : EntityStorageInterface::FIELD_LOAD_CURRENT; // Go through the list and determine the actual column name from field api. foreach ($options as $column) { - $name = $column; - if (isset($field_definition['storage_details']['sql'][$rkey][$this->table][$column])) { - $name = $field_definition['storage_details']['sql'][$rkey][$this->table][$column]; - } - - $fields[$column] = $name; + $fields[$column] = $this->getTableMapping()->getFieldColumnName($this->getFieldStorage(), $column); } $this->group_fields = $fields; @@ -364,11 +359,8 @@ public function clickSort($order) { } $this->ensureMyTable(); - $entity_type_id = $this->definition['entity_type']; $field_storage = $this->getFieldStorage(); - /** @var \Drupal\Core\Entity\Sql\DefaultTableMapping $table_mapping */ - $table_mapping = $this->entityManager->getStorage($entity_type_id)->getTableMapping(); - $column = $table_mapping->getFieldColumnName($field_storage, $this->options['click_sort_column']); + $column = $this->getTableMapping()->getFieldColumnName($field_storage, $this->options['click_sort_column']); if (!isset($this->aliases[$column])) { // Column is not in query; add a sort on it (without adding the column). $this->aliases[$column] = $this->tableAlias . '.' . $column; @@ -994,4 +986,10 @@ public function getCacheContexts() { return $contexts; } + /** + * @return \Drupal\Core\Entity\Sql\DefaultTableMapping + */ + protected function getTableMapping() { + return $this->entityManager->getStorage($this->definition['entity_type'])->getTableMapping(); + } } diff --git a/core/modules/field/tests/src/Unit/Plugin/views/field/FieldTest.php b/core/modules/field/tests/src/Unit/Plugin/views/field/FieldTest.php index cfac240..a74cd48 100644 --- a/core/modules/field/tests/src/Unit/Plugin/views/field/FieldTest.php +++ b/core/modules/field/tests/src/Unit/Plugin/views/field/FieldTest.php @@ -153,7 +153,7 @@ public function testCalculateDependenciesWithConfiguredField() { ]; $handler = new Field([], 'field', $definition, $this->entityManager, $this->formatterPluginManager, $this->fieldTypePluginManager, $this->languageManager); - $body_storage = $this->getFieldStorageConfig(); + $body_storage = $this->getConfigFieldStorage(); $this->entityManager->expects($this->atLeastOnce()) ->method('getFieldStorageDefinitions') ->with('test_entity') @@ -305,7 +305,7 @@ public function testClickSortWithConfiguredField($order) { $handler = new Field([], 'field', $definition, $this->entityManager, $this->formatterPluginManager, $this->fieldTypePluginManager, $this->languageManager); $handler->view = $this->executable; - $field_storage = $this->getFieldStorageConfig(); + $field_storage = $this->getConfigFieldStorage(); $this->entityManager->expects($this->atLeastOnce()) ->method('getFieldStorageDefinitions') ->with('test_entity') @@ -349,6 +349,120 @@ public function testClickSortWithConfiguredField($order) { $handler->clickSort($order); } + public function testQueryWithGroupByForBaseField() { + $definition = [ + 'entity_type' => 'test_entity', + 'field_name' => 'title', + 'entity_tables' => ['test_entity_table' => 'test_entity'], + ]; + $handler = new Field([], 'field', $definition, $this->entityManager, $this->formatterPluginManager, $this->fieldTypePluginManager, $this->languageManager); + $handler->view = $this->executable; + + $field_storage = $this->getBaseFieldStorage(); + $this->entityManager->expects($this->any()) + ->method('getFieldStorageDefinitions') + ->with('test_entity') + ->willReturn([ + 'title' => $field_storage, + ]); + + $table_mapping = $this->getMock('Drupal\Core\Entity\Sql\TableMappingInterface'); + $table_mapping + ->expects($this->any()) + ->method('getFieldColumnName') + ->with($field_storage, 'value') + ->willReturn('title'); + $entity_storage = $this->getMock('Drupal\Core\Entity\Sql\SqlEntityStorageInterface'); + $entity_storage->expects($this->any()) + ->method('getTableMapping') + ->willReturn($table_mapping); + $this->entityManager->expects($this->any()) + ->method('getStorage') + ->with('test_entity') + ->willReturn($entity_storage); + + $options = [ + 'group_column' => 'value', + 'group_columns' => [], + 'table' => 'test_entity_table', + ]; + $handler->init($this->executable, $this->display, $options); + + $query = $this->getMockBuilder('Drupal\views\Plugin\views\query\Sql') + ->disableOriginalConstructor() + ->getMock(); + $query->expects($this->once()) + ->method('ensureTable') + ->with('test_entity_table', NULL) + ->willReturn('test_entity_table'); + // Ensure that we add the title field to the query, if we group by some + // other field in the view. + $query->expects($this->once()) + ->method('addField') + ->with('test_entity_table', 'title'); + + $this->executable->query = $query; + + $handler->query(TRUE); + } + + public function testQueryWithGroupByForConfigField() { + $definition = [ + 'entity_type' => 'test_entity', + 'field_name' => 'body', + 'entity_tables' => ['test_entity_table' => 'test_entity'], + ]; + $handler = new Field([], 'field', $definition, $this->entityManager, $this->formatterPluginManager, $this->fieldTypePluginManager, $this->languageManager); + $handler->view = $this->executable; + + $field_storage = $this->getConfigFieldStorage(); + $this->entityManager->expects($this->any()) + ->method('getFieldStorageDefinitions') + ->with('test_entity') + ->willReturn([ + 'body' => $field_storage, + ]); + + $table_mapping = $this->getMock('Drupal\Core\Entity\Sql\TableMappingInterface'); + $table_mapping + ->expects($this->any()) + ->method('getFieldColumnName') + ->with($field_storage, 'value') + ->willReturn('body_value'); + $entity_storage = $this->getMock('Drupal\Core\Entity\Sql\SqlEntityStorageInterface'); + $entity_storage->expects($this->any()) + ->method('getTableMapping') + ->willReturn($table_mapping); + $this->entityManager->expects($this->any()) + ->method('getStorage') + ->with('test_entity') + ->willReturn($entity_storage); + + $options = [ + 'group_column' => 'value', + 'group_columns' => [], + 'table' => 'test_entity__body', + ]; + $handler->init($this->executable, $this->display, $options); + + $query = $this->getMockBuilder('Drupal\views\Plugin\views\query\Sql') + ->disableOriginalConstructor() + ->getMock(); + $query->expects($this->once()) + ->method('ensureTable') + ->with('test_entity__body', NULL) + ->willReturn('test_entity__body'); + // Ensure that we add the title field to the query, if we group by some + // other field in the view. + $query->expects($this->once()) + ->method('addField') + ->with('test_entity__body', 'body_value'); + + $this->executable->query = $query; + + $handler->query(TRUE); + } + /** * @return \Drupal\Core\Field\FieldStorageDefinitionInterface|\PHPUnit_Framework_MockObject_MockObject */ @@ -369,7 +483,7 @@ protected function getBaseFieldStorage() { /** * @return \Drupal\field\FieldStorageConfigInterface|\PHPUnit_Framework_MockObject_MockObject */ - protected function getFieldStorageConfig() { + protected function getConfigFieldStorage() { $title_storage = $this->getMock('Drupal\field\FieldStorageConfigInterface'); $title_storage->expects($this->any()) ->method('getColumns') diff --git a/core/modules/node/config/install/views.view.content.yml b/core/modules/node/config/install/views.view.content.yml index 1bacc0d..3198a5b 100644 --- a/core/modules/node/config/install/views.view.content.yml +++ b/core/modules/node/config/install/views.view.content.yml @@ -162,10 +162,10 @@ display: hide_empty: false empty_zero: false hide_alter_empty: true + type: string settings: link_to_entity: true plugin_id: field - type: id: type table: node_field_data diff --git a/core/modules/node/config/install/views.view.content_recent.yml b/core/modules/node/config/install/views.view.content_recent.yml index 87b7a43..91d9ab8 100644 --- a/core/modules/node/config/install/views.view.content_recent.yml +++ b/core/modules/node/config/install/views.view.content_recent.yml @@ -155,8 +155,9 @@ display: hide_empty: false empty_zero: false hide_alter_empty: true - link_to_node: true - plugin_id: node + settings: + link_to_entity: true + plugin_id: field name: id: name table: users_field_data diff --git a/core/modules/views/src/Tests/Plugin/BlockDependenciesTest.php b/core/modules/views/src/Tests/Plugin/BlockDependenciesTest.php index b7ece54..2861d69 100644 --- a/core/modules/views/src/Tests/Plugin/BlockDependenciesTest.php +++ b/core/modules/views/src/Tests/Plugin/BlockDependenciesTest.php @@ -28,7 +28,7 @@ class BlockDependenciesTest extends ViewUnitTestBase { * * @var array */ - public static $modules = array('node', 'block', 'user'); + public static $modules = array('node', 'block', 'user', 'field'); /** * Tests that exposed filter blocks have the correct dependencies. diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_dropbutton.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_dropbutton.yml index 5447c42..c4ca600 100644 --- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_dropbutton.yml +++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_dropbutton.yml @@ -90,7 +90,7 @@ display: id: title table: node_field_data field: title - plugin_id: node + plugin_id: field label: '' alter: alter_text: false @@ -103,7 +103,9 @@ display: html: false hide_empty: false empty_zero: false - link_to_node: true + type: string + settings: + link_to_entity: true nothing: id: nothing table: views diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_search.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_search.yml index 1e89c1a..93f875b 100644 --- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_search.yml +++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_search.yml @@ -73,7 +73,6 @@ display: html: false hide_empty: false empty_zero: false - link_to_node: true relationship: none group_type: group admin_label: '' @@ -89,7 +88,10 @@ display: element_default_classes: true empty: '' hide_alter_empty: true - plugin_id: node + plugin_id: field + type: string + settings: + link_to_entity: true filters: status: value: true 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..fc8f37c 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 @@ -51,8 +51,10 @@ display: hide_empty: false empty_zero: false hide_alter_empty: true - link_to_node: true - plugin_id: node + type: string + settings: + link_to_entity: true + plugin_id: field filters: type: id: type