diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc index f414d53..2a8eb4c 100644 --- a/core/includes/bootstrap.inc +++ b/core/includes/bootstrap.inc @@ -1673,14 +1673,7 @@ function drupal_get_messages($type = NULL, $clear_queue = TRUE) { * The current page's title. */ function drupal_get_title() { - $title = drupal_set_title(); - - // During a bootstrap, menu.inc is not included and thus we cannot provide a title. - if (!isset($title) && function_exists('menu_get_active_title')) { - $title = String::checkPlain(menu_get_active_title()); - } - - return $title; + return drupal_set_title(); } /** diff --git a/core/includes/menu.inc b/core/includes/menu.inc index 8ba4644..c0133b1 100644 --- a/core/includes/menu.inc +++ b/core/includes/menu.inc @@ -854,7 +854,7 @@ function menu_tail_load($arg, &$map, $index) { } /** - * Provides menu link access control, translation, and argument handling. + * Provides menu link unserializing, access control, and argument handling. * * This function is similar to _menu_translate(), but it also does * link-specific preparation (such as always calling to_arg() functions). @@ -863,52 +863,40 @@ function menu_tail_load($arg, &$map, $index) { * A menu link. * * $item['access'] becomes TRUE if the item is accessible, FALSE otherwise. - * $item['href'] is generated from link_path. - * $item['title'] is generated from link_title, and may be localized. - * $item['options'] is unserialized; it is also changed within the call here - * to $item['localized_options'] by _menu_item_localize(). + * $item['href'] is generated from link_path, or set to NULL for routes. + * $item['title'] is generated from link_title. + * $item['route_parameters'] is unserialized if needed. + * $item['options'] is unserialized and copied to $item['localized_options']. */ -function _menu_link_translate(&$item) { +function _menu_link_prepare(&$item) { if (!is_array($item['options'])) { $item['options'] = (array) unserialize($item['options']); } $item['localized_options'] = $item['options']; - if (!is_array($item['route_parameters'])) { - $item['route_parameters'] = (array) unserialize($item['route_parameters']); - } + $item['title'] = $item['link_title']; if ($item['external'] || empty($item['route_name'])) { $item['access'] = 1; $item['href'] = $item['link_path']; - $item['title'] = $item['link_title']; + $item['route_parameters'] = array(); + // Set to NULL so that drupal_pre_render_link() is certain to skip it. + $item['route_name'] = NULL; } else { + $item['href'] = NULL; + if (!is_array($item['route_parameters'])) { + $item['route_parameters'] = (array) unserialize($item['route_parameters']); + } // menu_tree_check_access() may set this ahead of time for links to nodes. if (!isset($item['access'])) { $item['access'] = Drupal::getContainer()->get('access_manager')->checkNamedRoute($item['route_name'], $item['route_parameters'], \Drupal::currentUser()); } - // For performance, don't localize a link the user can't access. - if ($item['access']) { - // @todo - we need a system path to pass to l(). Change to rendering - // this later from route name and parameters. - $item['href'] = Drupal::urlGenerator()->getPathFromRoute($item['route_name'], $item['route_parameters']); - if ($item['machine_name']) { - // This link is defined in code and can be localized. - $item['title'] = t($item['link_title']); - if (!empty($item['localized_options']['attributes']['title'])) { - $item['localized_options']['attributes']['title'] = t($item['localized_options']['attributes']['title']); - } - } - else { - $item['title'] = $item['link_title']; - } - } } // Allow other customizations - e.g. adding a page-specific query string to the // options array. For performance reasons we only invoke this hook if the link // has the 'alter' flag set in the options array. if (!empty($item['options']['alter'])) { - drupal_alter('translated_menu_link', $item); + drupal_alter('prepared_menu_link', $item); } } @@ -1064,7 +1052,6 @@ function menu_tree_output($tree) { } } - $router_item = menu_get_item(); $num_items = count($items); foreach ($items as $i => $data) { $class = array(); @@ -1091,21 +1078,17 @@ function menu_tree_output($tree) { $class[] = 'active-trail'; $data['link']['localized_options']['attributes']['class'][] = 'active-trail'; } - // Normally, l() compares the href of every link with the current path and - // sets the active class accordingly. But local tasks do not appear in menu - // trees, so if the current path is a local task, and this link is its - // tab root, then we have to set the class manually. - if ($data['link']['href'] == $router_item['tab_root_href'] && $data['link']['href'] != current_path()) { - $data['link']['localized_options']['attributes']['class'][] = 'active'; - } // Allow menu-specific theme overrides. $element['#theme'] = 'menu_link__' . strtr($data['link']['menu_name'], '-', '_'); $element['#attributes']['class'] = $class; - $element['#title'] = $data['link']['title']; - $element['#href'] = $data['link']['href']; - $element['#localized_options'] = !empty($data['link']['localized_options']) ? $data['link']['localized_options'] : array(); - $element['#below'] = $data['below'] ? menu_tree_output($data['below']) : $data['below']; + $element['link']['#type'] = 'link'; + $element['link']['#title'] = $data['link']['title']; + $element['link']['#href'] = $data['link']['href']; + $element['link']['#route_name'] = $data['link']['route_name']; + $element['link']['#route_parameters'] = $data['link']['route_parameters']; + $element['link']['#options'] = !empty($data['link']['localized_options']) ? $data['link']['localized_options'] : array(); + $element['below'] = $data['below'] ? menu_tree_output($data['below']) : $data['below']; $element['#original_link'] = $data['link']; // Index using the link's unique mlid. $build[$data['link']['mlid']] = $element; @@ -1543,7 +1526,7 @@ function _menu_tree_check_access(&$tree) { $new_tree = array(); foreach ($tree as $key => $v) { $item = &$tree[$key]['link']; - _menu_link_translate($item); + _menu_link_prepare($item); if ($item['access'] || ($item['in_active_trail'] && strpos($item['href'], '%') !== FALSE)) { if ($tree[$key]['below']) { _menu_tree_check_access($tree[$key]['below']); @@ -1660,10 +1643,10 @@ function theme_menu_link(array $variables) { $element = $variables['element']; $sub_menu = ''; - if ($element['#below']) { - $sub_menu = drupal_render($element['#below']); + if ($element['below']) { + $sub_menu = drupal_render($element['below']); } - $output = l($element['#title'], $element['#href'], $element['#localized_options']); + $output = drupal_render($element['link']); return '' . $output . $sub_menu . "\n"; } @@ -2464,19 +2447,6 @@ function menu_get_active_trail() { } /** - * Gets the title of the current page, as determined by the active trail. - */ -function menu_get_active_title() { - $active_trail = menu_get_active_trail(); - - foreach (array_reverse($active_trail) as $item) { - if (!(bool) ($item['type'] & MENU_IS_LOCAL_TASK)) { - return $item['title']; - } - } -} - -/** * Clears the cached cached data for a single named menu. */ function menu_cache_clear($menu_name = 'tools') { @@ -2694,10 +2664,6 @@ function menu_default_links_rebuild() { if ($link['type'] == MENU_SUGGESTED_ITEM) { $link['hidden'] = 1; } - // Hide all items that are not visible in the tree. - elseif (!($link['type'] & MENU_VISIBLE_IN_TREE)) { - $link['hidden'] = -1; - } // For performance reasons, do a straight query now and convert to a menu // link entity later. // @todo revisit before release. @@ -2759,23 +2725,8 @@ function menu_default_links_rebuild() { } } - // Find any item whose route does not exist any more. - return; - - // @todo - load all the route names? - $query = \Drupal::entityQuery('menu_link') - ->condition('link_path', $paths, 'NOT IN') - ->condition('external', 0) - ->condition('updated', 0) - ->condition('customized', 0) - ->sort('depth', 'DESC'); - $result = $query->execute(); - - // Remove all such items. Starting from those with the greatest depth will - // minimize the amount of re-parenting done by the menu link controller. - if (!empty($result)) { - menu_link_delete_multiple($result, TRUE); - } + // @todo - remove links based on their machine names when module are + // uninstalled, or mark them disabled if the route names are missing? } /** diff --git a/core/modules/menu_link/menu_link.api.php b/core/modules/menu_link/menu_link.api.php index 197aee8..e7b3dd7 100644 --- a/core/modules/menu_link/menu_link.api.php +++ b/core/modules/menu_link/menu_link.api.php @@ -11,14 +11,13 @@ */ /** - * Alter a menu link after it has been translated and before it is rendered. + * Alter a menu link after it has been prepared and before it is rendered. * - * This hook is invoked from _menu_link_translate() after a menu link has been - * translated; i.e., after dynamic path argument placeholders (%) have been - * replaced with actual values, the user access to the link's target page has - * been checked, and the link has been localized. It is only invoked if - * $menu_link['options']['alter'] has been set to a non-empty value (e.g. TRUE). - * This flag should be set using hook_menu_link_presave(). + * This hook is invoked from _menu_link_prepare() after a menu link has been + * translated; i.e., after the user access to the link's target page has + * been checked. It is only invoked if $menu_link['options']['alter'] has been + * set to a non-empty value (e.g. TRUE). This flag should be set using + * hook_menu_link_presave(). * * Implementations of this hook are able to alter any property of the menu link. * For example, this hook may be used to add a page-specific query string to all @@ -29,12 +28,10 @@ * * @param \Drupal\menu_link\Entity\MenuLink $menu_link * A menu link entity. - * @param array $map - * Associative array containing the menu $map (path parts and/or objects). * * @see hook_menu_link_alter() */ -function hook_translated_menu_link_alter(\Drupal\menu_link\Entity\MenuLink &$menu_link, $map) { +function hook_prepared_menu_link_alter(\Drupal\menu_link\Entity\MenuLink &$menu_link, $map) { if ($menu_link->href == 'devel/cache/clear') { $menu_link->localized_options['query'] = drupal_get_destination(); } diff --git a/core/modules/system/lib/Drupal/system/Tests/Menu/BreadcrumbTest.php b/core/modules/system/lib/Drupal/system/Tests/Menu/BreadcrumbTest.php index 9ab9103..6d7699a 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Menu/BreadcrumbTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Menu/BreadcrumbTest.php @@ -338,10 +338,7 @@ function testBreadCrumbs() { $trail += array( 'user/' . $this->web_user->id() => $this->web_user->getUsername(), ); - $tree = array( - 'user' => t('My account'), - ); - $this->assertBreadcrumb('user/' . $this->web_user->id() . '/edit', $trail, $this->web_user->getUsername(), $tree); + $this->assertBreadcrumb('user/' . $this->web_user->id() . '/edit', $trail, $this->web_user->getUsername()); // Create an only slightly privileged user being able to access site reports // but not administration pages.