You are here

protected function ResourceIdentifierNormalizer::guessFieldName in JSON:API Extras 8.3

Guesses the field name of a resource identifier pointing to a UUID.

Parameters

string $uuid: The uuid being referenced.

\Drupal\jsonapi\JsonApiResource\ResourceObject $resource_object: The object being normalized.

Return value

string|null The field name.

1 call to ResourceIdentifierNormalizer::guessFieldName()
ResourceIdentifierNormalizer::normalize in src/Normalizer/ResourceIdentifierNormalizer.php
Normalizes an object into a set of arrays/scalars.

File

src/Normalizer/ResourceIdentifierNormalizer.php, line 84

Class

ResourceIdentifierNormalizer
Converts the Drupal entity reference item object to a JSON:API structure.

Namespace

Drupal\jsonapi_extras\Normalizer

Code

protected function guessFieldName($uuid, ResourceObject $resource_object) {
  $resource_type = $resource_object
    ->getResourceType();
  assert($resource_type instanceof ConfigurableResourceType);

  // From the resource object get all the reference fields.
  $reference_field_names = array_keys($resource_type
    ->getRelatableResourceTypes());

  // Only consider the fields that contain enhancers. This is to improve
  // performance. Discard the candidates that will not have an enhancer.
  $ref_enhancers = array_filter(array_map(function ($public_field_name) use ($resource_type) {
    return $resource_type
      ->getFieldEnhancer($public_field_name, 'publicName');
  }, array_combine($reference_field_names, $reference_field_names)));

  // Get the field objects of the reference fields that have enhancers.
  $reference_fields = array_intersect_key($resource_object
    ->getFields(), array_flip(array_keys($ref_enhancers)));
  $reference_fields = array_filter($reference_fields, function ($reference_field) {

    // This is certainly a limitation.
    return $reference_field instanceof EntityReferenceFieldItemListInterface;
  });
  return array_reduce($reference_fields, function ($field_name, EntityReferenceFieldItemListInterface $object_field) use ($uuid) {
    if ($field_name) {
      return $field_name;
    }
    $referenced_entities = $object_field
      ->referencedEntities();

    // If any of the referenced entities contains the UUID of the field
    // being normalized, then we have our field name.
    $matches = array_filter($referenced_entities, function (EntityInterface $referenced_entity) use ($uuid) {
      return $uuid === $referenced_entity
        ->uuid();
    });
    return empty($matches) ? NULL : $object_field
      ->getName();
  });
}