You are here

public function EntityViewsData::getViewsData in Drupal 8

Same name and namespace in other branches
  1. 9 core/modules/views/src/EntityViewsData.php \Drupal\views\EntityViewsData::getViewsData()
  2. 10 core/modules/views/src/EntityViewsData.php \Drupal\views\EntityViewsData::getViewsData()

Returns views data for the entity type.

Return value

array Views data in the format of hook_views_data().

Overrides EntityViewsDataInterface::getViewsData

10 calls to EntityViewsData::getViewsData()
AggregatorFeedViewsData::getViewsData in core/modules/aggregator/src/AggregatorFeedViewsData.php
Returns views data for the entity type.
AggregatorItemViewsData::getViewsData in core/modules/aggregator/src/AggregatorItemViewsData.php
Returns views data for the entity type.
BlockContentViewsData::getViewsData in core/modules/block_content/src/BlockContentViewsData.php
Returns views data for the entity type.
CommentViewsData::getViewsData in core/modules/comment/src/CommentViewsData.php
Returns views data for the entity type.
EntityTestViewsData::getViewsData in core/modules/system/tests/modules/entity_test/src/EntityTestViewsData.php
Returns views data for the entity type.

... See full list

10 methods override EntityViewsData::getViewsData()
AggregatorFeedViewsData::getViewsData in core/modules/aggregator/src/AggregatorFeedViewsData.php
Returns views data for the entity type.
AggregatorItemViewsData::getViewsData in core/modules/aggregator/src/AggregatorItemViewsData.php
Returns views data for the entity type.
BlockContentViewsData::getViewsData in core/modules/block_content/src/BlockContentViewsData.php
Returns views data for the entity type.
CommentViewsData::getViewsData in core/modules/comment/src/CommentViewsData.php
Returns views data for the entity type.
EntityTestViewsData::getViewsData in core/modules/system/tests/modules/entity_test/src/EntityTestViewsData.php
Returns views data for the entity type.

... See full list

File

core/modules/views/src/EntityViewsData.php, line 140

Class

EntityViewsData
Provides generic views integration for entities.

Namespace

Drupal\views

Code

public function getViewsData() {
  $data = [];
  $base_table = $this->entityType
    ->getBaseTable() ?: $this->entityType
    ->id();
  $views_revision_base_table = NULL;
  $revisionable = $this->entityType
    ->isRevisionable();
  $base_field = $this->entityType
    ->getKey('id');
  $revision_table = '';
  if ($revisionable) {
    $revision_table = $this->entityType
      ->getRevisionTable() ?: $this->entityType
      ->id() . '_revision';
  }
  $translatable = $this->entityType
    ->isTranslatable();
  $data_table = '';
  if ($translatable) {
    $data_table = $this->entityType
      ->getDataTable() ?: $this->entityType
      ->id() . '_field_data';
  }

  // Some entity types do not have a revision data table defined, but still
  // have a revision table name set in
  // \Drupal\Core\Entity\Sql\SqlContentEntityStorage::initTableLayout() so we
  // apply the same kind of logic.
  $revision_data_table = '';
  if ($revisionable && $translatable) {
    $revision_data_table = $this->entityType
      ->getRevisionDataTable() ?: $this->entityType
      ->id() . '_field_revision';
  }
  $revision_field = $this->entityType
    ->getKey('revision');

  // Setup base information of the views data.
  $data[$base_table]['table']['group'] = $this->entityType
    ->getLabel();
  $data[$base_table]['table']['provider'] = $this->entityType
    ->getProvider();
  $views_base_table = $base_table;
  if ($data_table) {
    $views_base_table = $data_table;
  }
  $data[$views_base_table]['table']['base'] = [
    'field' => $base_field,
    'title' => $this->entityType
      ->getLabel(),
    'cache_contexts' => $this->entityType
      ->getListCacheContexts(),
    'access query tag' => $this->entityType
      ->id() . '_access',
  ];
  $data[$base_table]['table']['entity revision'] = FALSE;
  if ($label_key = $this->entityType
    ->getKey('label')) {
    if ($data_table) {
      $data[$views_base_table]['table']['base']['defaults'] = [
        'field' => $label_key,
        'table' => $data_table,
      ];
    }
    else {
      $data[$views_base_table]['table']['base']['defaults'] = [
        'field' => $label_key,
      ];
    }
  }

  // Entity types must implement a list_builder in order to use Views'
  // entity operations field.
  if ($this->entityType
    ->hasListBuilderClass()) {
    $data[$base_table]['operations'] = [
      'field' => [
        'title' => $this
          ->t('Operations links'),
        'help' => $this
          ->t('Provides links to perform entity operations.'),
        'id' => 'entity_operations',
      ],
    ];
    if ($revision_table) {
      $data[$revision_table]['operations'] = [
        'field' => [
          'title' => $this
            ->t('Operations links'),
          'help' => $this
            ->t('Provides links to perform entity operations.'),
          'id' => 'entity_operations',
        ],
      ];
    }
  }
  if ($this->entityType
    ->hasViewBuilderClass()) {
    $data[$base_table]['rendered_entity'] = [
      'field' => [
        'title' => $this
          ->t('Rendered entity'),
        'help' => $this
          ->t('Renders an entity in a view mode.'),
        'id' => 'rendered_entity',
      ],
    ];
  }

  // Setup relations to the revisions/property data.
  if ($data_table) {
    $data[$base_table]['table']['join'][$data_table] = [
      'left_field' => $base_field,
      'field' => $base_field,
      'type' => 'INNER',
    ];
    $data[$data_table]['table']['group'] = $this->entityType
      ->getLabel();
    $data[$data_table]['table']['provider'] = $this->entityType
      ->getProvider();
    $data[$data_table]['table']['entity revision'] = FALSE;
  }
  if ($revision_table) {
    $data[$revision_table]['table']['group'] = $this
      ->t('@entity_type revision', [
      '@entity_type' => $this->entityType
        ->getLabel(),
    ]);
    $data[$revision_table]['table']['provider'] = $this->entityType
      ->getProvider();
    $views_revision_base_table = $revision_table;
    if ($revision_data_table) {
      $views_revision_base_table = $revision_data_table;
    }
    $data[$views_revision_base_table]['table']['entity revision'] = TRUE;
    $data[$views_revision_base_table]['table']['base'] = [
      'field' => $revision_field,
      'title' => $this
        ->t('@entity_type revisions', [
        '@entity_type' => $this->entityType
          ->getLabel(),
      ]),
    ];

    // Join the revision table to the base table.
    $data[$views_revision_base_table]['table']['join'][$views_base_table] = [
      'left_field' => $revision_field,
      'field' => $revision_field,
      'type' => 'INNER',
    ];
    if ($revision_data_table) {
      $data[$revision_data_table]['table']['group'] = $this
        ->t('@entity_type revision', [
        '@entity_type' => $this->entityType
          ->getLabel(),
      ]);
      $data[$revision_data_table]['table']['entity revision'] = TRUE;
      $data[$revision_table]['table']['join'][$revision_data_table] = [
        'left_field' => $revision_field,
        'field' => $revision_field,
        'type' => 'INNER',
      ];
    }

    // Add a filter for showing only the latest revisions of an entity.
    $data[$revision_table]['latest_revision'] = [
      'title' => $this
        ->t('Is Latest Revision'),
      'help' => $this
        ->t('Restrict the view to only revisions that are the latest revision of their entity.'),
      'filter' => [
        'id' => 'latest_revision',
      ],
    ];
    if ($this->entityType
      ->isTranslatable()) {
      $data[$revision_table]['latest_translation_affected_revision'] = [
        'title' => $this
          ->t('Is Latest Translation Affected Revision'),
        'help' => $this
          ->t('Restrict the view to only revisions that are the latest translation affected revision of their entity.'),
        'filter' => [
          'id' => 'latest_translation_affected_revision',
        ],
      ];
    }
  }
  $this
    ->addEntityLinks($data[$base_table]);
  if ($views_revision_base_table) {
    $this
      ->addEntityLinks($data[$views_revision_base_table]);
  }

  // Load all typed data definitions of all fields. This should cover each of
  // the entity base, revision, data tables.
  $field_definitions = $this->entityFieldManager
    ->getBaseFieldDefinitions($this->entityType
    ->id());

  /** @var \Drupal\Core\Entity\Sql\DefaultTableMapping $table_mapping */
  if ($table_mapping = $this->storage
    ->getTableMapping($field_definitions)) {

    // Fetch all fields that can appear in both the base table and the data
    // table.
    $entity_keys = $this->entityType
      ->getKeys();
    $duplicate_fields = array_intersect_key($entity_keys, array_flip([
      'id',
      'revision',
      'bundle',
    ]));

    // Iterate over each table we have so far and collect field data for each.
    // Based on whether the field is in the field_definitions provided by the
    // entity manager.
    // @todo We should better just rely on information coming from the entity
    //   storage.
    // @todo https://www.drupal.org/node/2337511
    foreach ($table_mapping
      ->getTableNames() as $table) {
      foreach ($table_mapping
        ->getFieldNames($table) as $field_name) {

        // To avoid confusing duplication in the user interface, for fields
        // that are on both base and data tables, only add them on the data
        // table (same for revision vs. revision data).
        if ($data_table && ($table === $base_table || $table === $revision_table) && in_array($field_name, $duplicate_fields)) {
          continue;
        }
        $this
          ->mapFieldDefinition($table, $field_name, $field_definitions[$field_name], $table_mapping, $data[$table]);
      }
    }
    foreach ($field_definitions as $field_definition) {
      if ($table_mapping
        ->requiresDedicatedTableStorage($field_definition
        ->getFieldStorageDefinition())) {
        $table = $table_mapping
          ->getDedicatedDataTableName($field_definition
          ->getFieldStorageDefinition());
        $data[$table]['table']['group'] = $this->entityType
          ->getLabel();
        $data[$table]['table']['provider'] = $this->entityType
          ->getProvider();
        $data[$table]['table']['join'][$views_base_table] = [
          'left_field' => $base_field,
          'field' => 'entity_id',
          'extra' => [
            [
              'field' => 'deleted',
              'value' => 0,
              'numeric' => TRUE,
            ],
          ],
        ];
        if ($revisionable) {
          $revision_table = $table_mapping
            ->getDedicatedRevisionTableName($field_definition
            ->getFieldStorageDefinition());
          $data[$revision_table]['table']['group'] = $this
            ->t('@entity_type revision', [
            '@entity_type' => $this->entityType
              ->getLabel(),
          ]);
          $data[$revision_table]['table']['provider'] = $this->entityType
            ->getProvider();
          $data[$revision_table]['table']['join'][$views_revision_base_table] = [
            'left_field' => $revision_field,
            'field' => 'entity_id',
            'extra' => [
              [
                'field' => 'deleted',
                'value' => 0,
                'numeric' => TRUE,
              ],
            ],
          ];
        }
      }
    }
  }

  // Add the entity type key to each table generated.
  $entity_type_id = $this->entityType
    ->id();
  array_walk($data, function (&$table_data) use ($entity_type_id) {
    $table_data['table']['entity type'] = $entity_type_id;
  });
  return $data;
}