class FieldResolver (View source)

internal  JSON:API maintains no PHP API. The API is the HTTP API. This class may change at any time and could break any dependencies on it.
 

A service that evaluates external path expressions against Drupal fields.

This class performs 3 essential functions, path resolution, path validation and path expansion.

Path resolution: Path resolution refers to the ability to map a set of external field names to their internal counterparts. This is necessary because a resource type can provide aliases for its field names. For example, the resource type @code node--article @endcode might "alias" the internal field name @code uid @endcode to the external field name @code author @endcode. This permits an API consumer to request @code /jsonapi/node/article?include=author @endcode for a better developer experience.

Path validation: Path validation refers to the ability to ensure that a requested path corresponds to a valid set of internal fields. For example, if an API consumer may send a @code GET @endcode request to @code /jsonapi/node/article?sort=author.field_first_name @endcode. The field resolver ensures that @code uid @endcode (which would have been resolved from @code author @endcode) exists on article nodes and that @code field_first_name @endcode exists on user entities. However, in the case of an @code include @endcode path, the field resolver would raise a client error because @code field_first_name @endcode is not an entity reference field, meaning it does not identify any related resources that can be included in a compound document.

Path expansion: Path expansion refers to the ability to expand a path to an entity query compatible field expression. For example, a request URL might have a query string like @code ?filter[field_tags.name]=aviation @endcode, before constructing the appropriate entity query, the entity query system needs the path expression to be "expanded" into @code field_tags.entity.name @endcode. In some rare cases, the entity query system needs this to be expanded to

Properties

protected EntityTypeManagerInterface $entityTypeManager

The entity type manager.

protected EntityFieldManagerInterface $fieldManager

The field manager.

protected EntityTypeBundleInfoInterface $entityTypeBundleInfo

The entity type bundle information service.

protected ResourceTypeRepositoryInterface $resourceTypeRepository

The JSON:API resource type repository service.

protected ModuleHandlerInterface $moduleHandler

The module handler.

Methods

__construct(EntityTypeManagerInterface $entity_type_manager, EntityFieldManagerInterface $field_manager, EntityTypeBundleInfoInterface $entity_type_bundle_info, ResourceTypeRepositoryInterface $resource_type_repository, ModuleHandlerInterface $module_handler)

Creates a FieldResolver instance.

static string[]
resolveInternalIncludePath(ResourceType $resource_type, array $path_parts, int $depth = 0)

Validates and resolves an include path into its internal possibilities.

string
resolveInternalEntityQueryPath(ResourceType $resource_type, string $external_field_name, string $operator = NULL)

Resolves external field expressions into entity query compatible paths.

string
constructInternalPath(array $references, array $property_path = [])

Expands the internal path with the "entity" keyword.

getFieldItemDefinitions(array $resource_types, string $field_name)

Get all item definitions from a set of resources types by a field name.

string
getIdFieldName(ResourceType $resource_type)

Resolves the UUID field name for a resource type.

string
getInternalName(string $field_name, array $resource_types)

Resolves the internal field name based on a collection of resource types.

bool
isMemberFilterable(string $external_name, array $resource_types)

Determines if the given field or member name is filterable.

getRelatableResourceTypes(array $resource_types, array $definitions)

Get the referenceable ResourceTypes for a set of field definitions.

bool
resourceTypesAreTraversable(array $resource_types)

Whether the given resources can be traversed to other resources.

static string[]
getAllDataReferencePropertyNames(array $candidate_definitions)

Gets all unique reference property names from the given field definitions.

static string
getDataReferencePropertyName(array $candidate_definitions, array $remaining_parts, array $unresolved_path_parts)

Determines the reference property name for the remaining unresolved parts.

static bool
isDelta(string $part)

Determines if a path part targets a specific field delta.

static bool
isCandidateDefinitionProperty(string $part, array $candidate_definitions)

Determines if a path part targets a field property, not a subsequent field.

static bool
isCandidateDefinitionReferenceProperty(string $part, array $candidate_definitions)

Determines if a path part targets a reference property.

static string
getPathPartPropertyName(string $part)

Gets the property name from an entity typed or untyped path part.

getFieldAccess(ResourceType $resource_type, string $internal_field_name)

Gets the field access result for the 'view' operation.

Details

__construct(EntityTypeManagerInterface $entity_type_manager, EntityFieldManagerInterface $field_manager, EntityTypeBundleInfoInterface $entity_type_bundle_info, ResourceTypeRepositoryInterface $resource_type_repository, ModuleHandlerInterface $module_handler)

Creates a FieldResolver instance.

Parameters

EntityTypeManagerInterface $entity_type_manager

The entity type manager.

EntityFieldManagerInterface $field_manager

The field manager.

EntityTypeBundleInfoInterface $entity_type_bundle_info

The bundle info service.

ResourceTypeRepositoryInterface $resource_type_repository

The resource type repository.

ModuleHandlerInterface $module_handler

The module handler.

static string[] resolveInternalIncludePath(ResourceType $resource_type, array $path_parts, int $depth = 0)

Validates and resolves an include path into its internal possibilities.

Each resource type may define its own external names for its internal field names. As a result, a single external include path may target multiple internal paths.

This can happen when an entity reference field has different allowed entity types per bundle (as is possible with comment entities) or when different resource types share an external field name but resolve to different internal fields names.

Example 1: An installation may have three comment types for three different entity types, two of which have a file field and one of which does not. In that case, a path like @code field_comments.entity_id.media @endcode might be resolved to both @code field_comments.entity_id.field_audio @endcode and @code field_comments.entity_id.field_image @endcode.

Example 2: A path of @code field_author_profile.account @endcode might resolve to @code field_author_profile.uid @endcode and @code field_author_profile.field_user @endcode if @code field_author_profile @endcode can relate to two different JSON:API resource types (like node--profile and node--migrated_profile) which have the external field name @code account @endcode aliased to different internal field names.

Parameters

ResourceType $resource_type

The resource type for which the path should be validated.

array $path_parts

The include path as an array of strings. For example, the include query parameter string of @code field_tags.uid @endcode should be given as @code ['field_tags', 'uid'] @endcode.

int $depth

(internal) Used to track recursion depth in order to generate better exception messages.

Return Value

string[]

The resolved internal include paths.

Exceptions

BadRequestHttpException

string resolveInternalEntityQueryPath(ResourceType $resource_type, string $external_field_name, string $operator = NULL)

Resolves external field expressions into entity query compatible paths.

It is often required to reference data which may exist across a relationship. For example, you may want to sort a list of articles by a field on the article author's representative entity. Or you may wish to filter a list of content by the name of referenced taxonomy terms.

In an effort to simplify the referenced paths and align them with the structure of JSON:API responses and the structure of the hypothetical "reference document" (see link), it is possible to alias field names and elide the "entity" keyword from them (this word is used by the entity query system to traverse entity references).

This method takes this external field expression and attempts to resolve any aliases and/or abbreviations into a field expression that will be compatible with the entity query system.

Parameters

ResourceType $resource_type

The JSON:API resource type from which to resolve the field name.

string $external_field_name

The public field name to map to a Drupal field name.

string $operator

(optional) The operator of the condition for which the path should be resolved.

Return Value

string

The mapped field name.

Exceptions

CacheableBadRequestHttpException

protected string constructInternalPath(array $references, array $property_path = [])

Expands the internal path with the "entity" keyword.

Parameters

array $references

The resolved internal field names of all entity references.

array $property_path

(optional) A sub-property path for the last field in the path.

Return Value

string

The expanded and imploded path.

protected ComplexDataDefinitionInterface[] getFieldItemDefinitions(array $resource_types, string $field_name)

Get all item definitions from a set of resources types by a field name.

Parameters

array $resource_types

The resource types on which the field might exist.

string $field_name

The field for which to retrieve field item definitions.

Return Value

ComplexDataDefinitionInterface[]

The found field item definitions.

protected string getIdFieldName(ResourceType $resource_type)

Resolves the UUID field name for a resource type.

Parameters

ResourceType $resource_type

The resource type for which to get the UUID field name.

Return Value

string

The resolved internal name.

protected string getInternalName(string $field_name, array $resource_types)

Resolves the internal field name based on a collection of resource types.

Parameters

string $field_name

The external field name.

array $resource_types

The resource types from which to get an internal name.

Return Value

string

The resolved internal name.

protected bool isMemberFilterable(string $external_name, array $resource_types)

Determines if the given field or member name is filterable.

Parameters

string $external_name

The external field or member name.

array $resource_types

The resource types to test.

Return Value

bool

Whether the given field is present as a filterable member of the targeted resource objects.

protected ResourceType[] getRelatableResourceTypes(array $resource_types, array $definitions)

Get the referenceable ResourceTypes for a set of field definitions.

Parameters

array $resource_types

The resource types on which the reference field might exist.

array $definitions

The field item definitions of targeted fields, keyed by the resource type name on which they reside.

Return Value

ResourceType[]

The referenceable target resource types.

protected bool resourceTypesAreTraversable(array $resource_types)

Whether the given resources can be traversed to other resources.

This class shouldn't be aware of entity types and their definitions. Whether a resource can have relationships to other resources is information we ought to be able to discover on the ResourceType. However, we cannot reliably determine this information with existing APIs. Entities may be backed by various storages that are unable to perform queries across references and certain storages may not be able to store references at all.

Parameters

array $resource_types

The resources types to evaluate.

Return Value

bool

TRUE if any one of the given resource types is traversable.

static protected string[] getAllDataReferencePropertyNames(array $candidate_definitions)

Gets all unique reference property names from the given field definitions.

Parameters

array $candidate_definitions

A list of targeted field item definitions specified by the path.

Return Value

string[]

The reference property names, if any.

static protected string getDataReferencePropertyName(array $candidate_definitions, array $remaining_parts, array $unresolved_path_parts)

Determines the reference property name for the remaining unresolved parts.

Parameters

array $candidate_definitions

A list of targeted field item definitions specified by the path.

array $remaining_parts

The remaining path parts.

array $unresolved_path_parts

The unresolved path parts.

Return Value

string

The reference name.

static protected bool isDelta(string $part)

Determines if a path part targets a specific field delta.

Parameters

string $part

The path part.

Return Value

bool

TRUE if the part is an integer, FALSE otherwise.

static protected bool isCandidateDefinitionProperty(string $part, array $candidate_definitions)

Determines if a path part targets a field property, not a subsequent field.

Parameters

string $part

The path part.

array $candidate_definitions

A list of targeted field item definitions which are specified by the path.

Return Value

bool

TRUE if the part is a property of one of the candidate definitions, FALSE otherwise.

static protected bool isCandidateDefinitionReferenceProperty(string $part, array $candidate_definitions)

Determines if a path part targets a reference property.

Parameters

string $part

The path part.

array $candidate_definitions

A list of targeted field item definitions which are specified by the path.

Return Value

bool

TRUE if the part is a property of one of the candidate definitions, FALSE otherwise.

static protected string getPathPartPropertyName(string $part)

Gets the property name from an entity typed or untyped path part.

A path part may contain an entity type specifier like entity:node. This extracts the actual property name. If an entity type is not specified, then the path part is simply returned. For example, both foo and foo:bar will return foo.

Parameters

string $part

A path part.

Return Value

string

The property name from a path part.

protected AccessResultInterface getFieldAccess(ResourceType $resource_type, string $internal_field_name)

Gets the field access result for the 'view' operation.

Parameters

ResourceType $resource_type

The JSON:API resource type on which the field exists.

string $internal_field_name

The field name for which access should be checked.

Return Value

AccessResultInterface

The 'view' access result.