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

src/Plugin/GraphQL/DataProducer/LanguageSwitchLinks.php
<?php

namespace Drupal\graphql_core_schema\Plugin\GraphQL\DataProducer;

use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\TranslatableInterface;
use Drupal\Core\Language\LanguageInterface;
use Drupal\Core\Language\LanguageManagerInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Render\RenderContext;
use Drupal\Core\Render\RendererInterface;
use Drupal\Core\Url;
use Drupal\graphql\GraphQL\Execution\FieldContext;
use Drupal\graphql\Plugin\GraphQL\DataProducer\DataProducerPluginBase;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Routing\RouterInterface;

/**
 * The data producer for language switcher links.
 *
 * @DataProducer(
 *   id = "language_switch_links",
 *   name = @Translation("Language Switch Links"),
 *   description = @Translation("Return the language switch links for an URL."),
 *   produces = @ContextDefinition("any",
 *     label = @Translation("Language Switch Links")
 *   ),
 *   consumes = {
 *     "url" = @ContextDefinition("any",
 *       label = @Translation("Route URL"),
 *     )
 *   }
 * )
 */
class LanguageSwitchLinks extends DataProducerPluginBase implements ContainerFactoryPluginInterface {

  /**
   * {@inheritdoc}
   */
  public static function create(
    ContainerInterface $container,
    array $configuration,
    $pluginId,
    $pluginDefinition,
  ) {
    return new static(
      $configuration,
      $pluginId,
      $pluginDefinition,
      $container->get('language_manager'),
      $container->get('config.factory'),
      $container->get('renderer'),
      $container->get('router.no_access_checks')
    );
  }

  /**
   * LanguageSwitchLinks constructor.
   *
   * @param array $configuration
   *   The plugin configuration array.
   * @param string $pluginId
   *   The plugin id.
   * @param mixed $pluginDefinition
   *   The plugin definition.
   * @param \Drupal\Core\Language\LanguageManagerInterface $languageManager
   *   The language manager.
   * @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory
   *   The config factory.
   * @param \Drupal\Core\Render\RendererInterface $renderer
   *   The renderer service.
   * @param \Symfony\Component\Routing\RouterInterface $routing
   *   The routing service.
   */
  public function __construct(
    array $configuration,
    $pluginId,
    $pluginDefinition,
    protected LanguageManagerInterface $languageManager,
    protected ConfigFactoryInterface $configFactory,
    protected RendererInterface $renderer,
    protected RouterInterface $routing,
  ) {
    parent::__construct($configuration, $pluginId, $pluginDefinition);
  }

  /**
   * The resolver.
   *
   * @param \Drupal\Core\Url $url
   *   The url.
   * @param \Drupal\graphql\GraphQL\Execution\FieldContext $fieldContext
   *   The field context.
   *
   * @return array
   *   The language switch links.
   */
  public function resolve(Url $url, FieldContext $fieldContext) {
    $result = $this->languageManager->getLanguageSwitchLinks(LanguageInterface::TYPE_URL, $url);
    $links = ($result ? $result->links : []) ?? [];
    $currentLangcode = $fieldContext->getContextValue(name: 'language') ?? $this->languageManager->getCurrentLanguage()->getId();
    $context = new RenderContext();

    foreach ($links as $langcode => $link) {
      /** @var \Drupal\Core\Url $url */
      $url = $link['url'];
      $entities = [];
      $accessible_translations = [];
      if ($url->isRouted()) {
        [$entities, $accessible_translations] = $this->renderer->executeInRenderContext($context, function () use ($url) {
          return $this->getEntitiesAndTranslations($url);
        });
      }

      /** @var \Drupal\language\Entity\ConfigurableLanguage $linkLanguage */
      $linkLanguage = $link['language'];
      $links[$langcode]['active'] = $linkLanguage->getId() === $currentLangcode;

      // Language dependant url.
      $url->setOptions(
        [
          'query' => $link['query'],
          'language' => $link['language'],
          'attributes' => $link['attributes'] ?? [],
        ]
      );

      if ($entities && !in_array($langcode, $accessible_translations)) {
        unset($links[$langcode]);
      }
    }

    if (!$context->isEmpty()) {
      $fieldContext->addCacheableDependency($context->pop());
    }

    return $links;
  }

  /**
   * Get current route's translatable entities and accessible translations.
   *
   * @param Url $url
   *   The URL to get the entities from.
   */
  private function getEntitiesAndTranslations(Url $url) {
    $entities = [];
    $accessible_translations = [];
    $router_match = $this->routing->match($url->toString());

    // Find upcasted route entity.
    foreach (array_keys($url->getRouteParameters()) as $key) {
      if (!empty($router_match[$key])) {
        $entity = $router_match[$key];
        if ($entity instanceof TranslatableInterface) {
          $entities[] = $entity;
          $accessible_translations = array_merge(
            $accessible_translations,
            array_filter(array_keys($entity->getTranslationLanguages()), function ($langcode) use ($entity) {
              $translation = method_exists($entity, 'getTranslation') ? $entity->getTranslation($langcode) : FALSE;
              return $translation && method_exists($translation, 'access') && $translation->access('view');
            })
          );
        }
      }
    }
    return [$entities, $accessible_translations];
  }

}

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

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