class EntityReferenceFieldNormalizer

Same name in other branches
  1. 8.9.x core/modules/jsonapi/src/Normalizer/EntityReferenceFieldNormalizer.php \Drupal\jsonapi\Normalizer\EntityReferenceFieldNormalizer
  2. 10 core/modules/jsonapi/src/Normalizer/EntityReferenceFieldNormalizer.php \Drupal\jsonapi\Normalizer\EntityReferenceFieldNormalizer
  3. 11.x core/modules/jsonapi/src/Normalizer/EntityReferenceFieldNormalizer.php \Drupal\jsonapi\Normalizer\EntityReferenceFieldNormalizer

Normalizer class specific for entity reference field objects.

@internal JSON:API maintains no PHP API since its API is the HTTP API. This class may change at any time and this will break any dependencies on it.

Hierarchy

  • class \Drupal\serialization\Normalizer\NormalizerBase implements \Symfony\Component\Serializer\SerializerAwareInterface, \Drupal\serialization\Normalizer\CacheableNormalizerInterface, \Symfony\Component\Serializer\Normalizer\CacheableSupportsMethodInterface uses \Symfony\Component\Serializer\SerializerAwareTrait
    • class \Drupal\jsonapi\Normalizer\NormalizerBase extends \Drupal\serialization\Normalizer\NormalizerBase
      • class \Drupal\jsonapi\Normalizer\FieldNormalizer extends \Drupal\jsonapi\Normalizer\NormalizerBase implements \Symfony\Component\Serializer\Normalizer\DenormalizerInterface

Expanded class hierarchy of EntityReferenceFieldNormalizer

See also

https://www.drupal.org/project/drupal/issues/3032787

jsonapi.api.php

File

core/modules/jsonapi/src/Normalizer/EntityReferenceFieldNormalizer.php, line 25

Namespace

Drupal\jsonapi\Normalizer
View source
class EntityReferenceFieldNormalizer extends FieldNormalizer {
    
    /**
     * {@inheritdoc}
     */
    protected $supportedInterfaceOrClass = EntityReferenceFieldItemListInterface::class;
    
    /**
     * {@inheritdoc}
     */
    public function normalize($field, $format = NULL, array $context = []) {
        assert($field instanceof EntityReferenceFieldItemListInterface);
        // Build the relationship object based on the Entity Reference and normalize
        // that object instead.
        $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 = [
            // Empty 'to-one' relationships must be NULL.
            // Empty 'to-many' relationships must be an empty array.
            // @link http://jsonapi.org/format/#document-resource-object-linkage
'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);
    }
    
    /**
     * Gets the links for the relationship.
     *
     * @param \Drupal\jsonapi\JsonApiResource\ResourceObject $relationship_context
     *   The JSON:API resource object context of the relationship.
     * @param \Drupal\jsonapi\ResourceType\ResourceTypeRelationship $resource_relationship
     *   The resource type relationship field.
     *
     * @return array
     *   The relationship's links.
     */
    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;
    }
    
    /**
     * Determines if a given list of resource types contains a non-internal type.
     *
     * @param \Drupal\jsonapi\ResourceType\ResourceType[] $resource_types
     *   The JSON:API resource types to evaluate.
     *
     * @return bool
     *   FALSE if every resource type is internal, TRUE otherwise.
     */
    protected static function hasNonInternalResourceType(array $resource_types) {
        foreach ($resource_types as $resource_type) {
            if (!$resource_type->isInternal()) {
                return TRUE;
            }
        }
        return FALSE;
    }

}

Members

Title Sort descending Modifiers Object type Summary Overriden Title Overrides
CacheableNormalizerInterface::SERIALIZATION_CONTEXT_CACHEABILITY constant Name of key for bubbling cacheability metadata via serialization context.
EntityReferenceFieldNormalizer::$supportedInterfaceOrClass protected property The interface or class that this Normalizer supports. Overrides FieldNormalizer::$supportedInterfaceOrClass
EntityReferenceFieldNormalizer::getRelationshipLinks public static function Gets the links for the relationship.
EntityReferenceFieldNormalizer::hasNonInternalResourceType protected static function Determines if a given list of resource types contains a non-internal type.
EntityReferenceFieldNormalizer::normalize public function Overrides FieldNormalizer::normalize
FieldNormalizer::denormalize public function
FieldNormalizer::hasCacheableSupportsMethod public function Overrides NormalizerBase::hasCacheableSupportsMethod
FieldNormalizer::normalizeFieldItems protected function Helper function to normalize field items.
NormalizerBase::$format protected property List of formats which supports (de-)normalization. Overrides NormalizerBase::$format
NormalizerBase::addCacheableDependency protected function Adds cacheability if applicable.
NormalizerBase::checkFormat protected function Checks if the provided format is supported by this normalizer. Overrides NormalizerBase::checkFormat
NormalizerBase::rasterizeValueRecursive protected static function Rasterizes a value recursively.
NormalizerBase::supportsDenormalization public function Implements \Symfony\Component\Serializer\Normalizer\DenormalizerInterface::supportsDenormalization() 1
NormalizerBase::supportsNormalization public function 1

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.