As desribed in #526756: Duplicate entry errors on menu item update the menu_node there are many cases, where menu items are created, changed, or deleted, but the table menu_node does not. For correct operation menu_node needs to hook into menu_link_save and to recognize hidden menu trees. These are not treated correctly.

Comments

shaisachs’s picture

I think this is because the module doesn't respond to changes made to links through the admin/build/menu-customize/... pages. So when you drag an item around on that form, or when you add/edit a menu item (outside the node editing form), the menu_node module isn't notified.

In theory something like this should work:

function menu_node_menu_link_alter(&$item, $menu) {
  $matches = array();
  if (!preg_match('~^node/([0-9]+)$~', $item['link_path'], $matches)) {
    // this item does not have a link path like node/123; ignore
    return ;
  }

  $nid = (int) $matches[1];
  if (!$nid) {
    // sanity check for weird things like node/abc
    return ;
  }

  $node = node_load($nid);
  menu_node_save($nid, $item['mlid']);
}

However, the problem is that hook_menu_link_alter fires before an item is saved, not afterward, meaning that this will only work for existing items, not newly added items. Moreover, there are no notifications fired when an item is deleted.

It'd be nice if there was a hook_menu_link_api as a parallel to hook_nodeapi and hook_taxonomy, but alas, there's nothing quite like that. Probably the best approach is to latch on to the particular taxonomy add/edit/delete forms, register a submit callback, and fire the appropriate menu_node action from there. Such an approach would work in "most" cases, but if something funky is being done to the menu link editing form by another module, and/or another module is modifying the menu_links table directly, all bets are off.