class RelationshipItemNormalizer in JSON:API 8
Converts the Drupal entity reference item object to a JSON API structure.
@internal
Hierarchy
- class \Drupal\serialization\Normalizer\NormalizerBase implements \Symfony\Component\Serializer\SerializerAwareInterface, CacheableNormalizerInterface uses \Symfony\Component\Serializer\SerializerAwareTrait
- class \Drupal\jsonapi\Normalizer\NormalizerBase
- class \Drupal\jsonapi\Normalizer\FieldItemNormalizer
- class \Drupal\jsonapi\Normalizer\RelationshipItemNormalizer
- class \Drupal\jsonapi\Normalizer\FieldItemNormalizer
- class \Drupal\jsonapi\Normalizer\NormalizerBase
Expanded class hierarchy of RelationshipItemNormalizer
1 string reference to 'RelationshipItemNormalizer'
1 service uses RelationshipItemNormalizer
File
- src/
Normalizer/ RelationshipItemNormalizer.php, line 17
Namespace
Drupal\jsonapi\NormalizerView source
class RelationshipItemNormalizer extends FieldItemNormalizer {
/**
* The interface or class that this Normalizer supports.
*
* @var string
*/
protected $supportedInterfaceOrClass = RelationshipItem::class;
/**
* The JSON API resource type repository.
*
* @var \Drupal\jsonapi\ResourceType\ResourceTypeRepositoryInterface
*/
protected $resourceTypeRepository;
/**
* Instantiates a RelationshipItemNormalizer object.
*
* @param \Drupal\jsonapi\ResourceType\ResourceTypeRepositoryInterface $resource_type_repository
* The JSON API resource type repository.
*/
public function __construct(ResourceTypeRepositoryInterface $resource_type_repository) {
$this->resourceTypeRepository = $resource_type_repository;
}
/**
* {@inheritdoc}
*/
public function normalize($relationship_item, $format = NULL, array $context = []) {
/* @var $relationship_item \Drupal\jsonapi\Normalizer\RelationshipItem */
// TODO: We are always loading the referenced entity. Even if it is not
// going to be included. That may be a performance issue. We do it because
// we need to know the entity type and bundle to load the JSON API resource
// type for the relationship item. We need a better way of finding about
// this.
$target_entity = $relationship_item
->getTargetEntity();
$values = $relationship_item
->getValue();
if (isset($context['langcode'])) {
$values['lang'] = $context['langcode'];
}
$host_field_name = $relationship_item
->getParent()
->getPropertyName();
if (!empty($context['include']) && in_array($host_field_name, $context['include']) && $target_entity !== NULL) {
$context = $this
->buildSubContext($context, $target_entity, $host_field_name);
$entity_and_access = EntityResource::getEntityAndAccess($target_entity);
$included_normalizer_value = $this->serializer
->normalize(new JsonApiDocumentTopLevel($entity_and_access['entity']), $format, $context);
}
else {
$included_normalizer_value = NULL;
}
return new RelationshipItemNormalizerValue($values, new CacheableMetadata(), $relationship_item
->getTargetResourceType(), $included_normalizer_value);
}
/**
* Builds the sub-context for the relationship include.
*
* @param array $context
* The serialization context.
* @param \Drupal\Core\Entity\EntityInterface $entity
* The related entity.
* @param string $host_field_name
* The name of the field reference.
*
* @return array
* The modified new context.
*/
protected function buildSubContext(array $context, EntityInterface $entity, $host_field_name) {
// Swap out the context for the context of the referenced resource.
$context['resource_type'] = $this->resourceTypeRepository
->get($entity
->getEntityTypeId(), $entity
->bundle());
// Since we're going one level down the only includes we need are the ones
// that apply to this level as well.
$include_candidates = array_filter($context['include'], function ($include) use ($host_field_name) {
return strpos($include, $host_field_name . '.') === 0;
});
$context['include'] = array_map(function ($include) use ($host_field_name) {
return str_replace($host_field_name . '.', '', $include);
}, $include_candidates);
$context['is_include_normalization'] = TRUE;
return $context;
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
CacheableNormalizerInterface:: |
constant | Name of key for bubbling cacheability metadata via serialization context. | ||
FieldItemNormalizer:: |
protected | property |
The formats that the Normalizer can handle. Overrides NormalizerBase:: |
|
FieldItemNormalizer:: |
public | function | ||
NormalizerBase:: |
protected | property | List of formats which supports (de-)normalization. | 3 |
NormalizerBase:: |
protected | function | Adds cacheability if applicable. | |
NormalizerBase:: |
protected | function | Checks if the provided format is supported by this normalizer. | 2 |
NormalizerBase:: |
public | function |
Implements \Symfony\Component\Serializer\Normalizer\DenormalizerInterface::supportsDenormalization() Overrides NormalizerBase:: |
|
NormalizerBase:: |
public | function |
Checks whether the given class is supported for normalization by this normalizer. Overrides NormalizerBase:: |
|
RelationshipItemNormalizer:: |
protected | property | The JSON API resource type repository. | |
RelationshipItemNormalizer:: |
protected | property |
The interface or class that this Normalizer supports. Overrides FieldItemNormalizer:: |
|
RelationshipItemNormalizer:: |
protected | function | Builds the sub-context for the relationship include. | |
RelationshipItemNormalizer:: |
public | function |
This normalizer leaves JSON API normalizer land and enters the land of
Drupal core's serialization system. That system was never designed with
cacheability in mind, and hence bubbles cacheability out of band. This must
catch it, and pass it to… Overrides FieldItemNormalizer:: |
|
RelationshipItemNormalizer:: |
public | function | Instantiates a RelationshipItemNormalizer object. |