annotate 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
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 namespace Drupal\language\HttpKernel;
Chris@0 4
Chris@0 5 use Drupal\Component\Utility\Unicode;
Chris@0 6 use Drupal\Core\Config\ConfigFactoryInterface;
Chris@0 7 use Drupal\Core\PathProcessor\InboundPathProcessorInterface;
Chris@0 8 use Drupal\Core\PathProcessor\OutboundPathProcessorInterface;
Chris@0 9 use Drupal\Core\Render\BubbleableMetadata;
Chris@0 10 use Drupal\language\ConfigurableLanguageManagerInterface;
Chris@0 11 use Drupal\language\EventSubscriber\ConfigSubscriber;
Chris@0 12 use Drupal\language\LanguageNegotiatorInterface;
Chris@0 13 use Symfony\Component\HttpFoundation\Request;
Chris@0 14 use Drupal\Core\Session\AccountInterface;
Chris@0 15
Chris@0 16 /**
Chris@0 17 * Processes the inbound path using path alias lookups.
Chris@0 18 */
Chris@0 19 class PathProcessorLanguage implements InboundPathProcessorInterface, OutboundPathProcessorInterface {
Chris@0 20
Chris@0 21 /**
Chris@0 22 * A config factory for retrieving required config settings.
Chris@0 23 *
Chris@0 24 * @var \Drupal\Core\Config\ConfigFactoryInterface
Chris@0 25 */
Chris@0 26 protected $config;
Chris@0 27
Chris@0 28 /**
Chris@0 29 * Language manager for retrieving the url language type.
Chris@0 30 *
Chris@0 31 * @var \Drupal\language\ConfigurableLanguageManagerInterface
Chris@0 32 */
Chris@0 33 protected $languageManager;
Chris@0 34
Chris@0 35 /**
Chris@0 36 * The language negotiator.
Chris@0 37 *
Chris@0 38 * @var \Drupal\language\LanguageNegotiatorInterface
Chris@0 39 */
Chris@0 40 protected $negotiator;
Chris@0 41
Chris@0 42 /**
Chris@0 43 * Local cache for language path processors.
Chris@0 44 *
Chris@0 45 * @var array
Chris@0 46 */
Chris@0 47 protected $processors;
Chris@0 48
Chris@0 49 /**
Chris@0 50 * Flag indicating whether the site is multilingual.
Chris@0 51 *
Chris@0 52 * @var bool
Chris@0 53 */
Chris@0 54 protected $multilingual;
Chris@0 55
Chris@0 56 /**
Chris@0 57 * The language configuration event subscriber.
Chris@0 58 *
Chris@0 59 * @var \Drupal\language\EventSubscriber\ConfigSubscriber
Chris@0 60 */
Chris@0 61 protected $configSubscriber;
Chris@0 62
Chris@0 63
Chris@0 64 /**
Chris@0 65 * Constructs a PathProcessorLanguage object.
Chris@0 66 *
Chris@0 67 * @param \Drupal\Core\Config\ConfigFactoryInterface $config
Chris@0 68 * A config factory object for retrieving configuration settings.
Chris@0 69 * @param \Drupal\language\ConfigurableLanguageManagerInterface $language_manager
Chris@0 70 * The configurable language manager.
Chris@0 71 * @param \Drupal\language\LanguageNegotiatorInterface $negotiator
Chris@0 72 * The language negotiator.
Chris@0 73 * @param \Drupal\Core\Session\AccountInterface $current_user
Chris@0 74 * The current active user.
Chris@0 75 * @param \Drupal\language\EventSubscriber\ConfigSubscriber $config_subscriber
Chris@0 76 * The language configuration event subscriber.
Chris@0 77 */
Chris@0 78 public function __construct(ConfigFactoryInterface $config, ConfigurableLanguageManagerInterface $language_manager, LanguageNegotiatorInterface $negotiator, AccountInterface $current_user, ConfigSubscriber $config_subscriber) {
Chris@0 79 $this->config = $config;
Chris@0 80 $this->languageManager = $language_manager;
Chris@0 81 $this->negotiator = $negotiator;
Chris@0 82 $this->negotiator->setCurrentUser($current_user);
Chris@0 83 $this->configSubscriber = $config_subscriber;
Chris@0 84 }
Chris@0 85
Chris@0 86 /**
Chris@0 87 * {@inheritdoc}
Chris@0 88 */
Chris@0 89 public function processInbound($path, Request $request) {
Chris@0 90 if (!empty($path)) {
Chris@0 91 $scope = 'inbound';
Chris@0 92 if (!isset($this->processors[$scope])) {
Chris@0 93 $this->initProcessors($scope);
Chris@0 94 }
Chris@0 95 foreach ($this->processors[$scope] as $instance) {
Chris@0 96 $path = $instance->processInbound($path, $request);
Chris@0 97 }
Chris@0 98 }
Chris@0 99 return $path;
Chris@0 100 }
Chris@0 101
Chris@0 102 /**
Chris@0 103 * {@inheritdoc}
Chris@0 104 */
Chris@0 105 public function processOutbound($path, &$options = [], Request $request = NULL, BubbleableMetadata $bubbleable_metadata = NULL) {
Chris@0 106 if (!isset($this->multilingual)) {
Chris@0 107 $this->multilingual = $this->languageManager->isMultilingual();
Chris@0 108 }
Chris@0 109 if ($this->multilingual) {
Chris@0 110 $this->negotiator->reset();
Chris@0 111 $scope = 'outbound';
Chris@0 112 if (!isset($this->processors[$scope])) {
Chris@0 113 $this->initProcessors($scope);
Chris@0 114 }
Chris@0 115 foreach ($this->processors[$scope] as $instance) {
Chris@0 116 $path = $instance->processOutbound($path, $options, $request, $bubbleable_metadata);
Chris@0 117 }
Chris@0 118 // No language dependent path allowed in this mode.
Chris@0 119 if (empty($this->processors[$scope])) {
Chris@0 120 unset($options['language']);
Chris@0 121 }
Chris@0 122 }
Chris@0 123 return $path;
Chris@0 124 }
Chris@0 125
Chris@0 126 /**
Chris@0 127 * Initializes the local cache for language path processors.
Chris@0 128 *
Chris@0 129 * @param string $scope
Chris@0 130 * The scope of the processors: "inbound" or "outbound".
Chris@0 131 */
Chris@0 132 protected function initProcessors($scope) {
Chris@0 133 $interface = '\Drupal\Core\PathProcessor\\' . Unicode::ucfirst($scope) . 'PathProcessorInterface';
Chris@0 134 $this->processors[$scope] = [];
Chris@0 135 $weights = [];
Chris@0 136 foreach ($this->languageManager->getLanguageTypes() as $type) {
Chris@0 137 foreach ($this->negotiator->getNegotiationMethods($type) as $method_id => $method) {
Chris@0 138 if (!isset($this->processors[$scope][$method_id])) {
Chris@0 139 $reflector = new \ReflectionClass($method['class']);
Chris@0 140 if ($reflector->implementsInterface($interface)) {
Chris@0 141 $this->processors[$scope][$method_id] = $this->negotiator->getNegotiationMethodInstance($method_id);
Chris@0 142 $weights[$method_id] = $method['weight'];
Chris@0 143 }
Chris@0 144 }
Chris@0 145 }
Chris@0 146 }
Chris@0 147
Chris@0 148 // Sort the processors list, so that their functions are called in the
Chris@0 149 // order specified by the weight of the methods.
Chris@0 150 uksort($this->processors[$scope], function ($method_id_a, $method_id_b) use ($weights) {
Chris@0 151 $a_weight = $weights[$method_id_a];
Chris@0 152 $b_weight = $weights[$method_id_b];
Chris@0 153
Chris@0 154 if ($a_weight == $b_weight) {
Chris@0 155 return 0;
Chris@0 156 }
Chris@0 157
Chris@0 158 return ($a_weight < $b_weight) ? -1 : 1;
Chris@0 159 });
Chris@0 160 }
Chris@0 161
Chris@0 162 /**
Chris@0 163 * Initializes the injected event subscriber with the language path processor.
Chris@0 164 *
Chris@0 165 * The language path processor service is registered only on multilingual
Chris@0 166 * site configuration, thus we inject it in the event subscriber only when
Chris@0 167 * it is initialized.
Chris@0 168 */
Chris@0 169 public function initConfigSubscriber() {
Chris@0 170 $this->configSubscriber->setPathProcessorLanguage($this);
Chris@0 171 }
Chris@0 172
Chris@0 173 /**
Chris@0 174 * Resets the collected processors instances.
Chris@0 175 */
Chris@0 176 public function reset() {
Chris@0 177 $this->processors = [];
Chris@0 178 }
Chris@0 179
Chris@0 180 }