diff --git a/core/modules/book/book.services.yml b/core/modules/book/book.services.yml index 9ecb30d..762e60e 100644 --- a/core/modules/book/book.services.yml +++ b/core/modules/book/book.services.yml @@ -1,7 +1,7 @@ services: book.breadcrumb: class: Drupal\book\BookBreadcrumbBuilder - arguments: ['@router.route_provider', '@plugin.manager.entity', '@access_manager', '@string_translation'] + arguments: ['@router.route_provider', '@plugin.manager.entity', '@access_manager', '@string_translation', '@router.dynamic'] tags: - { name: breadcrumb_builder, priority: 701 } book.manager: diff --git a/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkBreadcrumbBuilder.php b/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkBreadcrumbBuilder.php index ac94afc..996716e 100644 --- a/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkBreadcrumbBuilder.php +++ b/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkBreadcrumbBuilder.php @@ -13,6 +13,8 @@ use Drupal\Core\Routing\RouteCompiler; use Drupal\Core\StringTranslation\TranslationInterface; use Drupal\Core\Access\AccessManager; +use Symfony\Cmf\Component\Routing\DynamicRouter; +use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\Routing\Exception\RouteNotFoundException; use Symfony\Component\Routing\Route; @@ -53,11 +55,18 @@ class MenuLinkBreadcrumbBuilder implements BreadcrumbBuilderInterface { /** * The menu storage controller. * - * @var Drupal\Core\Config\Entity\ConfigStorageController + * @var \Drupal\Core\Config\Entity\ConfigStorageController */ protected $menuStorage; /** + * The dynamic router service. + * + * @var \Symfony\Cmf\Component\Routing\DynamicRouter + */ + protected $dynamicRouter; + + /** * Constructs the MenuLinkBreadcrumbBuilder. * * @param \Drupal\Core\Routing\RouteProviderInterface $route_provider @@ -68,13 +77,16 @@ class MenuLinkBreadcrumbBuilder implements BreadcrumbBuilderInterface { * The menu link access service. * @param \Drupal\Core\StringTranslation\TranslationInterface $translation * The translation manager service. + * @param \Symfony\Cmf\Component\Routing\DynamicRouter $dynamic_router + * The dynamic router service. */ - public function __construct(RouteProviderInterface $route_provider, EntityManager $entity_manager, AccessManager $access_manager, TranslationInterface $translation) { + public function __construct(RouteProviderInterface $route_provider, EntityManager $entity_manager, AccessManager $access_manager, TranslationInterface $translation, DynamicRouter $dynamic_router) { $this->routeProvider = $route_provider; $this->menuLinkStorage = $entity_manager->getStorageController('menu_link'); $this->accessManager = $access_manager; $this->translation = $translation; $this->menuStorage = $entity_manager->getStorageController('menu'); + $this->dynamicRouter = $dynamic_router; } /** @@ -127,7 +139,7 @@ public function build(array $attributes) { if ($this->accessManager->checkNamedRoute($menu_link->route_name, $parameters)) { // _menu_item_localize expects an upcasted map. $map = $path_elements; - $this->upcastParameters($route, $attributes, $map); + $this->upcastParameters($route, $pattern, $map); // @todo Move _menu_item_localize() to a service. _menu_item_localize($menu_link, $map, FALSE); // @todo Replace with link generator service when @@ -169,12 +181,22 @@ public function build(array $attributes) { * * @param \Symfony\Component\Routing\Route $route * The route object. - * @param array $attributes - * The request attributes. + * @param string $href + * The request path. * @param array $map * The raw path map which is to be upcast. */ - protected function upcastParameters(Route $route, array $attributes, array &$map) { + protected function upcastParameters(Route $route, $href, array &$map) { + $request = Request::create('/' . $href); + $request->attributes->set('_system_path', $href); + // Attempt to match this path to provide a fully built request. + try { + $request->attributes->add($this->dynamicRouter->matchRequest($request)); + } + catch (NotFoundHttpException $e) { + return FALSE; + } + // Populate the map with any matching values from the request. $path_bits = explode('/', trim($route->getPath(), '/')); foreach ($map as $index => $map_item) { @@ -184,8 +206,8 @@ protected function upcastParameters(Route $route, array $attributes, array &$map if (isset($path_bits[$index]) && preg_match('/{(?.*)}/', $path_bits[$index], $matches)) { // If that placeholder is present on the request attributes, replace the // placeholder in the map with the value. - if (!empty($attributes[$matches['placeholder']])) { - $map[$index] = $attributes[$matches['placeholder']]; + if ($request->attributes->has($matches['placeholder'])) { + $map[$index] = $request->attributes->get($matches['placeholder']); } } } diff --git a/core/modules/menu_link/menu_link.services.yml b/core/modules/menu_link/menu_link.services.yml index 272f249..7161f42 100644 --- a/core/modules/menu_link/menu_link.services.yml +++ b/core/modules/menu_link/menu_link.services.yml @@ -1,6 +1,6 @@ services: menu_link.breadcrumb: class: Drupal\menu_link\MenuLinkBreadcrumbBuilder - arguments: ['@router.route_provider', '@plugin.manager.entity', '@access_manager', '@string_translation'] + arguments: ['@router.route_provider', '@plugin.manager.entity', '@access_manager', '@string_translation', '@router.dynamic'] tags: - { name: breadcrumb_builder, priority: 0 }