public function TermFieldAutocomplete::resolve in GraphQL 8.4
Gets term items matched against given query for given vocabulary.
Parameters
string $entity_type: Entity type the searchable term field is attached to.
string $bundle: Bundle the searchable term field is attached to.
string $field: Field name to search the terms on.
string|null $match_string: String to be matched.
bool $prioritize_start_with: Whether terms which start with matching string should come first.
int $limit: Number of items to be returned.
\Drupal\graphql\GraphQL\Execution\FieldContext $context: The caching context related to the current field.
Return value
array List of matched terms.
File
- src/
Plugin/ GraphQL/ DataProducer/ Taxonomy/ TermFieldAutocomplete.php, line 267
Class
- TermFieldAutocomplete
- Gets term items matching the given string in given field's vocabularies.
Namespace
Drupal\graphql\Plugin\GraphQL\DataProducer\TaxonomyCode
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;
}