class TermFieldAutocomplete in GraphQL 8.4
Gets term items matching the given string in given field's vocabularies.
Plugin annotation
@DataProducer(
id = "term_field_autocomplete",
name = @Translation("Term field autocomplete"),
description = @Translation("Returns autocomplete items matched against given string for vocabularies in given field"),
produces = @ContextDefinition("list",
label = @Translation("List of term ids matching the string.")
),
consumes = {
"entity_type" = @ContextDefinition("string",
label = @Translation("Entity type the searchable term field is attached to")
),
"bundle" = @ContextDefinition("string",
label = @Translation("Entity type the searchable term field is attached to")
),
"field" = @ContextDefinition("string",
label = @Translation("Field name to search the terms on")
),
"match_string" = @ContextDefinition("string",
label = @Translation("String to be matched"),
required = FALSE
),
"prioritize_start_with" = @ContextDefinition("boolean",
label = @Translation("Whether terms which start with matching string should come first"),
required = FALSE,
default_value = TRUE
),
"limit" = @ContextDefinition("integer",
label = @Translation("Number of items to be returned"),
required = FALSE,
default_value = 10
)
}
)
Hierarchy
- class \Drupal\Component\Plugin\PluginBase implements DerivativeInspectionInterface, PluginInspectionInterface
- class \Drupal\Component\Plugin\ContextAwarePluginBase implements ContextAwarePluginInterface
- class \Drupal\Core\Plugin\ContextAwarePluginBase implements CacheableDependencyInterface, ContextAwarePluginInterface uses DependencySerializationTrait, StringTranslationTrait, TypedDataTrait
- class \Drupal\graphql\Plugin\GraphQL\DataProducer\DataProducerPluginBase implements DataProducerPluginInterface uses DataProducerPluginCachingTrait
- class \Drupal\graphql\Plugin\GraphQL\DataProducer\Taxonomy\TermFieldAutocomplete implements ContainerFactoryPluginInterface
- class \Drupal\graphql\Plugin\GraphQL\DataProducer\DataProducerPluginBase implements DataProducerPluginInterface uses DataProducerPluginCachingTrait
- class \Drupal\Core\Plugin\ContextAwarePluginBase implements CacheableDependencyInterface, ContextAwarePluginInterface uses DependencySerializationTrait, StringTranslationTrait, TypedDataTrait
- class \Drupal\Component\Plugin\ContextAwarePluginBase implements ContextAwarePluginInterface
Expanded class hierarchy of TermFieldAutocomplete
File
- src/
Plugin/ GraphQL/ DataProducer/ Taxonomy/ TermFieldAutocomplete.php, line 54
Namespace
Drupal\graphql\Plugin\GraphQL\DataProducer\TaxonomyView source
class TermFieldAutocomplete extends DataProducerPluginBase implements ContainerFactoryPluginInterface {
/**
* The default maximum number of items to be capped to prevent DDOS attacks.
*/
const MAX_ITEMS = 100;
/**
* The database connection.
*
* @var \Drupal\Core\Database\Connection
*/
protected $database;
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* The term storage.
*
* @var \Drupal\taxonomy\TermStorageInterface
*/
protected $termStorage;
/**
* The term type.
*
* @var \Drupal\Core\Entity\ContentEntityTypeInterface
*/
protected $termType;
/**
* The module handler.
*
* @var \Drupal\Core\Extension\ModuleHandlerInterface
*/
protected $moduleHandler;
/**
* {@inheritdoc}
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, Connection $database, EntityTypeManagerInterface $entity_type_manager, ModuleHandlerInterface $module_handler) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->database = $database;
$this->entityTypeManager = $entity_type_manager;
$this->moduleHandler = $module_handler;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static($configuration, $plugin_id, $plugin_definition, $container
->get('database'), $container
->get('entity_type.manager'), $container
->get('module_handler'));
}
/**
* Gets the term storage.
*
* @return \Drupal\taxonomy\TermStorageInterface
* The term storage.
*/
protected function getTermStorage() : TermStorageInterface {
if (!isset($this->termStorage)) {
/** @var \Drupal\taxonomy\TermStorageInterface $term_storage */
$term_storage = $this->entityTypeManager
->getStorage('taxonomy_term');
$this->termStorage = $term_storage;
}
return $this->termStorage;
}
/**
* Gets the term type.
*
* @return \Drupal\Core\Entity\ContentEntityTypeInterface
* The term type.
*/
protected function getTermType() : ContentEntityTypeInterface {
if (!isset($this->termType)) {
/** @var \Drupal\Core\Entity\ContentEntityTypeInterface $term_type */
$term_type = $this->entityTypeManager
->getDefinition('taxonomy_term');
$this->termType = $term_type;
}
return $this->termType;
}
/**
* Gets the field config for given field of given entity type of given bundle.
*
* @param string $entity_type
* Entity type to get the field config for.
* @param string $bundle
* Bundle to get the field config for.
* @param string $field
* Field to get the field config for.
*
* @return \Drupal\field\FieldConfigInterface|null
* Field config for given field of given entity type of given bundle, or
* null if it does not exist.
*/
protected function getFieldConfig(string $entity_type, string $bundle, string $field) : ?FieldConfigInterface {
/** @var \Drupal\Core\Config\Entity\ConfigEntityStorageInterface $field_config_storage */
$field_config_storage = $this->entityTypeManager
->getStorage('field_config');
/** @var \Drupal\field\FieldConfigInterface|null $field_config */
$field_config = $field_config_storage
->load($entity_type . '.' . $bundle . '.' . $field);
return $field_config;
}
/**
* Whether given field storage config is configured for term field.
*
* @param \Drupal\Core\Field\FieldStorageDefinitionInterface $field_storage_config
* The field storage config to be examined.
*
* @return bool
* True if given field storage config is configured for term field.
*/
public function isTermFieldStorageConfig(FieldStorageDefinitionInterface $field_storage_config) : bool {
// Term level field is allowed.
$field_type = $field_storage_config
->getType();
if ($field_type == 'term_level') {
return TRUE;
}
// And term reference fields are allowed as well. Must be type of entity
// reference or entity reference revision and must target taxonomy terms.
if ($field_type != 'entity_reference' && $field_type != 'entity_reference_revisions') {
return FALSE;
}
if ($field_storage_config
->getSetting('target_type') != 'taxonomy_term') {
return FALSE;
}
return TRUE;
}
/**
* Gets the vocabularies configured for given field if it is a term field.
*
* @param string $entity_type
* Entity type of the field to get the vocabularies for.
* @param string $bundle
* Bundle of entity type of the field to get the vocabularies for.
* @param string $field
* Field name to get the vocabularies for.
*
* @return string[]
* Vocabularies configured for the field in case it is a term field, null
* otherwise.
*/
protected function getTermFieldVocabularies(string $entity_type, string $bundle, string $field) : ?array {
// Load field config of given entity type of given bundle. If not obtained,
// bail out.
if (!($field_config = $this
->getFieldConfig($entity_type, $bundle, $field))) {
return NULL;
}
// Make sure the field is configured for taxonomy terms.
$field_storage_config = $field_config
->getFieldStorageDefinition();
if (!$this
->isTermFieldStorageConfig($field_storage_config)) {
return NULL;
}
// Make sure that target vocabularies are configured.
$handler_settings = $field_config
->getSetting('handler_settings');
if (empty($handler_settings['target_bundles'])) {
return NULL;
}
// Return list of vocabularies.
return $handler_settings['target_bundles'];
}
/**
* Gets term items matched against given query for given vocabulary.
*
* @param string $entity_type
* Entity type the searchable term field is attached to.
* @param string $bundle
* Bundle the searchable term field is attached to.
* @param string $field
* Field name to search the terms on.
* @param string|null $match_string
* String to be matched.
* @param bool $prioritize_start_with
* Whether terms which start with matching string should come first.
* @param int $limit
* Number of items to be returned.
* @param \Drupal\graphql\GraphQL\Execution\FieldContext $context
* The caching context related to the current field.
*
* @return array
* List of matched terms.
*/
public function resolve(string $entity_type, string $bundle, string $field, ?string $match_string, bool $prioritize_start_with, int $limit, FieldContext $context) : ?array {
if ($limit <= 0) {
$limit = 10;
}
if ($limit > self::MAX_ITEMS) {
$limit = self::MAX_ITEMS;
}
// Get configured vocabulary. If none is obtained, bail out.
if (!($vocabularies = $this
->getTermFieldVocabularies($entity_type, $bundle, $field))) {
return NULL;
}
// Base of the query selecting term names and synonyms.
$query = $this->database
->select('taxonomy_term_field_data', 't');
$query
->fields('t', [
'tid',
]);
$query
->condition('t.vid', $vocabularies, 'IN');
$query
->range(0, $limit);
// Make condition matching name as OR condition group. This makes it
// extendable if a module needs to cover a match in term name OR in some
// other fields.
$like_contains = '%' . $query
->escapeLike($match_string) . '%';
$name_condition_group = $query
->orConditionGroup();
$name_condition_group
->condition('t.name', $like_contains, 'LIKE');
// Additional query logic for matches.
if ($match_string) {
// Prioritize terms starting with matching string.
if ($prioritize_start_with) {
// Get calculated meta weight value where terms which match the string
// at the start have higher meta weight value comparing to the terms
// which match the string in between.
$like_starts_with = $query
->escapeLike($match_string) . '%';
$query
->addExpression('(t.name LIKE :like_starts_with) * 1 + (t.name LIKE :like_contains) * 0.5', 'meta_weight', [
':like_starts_with' => $like_starts_with,
':like_contains' => $like_contains,
]);
// Order by calculated meta weight value as a first ordering criterion.
$query
->orderBy('meta_weight', 'DESC');
}
// Rest of ordering.
$query
->orderBy('t.weight', 'ASC');
$query
->orderBy('t.name', 'ASC');
}
// Allow modules to alter the term autocomplete query.
$args = [
'entity_type' => $entity_type,
'bundle' => $bundle,
'field' => $field,
'match_string' => $match_string,
'prioritize_start_with' => $prioritize_start_with,
'limit' => $limit,
];
$this->moduleHandler
->alter('graphql_term_autocomplete_query', $args, $query, $name_condition_group);
// Add name OR condition group after query was altered. If added sooner then
// condition group extensions done in alter hooks wouldn't be reflected.
$query
->condition($name_condition_group);
// Handle access on query.
$query
->addTag('taxonomy_term_access');
// Process the terms returned by term autocomplete query.
$terms = [];
foreach ($query
->execute() as $match) {
$terms[] = $match->tid;
// Invalidate on term update, because it may change the name which does
// not match the string anymore.
$context
->addCacheTags([
'taxonomy_term:' . $match->tid,
]);
}
$context
->addCacheTags($this
->getTermType()
->getListCacheTags());
return $terms;
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
ContextAwarePluginBase:: |
protected | property | The data objects representing the context of this plugin. | |
ContextAwarePluginBase:: |
private | property | Data objects representing the contexts passed in the plugin configuration. | |
ContextAwarePluginBase:: |
protected | function | Wraps the context handler. | |
ContextAwarePluginBase:: |
protected | function |
Overrides ContextAwarePluginBase:: |
|
ContextAwarePluginBase:: |
public | function |
The cache contexts associated with this object. Overrides CacheableDependencyInterface:: |
9 |
ContextAwarePluginBase:: |
public | function |
The maximum age for which this object may be cached. Overrides CacheableDependencyInterface:: |
7 |
ContextAwarePluginBase:: |
public | function |
The cache tags associated with this object. Overrides CacheableDependencyInterface:: |
4 |
ContextAwarePluginBase:: |
public | function |
This code is identical to the Component in order to pick up a different
Context class. Overrides ContextAwarePluginBase:: |
|
ContextAwarePluginBase:: |
public | function |
Gets a mapping of the expected assignment names to their context names. Overrides ContextAwarePluginInterface:: |
|
ContextAwarePluginBase:: |
public | function |
Gets the defined contexts. Overrides ContextAwarePluginInterface:: |
|
ContextAwarePluginBase:: |
public | function |
Gets the value for a defined context. Overrides ContextAwarePluginInterface:: |
|
ContextAwarePluginBase:: |
public | function |
Set a context on this plugin. Overrides ContextAwarePluginBase:: |
|
ContextAwarePluginBase:: |
public | function |
Sets a mapping of the expected assignment names to their context names. Overrides ContextAwarePluginInterface:: |
|
ContextAwarePluginBase:: |
public | function |
Sets the value for a defined context. Overrides ContextAwarePluginBase:: |
|
ContextAwarePluginBase:: |
public | function |
Validates the set values for the defined contexts. Overrides ContextAwarePluginInterface:: |
|
ContextAwarePluginBase:: |
public | function | Implements magic __get() method. | |
DataProducerPluginBase:: |
public | function |
Overrides ContextAwarePluginBase:: |
|
DataProducerPluginBase:: |
public | function |
Gets the context definitions of the plugin. Overrides ContextAwarePluginBase:: |
|
DataProducerPluginBase:: |
public | function |
Resolves the queried field with the given context. Overrides DataProducerPluginInterface:: |
|
DataProducerPluginCachingTrait:: |
public | function | ||
DataProducerPluginCachingTrait:: |
abstract public | function | ||
DependencySerializationTrait:: |
protected | property | An array of entity type IDs keyed by the property name of their storages. | |
DependencySerializationTrait:: |
protected | property | An array of service IDs keyed by property name used for serialization. | |
DependencySerializationTrait:: |
public | function | 1 | |
DependencySerializationTrait:: |
public | function | 2 | |
PluginBase:: |
protected | property | Configuration information passed into the plugin. | 1 |
PluginBase:: |
protected | property | The plugin implementation definition. | 1 |
PluginBase:: |
protected | property | The plugin_id. | |
PluginBase:: |
constant | A string which is used to separate base plugin IDs from the derivative ID. | ||
PluginBase:: |
public | function |
Gets the base_plugin_id of the plugin instance. Overrides DerivativeInspectionInterface:: |
|
PluginBase:: |
public | function |
Gets the derivative_id of the plugin instance. Overrides DerivativeInspectionInterface:: |
|
PluginBase:: |
public | function |
Gets the definition of the plugin implementation. Overrides PluginInspectionInterface:: |
3 |
PluginBase:: |
public | function |
Gets the plugin_id of the plugin instance. Overrides PluginInspectionInterface:: |
|
PluginBase:: |
public | function | Determines if the plugin is configurable. | |
StringTranslationTrait:: |
protected | property | The string translation service. | 1 |
StringTranslationTrait:: |
protected | function | Formats a string containing a count of items. | |
StringTranslationTrait:: |
protected | function | Returns the number of plurals supported by a given language. | |
StringTranslationTrait:: |
protected | function | Gets the string translation service. | |
StringTranslationTrait:: |
public | function | Sets the string translation service to use. | 2 |
StringTranslationTrait:: |
protected | function | Translates a string to the current language or to a given language. | |
TermFieldAutocomplete:: |
protected | property | The database connection. | |
TermFieldAutocomplete:: |
protected | property | The entity type manager. | |
TermFieldAutocomplete:: |
protected | property | The module handler. | |
TermFieldAutocomplete:: |
protected | property | The term storage. | |
TermFieldAutocomplete:: |
protected | property | The term type. | |
TermFieldAutocomplete:: |
public static | function |
Creates an instance of the plugin. Overrides ContainerFactoryPluginInterface:: |
|
TermFieldAutocomplete:: |
protected | function | Gets the field config for given field of given entity type of given bundle. | |
TermFieldAutocomplete:: |
protected | function | Gets the vocabularies configured for given field if it is a term field. | |
TermFieldAutocomplete:: |
protected | function | Gets the term storage. | |
TermFieldAutocomplete:: |
protected | function | Gets the term type. | |
TermFieldAutocomplete:: |
public | function | Whether given field storage config is configured for term field. | |
TermFieldAutocomplete:: |
constant | The default maximum number of items to be capped to prevent DDOS attacks. | ||
TermFieldAutocomplete:: |
public | function | Gets term items matched against given query for given vocabulary. | |
TermFieldAutocomplete:: |
public | function |
Overrides \Drupal\Component\Plugin\PluginBase::__construct(). Overrides ContextAwarePluginBase:: |
|
TypedDataTrait:: |
protected | property | The typed data manager used for creating the data types. | |
TypedDataTrait:: |
public | function | Gets the typed data manager. | 2 |
TypedDataTrait:: |
public | function | Sets the typed data manager. | 2 |