You are here

protected function RelationshipFieldDefinitionNormalizer::normalizeRelationship in JSON:API Schema 8

Normalizes the relationship.

Parameters

\Drupal\Core\Field\FieldDefinitionInterface $field_definition: The field definition.

Return value

array The normalized relationship.

1 call to RelationshipFieldDefinitionNormalizer::normalizeRelationship()
RelationshipFieldDefinitionNormalizer::normalize in src/Normalizer/RelationshipFieldDefinitionNormalizer.php

File

src/Normalizer/RelationshipFieldDefinitionNormalizer.php, line 94

Class

RelationshipFieldDefinitionNormalizer
Normalizer for RelationshipFieldDefinitionNormalizer objects.

Namespace

Drupal\jsonapi_schema\Normalizer

Code

protected function normalizeRelationship(FieldDefinitionInterface $field_definition, $format = NULL, $context = []) {
  $resource_type_repository = \Drupal::service('jsonapi.resource_type.repository');
  assert($resource_type_repository instanceof ResourceTypeRepositoryInterface);

  // A relationship has very similar schema every time.
  $resource_identifier_object = [
    'type' => 'object',
    'required' => [
      'type',
      'id',
    ],
    'properties' => [
      'type' => [
        'type' => 'string',
        'title' => t('Referenced resource'),
      ],
      'id' => [
        'type' => 'string',
        'title' => t('Resource ID'),
        'format' => 'uuid',
        'maxLength' => 128,
      ],
    ],
  ];

  // Handle the multivalue variant.
  $cardinality = $field_definition
    ->getFieldStorageDefinition()
    ->getCardinality();
  if ($target_entity_type = $field_definition
    ->getSetting('target_type')) {
    $handler_settings = $field_definition
      ->getSetting('handler_settings');
    $target_bundles = empty($handler_settings['target_bundles']) ? [
      $target_entity_type,
    ] : array_values($handler_settings['target_bundles']);
    $target_resource_types = array_map(function ($bundle) use ($target_entity_type, $resource_type_repository) {
      return $resource_type_repository
        ->get($target_entity_type, $bundle ?: $target_entity_type);
      return $resource_type
        ->getTypeName();
    }, $target_bundles);
    $enum = array_map(function (ResourceType $resource_type) {
      return $resource_type
        ->getTypeName();
    }, array_filter($target_resource_types));
  }
  $meta = $this->serializer
    ->normalize($field_definition
    ->getItemDefinition(), $format, $context);
  if ($cardinality == 1) {
    $data = $resource_identifier_object;
    if (!empty($enum)) {
      $data['properties']['type']['enum'] = $enum;
      $data['properties']['meta'] = $meta;
    }
  }
  else {
    $data = [
      'type' => 'array',
      'items' => $resource_identifier_object,
    ];
    if (!empty($enum)) {
      $data['items']['properties']['type']['enum'] = $enum;
      $data['items']['properties']['meta'] = $meta;
    }
  }
  $normalized = [
    'type' => 'object',
    'properties' => [
      'data' => $data,
    ],
    'title' => $field_definition
      ->getLabel(),
  ];
  return $normalized;
}