function ResourceObjectNormalizer::processContentEntitySchema

1 call to ResourceObjectNormalizer::processContentEntitySchema()
ResourceObjectNormalizer::getNormalizationSchema in core/modules/jsonapi/src/Normalizer/ResourceObjectNormalizer.php
Retrieve JSON Schema for the normalization.

File

core/modules/jsonapi/src/Normalizer/ResourceObjectNormalizer.php, line 323

Class

ResourceObjectNormalizer
Converts the JSON:API module ResourceObject into a JSON:API array structure.

Namespace

Drupal\jsonapi\Normalizer

Code

protected function processContentEntitySchema(ResourceObject $resource_object, array $context, array &$attributes_schema, &$relationships_schema) : void {
  // Actual normalization supports sparse fieldsets, however we provide schema
  // for all possible fields that may be retrieved.
  $resource_type = $resource_object->getResourceType();
  $field_definitions = $this->entityFieldManager
    ->getFieldDefinitions($resource_type->getEntityTypeId(), $resource_type->getBundle());
  $resource_fields = $resource_type->getFields();
  // User resource objects contain a read-only attribute that is not a real
  // field on the user entity type.
  // @see \Drupal\jsonapi\JsonApiResource\ResourceObject::extractContentEntityFields()
  // @todo Eliminate this special casing in https://www.drupal.org/project/drupal/issues/3079254.
  if ($resource_type->getEntityTypeId() === 'user') {
    $resource_fields = array_diff_key($resource_fields, array_flip([
      $resource_type->getPublicName('display_name'),
    ]));
  }
  /** @var \Drupal\Core\Field\FieldDefinitionInterface[] $fields */
  $fields = array_reduce($resource_fields, function (array $carry, ResourceTypeField $resource_field) use ($field_definitions) {
    if (!$resource_field->isFieldEnabled()) {
      return $carry;
    }
    $carry[$resource_field->getPublicName()] = $field_definitions[$resource_field->getInternalName()];
    return $carry;
  }, []);
  assert($this->serializer instanceof Serializer);
  $relationship_field_names = array_keys($resource_type->getRelatableResourceTypes());
  $create_values = [];
  if ($bundle_key = $this->entityTypeManager
    ->getDefinition($resource_type->getEntityTypeId())
    ->getKey('bundle')) {
    $create_values = [
      $bundle_key => $resource_type->getBundle(),
    ];
  }
  $stub_entity = $this->entityTypeManager
    ->getStorage($resource_type->getEntityTypeId())
    ->create($create_values);
  foreach ($fields as $field_name => $field) {
    $stub_field = $stub_entity->get($field->getName());
    if ($stub_field instanceof EntityReferenceFieldItemListInterface) {
      // Build the relationship object based on the entity reference and
      // retrieve normalizer for that object instead.
      // @see ::serializeField()
      $relationship = Relationship::createFromEntityReferenceField($resource_object, $stub_field);
      $schema = $this->serializer
        ->getJsonSchema($relationship, $context);
    }
    else {
      $schema = $this->serializer
        ->getJsonSchema($stub_field, $context);
    }
    // Fallback basic annotations.
    if (empty($schema['title']) && ($title = $field->getLabel())) {
      $schema['title'] = (string) $title;
    }
    if (empty($schema['description']) && ($description = $field->getFieldStorageDefinition()
      ->getDescription())) {
      $schema['description'] = (string) $description;
    }
    if (in_array($field_name, $relationship_field_names, TRUE)) {
      $relationships_schema['properties'][$field_name] = $schema;
    }
    else {
      $attributes_schema['properties'][$field_name] = $schema;
    }
  }
}

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