When using menu_link_maintain to edit a link ($op = 'update'), the menu cache is not cleared unless the menu item you're editing is the the 'navigation' menu. The reason is that menu_cache_clear isn't passed the correct menu_name as a parameter so uses 'navigation' by default.

A quick solution would be to patch menu_link_maintain to call menu_cache_clear_all instead.

Current code (menu.inc line 2040)

function menu_link_maintain($module, $op, $link_path, $link_title) {
  switch ($op) {
...............
    case 'update':
      db_query("UPDATE {menu_links} SET link_title = '%s' WHERE link_path = '%s' AND customized = 0 AND module = '%s'", $link_title, $link_path, $module);
      menu_cache_clear(); // clears cache for navigation menu when no parameter is passed in
      break;
...............
  }
}

A solution (maybe not a good one)

function menu_link_maintain($module, $op, $link_path, $link_title) {
  switch ($op) {
...............
    case 'update':
      db_query("UPDATE {menu_links} SET link_title = '%s' WHERE link_path = '%s' AND customized = 0 AND module = '%s'", $link_title, $link_path, $module);
      menu_cache_clear_all(); // clears cache for all menus
      break;
...............
  }
}
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

pwolanin’s picture

Version: 6.2 » 7.x-dev

Yeah, I think I noticed this at one point recently but didn't open an issue.

This code is problematic since we don't know which menus we are saving to. The solution you suggest would work, but we would invalidate less of the cache maybe if we did something like:

    case 'update':
      db_query("UPDATE {menu_links} SET link_title = '%s' WHERE link_path = '%s' AND customized = 0 AND module = '%s'", $link_title, $link_path, $module);
      $result = db_query("SELECT menu_name FROM {menu_links} WHERE link_path = '%s' AND customized = 0 AND module = '%s'", $link_title, $link_path, $module);
      while ($item = db_fetch_array($result)) {
        menu_cache_clear($item['menu_name']);
      }
      break;
pwolanin’s picture

so, chx agrees in IRC that this is the sensible approach

j0hn-smith’s picture

A much better solution.

pwolanin’s picture

Status: Active » Needs review
FileSize
920 bytes

just rolled the above into a patch. not really tested yet.

catch’s picture

Patch looks completely fine to me. I ran all tests, no regressions, and manually edited a menu item. Didn't yet look inside the cache_menu table to ensure it's actually deleting the correct records though.

catch’s picture

Status: Needs review » Reviewed & tested by the community

Spoke to pwolanin in irc, doesn't seem to be a way to reproduce this in core. Since it's pretty minor, going to call it RTBC.

catch’s picture

Status: Reviewed & tested by the community » Needs work

Nope, it doesn't work. Regression in aggregator module when changing a category name - menu items should change with it, but they don't with the patch applied.

pwolanin’s picture

Status: Needs work » Needs review
FileSize
907 bytes

ok, that was a stupid bug - extra argument to db_query() was causing the SELECT query to fail.

Tested and seems to work as expected.

catch’s picture

Status: Needs review » Reviewed & tested by the community

This one works fine :)

Dries’s picture

Version: 7.x-dev » 6.x-dev

Committed to CVS HEAD. Moving to Drupal 6.

Gábor Hojtsy’s picture

Status: Reviewed & tested by the community » Fixed

Committed to 6.x. Thanks!

Anonymous’s picture

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for two weeks with no activity.