diff --git a/core/modules/views/src/EntityViewsData.php b/core/modules/views/src/EntityViewsData.php index fb3d08a..c2d95b7 100644 --- a/core/modules/views/src/EntityViewsData.php +++ b/core/modules/views/src/EntityViewsData.php @@ -349,17 +349,19 @@ protected function mapFieldDefinition($table, $field_name, FieldDefinitionInterf $data = []; /** @var \Drupal\views\Plugin\views\FieldTypeViewsDataInterface $field_type_views_data_plugin */ - if ($field_type_views_data_plugin = $this->fieldTypeViewsData->createInstance($field_definition_type)) { - $data = $field_type_views_data_plugin->getViewsData($field_storage_definition); - } - else { - foreach ($field_column_mapping as $field_column_name => $schema_field_name) { - $views_field_name = ($multiple) ? $field_name . '__' . $field_column_name : $field_name; - $data[$views_field_name] = $this->mapSingleFieldViewsData($table, $field_name, $field_definition_type, $field_column_name, $field_schema['columns'][$field_column_name]['type'], $first, $field_definition); + $field_type_views_data_plugin = $this->fieldTypeViewsData->createInstance($field_definition_type); + foreach ($field_column_mapping as $field_column_name => $schema_field_name) { + $views_field_name = ($multiple) ? $field_name . '__' . $field_column_name : $field_name; - $data[$views_field_name]['entity field'] = $field_name; - $first = FALSE; + if ($field_type_views_data_plugin) { + $data[$views_field_name] = $field_type_views_data_plugin->getViewsData($field_storage_definition, $field_column_name); } + else { + $data[$views_field_name] = $this->mapSingleFieldViewsData($table, $field_name, $field_definition_type, $field_column_name, $field_schema['columns'][$field_column_name]['type'], $first, $field_definition); + } + + $data[$views_field_name]['entity field'] = $field_name; + $first = FALSE; } $this->moduleHandler->alter('field_type_views_data_alter', $data, $field_definition, $field_storage_definition); @@ -427,13 +429,6 @@ protected function mapSingleFieldViewsData($table, $field_name, $field_type, $co $views_field['sort']['id'] = 'standard'; break; - case 'boolean': - $views_field['field']['id'] = 'field'; - $views_field['argument']['id'] = 'numeric'; - $views_field['filter']['id'] = 'boolean'; - $views_field['sort']['id'] = 'standard'; - break; - case 'uri': // Let's render URIs as URIs by default, not links. $views_field['field']['id'] = 'field'; @@ -526,54 +521,6 @@ protected function processViewsDataForLanguage($table, FieldDefinitionInterface } /** - * Processes the views data for an entity reference field. - * - * @param string $table - * The table the language field is added to. - * @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition - * The field definition. - * @param array $views_field - * The views field data. - * @param string $field_column_name - * The field column being processed. - */ - protected function processViewsDataForEntityReference($table, FieldDefinitionInterface $field_definition, array &$views_field, $field_column_name) { - - // @todo Should the actual field handler respect that this just renders a - // number? - // @todo Create an optional entity field handler, that can render the - // entity. - // @see https://www.drupal.org/node/2322949 - - if ($entity_type_id = $field_definition->getItemDefinition()->getSetting('target_type')) { - $entity_type = $this->entityManager->getDefinition($entity_type_id); - if ($entity_type instanceof ContentEntityType) { - $views_field['relationship'] = [ - 'base' => $this->getViewsTableForEntityType($entity_type), - 'base field' => $entity_type->getKey('id'), - 'label' => $entity_type->getLabel(), - 'title' => $entity_type->getLabel(), - 'id' => 'standard', - ]; - $views_field['field']['id'] = 'field'; - $views_field['argument']['id'] = 'numeric'; - $views_field['filter']['id'] = 'numeric'; - $views_field['sort']['id'] = 'standard'; - } - else { - $views_field['field']['id'] = 'field'; - $views_field['argument']['id'] = 'string'; - $views_field['filter']['id'] = 'string'; - $views_field['sort']['id'] = 'standard'; - } - } - - if ($field_definition->getName() == $this->entityType->getKey('bundle')) { - $views_field['filter']['id'] = 'bundle'; - } - } - - /** * Processes the views data for a text field with formatting. * * @param string $table diff --git a/core/modules/views/src/Plugin/views/FieldTypeViewsData/Boolean.php b/core/modules/views/src/Plugin/views/FieldTypeViewsData/Boolean.php new file mode 100644 index 0000000..2311725 --- /dev/null +++ b/core/modules/views/src/Plugin/views/FieldTypeViewsData/Boolean.php @@ -0,0 +1,41 @@ +getMainPropertyName() == $column_name) { + $views_field['title'] = $field_storage->getLabel(); + } + else { + $views_field['title'] = $field_storage->getLabel() . " ($column_name)"; + } + + if ($description = $field_storage->getDescription()) { + $views_field['help'] = $description; + } + + $views_field['field']['id'] = 'field'; + $views_field['argument']['id'] = 'numeric'; + $views_field['filter']['id'] = 'boolean'; + $views_field['sort']['id'] = 'standard'; + + return $views_field; + } + +} diff --git a/core/modules/views/src/Plugin/views/FieldTypeViewsData/EntityReference.php b/core/modules/views/src/Plugin/views/FieldTypeViewsData/EntityReference.php new file mode 100644 index 0000000..c78b598 --- /dev/null +++ b/core/modules/views/src/Plugin/views/FieldTypeViewsData/EntityReference.php @@ -0,0 +1,86 @@ +entityTypeManager = $entityTypeManager; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { + return new static( + $container->get('entity_type.manager') + ); + } + + /** + * {@inheritdoc} + */ + public function getViewsData(FieldStorageDefinitionInterface $field_storage, $column_name) { + // @todo Should the actual field handler respect that this just renders a + // number? + // @todo Create an optional entity field handler, that can render the + // entity. + // @see https://www.drupal.org/node/2322949 + $views_field = []; + + /** @var \Drupal\views\EntityViewsDataInterface $views_data */ + $views_data = $this->entityTypeManager->getHandler($field_storage->getTargetEntityTypeId(), 'views_data'); + + if ($entity_type_id = $field_storage->getSetting('target_type')) { + $entity_type = $this->entityTypeManager->getDefinition($entity_type_id); + if ($entity_type instanceof ContentEntityType) { + $views_field['relationship'] = [ + 'base' => $views_data->getViewsTableForEntityType($entity_type), + 'base field' => $entity_type->getKey('id'), + 'label' => $entity_type->getLabel(), + 'title' => $entity_type->getLabel(), + 'id' => 'standard', + ]; + $views_field['field']['id'] = 'field'; + $views_field['argument']['id'] = 'numeric'; + $views_field['filter']['id'] = 'numeric'; + $views_field['sort']['id'] = 'standard'; + } + else { + $views_field['field']['id'] = 'field'; + $views_field['argument']['id'] = 'string'; + $views_field['filter']['id'] = 'string'; + $views_field['sort']['id'] = 'standard'; + } + } + + if ($field_storage->getName() == $this->entityTypeManager->getDefinition($field_storage->getTargetEntityTypeId())->getKey('bundle')) { + $views_field['filter']['id'] = 'bundle'; + } + + return $views_field; + } + +} diff --git a/core/modules/views/src/Plugin/views/FieldTypeViewsDataInterface.php b/core/modules/views/src/Plugin/views/FieldTypeViewsDataInterface.php index 193629e..3bdc346 100644 --- a/core/modules/views/src/Plugin/views/FieldTypeViewsDataInterface.php +++ b/core/modules/views/src/Plugin/views/FieldTypeViewsDataInterface.php @@ -9,6 +9,6 @@ /** * @return array */ - public function getViewsData(FieldStorageDefinitionInterface $field_storage); + public function getViewsData(FieldStorageDefinitionInterface $field_storage, $column_name); } diff --git a/core/modules/views/tests/src/Unit/EntityViewsDataTest.php b/core/modules/views/tests/src/Unit/EntityViewsDataTest.php index c1db0cf..ecf6ff4 100644 --- a/core/modules/views/tests/src/Unit/EntityViewsDataTest.php +++ b/core/modules/views/tests/src/Unit/EntityViewsDataTest.php @@ -7,11 +7,13 @@ namespace Drupal\Tests\views\Unit { -use Drupal\Core\Config\Entity\ConfigEntityType; + use Drupal\Component\Plugin\PluginManagerInterface; + use Drupal\Core\Config\Entity\ConfigEntityType; use Drupal\Core\Entity\ContentEntityType; use Drupal\Core\Entity\EntityType; use Drupal\Core\Entity\EntityTypeInterface; -use Drupal\Core\Field\BaseFieldDefinition; + use Drupal\Core\Entity\EntityTypeManagerInterface; + use Drupal\Core\Field\BaseFieldDefinition; use Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem; use Drupal\Core\Field\Plugin\Field\FieldType\IntegerItem; use Drupal\Core\Field\Plugin\Field\FieldType\LanguageItem; @@ -25,7 +27,10 @@ use Drupal\entity_test\Entity\EntityTestMulRev; use Drupal\Tests\UnitTestCase; use Drupal\views\EntityViewsData; -use Symfony\Component\DependencyInjection\ContainerBuilder; + use Drupal\views\Plugin\views\FieldTypeViewsData\Boolean; + use Drupal\views\Plugin\views\FieldTypeViewsData\EntityReference; + use Prophecy\Argument; + use Symfony\Component\DependencyInjection\ContainerBuilder; /** * @coversDefaultClass \Drupal\views\EntityViewsData @@ -106,7 +111,7 @@ protected function setUp() { $this->translationManager = $this->getStringTranslationStub(); $this->moduleHandler = $this->getMock('Drupal\Core\Extension\ModuleHandlerInterface'); - $this->viewsData = new TestEntityViewsData($this->baseEntityType, $this->entityStorage, $this->entityManager, $this->moduleHandler, $this->translationManager); + $this->viewsData = new TestEntityViewsData($this->baseEntityType, $this->entityStorage, $this->entityManager, $this->moduleHandler, $this->translationManager, $this->setupFieldTypeViewsData($this->entityManager)); $field_type_manager = $this->getMockBuilder('Drupal\Core\Field\FieldTypePluginManager') ->disableOriginalConstructor() @@ -126,6 +131,17 @@ protected function setUp() { } /** + * @return \Drupal\Component\Plugin\PluginManagerInterface + */ + protected function setupFieldTypeViewsData(EntityTypeManagerInterface $entity_type_manager) { + $field_type_views_data_manager = $this->prophesize(PluginManagerInterface::class); + $field_type_views_data_manager->createInstance('boolean')->willReturn(new Boolean()); + $field_type_views_data_manager->createInstance('entity_reference')->willReturn(new EntityReference($entity_type_manager)); + $field_type_views_data_manager->createInstance(Argument::any())->willReturn(NULL); + return $field_type_views_data_manager->reveal(); + } + + /** * Helper method to setup base fields. * * @param \Drupal\Core\Field\BaseFieldDefinition[] $base_fields