Issue #942782 by pillarsdotnet, xjm, becw, timhilliard, JohnAlbin, jrchamp, Tor Arne Thune, Damien Tournoud, jn2, James Andres, dstol, melon, colan: Fixed Custom menus never receive an active trail.
parent
fa4d4c5ce3
commit
1e126deba8
|
@ -274,6 +274,20 @@ define('MENU_MAX_DEPTH', 9);
|
|||
* @} End of "Menu tree parameters".
|
||||
*/
|
||||
|
||||
/**
|
||||
* Reserved key to identify the most specific menu link for a given path.
|
||||
*
|
||||
* The value of this constant is a hash of the constant name. We use the hash
|
||||
* so that the reserved key is over 32 characters in length and will not
|
||||
* collide with allowed menu names:
|
||||
* @code
|
||||
* sha1('MENU_PREFERRED_LINK') = 1cf698d64d1aa4b83907cf6ed55db3a7f8e92c91
|
||||
* @endcode
|
||||
*
|
||||
* @see menu_link_get_preferred()
|
||||
*/
|
||||
define('MENU_PREFERRED_LINK', '1cf698d64d1aa4b83907cf6ed55db3a7f8e92c91');
|
||||
|
||||
/**
|
||||
* Returns the ancestors (and relevant placeholders) for any given path.
|
||||
*
|
||||
|
@ -1241,7 +1255,7 @@ function menu_tree_page_data($menu_name, $max_depth = NULL, $only_active_trail =
|
|||
if ($item['access']) {
|
||||
// Find a menu link corresponding to the current path. If $active_path
|
||||
// is NULL, let menu_link_get_preferred() determine the path.
|
||||
if ($active_link = menu_link_get_preferred($active_path)) {
|
||||
if ($active_link = menu_link_get_preferred($active_path, $menu_name)) {
|
||||
// The active link may only be taken into account to build the
|
||||
// active trail, if it resides in the requested menu. Otherwise,
|
||||
// we'd needlessly re-run _menu_build_tree() queries for every menu
|
||||
|
@ -2260,6 +2274,13 @@ function theme_menu_local_tasks(&$variables) {
|
|||
|
||||
/**
|
||||
* Set (or get) the active menu for the current page - determines the active trail.
|
||||
*
|
||||
* @return
|
||||
* An array of menu machine names, in order of preference. The
|
||||
* 'menu_default_active_menus' variable may be used to assert a menu order
|
||||
* different from the order of creation, or to prevent a particular menu from
|
||||
* being used at all in the active trail.
|
||||
* E.g., $conf['menu_default_active_menus'] = array('navigation', 'main-menu')
|
||||
*/
|
||||
function menu_set_active_menu_names($menu_names = NULL) {
|
||||
$active = &drupal_static(__FUNCTION__);
|
||||
|
@ -2390,23 +2411,30 @@ function menu_set_active_trail($new_trail = NULL) {
|
|||
* @param $path
|
||||
* The path, for example 'node/5'. The function will find the corresponding
|
||||
* menu link ('node/5' if it exists, or fallback to 'node/%').
|
||||
* @param $selected_menu
|
||||
* The name of a menu used to restrict the search for a preferred menu link.
|
||||
* If not specified, all the menus returned by menu_get_active_menu_names()
|
||||
* will be used.
|
||||
*
|
||||
* @return
|
||||
* A fully translated menu link, or NULL if no matching menu link was
|
||||
* A fully translated menu link, or FALSE if no matching menu link was
|
||||
* found. The most specific menu link ('node/5' preferred over 'node/%') in
|
||||
* the most preferred menu (as defined by menu_get_active_menu_names()) is
|
||||
* returned.
|
||||
*/
|
||||
function menu_link_get_preferred($path = NULL) {
|
||||
function menu_link_get_preferred($path = NULL, $selected_menu = NULL) {
|
||||
$preferred_links = &drupal_static(__FUNCTION__);
|
||||
|
||||
if (!isset($path)) {
|
||||
$path = $_GET['q'];
|
||||
}
|
||||
|
||||
if (!isset($preferred_links[$path])) {
|
||||
$preferred_links[$path] = FALSE;
|
||||
if (empty($selected_menu)) {
|
||||
// Use an illegal menu name as the key for the preferred menu link.
|
||||
$selected_menu = MENU_PREFERRED_LINK;
|
||||
}
|
||||
|
||||
if (!isset($preferred_links[$path])) {
|
||||
// Look for the correct menu link by building a list of candidate paths,
|
||||
// which are ordered by priority (translated hrefs are preferred over
|
||||
// untranslated paths). Afterwards, the most relevant path is picked from
|
||||
|
@ -2428,6 +2456,8 @@ function menu_link_get_preferred($path = NULL) {
|
|||
|
||||
// Retrieve a list of menu names, ordered by preference.
|
||||
$menu_names = menu_get_active_menu_names();
|
||||
// Put the selected menu at the front of the list.
|
||||
array_unshift($menu_names, $selected_menu);
|
||||
|
||||
$query = db_select('menu_links', 'ml', array('fetch' => PDO::FETCH_ASSOC));
|
||||
$query->leftJoin('menu_router', 'm', 'm.path = ml.router_path');
|
||||
|
@ -2435,7 +2465,6 @@ function menu_link_get_preferred($path = NULL) {
|
|||
// Weight must be taken from {menu_links}, not {menu_router}.
|
||||
$query->addField('ml', 'weight', 'link_weight');
|
||||
$query->fields('m');
|
||||
$query->condition('ml.menu_name', $menu_names, 'IN');
|
||||
$query->condition('ml.link_path', $path_candidates, 'IN');
|
||||
|
||||
// Sort candidates by link path and menu name.
|
||||
|
@ -2443,29 +2472,35 @@ function menu_link_get_preferred($path = NULL) {
|
|||
foreach ($query->execute() as $candidate) {
|
||||
$candidate['weight'] = $candidate['link_weight'];
|
||||
$candidates[$candidate['link_path']][$candidate['menu_name']] = $candidate;
|
||||
// Add any menus not already in the menu name search list.
|
||||
if (!in_array($candidate['menu_name'], $menu_names)) {
|
||||
$menu_names[] = $candidate['menu_name'];
|
||||
}
|
||||
}
|
||||
|
||||
// Pick the most specific link, in the most preferred menu.
|
||||
// Store the most specific link for each menu. Also save the most specific
|
||||
// link of the most preferred menu in $preferred_link.
|
||||
foreach ($path_candidates as $link_path) {
|
||||
if (!isset($candidates[$link_path])) {
|
||||
continue;
|
||||
}
|
||||
if (isset($candidates[$link_path])) {
|
||||
foreach ($menu_names as $menu_name) {
|
||||
if (!isset($candidates[$link_path][$menu_name])) {
|
||||
continue;
|
||||
}
|
||||
if (empty($preferred_links[$path][$menu_name]) && isset($candidates[$link_path][$menu_name])) {
|
||||
$candidate_item = $candidates[$link_path][$menu_name];
|
||||
$map = explode('/', $path);
|
||||
_menu_translate($candidate_item, $map);
|
||||
if ($candidate_item['access']) {
|
||||
$preferred_links[$path] = $candidate_item;
|
||||
$preferred_links[$path][$menu_name] = $candidate_item;
|
||||
if (empty($preferred_links[$path][MENU_PREFERRED_LINK])) {
|
||||
// Store the most specific link.
|
||||
$preferred_links[$path][MENU_PREFERRED_LINK] = $candidate_item;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $preferred_links[$path];
|
||||
return isset($preferred_links[$path][$selected_menu]) ? $preferred_links[$path][$selected_menu] : FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -182,6 +182,28 @@ function menu_update_7002(&$sandbox) {
|
|||
update_fix_d7_block_deltas($sandbox, $renamed_deltas, $moved_deltas);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Add missing custom menus to active menus list.
|
||||
*/
|
||||
function menu_update_7003(&$sandbox) {
|
||||
// Make sure all custom menus are present in the active menus variable so that
|
||||
// their items may appear in the active trail.
|
||||
// @see menu_set_active_menu_names()
|
||||
$active_menus = variable_get('menu_default_active_menus', array_keys(menu_list_system_menus()));
|
||||
$update_variable = FALSE;
|
||||
foreach (menu_get_names() as $menu_name) {
|
||||
if (!in_array($menu_name, $active_menus) && (strpos($menu_name, 'menu-') === 0)) {
|
||||
$active_menus[] = $menu_name;
|
||||
$update_variable = TRUE;
|
||||
}
|
||||
}
|
||||
if ($update_variable) {
|
||||
variable_set('menu_default_active_menus', $active_menus);
|
||||
}
|
||||
// Clear the menu cache.
|
||||
cache_clear_all(NULL, 'cache_menu');
|
||||
}
|
||||
|
||||
/**
|
||||
* @} End of "defgroup updates-7.x-extra"
|
||||
* The next series of updates should start at 8000.
|
||||
|
|
|
@ -268,6 +268,15 @@ function menu_save($menu) {
|
|||
|
||||
switch ($status) {
|
||||
case SAVED_NEW:
|
||||
// Make sure the menu is present in the active menus variable so that its
|
||||
// items may appear in the menu active trail.
|
||||
// @see menu_set_active_menu_names()
|
||||
$active_menus = variable_get('menu_default_active_menus', array_keys(menu_get_menus()));
|
||||
if (!in_array($menu['menu_name'], $active_menus)) {
|
||||
$active_menus[] = $menu['menu_name'];
|
||||
variable_set('menu_default_active_menus', $active_menus);
|
||||
}
|
||||
|
||||
module_invoke_all('menu_insert', $menu);
|
||||
break;
|
||||
|
||||
|
@ -305,6 +314,15 @@ function menu_delete($menu) {
|
|||
// Delete all links from the menu.
|
||||
menu_delete_links($menu['menu_name']);
|
||||
|
||||
// Remove menu from active menus variable.
|
||||
$active_menus = variable_get('menu_default_active_menus', array_keys(menu_get_menus()));
|
||||
foreach ($active_menus as $i => $menu_name) {
|
||||
if ($menu['menu_name'] == $menu_name) {
|
||||
unset($active_menus[$i]);
|
||||
variable_set('menu_default_active_menus', $active_menus);
|
||||
}
|
||||
}
|
||||
|
||||
// Delete the custom menu.
|
||||
db_delete('menu_custom')
|
||||
->condition('menu_name', $menu['menu_name'])
|
||||
|
|
|
@ -205,7 +205,7 @@ class MenuTestCase extends DrupalWebTestCase {
|
|||
|
||||
// Add menu links.
|
||||
$item1 = $this->addMenuLink(0, 'node/' . $node1->nid, $menu_name);
|
||||
$item2 = $this->addMenuLink($item1['mlid'], 'node/' . $node2->nid, $menu_name);
|
||||
$item2 = $this->addMenuLink($item1['mlid'], 'node/' . $node2->nid, $menu_name, FALSE);
|
||||
$item3 = $this->addMenuLink($item2['mlid'], 'node/' . $node3->nid, $menu_name);
|
||||
$this->assertMenuLink($item1['mlid'], array('depth' => 1, 'has_children' => 1, 'p1' => $item1['mlid'], 'p2' => 0));
|
||||
$this->assertMenuLink($item2['mlid'], array('depth' => 2, 'has_children' => 1, 'p1' => $item1['mlid'], 'p2' => $item2['mlid'], 'p3' => 0));
|
||||
|
@ -283,7 +283,7 @@ class MenuTestCase extends DrupalWebTestCase {
|
|||
* @param string $menu_name Menu name.
|
||||
* @return array Menu link created.
|
||||
*/
|
||||
function addMenuLink($plid = 0, $link = '<front>', $menu_name = 'navigation') {
|
||||
function addMenuLink($plid = 0, $link = '<front>', $menu_name = 'navigation', $expanded = TRUE) {
|
||||
// View add menu link page.
|
||||
$this->drupalGet("admin/structure/menu/manage/$menu_name/add");
|
||||
$this->assertResponse(200);
|
||||
|
@ -294,7 +294,7 @@ class MenuTestCase extends DrupalWebTestCase {
|
|||
'link_title' => $title,
|
||||
'description' => '',
|
||||
'enabled' => TRUE, // Use this to disable the menu and test.
|
||||
'expanded' => TRUE, // Setting this to true should test whether it works when we do the std_user tests.
|
||||
'expanded' => $expanded, // Setting this to true should test whether it works when we do the std_user tests.
|
||||
'parent' => $menu_name . ':' . $plid,
|
||||
'weight' => '0',
|
||||
);
|
||||
|
@ -345,7 +345,7 @@ class MenuTestCase extends DrupalWebTestCase {
|
|||
if (isset($parent)) {
|
||||
// Verify menu link.
|
||||
$title = $parent['link_title'];
|
||||
$this->assertText($title, 'Parent menu link was displayed');
|
||||
$this->assertLink($title, 0, 'Parent menu link was displayed');
|
||||
|
||||
// Verify menu link link.
|
||||
$this->clickLink($title);
|
||||
|
@ -355,7 +355,7 @@ class MenuTestCase extends DrupalWebTestCase {
|
|||
|
||||
// Verify menu link.
|
||||
$title = $item['link_title'];
|
||||
$this->assertText($title, 'Menu link was displayed');
|
||||
$this->assertLink($title, 0, 'Menu link was displayed');
|
||||
|
||||
// Verify menu link link.
|
||||
$this->clickLink($title);
|
||||
|
|
Loading…
Reference in New Issue