You are here

protected static function ResourceIdentifier::getVirtualOrMissingResourceIdentifier in Drupal 8

Same name and namespace in other branches
  1. 9 core/modules/jsonapi/src/JsonApiResource/ResourceIdentifier.php \Drupal\jsonapi\JsonApiResource\ResourceIdentifier::getVirtualOrMissingResourceIdentifier()

Creates a ResourceIdentifier for a NULL or FALSE entity reference item.

Parameters

\Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem $item: The entity reference field item.

Return value

self A new ResourceIdentifier object.

1 call to ResourceIdentifier::getVirtualOrMissingResourceIdentifier()
ResourceIdentifier::toResourceIdentifier in core/modules/jsonapi/src/JsonApiResource/ResourceIdentifier.php
Creates a ResourceIdentifier object.

File

core/modules/jsonapi/src/JsonApiResource/ResourceIdentifier.php, line 411

Class

ResourceIdentifier
Represents a JSON:API resource identifier object.

Namespace

Drupal\jsonapi\JsonApiResource

Code

protected static function getVirtualOrMissingResourceIdentifier(EntityReferenceItem $item) {
  $resource_type_repository = \Drupal::service('jsonapi.resource_type.repository');
  $property_name = static::getDataReferencePropertyName($item);
  $value = $item
    ->get($property_name)
    ->getValue();
  assert($value === NULL);
  $field = $item
    ->getParent();
  assert($field instanceof EntityReferenceFieldItemListInterface);
  $host_entity = $field
    ->getEntity();
  assert($host_entity instanceof EntityInterface);
  $resource_type = $resource_type_repository
    ->get($host_entity
    ->getEntityTypeId(), $host_entity
    ->bundle());
  assert($resource_type instanceof ResourceType);
  $relatable_resource_types = $resource_type
    ->getRelatableResourceTypesByField($resource_type
    ->getPublicName($field
    ->getName()));
  assert(!empty($relatable_resource_types));
  $get_metadata = function ($type) {
    return [
      'links' => [
        'help' => [
          'href' => "https://www.drupal.org/docs/8/modules/json-api/core-concepts#{$type}",
          'meta' => [
            'about' => "Usage and meaning of the '{$type}' resource identifier.",
          ],
        ],
      ],
    ];
  };
  $resource_type = reset($relatable_resource_types);

  // A non-empty entity reference field that refers to a non-existent entity
  // is not a data integrity problem. For example, Term entities' "parent"
  // entity reference field uses target_id zero to refer to the non-existent
  // "<root>" term. And references to entities that no longer exist are not
  // cleaned up by Drupal; hence we map it to a "missing" resource.
  if ($field
    ->getFieldDefinition()
    ->getSetting('target_type') === 'taxonomy_term' && $item
    ->get('target_id')
    ->getCastedValue() === 0) {
    if (count($relatable_resource_types) !== 1) {
      throw new \RuntimeException('Relationships to virtual resources are possible only if a single resource type is relatable.');
    }
    return new static($resource_type, 'virtual', $get_metadata('virtual'));
  }
  else {

    // In case of a dangling reference, it is impossible to determine which
    // resource type it used to reference, because that requires knowing the
    // referenced bundle, which Drupal does not store.
    // If we can reliably determine the resource type of the dangling
    // reference, use it; otherwise conjure a fake resource type out of thin
    // air, one that indicates we don't know the bundle.
    $resource_type = count($relatable_resource_types) > 1 ? new ResourceType('?', '?', '') : reset($relatable_resource_types);
    return new static($resource_type, 'missing', $get_metadata('missing'));
  }
}