You are here

class NodeTranslationExceptionSubscriber in Drupal 10

Same name and namespace in other branches
  1. 8 core/modules/node/src/EventSubscriber/NodeTranslationExceptionSubscriber.php \Drupal\node\EventSubscriber\NodeTranslationExceptionSubscriber
  2. 9 core/modules/node/src/EventSubscriber/NodeTranslationExceptionSubscriber.php \Drupal\node\EventSubscriber\NodeTranslationExceptionSubscriber

Redirect node translations that have been consolidated by migration.

If we migrated node translations from Drupal 6 or 7, these nodes are now combined with their source language node. Since there still might be references to the URLs of these now consolidated nodes, this service catches the 404s and try to redirect them to the right node in the right language.

The mapping of the old nids to the new ones is made by the NodeTranslationMigrateSubscriber class during the migration and is stored in the "node_translation_redirect" key/value collection.

Hierarchy

Expanded class hierarchy of NodeTranslationExceptionSubscriber

See also

\Drupal\node\NodeServiceProvider

\Drupal\node\EventSubscriber\NodeTranslationMigrateSubscriber

1 file declares its use of NodeTranslationExceptionSubscriber
NodeServiceProvider.php in core/modules/node/src/NodeServiceProvider.php

File

core/modules/node/src/EventSubscriber/NodeTranslationExceptionSubscriber.php, line 31

Namespace

Drupal\node\EventSubscriber
View source
class NodeTranslationExceptionSubscriber implements EventSubscriberInterface {

  /**
   * The key value factory.
   *
   * @var \Drupal\Core\KeyValueStore\KeyValueFactoryInterface
   */
  protected $keyValue;

  /**
   * The language manager.
   *
   * @var \Drupal\Core\Language\LanguageManagerInterface
   */
  protected $languageManager;

  /**
   * The URL generator.
   *
   * @var \Drupal\Core\Routing\UrlGeneratorInterface
   */
  protected $urlGenerator;

  /**
   * The state service.
   *
   * @var \Drupal\Core\State\StateInterface
   */
  protected $state;

  /**
   * Constructs the NodeTranslationExceptionSubscriber.
   *
   * @param \Drupal\Core\KeyValueStore\KeyValueFactoryInterface $key_value
   *   The key value factory.
   * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
   *   The language manager.
   * @param \Drupal\Core\Routing\UrlGeneratorInterface $url_generator
   *   The URL generator.
   * @param \Drupal\Core\State\StateInterface $state
   *   The state service.
   */
  public function __construct(KeyValueFactoryInterface $key_value, LanguageManagerInterface $language_manager, UrlGeneratorInterface $url_generator, StateInterface $state) {
    $this->keyValue = $key_value;
    $this->languageManager = $language_manager;
    $this->urlGenerator = $url_generator;
    $this->state = $state;
  }

  /**
   * Redirects not found node translations using the key value collection.
   *
   * @param \Symfony\Component\HttpKernel\Event\ExceptionEvent $event
   *   The exception event.
   */
  public function onException(ExceptionEvent $event) {
    $exception = $event
      ->getThrowable();

    // If this is not a 404, we don't need to check for a redirection.
    if (!$exception instanceof NotFoundHttpException) {
      return;
    }
    $previous_exception = $exception
      ->getPrevious();
    if ($previous_exception instanceof ParamNotConvertedException) {
      $route_name = $previous_exception
        ->getRouteName();
      $parameters = $previous_exception
        ->getRawParameters();
      if ($route_name === 'entity.node.canonical' && isset($parameters['node'])) {

        // If the node_translation_redirect state is not set, we don't need to check
        // for a redirection.
        if (!$this->state
          ->get('node_translation_redirect')) {
          return;
        }
        $old_nid = $parameters['node'];
        $collection = $this->keyValue
          ->get('node_translation_redirect');
        if ($old_nid && ($value = $collection
          ->get($old_nid))) {
          [
            $nid,
            $langcode,
          ] = $value;
          $language = $this->languageManager
            ->getLanguage($langcode);
          $url = $this->urlGenerator
            ->generateFromRoute('entity.node.canonical', [
            'node' => $nid,
          ], [
            'language' => $language,
          ]);
          $response = new RedirectResponse($url, 301);
          $event
            ->setResponse($response);
        }
      }
    }
  }

  /**
   * {@inheritdoc}
   */
  public static function getSubscribedEvents() : array {
    $events = [];
    $events[KernelEvents::EXCEPTION] = [
      'onException',
    ];
    return $events;
  }

}

Members