function ResourceIdentifierNormalizer::denormalize

Same name in other branches
  1. 9 core/modules/jsonapi/src/Normalizer/ResourceIdentifierNormalizer.php \Drupal\jsonapi\Normalizer\ResourceIdentifierNormalizer::denormalize()
  2. 10 core/modules/jsonapi/src/Normalizer/ResourceIdentifierNormalizer.php \Drupal\jsonapi\Normalizer\ResourceIdentifierNormalizer::denormalize()
  3. 11.x core/modules/jsonapi/src/Normalizer/ResourceIdentifierNormalizer.php \Drupal\jsonapi\Normalizer\ResourceIdentifierNormalizer::denormalize()

File

core/modules/jsonapi/src/Normalizer/ResourceIdentifierNormalizer.php, line 66

Class

ResourceIdentifierNormalizer
Normalizes a Relationship according to the JSON:API specification.

Namespace

Drupal\jsonapi\Normalizer

Code

public function denormalize($data, $class, $format = NULL, array $context = []) {
    // If we get here, it's via a relationship POST/PATCH.
    
    /** @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($resource_type->getPublicName($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);
    $resource_identifiers = 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)));
        }
        return new ResourceIdentifier($value['type'], $value['id'], isset($value['meta']) ? $value['meta'] : []);
    }, $data['data']);
    if (!ResourceIdentifier::areResourceIdentifiersUnique($resource_identifiers)) {
        throw new BadRequestHttpException('Duplicate relationships are not permitted. Use `meta.arity` to distinguish resource identifiers with matching `type` and `id` values.');
    }
    return $resource_identifiers;
}

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