headless_cms-1.0.3/modules/headless_cms_preview/src/JsonApi/PreviewIncludeResolver.php

modules/headless_cms_preview/src/JsonApi/PreviewIncludeResolver.php
<?php

declare(strict_types=1);

namespace Drupal\headless_cms_preview\JsonApi;

use Drupal\Core\Access\AccessResult;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItemInterface;
use Drupal\Core\TypedData\DataReferenceDefinitionInterface;
use Drupal\jsonapi\Exception\EntityAccessDeniedHttpException;
use Drupal\jsonapi\IncludeResolver as BaseIncludeResolver;
use Drupal\jsonapi\JsonApiResource\Data;
use Drupal\jsonapi\JsonApiResource\IncludedData;
use Drupal\jsonapi\JsonApiResource\LabelOnlyResourceObject;
use Drupal\jsonapi\JsonApiResource\ResourceIdentifierInterface;
use Drupal\jsonapi\JsonApiResource\ResourceObject;

/**
 * Custom JSON:API include resolver for preview data.
 */
class PreviewIncludeResolver extends BaseIncludeResolver {

  /**
   * {@inheritdoc}
   *
   * Alters the core `resolveIncludeTree` method to only load entities from
   * the preview data directly stored on the field_items.
   *
   * Major changes are marked with `CUSTOMIZATION START` and `CUSTOMIZATION
   * END`.
   */
  protected function resolveIncludeTree(array $include_tree, Data $data, ?Data $includes = NULL) {
    $includes = is_null($includes) ? new IncludedData([]) : $includes;
    foreach ($include_tree as $field_name => $children) {
      $references = [];
      foreach ($data as $resource_object) {
        // Some objects in the collection may be LabelOnlyResourceObjects or
        // EntityAccessDeniedHttpException objects.
        assert($resource_object instanceof ResourceIdentifierInterface);
        $public_field_name = $resource_object->getResourceType()->getPublicName($field_name);

        if ($resource_object instanceof LabelOnlyResourceObject) {
          $message = "The current user is not allowed to view this relationship.";
          $exception = new EntityAccessDeniedHttpException($resource_object->getEntity(), AccessResult::forbidden("The user only has authorization for the 'view label' operation."), '', $message, $public_field_name);
          $includes = IncludedData::merge($includes, new IncludedData([$exception]));
          continue;
        }
        elseif (!$resource_object instanceof ResourceObject) {
          continue;
        }

        // Not all entities in $entity_collection will be of the same bundle and
        // may not have all of the same fields. Therefore, calling
        // $resource_object->get($a_missing_field_name) will result in an
        // exception.
        if (!$resource_object->hasField($public_field_name)) {
          continue;
        }
        $field_list = $resource_object->getField($public_field_name);
        // Config entities don't have real fields and can't have relationships.
        if (!$field_list instanceof FieldItemListInterface) {
          continue;
        }
        $field_access = $field_list->access('view', NULL, TRUE);
        if (!$field_access->isAllowed()) {
          $message = 'The current user is not allowed to view this relationship.';
          $exception = new EntityAccessDeniedHttpException($field_list->getEntity(), $field_access, '', $message, $public_field_name);
          $includes = IncludedData::merge($includes, new IncludedData([$exception]));
          continue;
        }
        if (is_subclass_of($field_list->getItemDefinition()->getClass(), EntityReferenceItemInterface::class)) {

          foreach ($field_list as $field_item) {
            if (!($field_item->getDataDefinition()->getPropertyDefinition('entity') instanceof DataReferenceDefinitionInterface)) {
              continue;
            }

            if (!($field_item->entity instanceof EntityInterface)) {
              continue;
            }

            $target_type = $field_item->entity->getEntityTypeId();
            // CUSTOMIZATION START - Support preview.
            $entity = $field_item->entity;
            $entity->mergeCacheMaxAge(0);
            $references[$target_type . ':preview'][] = $entity;
            // CUSTOMIZATION END.
          }
        }
      }
      foreach ($references as $target_type_and_rev => $ids) {
        // Revision type might be null, so we suppress the warning.
        @[$target_type] = array_pad(explode(':', $target_type_and_rev), 2, NULL);

        // CUSTOMIZATION START - Support preview.
        $ids = array_filter($ids, fn($i) => !is_null($i));
        $targeted_entities = array_reduce($ids, function ($carry, $entity) {
          /** @var \Drupal\Core\Entity\EntityInterface $entity */
          $carry[$entity->id()] = $entity;

          return $carry;
        }, []);
        // CUSTOMIZATION END.
        $access_checked_entities = array_map(function (EntityInterface $entity) {
          return $this->entityAccessChecker->getAccessCheckedResourceObject($entity);
        }, $targeted_entities);
        $targeted_collection = new IncludedData(array_filter($access_checked_entities, function (ResourceIdentifierInterface $resource_object) {
          return !$resource_object->getResourceType()->isInternal();
        }));
        $includes = static::resolveIncludeTree($children, $targeted_collection, IncludedData::merge($includes, $targeted_collection));
      }
    }
    return $includes;
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc