diff --git a/core/includes/menu.inc b/core/includes/menu.inc index 824c40f..8ba4644 100644 --- a/core/includes/menu.inc +++ b/core/includes/menu.inc @@ -929,9 +929,11 @@ function _menu_link_translate(&$item) { * @throws \Symfony\Component\Routing\Exception\ResourceNotFoundException * If the system path in $href does not match the $route. */ -function menu_item_route_access(Route $route, $href, &$map) { - $request = RequestHelper::duplicate(\Drupal::request(), '/' . $href); - $request->attributes->set('_system_path', $href); +function menu_item_route_access(Route $route, $href, &$map, Request $request = NULL) { + if (!isset($request)) { + $request = RequestHelper::duplicate(\Drupal::request(), '/' . $href); + $request->attributes->set('_system_path', $href); + } // Attempt to match this path to provide a fully built request to the // access checker. try { @@ -2762,7 +2764,7 @@ function menu_default_links_rebuild() { // @todo - load all the route names? $query = \Drupal::entityQuery('menu_link') - ->condition('router_path', $paths, 'NOT IN') + ->condition('link_path', $paths, 'NOT IN') ->condition('external', 0) ->condition('updated', 0) ->condition('customized', 0) @@ -2999,7 +3001,7 @@ function _menu_router_build($callbacks, $save = FALSE) { // previous iteration assigned one already), try to find the menu name // of the parent item in the currently stored menu links. if (!isset($parent['menu_name'])) { - $menu_name = db_query("SELECT menu_name FROM {menu_links} WHERE link_path = :router_path AND module = 'system'", array(':router_path' => $parent_path))->fetchField(); + $menu_name = db_query("SELECT menu_name FROM {menu_links} WHERE link_path = :link_path AND module = 'system'", array(':link_path' => $parent_path))->fetchField(); if ($menu_name) { $parent['menu_name'] = $menu_name; } diff --git a/core/includes/path.inc b/core/includes/path.inc index 9c41abd..58bd0a1 100644 --- a/core/includes/path.inc +++ b/core/includes/path.inc @@ -5,6 +5,7 @@ * Functions to handle paths in Drupal. */ +use Drupal\Core\Routing\RequestHelper; use Symfony\Component\HttpFoundation\Request; /** @@ -195,9 +196,24 @@ function drupal_valid_path($path, $dynamic_allowed = FALSE) { global $menu_admin; // We indicate that a menu administrator is running the menu access check. $menu_admin = TRUE; + /** @var $route_provider \Drupal\Core\Routing\RouteProviderInterface */ + $route_provider = \Drupal::service('router.route_provider'); + + if ($dynamic_allowed && preg_match('/\/\%/', $path)) { + $router_path = '/' . str_replace('%', '{}', $path); + } + else { + $router_path = $path; + } + if ($path == '' || url_is_external($path)) { $item = array('access' => TRUE); } + elseif (($collection = $route_provider->getRoutesByPattern('/' . $router_path)) && $collection->count() > 0) { + $routes = $collection->all(); + $route = reset($routes); + $route_name = key($routes); + } elseif ($dynamic_allowed && preg_match('/\/\%/', $path)) { // Path is dynamic (ie 'user/%'), so check directly against menu_router table. if ($item = db_query("SELECT * FROM {menu_router} where path = :path", array(':path' => $path))->fetchAssoc()) { @@ -206,16 +222,22 @@ function drupal_valid_path($path, $dynamic_allowed = FALSE) { $item['external'] = FALSE; $item['options'] = ''; _menu_link_translate($item); + $route_name = $item['route_name']; } } else { $item = menu_get_item($path); + $route_name = $item['route_name']; } // Check the new routing system. - if (!empty($item['route_name'])) { + if (!empty($route_name)) { $map = array(); - $route = \Drupal::service('router.route_provider')->getRouteByName($item['route_name']); - $item['access'] = menu_item_route_access($route, $path, $map); + $route = \Drupal::service('router.route_provider')->getRouteByName($route_name); + $request = RequestHelper::duplicate(\Drupal::request(), '/' . $path); + $request->attributes->set('_system_path', $path); + $request->attributes->set('_menu_admin', TRUE); + + $item['access'] = menu_item_route_access($route, $path, $map, $request); } $menu_admin = FALSE; return $item && $item['access']; diff --git a/core/modules/book/book.module b/core/modules/book/book.module index bbe3efa..3a01a23 100644 --- a/core/modules/book/book.module +++ b/core/modules/book/book.module @@ -908,7 +908,7 @@ function book_menu_subtree_data($link) { // If the subtree data was not in the cache, $data will be NULL. if (!isset($data)) { $query = db_select('menu_links', 'ml', array('fetch' => PDO::FETCH_ASSOC)); - $query->join('menu_router', 'm', 'm.path = ml.router_path'); + $query->join('menu_router', 'm', 'm.path = ml.link_path'); $query->join('book', 'b', 'ml.mlid = b.mlid'); $query->fields('b'); $query->fields('m', array('load_functions', 'to_arg_functions', 'access_callback', 'access_arguments', 'page_callback', 'page_arguments', 'title', 'title_callback', 'title_arguments', 'type')); diff --git a/core/modules/book/lib/Drupal/book/BookManager.php b/core/modules/book/lib/Drupal/book/BookManager.php index d246632..789743c 100644 --- a/core/modules/book/lib/Drupal/book/BookManager.php +++ b/core/modules/book/lib/Drupal/book/BookManager.php @@ -129,7 +129,7 @@ public function getLinkDefaults($nid) { 'menu_name' => '', 'nid' => $nid, 'bid' => 0, - 'router_path' => 'node/%', + 'link_path' => 'node/%', 'plid' => 0, 'mlid' => 0, 'has_children' => 0, @@ -187,7 +187,7 @@ public function addFormElements(array $form, array &$form_state, NodeInterface $ ), '#tree' => TRUE, ); - foreach (array('menu_name', 'mlid', 'nid', 'router_path', 'has_children', 'options', 'module', 'original_bid', 'parent_depth_limit') as $key) { + foreach (array('menu_name', 'mlid', 'nid', 'link_path', 'has_children', 'options', 'module', 'original_bid', 'parent_depth_limit') as $key) { $form['book'][$key] = array( '#type' => 'value', '#value' => $node->book[$key], diff --git a/core/modules/field_ui/field_ui.module b/core/modules/field_ui/field_ui.module index 14e8e42..a6085b4 100644 --- a/core/modules/field_ui/field_ui.module +++ b/core/modules/field_ui/field_ui.module @@ -69,11 +69,11 @@ function field_ui_menu() { * Implements hook_default_menu_links(). */ function field_ui_default_menu_links() { - $links['admin.report.fields'] = array( + $links['admin.reports.fields'] = array( 'link_title' => 'Field list', 'description' => 'Overview of fields on all entity types.', 'route_name' => 'field_ui.list', - 'parent' => 'admin.report', + 'parent' => 'admin.reports', ); return $links; diff --git a/core/modules/forum/forum.routing.yml b/core/modules/forum/forum.routing.yml index 3a0b6b9..aa21336 100644 --- a/core/modules/forum/forum.routing.yml +++ b/core/modules/forum/forum.routing.yml @@ -26,6 +26,7 @@ forum.page: path: '/forum/{taxonomy_term}' defaults: _content: '\Drupal\forum\Controller\ForumController::forumPage' + _title_callback: '\Drupal\taxonomy\Controller\TaxonomyController::termTitle' requirements: _permission: 'access content' diff --git a/core/modules/menu/lib/Drupal/menu/Form/MenuDeleteForm.php b/core/modules/menu/lib/Drupal/menu/Form/MenuDeleteForm.php index 35d074d..36fc607 100644 --- a/core/modules/menu/lib/Drupal/menu/Form/MenuDeleteForm.php +++ b/core/modules/menu/lib/Drupal/menu/Form/MenuDeleteForm.php @@ -106,7 +106,7 @@ public function submit(array $form, array &$form_state) { // Reset all the menu links defined by the system via hook_menu(). // @todo Convert this to an EFQ once we figure out 'ORDER BY m.number_parts'. - $result = $this->connection->query("SELECT mlid FROM {menu_links} ml INNER JOIN {menu_router} m ON ml.router_path = m.path WHERE ml.menu_name = :menu AND ml.module = 'system' ORDER BY m.number_parts ASC", array(':menu' => $this->entity->id()), array('fetch' => \PDO::FETCH_ASSOC))->fetchCol(); + $result = $this->connection->query("SELECT mlid FROM {menu_links} ml INNER JOIN {menu_router} m ON ml.link_path = m.path WHERE ml.menu_name = :menu AND ml.module = 'system' ORDER BY m.number_parts ASC", array(':menu' => $this->entity->id()), array('fetch' => \PDO::FETCH_ASSOC))->fetchCol(); $menu_links = $this->storageController->loadMultiple($result); foreach ($menu_links as $link) { $link->reset(); diff --git a/core/modules/menu/menu.install b/core/modules/menu/menu.install index b7dc67d..2fee65e 100644 --- a/core/modules/menu/menu.install +++ b/core/modules/menu/menu.install @@ -19,7 +19,7 @@ function menu_install() { $base_link = entity_create('menu_link', array( 'menu_name' => $system_link->menu_name, - 'router_path' => 'admin/structure/menu/manage/%', + 'link_path' => 'admin/structure/menu/manage/%', 'module' => 'menu', )); diff --git a/core/modules/menu_link/lib/Drupal/menu_link/Entity/MenuLink.php b/core/modules/menu_link/lib/Drupal/menu_link/Entity/MenuLink.php index 4af8827..36ef6c1 100644 --- a/core/modules/menu_link/lib/Drupal/menu_link/Entity/MenuLink.php +++ b/core/modules/menu_link/lib/Drupal/menu_link/Entity/MenuLink.php @@ -379,8 +379,9 @@ public function reset() { // would not be reset, because properties like the original 'menu_name' are // not stored anywhere else. Since resetting a link happens rarely and this // is a one-time operation, retrieving the full menu router does no harm. + // @FIXME Decide whether we want to keep the reset functionality. $menu = menu_get_router(); - $router_item = $menu[$this->router_path]; + $router_item = $menu[$this->link_path]; $new_link = self::buildFromRouterItem($router_item); // Merge existing menu link's ID and 'has_children' property. foreach (array('mlid', 'has_children') as $key) { diff --git a/core/modules/picture/picture.module b/core/modules/picture/picture.module index 817ee6f..5d5d10c 100644 --- a/core/modules/picture/picture.module +++ b/core/modules/picture/picture.module @@ -85,7 +85,7 @@ function picture_default_menu_links() { 'description' => 'Manage picture mappings', 'weight' => 10, 'route_name' => 'picture.mapping_page', - 'parent' => 'admin.config.media.picturemapping', + 'parent' => 'admin.config.media', ); return $links; diff --git a/core/modules/system/lib/Drupal/system/Tests/Menu/MenuRouterTest.php b/core/modules/system/lib/Drupal/system/Tests/Menu/MenuRouterTest.php index 909eeeb..ab55143 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Menu/MenuRouterTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Menu/MenuRouterTest.php @@ -221,7 +221,7 @@ protected function doTestMenuHidden() { $links = array(); foreach ($menu_links as $menu_link) { - $links[$menu_link->router_path] = $menu_link; + $links[$menu_link->link_path] = $menu_link; } $parent = $links['menu-test/hidden/menu']; diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Controller/TaxonomyController.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Controller/TaxonomyController.php index e79c37c..7685cd4 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/Controller/TaxonomyController.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Controller/TaxonomyController.php @@ -57,6 +57,19 @@ public function termTitle(TermInterface $taxonomy_term) { } /** + * Route title callback. + * + * @param \Drupal\taxonomy\VocabularyInterface $taxonomy_vocabulary + * The taxonomy term. + * + * @return string + * The term label. + */ + public function vocabularyTitle(VocabularyInterface $taxonomy_vocabulary) { + return Xss::filter($taxonomy_vocabulary->label()); + } + + /** * @todo Remove taxonomy_term_feed(). */ public function termFeed(TermInterface $taxonomy_term) { diff --git a/core/modules/taxonomy/taxonomy.routing.yml b/core/modules/taxonomy/taxonomy.routing.yml index 8040860..b5f3c2e 100644 --- a/core/modules/taxonomy/taxonomy.routing.yml +++ b/core/modules/taxonomy/taxonomy.routing.yml @@ -79,6 +79,7 @@ taxonomy.overview_terms: path: '/admin/structure/taxonomy/manage/{taxonomy_vocabulary}' defaults: _form: 'Drupal\taxonomy\Form\OverviewTerms' + _title_callback: 'Drupal\taxonomy\Controller\TaxonomyController::vocabularyTitle' requirements: _entity_access: 'taxonomy_vocabulary.view' diff --git a/core/modules/user/lib/Drupal/user/Access/LoginStatusCheck.php b/core/modules/user/lib/Drupal/user/Access/LoginStatusCheck.php index 547057b..ae11687 100644 --- a/core/modules/user/lib/Drupal/user/Access/LoginStatusCheck.php +++ b/core/modules/user/lib/Drupal/user/Access/LoginStatusCheck.php @@ -28,7 +28,7 @@ public function appliesTo() { * {@inheritdoc} */ public function access(Route $route, Request $request, AccountInterface $account) { - return $account->isAuthenticated() ? static::ALLOW : static::DENY; + return ($request->attributes->get('_menu_admin') || $account->isAuthenticated()) ? static::ALLOW : static::DENY; } }