farmOS/modules/core/ui/views/src/Plugin/views/argument/EntityTaxonomyTermReference...

195 lines
7.0 KiB
PHP

<?php
namespace Drupal\farm_ui_views\Plugin\views\argument;
use Drupal\Core\Entity\Sql\SqlContentEntityStorage;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\taxonomy\Plugin\views\argument\Taxonomy;
use Drupal\views\Views;
/**
* Argument handler for taxonomy term references from an arbitrary entity field.
*
* @ingroup views_argument_handlers
*
* @ViewsArgument("entity_taxonomy_term_reference")
*/
class EntityTaxonomyTermReferenceArgument extends Taxonomy {
/**
* The entity type manager service.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* The entity type bundle info.
*
* @var \Drupal\Core\Entity\EntityTypeBundleInfoInterface
*/
protected $entityTypeBundleInfo;
/**
* The entity field manager service.
*
* @var \Drupal\Core\Entity\EntityFieldManagerInterface
*/
protected $entityFieldManager;
/**
* EntityTaxonomyTermReferenceArgument constructor.
*
* @param array $configuration
* A configuration array containing information about the plugin instance.
* @param string $plugin_id
* The plugin ID for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param \Drupal\Core\Entity\EntityStorageInterface $term_storage
* The taxonomy term storage service.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager service.
* @param \Drupal\Core\Entity\EntityTypeBundleInfoInterface $entity_bundle_info
* The entity type bundle info service.
* @param \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager
* The entity field manager service.
*/
public function __construct(array $configuration,
$plugin_id,
$plugin_definition,
EntityStorageInterface $term_storage,
EntityTypeManagerInterface $entity_type_manager,
EntityTypeBundleInfoInterface $entity_bundle_info,
EntityFieldManagerInterface $entity_field_manager) {
parent::__construct($configuration, $plugin_id, $plugin_definition, $term_storage);
$this->entityTypeManager = $entity_type_manager;
$this->entityTypeBundleInfo = $entity_bundle_info;
$this->entityFieldManager = $entity_field_manager;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static($configuration, $plugin_id, $plugin_definition,
$container->get('entity_type.manager')->getStorage('taxonomy_term'),
$container->get('entity_type.manager'),
$container->get('entity_type.bundle.info'),
$container->get('entity_field.manager'));
}
/**
* {@inheritdoc}
*/
public function query($group_by = FALSE) {
// Getting the arguments through views rather than
// from the Drupal route is important since it allows
// the contextual filter previews in the views UI to
// work correctly.
$term_id = $this->argument;
$entity_bundle = $this->view->args[1] ?: 'all';
if (empty($term_id)) {
return;
}
$term = $this->termStorage->load($term_id);
// This is a value like 'asset' or 'log'.
$base_entity_type = $this->view->getBaseEntityType()->id();
$entity_storage = $this->entityTypeManager->getStorage($base_entity_type);
if (!($entity_storage instanceof SqlContentEntityStorage)) {
return;
}
$entity_data_table = $entity_storage->getDataTable();
$entity_table_mapping = $entity_storage->getTableMapping();
$conditions = [];
// Keep track of which field tables we've already joined with since some
// assets share the same field e.g. plant and seed assets.
$already_joined_term_field_tables = [];
// Loop through all the bundles of the base entity type for this view.
$bundles = $this->entityTypeBundleInfo->getBundleInfo($base_entity_type);
foreach (array_keys($bundles) as $type) {
// Consider either all of them or just the one matching the
// bundle argument.
if ($entity_bundle == 'all' || $type == $entity_bundle) {
$field_definitions = $this->entityFieldManager->getFieldDefinitions($base_entity_type, $type);
foreach ($field_definitions as $field_id => $field_definition) {
// Look for taxonomy term entity reference fields which reference the
// target bundle of the term we loaded above.
if ($field_definition->getType() == "entity_reference" && $field_definition->getSetting('target_type') == "taxonomy_term") {
$handler_settings = $field_definition->getSetting('handler_settings') ?? [];
if (in_array($term->bundle(), $handler_settings['target_bundles'] ?? [])) {
// Now that we have found such a field, get the parameters to
// construct a join to allow us to filter only those entities
// which actually reference the term we loaded above.
$field_table_name = $entity_table_mapping->getFieldTableName($field_id);
// Don't add the same join more than once.
if (array_key_exists($field_table_name, $already_joined_term_field_tables)) {
continue;
}
$column_names = $entity_table_mapping->getColumnNames($field_id);
$target_id_column_name = $column_names['target_id'];
// Join the taxonomy reference field table with the entity.
/** @var \Drupal\views\Plugin\views\join\JoinPluginBase $join */
$join = Views::pluginManager('join')->createInstance('standard', [
'table' => $field_table_name,
'field' => 'entity_id',
'left_table' => $entity_data_table,
'left_field' => 'id',
'extra' => [
[
'field' => 'deleted',
'value' => 0,
],
[
'field' => $target_id_column_name,
'value' => $term->id(),
],
],
]);
// Add the relationship.
$relationship_alias = $this->query->addRelationship($field_table_name, $join, $entity_data_table);
// Keep track that we've now joined with that field table.
$already_joined_term_field_tables[$field_table_name] = 1;
// Add a condition to our final WHERE statement that the joined
// taxonomy term reference target id is not NULL.
$conditions[] = "$relationship_alias.$target_id_column_name IS NOT NULL";
}
}
}
}
}
if (!empty($conditions)) {
$combined_conditions = implode(" OR ", $conditions);
$this->query->addWhereExpression(0, "$entity_data_table.id IS NOT NULL AND ($combined_conditions)");
}
}
}