public function EntityViewsData::getViewsData in Drupal 10
Same name and namespace in other branches
- 8 core/modules/views/src/EntityViewsData.php \Drupal\views\EntityViewsData::getViewsData()
- 9 core/modules/views/src/EntityViewsData.php \Drupal\views\EntityViewsData::getViewsData()
1 method overrides EntityViewsData::getViewsData()
- EntityTestViewsData::getViewsData in core/
modules/ system/ tests/ modules/ entity_test/ src/ EntityTestViewsData.php - Returns views data for the entity type.
File
- core/
modules/ views/ src/ EntityViewsData.php, line 130
Class
- EntityViewsData
- Provides generic views integration for entities.
Namespace
Drupal\viewsCode
public function getViewsData() {
$data = [];
$base_table = $this->entityType
->getBaseTable() ?: $this->entityType
->id();
$views_revision_base_table = NULL;
$revisionable = $this->entityType
->isRevisionable();
$entity_id_key = $this->entityType
->getKey('id');
$entity_keys = $this->entityType
->getKeys();
$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';
}
$entity_revision_key = $this->entityType
->getKey('revision');
$revision_field = $entity_revision_key;
// 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' => $entity_id_key,
'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' => $entity_id_key,
'field' => $entity_id_key,
'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',
],
];
}
// Add a relationship from the revision table back to the main table.
$entity_type_label = $this->entityType
->getLabel();
$data[$views_revision_base_table][$entity_id_key]['relationship'] = [
'id' => 'standard',
'base' => $views_base_table,
'base field' => $entity_id_key,
'title' => $entity_type_label,
'help' => $this
->t('Get the actual @label from a @label revision', [
'@label' => $entity_type_label,
]),
];
$data[$views_revision_base_table][$entity_revision_key]['relationship'] = [
'id' => 'standard',
'base' => $views_base_table,
'base field' => $entity_revision_key,
'title' => $this
->t('@label revision', [
'@label' => $entity_type_label,
]),
'help' => $this
->t('Get the actual @label from a @label revision', [
'@label' => $entity_type_label,
]),
];
if ($translatable) {
$extra = [
'field' => $entity_keys['langcode'],
'left_field' => $entity_keys['langcode'],
];
$data[$views_revision_base_table][$entity_id_key]['relationship']['extra'][] = $extra;
$data[$views_revision_base_table][$entity_revision_key]['relationship']['extra'][] = $extra;
$data[$revision_table]['table']['join'][$views_base_table]['left_field'] = $entity_revision_key;
$data[$revision_table]['table']['join'][$views_base_table]['field'] = $entity_revision_key;
}
}
$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.
$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 field 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' => $entity_id_key,
'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,
],
],
];
}
}
}
if ($uid_key = $entity_keys['uid'] ?? '') {
$data[$data_table][$uid_key]['filter']['id'] = 'user_name';
}
if ($revision_table && ($revision_uid_key = $this->entityType
->getRevisionMetadataKeys()['revision_user'] ?? '')) {
$data[$revision_table][$revision_uid_key]['filter']['id'] = 'user_name';
}
}
// 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;
}