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.