X-Git-Url: http://aleph1.co.uk/gitweb/?a=blobdiff_plain;f=web%2Fcore%2Flib%2FDrupal%2FCore%2FRouting%2FRouteProvider.php;h=d31f293e18c411c660c4c96989e0fef7625f66c9;hb=refs%2Fheads%2Fd864;hp=5d92e77e0f1908527b21c26d1da5090c13b43f51;hpb=a2bd1bf0c2c1f1a17d188f4dc0726a45494cefae;p=yaffs-website diff --git a/web/core/lib/Drupal/Core/Routing/RouteProvider.php b/web/core/lib/Drupal/Core/Routing/RouteProvider.php index 5d92e77e0..d31f293e1 100644 --- a/web/core/lib/Drupal/Core/Routing/RouteProvider.php +++ b/web/core/lib/Drupal/Core/Routing/RouteProvider.php @@ -2,10 +2,11 @@ namespace Drupal\Core\Routing; -use Drupal\Component\Utility\Unicode; use Drupal\Core\Cache\Cache; use Drupal\Core\Cache\CacheBackendInterface; use Drupal\Core\Cache\CacheTagsInvalidatorInterface; +use Drupal\Core\Language\LanguageInterface; +use Drupal\Core\Language\LanguageManagerInterface; use Drupal\Core\Path\CurrentPathStack; use Drupal\Core\PathProcessor\InboundPathProcessorInterface; use Drupal\Core\State\StateInterface; @@ -15,7 +16,7 @@ use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Routing\Exception\RouteNotFoundException; use Symfony\Component\Routing\RouteCollection; -use \Drupal\Core\Database\Connection; +use Drupal\Core\Database\Connection; /** * A Route Provider front-end for all Drupal-stored routes. @@ -85,6 +86,13 @@ class RouteProvider implements PreloadableRouteProviderInterface, PagedRouteProv */ protected $pathProcessor; + /** + * The language manager. + * + * @var \Drupal\Core\Language\LanguageManagerInterface + */ + protected $languageManager; + /** * Cache ID prefix used to load routes. */ @@ -107,8 +115,10 @@ class RouteProvider implements PreloadableRouteProviderInterface, PagedRouteProv * The cache tag invalidator. * @param string $table * (Optional) The table in the database to use for matching. Defaults to 'router' + * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager + * (Optional) The language manager. */ - public function __construct(Connection $connection, StateInterface $state, CurrentPathStack $current_path, CacheBackendInterface $cache_backend, InboundPathProcessorInterface $path_processor, CacheTagsInvalidatorInterface $cache_tag_invalidator, $table = 'router') { + public function __construct(Connection $connection, StateInterface $state, CurrentPathStack $current_path, CacheBackendInterface $cache_backend, InboundPathProcessorInterface $path_processor, CacheTagsInvalidatorInterface $cache_tag_invalidator, $table = 'router', LanguageManagerInterface $language_manager = NULL) { $this->connection = $connection; $this->state = $state; $this->currentPath = $current_path; @@ -116,6 +126,7 @@ class RouteProvider implements PreloadableRouteProviderInterface, PagedRouteProv $this->cacheTagInvalidator = $cache_tag_invalidator; $this->pathProcessor = $path_processor; $this->tableName = $table; + $this->languageManager = $language_manager ?: \Drupal::languageManager(); } /** @@ -135,19 +146,19 @@ class RouteProvider implements PreloadableRouteProviderInterface, PagedRouteProv * very large route sets to be filtered down to likely candidates, which * may then be filtered in memory more completely. * - * @param Request $request + * @param \Symfony\Component\HttpFoundation\Request $request * A request against which to match. * - * @return \Symfony\Component\Routing\RouteCollection with all urls that - * could potentially match $request. Empty collection if nothing can - * match. The collection will be sorted from highest to lowest fit (match - * of path parts) and then in ascending order by route name for routes - * with the same fit. + * @return \Symfony\Component\Routing\RouteCollection + * RouteCollection with all urls that could potentially match $request. + * Empty collection if nothing can match. The collection will be sorted from + * highest to lowest fit (match of path parts) and then in ascending order + * by route name for routes with the same fit. */ public function getRouteCollectionForRequest(Request $request) { // Cache both the system path as well as route parameters and matching // routes. - $cid = 'route:' . $request->getPathInfo() . ':' . $request->getQueryString(); + $cid = $this->getRouteCollectionCacheId($request); if ($cached = $this->cache->get($cid)) { $this->currentPath->setPath($cached->data['path'], $request); $request->query->replace($cached->data['query']); @@ -333,7 +344,7 @@ class RouteProvider implements PreloadableRouteProviderInterface, PagedRouteProv // have a case-insensitive match from the incoming path to the lower case // pattern outlines from \Drupal\Core\Routing\RouteCompiler::compile(). // @see \Drupal\Core\Routing\CompiledRoute::__construct() - $parts = preg_split('@/+@', Unicode::strtolower($path), NULL, PREG_SPLIT_NO_EMPTY); + $parts = preg_split('@/+@', mb_strtolower($path), NULL, PREG_SPLIT_NO_EMPTY); $collection = new RouteCollection(); @@ -347,7 +358,8 @@ class RouteProvider implements PreloadableRouteProviderInterface, PagedRouteProv // dump the route pattern without those optional parts. try { $routes = $this->connection->query("SELECT name, route, fit FROM {" . $this->connection->escapeTable($this->tableName) . "} WHERE pattern_outline IN ( :patterns[] ) AND number_parts >= :count_parts", [ - ':patterns[]' => $ancestors, ':count_parts' => count($parts), + ':patterns[]' => $ancestors, + ':count_parts' => count($parts), ]) ->fetchAll(\PDO::FETCH_ASSOC); } @@ -389,7 +401,7 @@ class RouteProvider implements PreloadableRouteProviderInterface, PagedRouteProv * {@inheritdoc} */ public function reset() { - $this->routes = []; + $this->routes = []; $this->serializedRoutes = []; $this->cacheTagInvalidator->invalidateTags(['routes']); } @@ -430,4 +442,35 @@ class RouteProvider implements PreloadableRouteProviderInterface, PagedRouteProv return $this->connection->query("SELECT COUNT(*) FROM {" . $this->connection->escapeTable($this->tableName) . "}")->fetchField(); } + /** + * Returns the cache ID for the route collection cache. + * + * @param \Symfony\Component\HttpFoundation\Request $request + * The request object. + * + * @return string + * The cache ID. + */ + protected function getRouteCollectionCacheId(Request $request) { + // Include the current language code in the cache identifier as + // the language information can be elsewhere than in the path, for example + // based on the domain. + $language_part = $this->getCurrentLanguageCacheIdPart(); + return 'route:' . $language_part . ':' . $request->getPathInfo() . ':' . $request->getQueryString(); + } + + /** + * Returns the language identifier for the route collection cache. + * + * @return string + * The language identifier. + */ + protected function getCurrentLanguageCacheIdPart() { + // This must be in sync with the language logic in + // \Drupal\Core\PathProcessor\PathProcessorAlias::processInbound() and + // \Drupal\Core\Path\AliasManager::getPathByAlias(). + // @todo Update this if necessary in https://www.drupal.org/node/1125428. + return $this->languageManager->getCurrentLanguage(LanguageInterface::TYPE_URL)->getId(); + } + }