EntityReferenceFieldNormalizer.php in Drupal 9
File
core/modules/jsonapi/src/Normalizer/EntityReferenceFieldNormalizer.php
View source
<?php
namespace Drupal\jsonapi\Normalizer;
use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Field\EntityReferenceFieldItemListInterface;
use Drupal\Core\Url;
use Drupal\jsonapi\JsonApiResource\ResourceIdentifier;
use Drupal\jsonapi\JsonApiResource\ResourceIdentifierInterface;
use Drupal\jsonapi\JsonApiResource\ResourceObject;
use Drupal\jsonapi\JsonApiSpec;
use Drupal\jsonapi\Normalizer\Value\CacheableNormalization;
use Drupal\jsonapi\ResourceType\ResourceTypeRelationship;
use Drupal\jsonapi\Routing\Routes;
class EntityReferenceFieldNormalizer extends FieldNormalizer {
protected $supportedInterfaceOrClass = EntityReferenceFieldItemListInterface::class;
public function normalize($field, $format = NULL, array $context = []) {
assert($field instanceof EntityReferenceFieldItemListInterface);
$resource_identifiers = array_filter(ResourceIdentifier::toResourceIdentifiers($field
->filterEmptyItems()), function (ResourceIdentifierInterface $resource_identifier) {
return !$resource_identifier
->getResourceType()
->isInternal();
});
$normalized_items = CacheableNormalization::aggregate($this->serializer
->normalize($resource_identifiers, $format, $context));
assert($context['resource_object'] instanceof ResourceObject);
$resource_relationship = $context['resource_object']
->getResourceType()
->getFieldByInternalName($field
->getName());
assert($resource_relationship instanceof ResourceTypeRelationship);
$link_cacheability = new CacheableMetadata();
$links = array_map(function (Url $link) use ($link_cacheability) {
$href = $link
->setAbsolute()
->toString(TRUE);
$link_cacheability
->addCacheableDependency($href);
return [
'href' => $href
->getGeneratedUrl(),
];
}, static::getRelationshipLinks($context['resource_object'], $resource_relationship));
$data_normalization = $normalized_items
->getNormalization();
$normalization = [
'data' => $resource_relationship
->hasOne() ? array_shift($data_normalization) : $data_normalization,
];
if (!empty($links)) {
$normalization['links'] = $links;
}
return (new CacheableNormalization($normalized_items, $normalization))
->withCacheableDependency($link_cacheability);
}
public static function getRelationshipLinks(ResourceObject $relationship_context, ResourceTypeRelationship $resource_relationship) {
$resource_type = $relationship_context
->getResourceType();
if ($resource_type
->isInternal() || !$resource_type
->isLocatable()) {
return [];
}
$public_field_name = $resource_relationship
->getPublicName();
$relationship_route_name = Routes::getRouteName($resource_type, "{$public_field_name}.relationship.get");
$links = [
'self' => Url::fromRoute($relationship_route_name, [
'entity' => $relationship_context
->getId(),
]),
];
if (static::hasNonInternalResourceType($resource_type
->getRelatableResourceTypesByField($public_field_name))) {
$related_route_name = Routes::getRouteName($resource_type, "{$public_field_name}.related");
$links['related'] = Url::fromRoute($related_route_name, [
'entity' => $relationship_context
->getId(),
]);
}
if ($resource_type
->isVersionable()) {
$version_query_parameter = [
JsonApiSpec::VERSION_QUERY_PARAMETER => $relationship_context
->getVersionIdentifier(),
];
$links['self']
->setOption('query', $version_query_parameter);
if (isset($links['related'])) {
$links['related']
->setOption('query', $version_query_parameter);
}
}
return $links;
}
protected static function hasNonInternalResourceType(array $resource_types) {
foreach ($resource_types as $resource_type) {
if (!$resource_type
->isInternal()) {
return TRUE;
}
}
return FALSE;
}
}