? 457450-menu-objects.patch
? test.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	22 Jun 2009 00:01:40 -0000
@@ -2065,6 +2065,9 @@ function _menu_delete_item($item, $force
     // Update the has_children status of the parent.
     _menu_update_parental_status($item);
     menu_cache_clear($item['menu_name']);
+    // Notify modules we have deleted the item.
+    module_invoke_all('menu_item_delete', $item);
+    // Clear the cache.
     _menu_clear_page_cache();
   }
 }
@@ -2105,7 +2108,16 @@ function menu_link_save(&$item) {
     'module' => 'menu',
     'customized' => 0,
     'updated' => 0,
+    'object_type' => '',
+    'object_id' => '',
   );
+  // Get the object type by reference.
+  if (empty($item['object_type'])) {
+    foreach(module_implements('menu_object') as $module) { 
+      $hook = $module . '_menu_object';
+      $hook($item);
+    }
+  }
   $existing_item = FALSE;
   if (isset($item['mlid'])) {
     if ($existing_item = db_query("SELECT * FROM {menu_links} WHERE mlid = :mlid", array(':mlid' => $item['mlid']))->fetchAssoc()) {
@@ -2176,6 +2188,8 @@ function menu_link_save(&$item) {
         'options' => serialize($item['options']),
         'customized' => $item['customized'],
         'updated' => $item['updated'],
+        'object_type' => $item['object_type'],
+        'object_id' => $item['object_id'],
       ))
       ->execute();
   }
@@ -2247,6 +2261,8 @@ function menu_link_save(&$item) {
         'link_title' => $item['link_title'],
         'options' => serialize($item['options']),
         'customized' => $item['customized'],
+        'object_type' => $item['object_type'],
+        'object_id' => $item['object_id'],
       ))
       ->condition('mlid', $item['mlid'])
       ->execute();
@@ -2257,6 +2273,10 @@ function menu_link_save(&$item) {
       menu_cache_clear($existing_item['menu_name']);
     }
 
+    // Notify modules we have acted on a menu item.
+    ($existing_item) ? $hook = 'menu_item_update' : $hook = 'menu_item_insert';
+    module_invoke_all($hook, $item);
+
     _menu_clear_page_cache();
   }
   return $item['mlid'];
Index: modules/menu/menu.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/menu/menu.module,v
retrieving revision 1.192
diff -u -p -r1.192 menu.module
--- modules/menu/menu.module	27 May 2009 18:33:58 -0000	1.192
+++ modules/menu/menu.module	22 Jun 2009 00:01:41 -0000
@@ -304,6 +304,8 @@ function menu_node_insert($node) {
     elseif (trim($item['link_title'])) {
       $item['link_title'] = trim($item['link_title']);
       $item['link_path'] = "node/$node->nid";
+      $item['object_type'] = 'node';
+      $item['object_id'] = $node->nid;
       if (!$item['customized']) {
         $item['options']['attributes']['title'] = trim($node->title);
       }
Index: modules/node/node.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/node/node.module,v
retrieving revision 1.1071
diff -u -p -r1.1071 node.module
--- modules/node/node.module	18 Jun 2009 21:19:02 -0000	1.1071
+++ modules/node/node.module	22 Jun 2009 00:01:46 -0000
@@ -3219,3 +3219,18 @@ function node_requirements($phase) {
   );
   return $requirements;
 }
+
+/**
+ * Implement hook_menu_object().
+ */
+function node_menu_object(&$item) {
+  $data = explode('/', $item['link_path']);
+  if ($data[0] != 'node' || !is_numeric($data[1])) {
+    return;
+  }
+  $node = node_load($data[1]);
+  if (!empty($node->nid)) {
+    $item['object_type'] = 'node';
+    $item['object_id'] = $node->nid;
+  }
+}
Index: modules/system/system.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.install,v
retrieving revision 1.346
diff -u -p -r1.346 system.install
--- modules/system/system.install	21 Jun 2009 05:18:44 -0000	1.346
+++ modules/system/system.install	22 Jun 2009 00:01:51 -0000
@@ -1053,12 +1053,27 @@ function system_schema() {
         'default' => 0,
         'size' => 'small',
       ),
+      'object_type' => array(
+        'description' => 'An object type identifier for connecting menu items to external systems.',
+        'type' => 'varchar',
+        'length' => 255,
+        'not null' => TRUE,
+        'default' => '',
+      ),
+      'object_id' => array(
+        'description' => 'A foreign key for objects stored in external systems.',
+        'type' => 'varchar',
+        'length' => 255,
+        'not null' => TRUE,
+        'default' => '',
+      ),
     ),
     'indexes' => array(
       'path_menu' => array(array('link_path', 128), 'menu_name'),
       'menu_plid_expand_child' => array('menu_name', 'plid', 'expanded', 'has_children'),
       'menu_parents' => array('menu_name', 'p1', 'p2', 'p3', 'p4', 'p5', 'p6', 'p7', 'p8', 'p9'),
       'router_path' => array(array('router_path', 128)),
+      'object' => array('object_type', 'object_id'),
     ),
     'primary key' => array('mlid'),
   );
@@ -3576,7 +3591,16 @@ function system_update_7028() {
   return $ret;
 }
 
-
+/**
+ * Add foreign object tracking data to {menu_links}.
+ */
+function system_update_7029() {
+  $ret = array();
+  db_add_field($ret, 'menu_links', 'object_type', array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''));
+  db_add_field($ret, 'menu_links', 'object_id', array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''));
+  db_add_index($ret, 'menu_links', 'object', array('object_type', 'object_id'));
+  return $ret;
+}
 
 /**
  * @} End of "defgroup updates-6.x-to-7.x"
