EntityViewsData::getViewsData

public EntityViewsData::getViewsData()

Returns views data for the entity type.

Return value

array Views data in the format of hook_views_data().

Overrides EntityViewsDataInterface::getViewsData

File

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

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(),
  ];
  $data[$base_table]['table']['entity revision'] = FALSE;

  if ($label_key = $this->entityType->getKey('label')) {
    if ($data_table) {
      $data[$views_base_table]['table']['base']['defaults'] = array(
        'field' => $label_key,
        'table' => $data_table,
      );
    }
    else {
      $data[$views_base_table]['table']['base']['defaults'] = array(
        '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'] = array(
      'field' => array(
        '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'] = array(
      'field' => $revision_field,
      'title' => $this->t('@entity_type revisions', array('@entity_type' => $this->entityType->getLabel())),
    );
    // Join the revision table to the base table.
    $data[$views_revision_base_table]['table']['join'][$views_base_table] = array(
      '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] = array(
        'left_field' => $revision_field,
        'field' => $revision_field,
        'type' => 'INNER',
      );
    }
  }

  $this->addEntityLinks($data[$base_table]);

  // Load all typed data definitions of all fields. This should cover each of
  // the entity base, revision, data tables.
  $field_definitions = $this->entityManager->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;
}
doc_Drupal
2016-10-29 09:09:11
Comments
Leave a Comment

Please login to continue.