? 457450-menu-node.patch
? sites/all/modules/admin_menu
? sites/all/modules/coder
? sites/all/modules/devel
? sites/all/modules/devel 2
? sites/all/modules/devel-7.x-1.x-dev.tar.gz
? sites/default/files
Index: includes/menu.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/menu.inc,v
retrieving revision 1.328
diff -u -p -r1.328 menu.inc
--- includes/menu.inc	10 Jun 2009 21:52:36 -0000	1.328
+++ includes/menu.inc	20 Jun 2009 17:21:16 -0000
@@ -2051,6 +2051,8 @@ function menu_link_delete($mlid, $path =
 function _menu_delete_item($item, $force = FALSE) {
   $item = is_object($item) ? get_object_vars($item) : $item;
   if ($item && ($item['module'] != 'system' || $item['updated'] || $force)) {
+    // Update records in {menu_node} before the delete.
+    _menu_node_delete($item);
     // Children get re-attached to the item's parent.
     if ($item['has_children']) {
       $result = db_query("SELECT mlid FROM {menu_links} WHERE plid = :plid", array(':plid' => $item['mlid']));
@@ -2252,6 +2254,8 @@ function menu_link_save(&$item) {
       ->execute();
     // Check the has_children status of the parent.
     _menu_update_parental_status($item);
+    // Notify the {menu_node} table of this item.
+    _menu_node_save($item);
     menu_cache_clear($menu_name);
     if ($existing_item && $menu_name != $existing_item['menu_name']) {
       menu_cache_clear($existing_item['menu_name']);
@@ -2481,6 +2485,65 @@ function _menu_update_parental_status($i
 }
 
 /**
+ * Update the {menu_node} table if a node is assigned to a menu.
+ *
+ * @param $item
+ *   The menu item being saved.
+ * @return
+ *   No return value; we fire hook_menu_node_insert() or
+ *   hook_menu_node_update() to notify modules of any changes
+ *   to the {menu_node} table.
+ */
+function _menu_node_save($item) {
+  if ($node = _menu_node_link($item)) {
+    $count = db_query("SELECT COUNT(*) FROM {menu_node} WHERE mlid = :mlid AND nid = :nid", array(':mlid' => $item['mlid'], ':nid' => $node->nid))->fetchField();
+    if ($count == 0) {
+      $record = array('mlid' => $item['mlid'], 'nid' => $node->nid);
+      drupal_write_record('menu_node', $record);
+      module_invoke_all('menu_node_insert', $item, $node);
+    }
+    else {
+      module_invoke_all('menu_node_update', $item, $node);
+    }
+  }
+}
+
+/**
+ * Delete an entry from the {menu_node} table.
+ *
+ * @param $item
+ *   The menu item being deleted.
+ * @return
+ *   No return value; we fire hook_menu_node_delete() to
+ *   notify modules of any changes to the {menu_node} table.
+ */
+function _menu_node_delete($item) {
+  if ($node = _menu_node_link($item)) {
+    module_invoke_all('menu_node_delete', $item, $node);
+    db_delete('menu_node')
+      ->condition('mlid', $item['mlid'])
+      ->condition('nid', $node->nid)
+      ->execute();
+  }
+}
+
+/**
+ * Helper function to determine if a menu link is a node.
+ *
+ * @param $item
+ *   The menu item being tested.
+ * @return
+ *   A node object if this menu item is a node, or FALSE if not.
+ */
+function _menu_node_link($item) {
+  if ($item['router_path'] == 'node/%') {
+    $path = explode('/', $item['link_path']);
+    return node_load($path[1]);
+  }
+  return FALSE;
+}
+
+/**
  * Helper function that sets the p1..p9 values for a menu link being saved.
  */
 function _menu_link_parents_set(&$item, $parent) {
Index: modules/system/system.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.install,v
retrieving revision 1.345
diff -u -p -r1.345 system.install
--- modules/system/system.install	18 Jun 2009 15:46:30 -0000	1.345
+++ modules/system/system.install	20 Jun 2009 17:21:17 -0000
@@ -1063,6 +1063,13 @@ function system_schema() {
     'primary key' => array('mlid'),
   );
 
+  $schema['menu_node'] = array(
+    'fields' => array(
+      'nid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
+      'mlid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0)),
+    'primary key' => array('nid', 'mlid'),
+  );
+
   $schema['queue'] = array(
     'description' => 'Stores items in queues.',
     'fields' => array(
@@ -3576,7 +3583,26 @@ function system_update_7028() {
   return $ret;
 }
 
-
+function system_update_7777() {
+  $ret = array();
+  $schema['menu_node'] = array(
+    'fields' => array(
+      'nid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
+      'mlid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0)),
+    'primary key' => array('nid', 'mlid'),
+  );
+  db_create_table($ret, 'menu_node', $schema['menu_node']);
+  $items = array();
+  $result = db_query("SELECT mlid, link_path FROM {menu_links} WHERE link_path LIKE 'node/%' AND router_path = 'node/%%'");
+  while ($data = db_fetch_object($result)) {
+    $nid = str_replace('node/', '', $data->link_path);
+    // Ensure that we did not grab any bad links accidentally.
+    if (is_numeric($nid)) {
+      $ret[] = update_sql("INSERT INTO {menu_node} (nid, mlid) VALUES ($data->mlid, $nid)");
+    }
+  }
+  return $ret;
+}
 
 /**
  * @} End of "defgroup updates-6.x-to-7.x"
