function ResourceTypeRepository::getFields
Same name in other branches
- 8.9.x core/modules/jsonapi/src/ResourceType/ResourceTypeRepository.php \Drupal\jsonapi\ResourceType\ResourceTypeRepository::getFields()
- 10 core/modules/jsonapi/src/ResourceType/ResourceTypeRepository.php \Drupal\jsonapi\ResourceType\ResourceTypeRepository::getFields()
- 11.x core/modules/jsonapi/src/ResourceType/ResourceTypeRepository.php \Drupal\jsonapi\ResourceType\ResourceTypeRepository::getFields()
Gets the field mapping for the given field names and entity type + bundle.
Parameters
string[] $field_names: All field names on a bundle of the given entity type.
\Drupal\Core\Entity\EntityTypeInterface $entity_type: The entity type for which to get the field mapping.
string $bundle: The bundle to assess.
Return value
\Drupal\jsonapi\ResourceType\ResourceTypeField[] An array of JSON:API resource type fields keyed by internal field names.
2 calls to ResourceTypeRepository::getFields()
- AliasingResourceTypeRepository::getFields in core/
modules/ jsonapi/ tests/ modules/ jsonapi_test_field_aliasing/ src/ ResourceType/ AliasingResourceTypeRepository.php - Gets the field mapping for the given field names and entity type + bundle.
- ResourceTypeRepository::createResourceType in core/
modules/ jsonapi/ src/ ResourceType/ ResourceTypeRepository.php - Creates a ResourceType value object for the given entity type + bundle.
1 method overrides ResourceTypeRepository::getFields()
- AliasingResourceTypeRepository::getFields in core/
modules/ jsonapi/ tests/ modules/ jsonapi_test_field_aliasing/ src/ ResourceType/ AliasingResourceTypeRepository.php - Gets the field mapping for the given field names and entity type + bundle.
File
-
core/
modules/ jsonapi/ src/ ResourceType/ ResourceTypeRepository.php, line 223
Class
- ResourceTypeRepository
- Provides a repository of all JSON:API resource types.
Namespace
Drupal\jsonapi\ResourceTypeCode
protected function getFields(array $field_names, EntityTypeInterface $entity_type, $bundle) {
assert(Inspector::assertAllStrings($field_names));
assert($entity_type instanceof ContentEntityTypeInterface || $entity_type instanceof ConfigEntityTypeInterface);
assert(is_string($bundle) && !empty($bundle), 'A bundle ID is required. Bundleless entity types should pass the entity type ID again.');
// JSON:API resource identifier objects are sufficient to identify
// entities. By exposing all fields as attributes, we expose unwanted,
// confusing or duplicate information:
// - exposing an entity's ID (which is not a UUID) is bad, but it's
// necessary for certain Drupal-coupled clients, so we alias it by
// prefixing it with `drupal_internal__`.
// - exposing an entity's UUID as an attribute is useless (it's already part
// of the mandatory "id" attribute in JSON:API), so we disable it in most
// cases.
// - exposing its revision ID as an attribute will compete with any profile
// defined meta members used for resource object versioning.
// @see http://jsonapi.org/format/#document-resource-identifier-objects
$id_field_name = $entity_type->getKey('id');
$uuid_field_name = $entity_type->getKey('uuid');
if ($uuid_field_name && $uuid_field_name !== 'id') {
$fields[$uuid_field_name] = new ResourceTypeAttribute($uuid_field_name, NULL, FALSE);
}
$fields[$id_field_name] = new ResourceTypeAttribute($id_field_name, "drupal_internal__{$id_field_name}");
if ($entity_type->isRevisionable() && ($revision_id_field_name = $entity_type->getKey('revision'))) {
$fields[$revision_id_field_name] = new ResourceTypeAttribute($revision_id_field_name, "drupal_internal__{$revision_id_field_name}");
}
if ($entity_type instanceof ConfigEntityTypeInterface) {
// The '_core' key is reserved by Drupal core to handle complex edge cases
// correctly. Data in the '_core' key is irrelevant to clients reading
// configuration, and is not allowed to be set by clients writing
// configuration: it is for Drupal core only, and managed by Drupal core.
// @see https://www.drupal.org/node/2653358
$fields['_core'] = new ResourceTypeAttribute('_core', NULL, FALSE);
}
$is_fieldable = $entity_type->entityClassImplements(FieldableEntityInterface::class);
if ($is_fieldable) {
$field_definitions = $this->entityFieldManager
->getFieldDefinitions($entity_type->id(), $bundle);
}
// For all other fields, use their internal field name also as their public
// field name. Unless they're called "id" or "type": those names are
// reserved by the JSON:API spec.
// @see http://jsonapi.org/format/#document-resource-object-fields
$reserved_field_names = [
'id',
'type',
];
foreach (array_diff($field_names, array_keys($fields)) as $field_name) {
$alias = $field_name;
// Alias the fields reserved by the JSON:API spec with `{entity_type}_`.
if (in_array($field_name, $reserved_field_names, TRUE)) {
$alias = $entity_type->id() . '_' . $field_name;
}
// The default, which applies to most fields: expose as-is.
$field_definition = $is_fieldable && !empty($field_definitions[$field_name]) ? $field_definitions[$field_name] : NULL;
$is_relationship_field = $field_definition && static::isReferenceFieldDefinition($field_definition);
$has_one = !$field_definition || $field_definition->getFieldStorageDefinition()
->getCardinality() === 1;
$fields[$field_name] = $is_relationship_field ? new ResourceTypeRelationship($field_name, $alias, TRUE, $has_one) : new ResourceTypeAttribute($field_name, $alias, TRUE, $has_one);
}
// With all fields now aliased, detect any conflicts caused by the
// automatically generated aliases above.
foreach (array_intersect($reserved_field_names, array_keys($fields)) as $reserved_field_name) {
/** @var \Drupal\jsonapi\ResourceType\ResourceTypeField $aliased_reserved_field */
$aliased_reserved_field = $fields[$reserved_field_name];
/** @var \Drupal\jsonapi\ResourceType\ResourceTypeField $field */
foreach (array_diff_key($fields, array_flip([
$reserved_field_name,
])) as $field) {
if ($aliased_reserved_field->getPublicName() === $field->getPublicName()) {
throw new \LogicException("The generated alias '{$aliased_reserved_field->getPublicName()}' for field name '{$aliased_reserved_field->getInternalName()}' conflicts with an existing field. Please report this in the JSON:API issue queue!");
}
}
}
// Special handling for user entities that allows a JSON:API user agent to
// access the display name of a user. This is useful when displaying the
// name of a node's author.
// @see \Drupal\jsonapi\JsonApiResource\ResourceObject::extractContentEntityFields()
// @todo: eliminate this special casing in https://www.drupal.org/project/drupal/issues/3079254.
if ($entity_type->id() === 'user') {
$fields['display_name'] = new ResourceTypeAttribute('display_name');
}
return $fields;
}
Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.