datafield-1.x-dev/datafield.views.inc
datafield.views.inc
<?php
/**
* @file
* Provide Views data for the datafield module.
*
* @ingroup views_module_handlers
*/
use Drupal\field\FieldStorageConfigInterface;
/**
* Implements hook_field_views_data().
*/
function datafield_field_views_data(FieldStorageConfigInterface $field_storage) {
$container = \Drupal::getContainer();
if ($container->has('views.field_data_provider')) {
$data = \Drupal::service('views.field_data_provider')->defaultFieldImplementation($field_storage);
}
else {
// @phpstan-ignore-next-line
$data = views_field_default_views_data($field_storage);
}
$entity_type_manager = \Drupal::entityTypeManager();
$field_name = $field_storage->getName();
$columns = $field_storage->getSetting('columns');
$field_configs = $entity_type_manager->getStorage('field_config')->loadByProperties([
'field_name' => $field_name,
'entity_type' => $field_storage->getTargetEntityTypeId(),
]);
$field_config = reset($field_configs);
$field_settings = $field_config ? $field_config->getSetting('field_settings') : [];
$types_with_relationships = ['file', 'image', 'entity_reference'];
// Entity type information about the *host* entity.
$source_entity_type_id = $field_storage->getTargetEntityTypeId();
$source_entity_type = $entity_type_manager->getDefinition($source_entity_type_id);
$source_views_handler = $entity_type_manager->getHandler($source_entity_type_id, 'views_data');
// Iterate over each SQL column (= sub-field) and enrich Views data.
foreach ($data as $table_name => $table_data) {
foreach ($columns as $subfield_name => $column) {
$field_key = $field_name . '_' . $subfield_name;
// Always provide a basic field handler.
$data[$table_name][$field_key]['field'] = [
'id' => 'standard',
'field_name' => $field_name,
'property' => $subfield_name,
];
if (!in_array($column['type'], $types_with_relationships, TRUE)) {
continue;
}
// Find the target entity type that this sub-field points to.
$target_type_setting = $field_settings[$subfield_name]['entity_reference_type'] ?? '';
if (!$target_type_setting) {
// No setting nothing we can do.
continue;
}
// Allow values like "module:node" only keep the actual entity type id.
$parts = explode(':', $target_type_setting);
$target_entity_type_id = end($parts);
if (!$entity_type_manager->hasDefinition($target_entity_type_id)) {
continue;
}
$target_entity_type = $entity_type_manager->getDefinition($target_entity_type_id);
$target_views_handler = $entity_type_manager->getHandler($target_entity_type_id, 'views_data');
$target_base_table = $target_views_handler->getViewsTableForEntityType($target_entity_type);
$args = [
'@label' => $target_entity_type->getLabel(),
'@field_name' => $field_key,
];
$data[$table_name][$field_key]['relationship'] = [
'title' => t('@label referenced from @field_name', $args),
'group' => $source_entity_type->getLabel(),
'id' => 'standard',
'base' => $target_base_table,
'entity type' => $target_entity_type_id,
'base field' => $target_entity_type->getKey('id'),
'relationship field' => $field_key,
'label' => t('@field_name: @label', $args),
];
$pseudo_field_name = 'reverse__' . $source_entity_type_id . '__' . $field_key;
$table_mapping = $entity_type_manager
->getStorage($source_entity_type_id)
->getTableMapping();
$reverse_args = [
'@entity' => $source_entity_type->getLabel(),
'@field_name' => $field_key,
'@label' => $target_entity_type->getSingularLabel(),
];
$data[$target_base_table][$pseudo_field_name]['relationship'] = [
'title' => t('@entity using @field_name', $reverse_args),
'label' => t('@field_name', ['@field_name' => $field_key]),
'group' => $target_entity_type->getLabel(),
'help' => t('Relate each @entity with a @field_name set to the @label.', $reverse_args),
'id' => 'entity_reverse',
'base' => $source_views_handler->getViewsTableForEntityType($source_entity_type),
'entity_type' => $source_entity_type_id,
'base field' => $source_entity_type->getKey('id'),
'field_name' => $field_name,
'field table' => $table_mapping->getDedicatedDataTableName($field_storage),
'field field' => $field_key,
];
}
}
return $data;
}
