protected static function TemporaryQueryGuard::secureQuery in JSON:API 8
Same name and namespace in other branches
- 8.2 src/Access/TemporaryQueryGuard.php \Drupal\jsonapi\Access\TemporaryQueryGuard::secureQuery()
Applies tags, metadata and conditions to secure an entity query.
Parameters
\Drupal\Core\Entity\Query\QueryInterface $query: The query to be secured.
string $entity_type_id: An entity type ID.
array $tree: A tree of field specifiers in an entity query condition. The tree is a multi-dimensional array where the keys are field specifiers and the values are multi-dimensional array of the same form, containing only subsequent specifiers. @see ::buildTree().
\Drupal\Core\Cache\CacheableMetadata $cacheability: Collects cacheability for the query.
string|null $field_prefix: Internal use only. Contains a string representation of the previously visited field specifiers.
\Drupal\Core\Field\FieldStorageDefinitionInterface $field_storage_definition: Internal use only. The current field storage definition, if known.
See also
\Drupal\Core\Database\Query\AlterableInterface::addTag()
\Drupal\Core\Database\Query\AlterableInterface::addMetaData()
\Drupal\Core\Database\Query\ConditionInterface
1 call to TemporaryQueryGuard::secureQuery()
- TemporaryQueryGuard::applyAccessControls in src/
Access/ TemporaryQueryGuard.php - Applies access controls to an entity query.
File
- src/
Access/ TemporaryQueryGuard.php, line 113
Class
- TemporaryQueryGuard
- Adds sufficient access control to collection queries.
Namespace
Drupal\jsonapi\AccessCode
protected static function secureQuery(QueryInterface $query, $entity_type_id, array $tree, CacheableMetadata $cacheability, $field_prefix = NULL, FieldStorageDefinitionInterface $field_storage_definition = NULL) {
$entity_type = \Drupal::entityTypeManager()
->getDefinition($entity_type_id);
// Config entity types are not fieldable, therefore they do not have field
// access restrictions, nor entity references to other entity types.
if ($entity_type instanceof ConfigEntityTypeInterface) {
return;
}
foreach ($tree as $specifier => $children) {
// The field path reconstructs the entity condition fields.
// E.g. `uid.0` would become `uid.0.name` if $specifier === 'name'.
$child_prefix = is_null($field_prefix) ? $specifier : "{$field_prefix}.{$specifier}";
if (is_null($field_storage_definition)) {
// When the field storage definition is NULL, this specifier is the
// first specifier in an entity query field path or the previous
// specifier was a data reference that has been traversed. In both
// cases, the specifier must be a field name.
$field_storage_definitions = static::$fieldManager
->getFieldStorageDefinitions($entity_type_id);
static::secureQuery($query, $entity_type_id, $children, $cacheability, $child_prefix, $field_storage_definitions[$specifier]);
// When $field_prefix is NULL, this must be the first specifier in the
// entity query field path and a condition for the query's base entity
// type must be applied.
if (is_null($field_prefix)) {
static::applyAccessConditions($query, $entity_type_id, NULL, $cacheability);
}
}
else {
// When the specifier is an entity reference, it can contain an entity
// type specifier, like so: `entity:node`. This extracts the `entity`
// portion. JSON:API will have already validated that the property
// exists.
$split_specifier = explode(':', $specifier, 2);
list($property_name, $target_entity_type_id) = array_merge($split_specifier, count($split_specifier) === 2 ? [] : [
NULL,
]);
// The specifier is either a field property or a delta. If it is a data
// reference or a delta, then it needs to be traversed to the next
// specifier. However, if the specific is a simple field property, i.e.
// it is neither a data reference nor a delta, then there is no need to
// evaluate the remaining specifiers.
$property_definition = $field_storage_definition
->getPropertyDefinition($property_name);
if ($property_definition instanceof DataReferenceDefinitionInterface) {
// Because the filter is following an entity reference, ensure
// access is respected on those targeted entities.
// Examples:
// - node_query_node_access_alter()
$target_entity_type_id = $target_entity_type_id ?: $field_storage_definition
->getSetting('target_type');
$query
->addTag("{$target_entity_type_id}_access");
static::applyAccessConditions($query, $target_entity_type_id, $child_prefix, $cacheability);
// Keep descending the tree.
static::secureQuery($query, $target_entity_type_id, $children, $cacheability, $child_prefix);
}
elseif (is_null($property_definition)) {
assert(is_numeric($property_name), 'The specifier is not a property name, it must be a delta.');
// Keep descending the tree.
static::secureQuery($query, $entity_type_id, $children, $cacheability, $child_prefix, $field_storage_definition);
}
}
}
}