graphql_compose-1.0.0-beta20/modules/graphql_compose_routes/src/Plugin/GraphQL/SchemaExtension/RouteSchemaExtension.php

modules/graphql_compose_routes/src/Plugin/GraphQL/SchemaExtension/RouteSchemaExtension.php
<?php

declare(strict_types=1);

namespace Drupal\graphql_compose_routes\Plugin\GraphQL\SchemaExtension;

use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Path\PathValidatorInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\Url;
use Drupal\graphql\Attribute\SchemaExtension;
use Drupal\graphql\GraphQL\ResolverBuilder;
use Drupal\graphql\GraphQL\ResolverRegistryInterface;
use Drupal\graphql_compose\Utility\ComposeProviders;
use Drupal\graphql_compose\Plugin\GraphQL\SchemaExtension\ResolverOnlySchemaExtensionPluginBase;
use GraphQL\Error\UserError;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Add route resolution.
 */
#[SchemaExtension(
  id: "graphql_compose_route",
  name: new TranslatableMarkup("GraphQL Compose Routes"),
  description: new TranslatableMarkup("URL, Links and paths"),
  schema: "graphql_compose",
  priority: 0,
)]
class RouteSchemaExtension extends ResolverOnlySchemaExtensionPluginBase implements ContainerFactoryPluginInterface {

  /**
   * The path validator service.
   *
   * @var \Drupal\Core\Path\PathValidatorInterface
   */
  protected PathValidatorInterface $pathValidator;

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    $instance = parent::create(
      $container,
      $configuration,
      $plugin_id,
      $plugin_definition,
    );

    $instance->pathValidator = $container->get('path.validator');

    return $instance;
  }

  /**
   * {@inheritdoc}
   */
  public function registerResolvers(ResolverRegistryInterface $registry): void {
    $builder = new ResolverBuilder();

    $this->addRouteInternal($registry, $builder);
    $this->addRouteExternal($registry, $builder);
    $this->addRouteUnion($registry, $builder);

    if ($this->moduleHandler->moduleExists('redirect')) {
      $this->addRedirect($registry, $builder);
    }

    $registry->addFieldResolver(
      'Query',
      'route',
      $builder->compose(
        $builder->context('revision', $builder->fromArgument('revision')),

        // Get the language from the route path.
        $builder->produce('route_language')
          ->map('path', $builder->fromArgument('path'))
          ->map('language', $builder->fromArgument('langcode')),

        // Change the active language.
        $builder->produce('language_context')
          ->map('language', $builder->fromParent()),

        $builder->produce('route_path')
          ->map('path', $builder->fromArgument('path')),

        $builder->produce('url_or_redirect')
          ->map('path', $builder->fromParent()),
      )
    );

    $registry->addTypeResolver(
      'RouteUnion',
      function ($value) {
        $type = NULL;

        if ($value instanceof Url) {
          $type = $value->isRouted() ? 'RouteInternal' : 'RouteExternal';
        }

        // Give opportunity to extend this union.
        ComposeProviders::invoke('graphql_compose_routes_union_alter', [
          $value,
          &$type,
        ]);

        if ($type) {
          return $type;
        }

        throw new UserError('Could not resolve route type.');
      });

  }

  /**
   * Add internal routes to the registry.
   *
   * @param \Drupal\graphql\GraphQL\ResolverRegistryInterface $registry
   *   The resolver registry.
   * @param \Drupal\graphql\GraphQL\ResolverBuilder $builder
   *   The resolver builder.
   */
  protected function addRouteInternal(ResolverRegistryInterface $registry, ResolverBuilder $builder) {

    $registry->addFieldResolver(
      'RouteInternal',
      'entity',
      $builder->compose(
        $builder->produce('route_entity_extra')
          ->map('url', $builder->fromParent()),
        $builder->produce('entity_load_revision')
          ->map('entity', $builder->fromParent())
          ->map('identifier', $builder->fromContext('revision'))
      )
    );

    $registry->addFieldResolver(
      'RouteInternal',
      'breadcrumbs',
      $builder->produce('breadcrumbs')
        ->map('url', $builder->fromParent())
    );

    $registry->addFieldResolver(
      'RouteInternal',
      'url',
      $builder->produce('url_path')
        ->map('url', $builder->fromParent())
    );

    $registry->addFieldResolver(
      'RouteInternal',
      'internal',
      $builder->fromValue(TRUE)
    );
  }

  /**
   * Add external routes to the registry.
   *
   * @param \Drupal\graphql\GraphQL\ResolverRegistryInterface $registry
   *   The resolver registry.
   * @param \Drupal\graphql\GraphQL\ResolverBuilder $builder
   *   The resolver builder.
   */
  protected function addRouteExternal(ResolverRegistryInterface $registry, ResolverBuilder $builder) {
    $registry->addFieldResolver(
      'RouteExternal',
      'url',
      $builder->produce('url_path')
        ->map('url', $builder->fromParent())
    );

    $registry->addFieldResolver(
      'RouteExternal',
      'internal',
      $builder->fromValue(FALSE)
    );
  }

  /**
   * Add redirect routes to the registry.
   *
   * @param \Drupal\graphql\GraphQL\ResolverRegistryInterface $registry
   *   The resolver registry.
   * @param \Drupal\graphql\GraphQL\ResolverBuilder $builder
   *   The resolver builder.
   */
  protected function addRedirect(ResolverRegistryInterface $registry, ResolverBuilder $builder) {
    $registry->addFieldResolver(
      'RouteRedirect',
      'url',
      $builder->compose(
        $builder->callback(fn ($redirect) => $redirect->getRedirectUrl()),
        $builder->produce('url_path')
          ->map('url', $builder->fromParent())
      )
    );

    $registry->addFieldResolver(
      'RouteRedirect',
      'internal',
      $builder->compose(
        $builder->callback(fn ($redirect) => $redirect->getRedirectUrl()),
        $builder->callback(fn ($url) => $url->isRouted())
      )
    );

    $registry->addFieldResolver(
      'RouteRedirect',
      'status',
      $builder->callback(fn ($redirect) => $redirect->getStatusCode())
    );

    $registry->addFieldResolver(
      'RouteRedirect',
      'redirect',
      $builder->fromValue(TRUE)
    );
  }

  /**
   * Resolve union type for Routed results.
   *
   * @param \Drupal\graphql\GraphQL\ResolverRegistryInterface $registry
   *   The resolver registry.
   * @param \Drupal\graphql\GraphQL\ResolverBuilder $builder
   *   The resolver builder.
   *
   * @throws \GraphQL\Error\UserError
   *   If the entity type is not exposed.
   */
  protected function addRouteUnion(ResolverRegistryInterface $registry, ResolverBuilder $builder) {
    $registry->addTypeResolver(
      'RouteEntityUnion',
      function (EntityInterface $value) {
        // Find the enabled entity type plugin.
        $entity_type = $this->gqlEntityTypeManager->getPluginInstance($value->getEntityTypeId());

        if ($entity_type) {
          $bundle = $entity_type->getBundle($value->bundle());
          if ($bundle) {
            return $bundle->getTypeSdl();
          }
        }

        // It's not a 404 but its not exposed.
        throw new UserError('Entity type cannot be loaded by route.');
      }
    );
  }

}

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

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