graphql_core_schema-1.0.x-dev/src/Plugin/GraphQL/DataProducer/Route/EnhancedRouteEntity.php

src/Plugin/GraphQL/DataProducer/Route/EnhancedRouteEntity.php
<?php

namespace Drupal\graphql_core_schema\Plugin\GraphQL\DataProducer\Route;

use Drupal\Core\DependencyInjection\DependencySerializationTrait;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\TranslatableInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\TempStore\PrivateTempStoreFactory;
use Drupal\Core\Url;
use Drupal\graphql\GraphQL\Buffers\EntityBuffer;
use Drupal\graphql\GraphQL\Buffers\EntityRevisionBuffer;
use Drupal\graphql\GraphQL\Execution\FieldContext;
use Drupal\graphql\Plugin\GraphQL\DataProducer\DataProducerPluginBase;
use GraphQL\Deferred;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Loads the entity associated with the current URL.
 *
 * @DataProducer(
 *   id = "enhanced_route_entity",
 *   name = @Translation("Enhanced Route Entity"),
 *   description = @Translation("The entity belonging to the current url."),
 *   produces = @ContextDefinition("entity",
 *     label = @Translation("Entity")
 *   ),
 *   consumes = {
 *     "url" = @ContextDefinition("any",
 *       label = @Translation("The URL")
 *     ),
 *     "language" = @ContextDefinition("string",
 *       label = @Translation("Language"),
 *       required = FALSE
 *     )
 *   }
 * )
 */
class EnhancedRouteEntity extends DataProducerPluginBase implements ContainerFactoryPluginInterface {
  use DependencySerializationTrait;

  /**
   * The entity type manager.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * The entity buffer service.
   *
   * @var \Drupal\graphql\GraphQL\Buffers\EntityBuffer
   */
  protected $entityBuffer;

  /**
   * The entity revision buffer service.
   *
   * @var \Drupal\graphql\GraphQL\Buffers\EntityRevisionBuffer
   */
  protected $entityRevisionBuffer;

  /**
   * Stores the tempstore factory.
   *
   * @var \Drupal\Core\TempStore\PrivateTempStoreFactory
   */
  protected $tempStoreFactory;

  /**
   * {@inheritdoc}
   *
   * @codeCoverageIgnore
   */
  public static function create(ContainerInterface $container, array $configuration, $pluginId, $pluginDefinition) {
    return new static(
      $configuration,
      $pluginId,
      $pluginDefinition,
      $container->get('entity_type.manager'),
      $container->get('graphql.buffer.entity'),
      $container->get('graphql.buffer.entity_revision'),
      $container->get('tempstore.private')
    );
  }

  /**
   * RouteEntity constructor.
   *
   * @param array $configuration
   *   The plugin configuration array.
   * @param string $pluginId
   *   The plugin id.
   * @param mixed $pluginDefinition
   *   The plugin definition array.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
   *   The language manager service.
   * @param \Drupal\graphql\GraphQL\Buffers\EntityBuffer $entityBuffer
   *   The entity buffer service.
   * @param \Drupal\graphql\GraphQL\Buffers\EntityRevisionBuffer $entityRevisionBuffer
   *   The entity revision buffer service.
   * @param \Drupal\Core\TempStore\PrivateTempStoreFactory $tempStoreFactory
   *   The factory for the temp store object.
   *
   * @codeCoverageIgnore
   */
  public function __construct(
    array $configuration,
    $pluginId,
    $pluginDefinition,
    EntityTypeManagerInterface $entityTypeManager,
    EntityBuffer $entityBuffer,
    EntityRevisionBuffer $entityRevisionBuffer,
    PrivateTempStoreFactory $tempStoreFactory,
  ) {
    parent::__construct($configuration, $pluginId, $pluginDefinition);
    $this->entityTypeManager = $entityTypeManager;
    $this->entityBuffer = $entityBuffer;
    $this->entityRevisionBuffer = $entityRevisionBuffer;
    $this->tempStoreFactory = $tempStoreFactory;
  }

  /**
   * Resolver.
   *
   * @param \Drupal\Core\Url|mixed $url
   *   The URL to get the route entity from.
   * @param string|null $language
   *   The language code to get a translation of the entity.
   * @param \Drupal\graphql\GraphQL\Execution\FieldContext $context
   *   The GraphQL field context.
   */
  public function resolve($url, ?string $language, FieldContext $context) {
    if ($url instanceof Url) {
      $routeName = $url->getRouteName();
      $parameters = $url->getRouteParameters();

      // Special handling for node preview URLs.
      // The preview entity's form state is stored in the tempstore. From the
      // form state we can extract the entity. This is basically what
      // \Drupal\node\ParamConverter\NodePreviewConverter is doing.
      if ($routeName === 'entity.node.preview') {
        $store = $this->tempStoreFactory->get('node_preview');
        if ($form_state = $store->get($parameters['node_preview'])) {
          $context->mergeCacheMaxAge(0);
          return $form_state->getFormObject()->getEntity();
        }
        return NULL;
      }

      [, $type] = explode('.', $routeName);
      $id = $parameters[$type] ?? NULL;
      if (!$id) {
        return NULL;
      }

      $revisionId = $parameters[$type . '_revision'] ?? NULL;
      if ($routeName === 'entity.node.latest_version') {
        /** @var \Drupal\node\NodeStorageInterface $nodeStorage */
        $nodeStorage = $this->entityTypeManager->getStorage('node');
        $revisionId = $nodeStorage->getLatestRevisionId($id);
      }
      $resolver = $revisionId
        ? $this->entityRevisionBuffer->add($type, $revisionId)
        : $this->entityBuffer->add($type, $id);

      return new Deferred(function () use ($type, $resolver, $context, $language) {
        /** @var \Drupal\Core\Entity\EntityInterface|null $entity */
        $entity = $resolver();
        if (!$entity) {
          // If there is no entity with this id, add the list cache tags so that
          // the cache entry is purged whenever a new entity of this type is
          // saved.
          $type = $this->entityTypeManager->getDefinition($type);
          /** @var \Drupal\Core\Entity\EntityTypeInterface $type */
          $tags = $type->getListCacheTags();
          $context->addCacheTags($tags)->addCacheTags(['4xx-response']);
          return NULL;
        }

        // Get the correct translation.
        if (isset($language) && $language != $entity->language()->getId() && $entity instanceof TranslatableInterface) {
          $entity = $entity->getTranslation($language);
          $entity->addCacheContexts(["static:language:{$language}"]);
        }

        $access = $entity->access('view', NULL, TRUE);
        $context->addCacheableDependency($access);
        if ($access->isAllowed()) {
          return $entity;
        }
        return NULL;
      });
    }
    return NULL;
  }

}

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

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