#576290: fix the breadcrumb and active-trail logic.

From: Damien Tournoud <damien@tournoud.net>


---
 menu.inc |   54 ++++++++++++++++++++++++++++++++----------------------
 1 files changed, 32 insertions(+), 22 deletions(-)

diff --git includes/menu.inc includes/menu.inc
index 8592317..f21d7e1 100644
--- includes/menu.inc
+++ includes/menu.inc
@@ -1089,8 +1089,24 @@ function menu_tree_page_data($menu_name, $max_depth = NULL) {
           if (drupal_is_front_page()) {
             $args[] = '<front>';
           }
-          $parents = db_select('menu_links')
+          if (!empty($item['tab_root'])) {
+            // Replace wildcards in the root path using the current path.
+            $parts = arg(NULL, $item['tab_root']);
+            $map = $item['original_map'];
+            foreach ($parts as $index => $part) {
+              if ($part == '%') {
+                $parts[$index] = $map[$index];
+              }
+            }
+            $args[] = implode('/', $parts);
+
+            // And fallback to the untranslated tab root.
+            $args[] = $item['tab_root'];
+          }
+
+          $parents_candidates = db_select('menu_links')
             ->fields('menu_links', array(
+              'link_path',
               'p1',
               'p2',
               'p3',
@@ -1102,26 +1118,16 @@ function menu_tree_page_data($menu_name, $max_depth = NULL) {
             ))
             ->condition('menu_name', $menu_name)
             ->condition('link_path', $args, 'IN')
-            ->execute()->fetchAssoc();
-
-          if (empty($parents)) {
-            // If no link exists, we may be on a local task that's not in the links.
-            // TODO: Handle the case like a local task on a specific node in the menu.
-            $parents = db_select('menu_links')
-              ->fields('menu_links', array(
-                'p1',
-                'p2',
-                'p3',
-                'p4',
-                'p5',
-                'p6',
-                'p7',
-                'p8',
-              ))
-              ->condition('menu_name', $menu_name)
-              ->condition('link_path', $item['tab_root'])
-              ->execute()->fetchAssoc();
+            ->execute()->fetchAllAssoc('link_path', PDO::FETCH_ASSOC);
+
+          $parents = array();
+          foreach ($args as $arg) {
+            if (isset($parents_candidates[$arg])) {
+              $parents = $parents_candidates[$arg];
+              break;
+            }
           }
+
           // We always want all the top-level links with plid == 0.
           $parents[] = '0';
 
@@ -1995,7 +2001,6 @@ function menu_set_active_trail($new_trail = NULL) {
     $trail = array();
     $trail[] = array('title' => t('Home'), 'href' => '<front>', 'localized_options' => array(), 'type' => 0);
     $item = menu_get_item();
-
     // Check whether the current item is a local task (displayed as a tab).
     if ($item['tab_parent']) {
       // The title of a local task is used for the tab, never the page title.
@@ -2016,14 +2021,19 @@ function menu_set_active_trail($new_trail = NULL) {
         $item = $root_item;
       }
     }
+
     $menu_names = menu_get_active_menu_names();
     $curr = FALSE;
     // Determine if the current page is a link in any of the active menus.
     if ($menu_names) {
       $query = db_select('menu_links', 'ml');
       $query->fields('ml', array('menu_name'));
-      $query->condition('ml.link_path', $item['href']);
+      $query->condition(db_or()
+        ->condition('ml.link_path', $item['path'])
+        ->condition('ml.link_path', $item['href'])
+      );
       $query->condition('ml.menu_name', $menu_names, 'IN');
+      $query->orderBy('ml.hidden', 'DESC');
       $result = $query->execute();
       $found = array();
       foreach ($result as $menu) {
