summaryrefslogtreecommitdiff
path: root/includes/menu.inc
diff options
context:
space:
mode:
authorwebchick <webchick@24967.no-reply.drupal.org>2011-12-24 17:20:23 -0800
committerwebchick <webchick@24967.no-reply.drupal.org>2011-12-24 17:20:23 -0800
commit1e126deba866db54fe1f55b0211bb7c6341e6612 (patch)
treea4fe7c816b6385924c47dce5a8dcc01aaa32f761 /includes/menu.inc
parentfa4d4c5ce3c9e2d156ea00ca3d3299ac90d37a3b (diff)
downloadbrdo-1e126deba866db54fe1f55b0211bb7c6341e6612.tar.gz
brdo-1e126deba866db54fe1f55b0211bb7c6341e6612.tar.bz2
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.
Diffstat (limited to 'includes/menu.inc')
-rw-r--r--includes/menu.inc77
1 files changed, 56 insertions, 21 deletions
diff --git a/includes/menu.inc b/includes/menu.inc
index dad65d727..bdbbbb62c 100644
--- a/includes/menu.inc
+++ b/includes/menu.inc
@@ -275,6 +275,20 @@ define('MENU_MAX_DEPTH', 9);
*/
/**
+ * 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.
*
* For example, the ancestors of node/12345/edit are:
@@ -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;
- }
- foreach ($menu_names as $menu_name) {
- if (!isset($candidates[$link_path][$menu_name])) {
- continue;
- }
- $candidate_item = $candidates[$link_path][$menu_name];
- $map = explode('/', $path);
- _menu_translate($candidate_item, $map);
- if ($candidate_item['access']) {
- $preferred_links[$path] = $candidate_item;
+ if (isset($candidates[$link_path])) {
+ foreach ($menu_names as $menu_name) {
+ 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][$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;
}
/**