diff core/modules/language/src/HttpKernel/PathProcessorLanguage.php @ 0:4c8ae668cc8c

Initial import (non-working)
author Chris Cannam
date Wed, 29 Nov 2017 16:09:58 +0000
parents
children 129ea1e6d783
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/modules/language/src/HttpKernel/PathProcessorLanguage.php	Wed Nov 29 16:09:58 2017 +0000
@@ -0,0 +1,180 @@
+<?php
+
+namespace Drupal\language\HttpKernel;
+
+use Drupal\Component\Utility\Unicode;
+use Drupal\Core\Config\ConfigFactoryInterface;
+use Drupal\Core\PathProcessor\InboundPathProcessorInterface;
+use Drupal\Core\PathProcessor\OutboundPathProcessorInterface;
+use Drupal\Core\Render\BubbleableMetadata;
+use Drupal\language\ConfigurableLanguageManagerInterface;
+use Drupal\language\EventSubscriber\ConfigSubscriber;
+use Drupal\language\LanguageNegotiatorInterface;
+use Symfony\Component\HttpFoundation\Request;
+use Drupal\Core\Session\AccountInterface;
+
+/**
+ * Processes the inbound path using path alias lookups.
+ */
+class PathProcessorLanguage implements InboundPathProcessorInterface, OutboundPathProcessorInterface {
+
+  /**
+   * A config factory for retrieving required config settings.
+   *
+   * @var \Drupal\Core\Config\ConfigFactoryInterface
+   */
+  protected $config;
+
+  /**
+   * Language manager for retrieving the url language type.
+   *
+   * @var \Drupal\language\ConfigurableLanguageManagerInterface
+   */
+  protected $languageManager;
+
+  /**
+   * The language negotiator.
+   *
+   * @var \Drupal\language\LanguageNegotiatorInterface
+   */
+  protected $negotiator;
+
+  /**
+   * Local cache for language path processors.
+   *
+   * @var array
+   */
+  protected $processors;
+
+  /**
+   * Flag indicating whether the site is multilingual.
+   *
+   * @var bool
+   */
+  protected $multilingual;
+
+  /**
+   * The language configuration event subscriber.
+   *
+   * @var \Drupal\language\EventSubscriber\ConfigSubscriber
+   */
+  protected $configSubscriber;
+
+
+  /**
+   * Constructs a PathProcessorLanguage object.
+   *
+   * @param \Drupal\Core\Config\ConfigFactoryInterface $config
+   *   A config factory object for retrieving configuration settings.
+   * @param \Drupal\language\ConfigurableLanguageManagerInterface $language_manager
+   *   The configurable language manager.
+   * @param \Drupal\language\LanguageNegotiatorInterface $negotiator
+   *   The language negotiator.
+   * @param \Drupal\Core\Session\AccountInterface $current_user
+   *   The current active user.
+   * @param \Drupal\language\EventSubscriber\ConfigSubscriber $config_subscriber
+   *   The language configuration event subscriber.
+   */
+  public function __construct(ConfigFactoryInterface $config, ConfigurableLanguageManagerInterface $language_manager, LanguageNegotiatorInterface $negotiator, AccountInterface $current_user, ConfigSubscriber $config_subscriber) {
+    $this->config = $config;
+    $this->languageManager = $language_manager;
+    $this->negotiator = $negotiator;
+    $this->negotiator->setCurrentUser($current_user);
+    $this->configSubscriber = $config_subscriber;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function processInbound($path, Request $request) {
+    if (!empty($path)) {
+      $scope = 'inbound';
+      if (!isset($this->processors[$scope])) {
+        $this->initProcessors($scope);
+      }
+      foreach ($this->processors[$scope] as $instance) {
+        $path = $instance->processInbound($path, $request);
+      }
+    }
+    return $path;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function processOutbound($path, &$options = [], Request $request = NULL, BubbleableMetadata $bubbleable_metadata = NULL) {
+    if (!isset($this->multilingual)) {
+      $this->multilingual = $this->languageManager->isMultilingual();
+    }
+    if ($this->multilingual) {
+      $this->negotiator->reset();
+      $scope = 'outbound';
+      if (!isset($this->processors[$scope])) {
+        $this->initProcessors($scope);
+      }
+      foreach ($this->processors[$scope] as $instance) {
+        $path = $instance->processOutbound($path, $options, $request, $bubbleable_metadata);
+      }
+      // No language dependent path allowed in this mode.
+      if (empty($this->processors[$scope])) {
+        unset($options['language']);
+      }
+    }
+    return $path;
+  }
+
+  /**
+   * Initializes the local cache for language path processors.
+   *
+   * @param string $scope
+   *   The scope of the processors: "inbound" or "outbound".
+   */
+  protected function initProcessors($scope) {
+    $interface = '\Drupal\Core\PathProcessor\\' . Unicode::ucfirst($scope) . 'PathProcessorInterface';
+    $this->processors[$scope] = [];
+    $weights = [];
+    foreach ($this->languageManager->getLanguageTypes() as $type) {
+      foreach ($this->negotiator->getNegotiationMethods($type) as $method_id => $method) {
+        if (!isset($this->processors[$scope][$method_id])) {
+          $reflector = new \ReflectionClass($method['class']);
+          if ($reflector->implementsInterface($interface)) {
+            $this->processors[$scope][$method_id] = $this->negotiator->getNegotiationMethodInstance($method_id);
+            $weights[$method_id] = $method['weight'];
+          }
+        }
+      }
+    }
+
+    // Sort the processors list, so that their functions are called in the
+    // order specified by the weight of the methods.
+    uksort($this->processors[$scope], function ($method_id_a, $method_id_b) use ($weights) {
+      $a_weight = $weights[$method_id_a];
+      $b_weight = $weights[$method_id_b];
+
+      if ($a_weight == $b_weight) {
+        return 0;
+      }
+
+      return ($a_weight < $b_weight) ? -1 : 1;
+    });
+  }
+
+  /**
+   * Initializes the injected event subscriber with the language path processor.
+   *
+   * The language path processor service is registered only on multilingual
+   * site configuration, thus we inject it in the event subscriber only when
+   * it is initialized.
+   */
+  public function initConfigSubscriber() {
+    $this->configSubscriber->setPathProcessorLanguage($this);
+  }
+
+  /**
+   * Resets the collected processors instances.
+   */
+  public function reset() {
+    $this->processors = [];
+  }
+
+}