external_entity-1.0.x-dev/src/Entity/ExternalEntityViewsData.php
src/Entity/ExternalEntityViewsData.php
<?php
declare(strict_types=1);
namespace Drupal\external_entity\Entity;
use Drupal\Core\Entity\EntityHandlerBase;
use Drupal\views\EntityViewsDataInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Entity\EntityHandlerInterface;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Define the external entity views data entity handler.
*/
class ExternalEntityViewsData extends EntityHandlerBase implements EntityHandlerInterface, EntityViewsDataInterface {
/**
* @var \Drupal\Core\Entity\EntityTypeInterface
*/
protected $entityType;
/**
* @var \Drupal\Core\Extension\ModuleHandlerInterface
*/
protected $moduleHandler;
/**
* @var \Drupal\Core\Entity\EntityTypeManager
*/
protected $entityTypeManager;
/**
* @var \Drupal\Core\Entity\EntityStorageInterface
*/
protected $entityTypeBundleStorage;
/**
* External entity views data constructor.
*/
public function __construct(
EntityTypeInterface $entity_type,
EntityTypeManagerInterface $entity_type_manager,
ModuleHandlerInterface $module_handler,
EntityStorageInterface $entity_type_bundle_storage,
) {
$this->entityType = $entity_type;
$this->moduleHandler = $module_handler;
$this->entityTypeManager = $entity_type_manager;
$this->entityTypeBundleStorage = $entity_type_bundle_storage;
}
/**
* {@inheritDoc}
*/
public static function createInstance(
ContainerInterface $container,
EntityTypeInterface $entity_type,
) {
$entity_type_manager = $container->get('entity_type.manager');
return new static(
$entity_type,
$entity_type_manager,
$container->get('module_handler'),
$entity_type_manager->getStorage($entity_type->getBundleEntityType())
);
}
/**
* {@inheritDoc}
*/
public function getViewsTableForEntityType(
EntityTypeInterface $entity_type,
): ?string {
return NULL;
}
/**
* {@inheritDoc}
*/
public function getViewsData(): array {
$data = [
'external_entity' => [
'table' => [
'group' => $this->t('External Entity'),
'wizard_id' => 'external_entity_standard',
'base' => [
'title' => $this->t('External Entity'),
'help' => $this->t('Fetch external entity data.'),
'query_id' => 'external_entity',
],
],
],
];
if ($this->moduleHandler->moduleExists('entity_browser')) {
$data['external_entity']['entity_browser_select'] = [
'title' => $this->t('Entity browser bulk select form'),
'help' => $this->t('Add a form element that lets you use a view as a base to select entities in entity browser.'),
'field' => [
'id' => 'entity_browser_select',
],
];
}
$data['external_entity']['external_entity_variation'] = [
'title' => $this->t('External entity resource variation'),
'help' => $this->t('Filter external entity by resource variations.'),
'filter' => [
'id' => 'external_entity_variation_filter',
],
];
/** @var \Drupal\external_entity\Entity\ExternalEntityType $external_entity_type */
foreach ($this->entityTypeBundleStorage->loadMultiple() as $external_entity_type) {
$type = $external_entity_type->id();
foreach ($external_entity_type->getAllResourceProperties() as $resource => $variations) {
foreach ($variations as $properties) {
foreach ($properties as $property => $property_info) {
if (!isset($property_info['type'])) {
continue;
}
$label = $property_info['label'];
$definition = [
'title' => $this->t('@label', ['@label' => $label]),
'help' => $this->t('Display the external entity @property property.', [
'@property' => $property,
]),
];
$this->appendViewDefinitionByProperty(
$definition,
$property,
$property_info
);
$data['external_entity']["{$type}__{$resource}__$property"] = $definition;
if (isset($property_info['properties']) && !empty($property_info['properties'])) {
$field = $property_info['name'];
foreach ($property_info['properties'] as $key => $field_properties) {
$real_field = "$field.$key";
$plugin_id = $this->normalizeDataTypeViewsPluginId($field_properties['type']);
$data['external_entity']["{$type}__{$resource}__{$property}__$key"] = [
'title' => $this->t('@label', ['@label' => "$label ($key)"]),
'help' => $this->t('Display the external entity @property:@key property.', [
'@property' => $property,
'@key' => $key,
]),
'filter' => [
'id' => $plugin_id,
'real field' => $real_field,
],
'sort' => [
'id' => $plugin_id,
'real field' => $real_field,
],
];
}
}
}
}
}
}
return $data;
}
/**
* Normalize field data type views plugin ID.
*
* @param string $data_type
* The field data type.
*
* @return string
* The views plugin ID based on the provided data type.
*/
protected function normalizeDataTypeViewsPluginId(
string $data_type,
): string {
if (in_array($data_type, ['string', 'boolean'])) {
return $data_type;
}
$views_plugin_id = 'string';
if ($data_type === 'integer') {
$views_plugin_id = 'numeric';
}
elseif (strpos($data_type, 'date') === 0) {
$views_plugin_id = 'date';
}
return $views_plugin_id;
}
/**
* Append view definition by property.
*
* @param array $definition
* The view data definition.
* @param string $property
* The external entity property name.
* @param array $property_info
* An array of the external entity property information.
*/
protected function appendViewDefinitionByProperty(
array &$definition,
string $property,
array $property_info,
): void {
if (isset($property_info['name'], $property_info['type'])) {
$field = $property_info['name'];
$field_type = $property_info['type'];
$definition += [
'field' => [
'id' => 'external_entity_field',
'field' => $property,
'real field' => $field,
'click sortable' => FALSE,
'field_type' => $field_type,
'entity_type' => 'external_entity',
],
'filter' => [
'id' => 'string',
'real field' => $field,
],
'argument' => [
'id' => 'string',
],
'sort' => [
'id' => 'standard',
'real field' => $field,
'title' => $this->t('@name', [
'@name' => $property_info['label'],
]),
],
];
switch ($field_type) {
case 'created':
case 'changed':
case 'datetime':
case 'timestamp':
case 'daterange':
$definition['sort']['id'] = 'date';
$definition['filter']['id'] = 'date';
$definition['argument']['id'] = 'date';
break;
case 'language':
$definition['filter']['id'] = 'language';
$definition['argument']['id'] = 'language';
break;
case 'boolean':
$definition['filter']['id'] = 'boolean';
$definition['argument']['id'] = 'numeric';
break;
}
}
}
}
