Download & Extend

local_menu can behave inconsistently if links exist in multiple menus

Project:Local Menu
Version:6.x-1.6
Component:Code
Category:bug report
Priority:normal
Assigned:grobot
Status:needs review

Issue Summary

On one site, we observed a behaviour where local_menu would behave inconsistently and simply not appear on some (mostly top-level) pages. Our site structure was the following:

  • Primary Links was used to define the usual primary links, with no children configured
  • Navigation was used to define the full site tree, including children, and to some extent replicating the structure of primary links

The query in local_menu_block() was looking up entries in the menu_links table, but did not include any ORDER statement, so the returned values for a page with a top-level menu entry would behave inconsistently depending on which item was returned from the DB.

Comments

#1

Here's a fix which should give a precedence order to the menu trees, which produces more consistent behaviour for pages with multiple menu entries.

The only major change is that we add ORDER BY menu_name = $active DESC, menu_name = $primary DESC, menu_name = $secondary DESC to the query which looks for which menu to use.

There may be a better way to decide this (perhaps menu item depth?) but this seems a step in the right direction.

Using menu_get_active_menu_name() as the preferred selection means that we're

<?php
   
// for consistency, we will order these results to match against primary, secondary, active menus,
    // with preference for the active menu, then primary, then secondary
   
$active_menu_name    = menu_get_active_menu_name() ;
   
$primary_menu_name   = variable_get('menu_primary_links_source', 'primary-links') ;
   
$secondary_menu_name = variable_get('menu_secondary_links_source', 'secondary-links') ;

   
// Get the menu link and set the active menu to the menu it's in, so Drupal can find its way and make correct breadcrumbs at the same time
   
$sql = "
  SELECT mlid
    FROM {menu_links}
   WHERE link_path = '%s'
     AND hidden <> 1
     AND menu_name NOT IN ('admin_menu', 'devel')
ORDER BY menu_name = '%s' DESC, menu_name = '%s' DESC, menu_name = '%s' DESC
"
;
   
$result = db_query($sql, $item['href'], $active_menu_name, $primary_menu_name, $secondary_menu_name);
   
// In case there are multiple, let's find the most appropriate one
   
while ($link = menu_link_load(db_result($result))) {
      if (
in_array($link['menu_name'], array(
           
$active_menu,
           
$primary_menu_name,
           
$secondary_menu_name,
          ))) {
        break;
      }
    }

?>

Patch is against HEAD.

AttachmentSize
561798-local_menu_inconsistent_matching.patch 2.05 KB

#2

Status:active» needs review

I have to write myself a userscript that detects when I've attached a .patch file, and reminds me to change the issue status.

#3

Also of interest: implementation of menu weighting @ http://drupal.org/node/595282

nobody click here