diff -u b/core/includes/menu.inc b/core/includes/menu.inc --- b/core/includes/menu.inc +++ b/core/includes/menu.inc @@ -777,13 +777,15 @@ $router_item['tab_parent_href'] = implode('/', $tab_parent_map); $router_item['options'] = array(); if (!empty($router_item['route_name'])) { - // Route-provided menu items do not have menu loaders, so replace the map - // with the link map. - $map = $link_map; - $route_provider = Drupal::getContainer()->get('router.route_provider'); $route = $route_provider->getRouteByName($router_item['route_name']); - $router_item['access'] = menu_item_route_access($route, $router_item['href'], $map); + // Create a mock request for the path. + $request = Request::create('/' . $router_item['href']); + $request->attributes->set('system_path', $router_item['href']); + $router_item['access'] = menu_item_route_access($route, $request); + // Route-provided menu items do not have menu loaders, so replace the map + // with the link map and populate any placeholders. + $map = menu_item_populate_map($route, $request, $link_map); } else { // @todo: Remove once all routes are converted. @@ -921,7 +923,11 @@ // menu_tree_check_access() may set this ahead of time for links to nodes. if (!isset($item['access'])) { if ($route = $item->getRoute()) { - $item['access'] = menu_item_route_access($route, $item['href'], $map); + // Create a mock request for the path. + $request = Request::create('/' . $item['href']); + $request->attributes->set('system_path', $item['href']); + $item['access'] = menu_item_route_access($route, $request); + $map = menu_item_populate_map($route, $request, $map); } elseif (!empty($item['load_functions']) && !_menu_load_objects($item, $map)) { // An error occurred loading an object. @@ -951,31 +957,43 @@ } /** - * Checks access to a menu item by mocking a request for a path. + * Checks access to a menu item. * * @param \Symfony\Component\Routing\Route $route * Router for the given menu item. - * @param string $href - * Menu path as returned by $item['href'] of menu_get_item(). - * @param array $map - * An array of path arguments, for example, array('node', '5'). + * @param \Symfony\Component\HttpFoundation\Request $request + * The mock a request for a path. * * @return bool * TRUE if the user has access or FALSE if the user should be presented * with access denied. */ -function menu_item_route_access(Route $route, $href, &$map) { - $request = Request::create('/' . $href); - $request->attributes->set('system_path', $href); +function menu_item_route_access(Route $route, Request $request) { // Attempt to match this path to provide a fully built request to the // access checker. try { $request->attributes->add(Drupal::service('router.dynamic')->matchRequest($request)); + return Drupal::service('access_manager')->check($route, $request); } catch (NotFoundHttpException $e) { return FALSE; } +} +/** + * Populate the map with any matching values from the request. + * + * @param \Symfony\Component\Routing\Route $route + * Router for the given menu item. + * @param \Symfony\Component\HttpFoundation\Request $request + * The mock a request for a path. + * @param array $map + * The map. + * + * return array + * The populated map. + */ +function menu_item_populate_map(Route $route, Request $request, array $map) { // Populate the map with any matching values from the request. $path_bits = explode('/', trim($route->getPath(), '/')); foreach ($map as $index => $map_item) { @@ -990,8 +1008,7 @@ } } } - - return Drupal::service('access_manager')->check($route, $request); + return $map; } /**