diff --git a/core/modules/system/lib/Drupal/system/PathBasedBreadcrumbBuilder.php b/core/modules/system/lib/Drupal/system/PathBasedBreadcrumbBuilder.php index 7e6f20f..c7413a6 100644 --- a/core/modules/system/lib/Drupal/system/PathBasedBreadcrumbBuilder.php +++ b/core/modules/system/lib/Drupal/system/PathBasedBreadcrumbBuilder.php @@ -14,6 +14,7 @@ use Drupal\Core\Access\AccessManager; use Drupal\Core\PathProcessor\InboundPathProcessorInterface; use Drupal\Component\Utility\Unicode; +use Drupal\Core\Routing\RouteProviderInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Cmf\Component\Routing\RouteObjectInterface; @@ -74,6 +75,12 @@ class PathBasedBreadcrumbBuilder extends BreadcrumbBuilderBase { */ protected $titleResolver; + /** + * The route provider to load all involved routes at once. + * + * @var \Drupal\Core\Routing\RouteProviderInterface + */ + protected $routeProvider; /** * Constructs the PathBasedBreadcrumbBuilder. @@ -92,8 +99,10 @@ class PathBasedBreadcrumbBuilder extends BreadcrumbBuilderBase { * The config factory service. * @param \Drupal\Core\Controller\TitleResolverInterface $title_resolver * The title resolver service. + * @param \Drupal\Core\Routing\RouteProviderInterface $route_provider + * The route provider to load all involved routes at once. */ - public function __construct(Request $request, EntityManager $entity_manager, AccessManager $access_manager, RequestMatcherInterface $router, InboundPathProcessorInterface $path_processor, ConfigFactory $config_factory, TitleResolverInterface $title_resolver) { + public function __construct(Request $request, EntityManager $entity_manager, AccessManager $access_manager, RequestMatcherInterface $router, InboundPathProcessorInterface $path_processor, ConfigFactory $config_factory, TitleResolverInterface $title_resolver, RouteProviderInterface $route_provider) { $this->request = $request; $this->accessManager = $access_manager; $this->menuStorage = $entity_manager->getStorageController('menu'); @@ -101,6 +110,7 @@ public function __construct(Request $request, EntityManager $entity_manager, Acc $this->pathProcessor = $path_processor; $this->config = $config_factory->get('system.site'); $this->titleResolver = $title_resolver; + $this->routeProvider = $route_provider; } /** @@ -121,13 +131,31 @@ public function build(array $attributes) { // /user is just a redirect, so skip it. // @todo Find a better way to deal with /user. $exclude['user'] = TRUE; + + $paths_route_names = array(); + $paths_route_requests = array(); while (count($path_elements) > 1) { array_pop($path_elements); + + // Copy the path elements for up-casting. + $path = implode('/', $path_elements); + $route_request = $this->getRequestForPath($path, $exclude); + if ($route_request) { + $route_name = $route_request->attributes->get(RouteObjectInterface::ROUTE_NAME); + $paths_route_names[$path] = $route_name; + $paths_route_requests[$path] = $route_request; + } + } + + // Load all routes at once. + $this->routeProvider->getRoutesByNames(array_values($paths_route_names)); + + foreach ($paths_route_names as $path => $route_name) { // Copy the path elements for up-casting. - $route_request = $this->getRequestForPath(implode('/', $path_elements), $exclude); + $route_request = $paths_route_requests[$path]; if ($route_request) { if (!$route_request->attributes->get('_legacy')) { - $route_name = $route_request->attributes->get(RouteObjectInterface::ROUTE_NAME); + $route_name = $paths_route_names[$path]; // Note that the parameters don't really matter here since we're // passing in the request which already has the upcast attributes. $parameters = array();