diff -u b/includes/menu.inc b/includes/menu.inc --- b/includes/menu.inc +++ b/includes/menu.inc @@ -2895,11 +2895,7 @@ array_multisort($sort, SORT_NUMERIC, $menu_links); foreach ($menu_links as $key => $item) { - $existing_item = db_select('menu_links') - ->fields('menu_links') - ->condition('link_path', $item['path']) - ->condition('module', 'system') - ->execute()->fetchAssoc(); + $existing_item = empty($item['_existing_item']) ? _menu_rebuild_get_existing_item($item['path']) : $item['_existing_item']; if ($existing_item) { $item['mlid'] = $existing_item['mlid']; // A change in hook_menu may move the link to a different menu @@ -2929,6 +2925,21 @@ } /** + * Gets an existing item for rebuild purposes. + * + * @param $path + * + * @return bool + */ +function _menu_rebuild_get_existing_item($path) { + return db_select('menu_links') + ->fields('menu_links') + ->condition('link_path', $path) + ->condition('module', 'system') + ->execute()->fetchAssoc(); +} + +/** * Find new router paths where necessary and delete obsolete links. * * @param $menu @@ -3618,6 +3629,13 @@ $masks = array(); $link_fields = array_flip(drupal_schema_fields_sql('menu_links')); unset($link_fields['weight'], $link_fields['module']); + $link_field_defaults = array( + 'node' => array('menu_name' => 'navigation'), + 'admin' => array('menu_name' => 'management'), + 'user' => array('menu_name' => 'user-menu'), + 'user/logout' => array('menu_name' => 'user-menu'), + 'user/%user' => array('menu_name' => 'navigation'), + ); foreach ($callbacks as $path => $item) { $load_functions = array(); $to_arg_functions = array(); @@ -3680,12 +3698,24 @@ '_number_parts' => $number_parts, '_parts' => $parts, '_fit' => $fit, - '_keep' => count(array_intersect_key($item, $link_fields)), + '_keep' => FALSE, ); $item += array( '_visible' => (bool) ($item['type'] & MENU_VISIBLE_IN_BREADCRUMB), '_tab' => (bool) ($item['type'] & MENU_IS_LOCAL_TASK), ); + $link_fields_set = array_intersect_key($item, $link_fields); + if ($link_fields_set) { + if (isset($link_field_defaults[$path]) && $link_fields_set === $link_field_defaults[$path]) { + // Nothing to be done. + } + elseif ($item['_existing_item'] = _menu_rebuild_get_existing_item($path)) { + $item['_keep'] = (bool) array_diff_assoc($link_fields_set, $item['_existing_item']); + } + elseif ($item['_visible']) { + $item['_keep'] = TRUE; + } + } if ($move) { $new_path = implode('/', $item['_parts']); $menu[$new_path] = $item; @@ -3728,6 +3758,9 @@ } // If the parent item defines a menu name, inherit it. if (!empty($parent['menu_name'])) { + if (!empty($parent['_keep'])) { + $item['_keep'] = TRUE; + } $item['menu_name'] = $parent['menu_name']; } }