public function EntityReferenceFieldNormalizer::denormalize in JSON:API 8
Overrides FieldNormalizer::denormalize
File
- src/
Normalizer/ EntityReferenceFieldNormalizer.php, line 153
Class
- EntityReferenceFieldNormalizer
- Normalizer class specific for entity reference field objects.
Namespace
Drupal\jsonapi\NormalizerCode
public function denormalize($data, $class, $format = NULL, array $context = []) {
// If we get to here is through a write method on a relationship operation.
/** @var \Drupal\jsonapi\ResourceType\ResourceType $resource_type */
$resource_type = $context['resource_type'];
$entity_type_id = $resource_type
->getEntityTypeId();
$field_definitions = $this->fieldManager
->getFieldDefinitions($entity_type_id, $resource_type
->getBundle());
if (empty($context['related']) || empty($field_definitions[$context['related']])) {
throw new BadRequestHttpException('Invalid or missing related field.');
}
/* @var \Drupal\field\Entity\FieldConfig $field_definition */
$field_definition = $field_definitions[$context['related']];
// This is typically 'target_id'.
$item_definition = $field_definition
->getItemDefinition();
$property_key = $item_definition
->getMainPropertyName();
$target_resource_types = $resource_type
->getRelatableResourceTypesByField($context['related']);
$target_resource_type_names = array_map(function (ResourceType $resource_type) {
return $resource_type
->getTypeName();
}, $target_resource_types);
$is_multiple = $field_definition
->getFieldStorageDefinition()
->isMultiple();
$data = $this
->massageRelationshipInput($data, $is_multiple);
$values = array_map(function ($value) use ($property_key, $target_resource_type_names) {
// Make sure that the provided type is compatible with the targeted
// resource.
if (!in_array($value['type'], $target_resource_type_names)) {
throw new BadRequestHttpException(sprintf('The provided type (%s) does not mach the destination resource types (%s).', $value['type'], implode(', ', $target_resource_type_names)));
}
// Load the entity by UUID.
list($entity_type_id, ) = explode('--', $value['type']);
$entity = $this->entityRepository
->loadEntityByUuid($entity_type_id, $value['id']);
$value['id'] = $entity ? $entity
->id() : NULL;
$properties = [
$property_key => $value['id'],
];
// Also take into account additional properties provided by the field
// type.
if (!empty($value['meta'])) {
foreach ($value['meta'] as $meta_key => $meta_value) {
$properties[$meta_key] = $meta_value;
}
}
return $properties;
}, $data['data']);
return $this->pluginManager
->createFieldItemList($context['target_entity'], $context['related'], $values);
}