menu_node_nodeapi() calls menu_node_delete() when the menu item has been deleted (i.e. $node->menu['delete'] = 1):

// Line 41:
menu_node_delete($node->nid, $mlid);

But the function is actually defined like this:

// Line 361:
function menu_node_delete($node) {
  #<snip>
  db_query("DELETE FROM {menu_node} WHERE nid = %d", $node->nid);
}

Which means it doesn't actually do anything.

I fixed it on my site as follows:

// Line 41:
menu_node_delete($node, $mlid);
// Line 361:
function menu_node_delete($node, $mlid = null) {
  #<snip>
  if ($mlid) {
    db_query("DELETE FROM {menu_node} WHERE nid = %d AND mlid = %d", $node->nid, $mlid);
  } else {
    db_query("DELETE FROM {menu_node} WHERE nid = %d", $node->nid);
  }
}

I didn't alter the module_invoke_all() calls because I don't know how they should handle deleting a specific menu item rather than the whole node...

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

joglin’s picture

Subscribe for D7,

steps to replicate the error:
* Create 2 menu link items to same node
* Check menu_node table: it has 2 rows for the same node
* Delete only one menu link item
* Check the table menu_node must have a row for the node, but has none.

I splitted menu_node_node_delete() in menu_node_record_delete_by_node() and menu_node_record_delete_by_link() then I commented menu_node_node_delete() because it is needless: menu module deletes each menu item when node is deleted then invoke hook_menu_link_delete() for each item

agentrickard’s picture

Status: Active » Needs review

What version is this patch for?

joglin’s picture

Rolled for D7 from git master

agentrickard’s picture

Version: 6.x-1.5 » 7.x-1.x-dev
agentrickard’s picture

Please explain why the two existing tests for this behavior are incorrect.

I should point out, by the way, that supporting multiple menu links to the same node is not really supported by core because if you edit the node, one of the links will also be deleted, yes?

Status: Needs review » Needs work
joglin’s picture

I do not know, the test reports:
* Failed to fetch file [http://drupal.org/files/menu_node-improper-delete record-when-menu-link-delete-D7-1257254-2.patch], instead received response [404]
maybe because the file contains a space.

Yes, multiple menu links to the same node is not really supported but multiple links are not deleted because menu module update or delete mlid. In node_prepare hook the menu module seeks mlid first in the default menu then in allowed menus based on settings in the content type.

For example, I can create multiple menus with duplicate links and enable each menu block in different pages of the site then correct the breadcrumbs with a module like custom breadcrumbs

menu_node binds menu links to node (the table primary field is mlid) then menu_node must respond primarily to menu hook and secondarily to node hook. Because the menu module already reflects the node module hook and in turn generates its hook.

agentrickard’s picture

Status: Needs work » Needs review

Thanks.

gabriel.achille’s picture

Title: Doesn't delete record from menu_node table when menu item is deleted » Improper delete record when menu link delete
FileSize
473 bytes
3.43 KB

good for me.
Following recent recent fix (issue 1361746) commited in dev branch, i updated this patch to use the new function menu_node_record_delete_by_link() where it should be used in the new code introduced by #1361746 fix.
Also i update the issue title, following joglin patch name and joglin patch purpose because it make more sense.

gabriel.achille’s picture

sorry: clean up as well when merging with this other patch (#1361746)

gabriel.achille’s picture

Status: Needs review » Reviewed & tested by the community
gabriel.achille’s picture

Status: Reviewed & tested by the community » Fixed

Status: Fixed » Closed (fixed)

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