Index: includes/menu.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/menu.inc,v retrieving revision 1.413 diff -u -p -r1.413 menu.inc --- includes/menu.inc 3 Oct 2010 23:29:09 -0000 1.413 +++ includes/menu.inc 7 Oct 2010 04:55:15 -0000 @@ -2890,24 +2890,22 @@ function menu_link_save(&$item) { } } - // If we have a parent link ID, we use it to inherit 'menu_name' and 'depth'. + // If this link defines a parent link id, try to find it in the current menu + // links. If found, we use it for the re-parenting process below. This parent + // link validation also needs to be done for links specifying a plid of 0 + // (zero), since {menu_links} may contain stale/bogus data caused by a + // re-parenting process that went wrong in a previous rebuild. if (isset($item['plid'])) { - if ($item['plid']) { - $parent = db_query("SELECT * FROM {menu_links} WHERE mlid = :mlid", array(':mlid' => $item['plid']))->fetchAssoc(); - } - // If the parent link ID is zero, then this link lives at the top-level. - else { - $parent = FALSE; - } + $parent = db_query("SELECT * FROM {menu_links} WHERE mlid = :mlid", array(':mlid' => $item['plid']))->fetchAssoc(); } - // Otherwise, try to find a valid parent link for this link. - else { + // If no plid was specified or it was not found, try to find a new, valid + // parent link for this link. Only do this if this is a menu link provided + // through hook_menu(). We can not guess the parent for menu items added + // through the UI or modules since we can not assume that they are parented + // by their path. + if (empty($parent) && $item['module'] == 'system') { $query = db_select('menu_links'); - // Only links derived from router items should have module == 'system', and - // we want to find the parent even if it's in a different menu. - if ($item['module'] == 'system') { - $query->condition('module', 'system'); - } + $query->condition('module', 'system'); // We always respect the link's 'menu_name'; inheritance for router items is // ensured in _menu_router_build(). $query->condition('menu_name', $item['menu_name']); Index: modules/menu/menu.test =================================================================== RCS file: /cvs/drupal/drupal/modules/menu/menu.test,v retrieving revision 1.41 diff -u -p -r1.41 menu.test --- modules/menu/menu.test 24 Sep 2010 00:37:43 -0000 1.41 +++ modules/menu/menu.test 7 Oct 2010 04:55:16 -0000 @@ -609,7 +609,7 @@ class MenuNodeTestCase extends DrupalWeb // Change default parent item to Navigation menu, so we can assert more // easily. $edit = array( - 'menu_parent' => 'navigation:0', + 'menu_parent' => 'main-menu:0', ); $this->drupalPost('admin/structure/types/manage/page', $edit, t('Save content type')); Index: modules/simpletest/tests/upgrade/upgrade.test =================================================================== RCS file: /cvs/drupal/drupal/modules/simpletest/tests/upgrade/upgrade.test,v retrieving revision 1.8 diff -u -p -r1.8 upgrade.test --- modules/simpletest/tests/upgrade/upgrade.test 1 Oct 2010 18:37:22 -0000 1.8 +++ modules/simpletest/tests/upgrade/upgrade.test 7 Oct 2010 04:55:16 -0000 @@ -381,5 +381,9 @@ class BasicUpgradePath extends UpgradePa $this->assertText(t('Reports')); $this->assertText(t('Structure')); $this->assertText(t('Modules')); + + // Confirm that no {menu_links} entry exists for user/autocomplete. + $result = db_query('SELECT COUNT(*) FROM {menu_links} WHERE link_path = :user_autocomplete', array(':user_autocomplete' => 'user/autocomplete'))->fetchField(); + $this->assertFalse($result, t('No {menu_links} entry exists for user/autocomplete')); } }