diff --git a/includes/menu.inc b/includes/menu.inc index 1fe5a64..6f6392b 100644 --- a/includes/menu.inc +++ b/includes/menu.inc @@ -317,7 +317,7 @@ define('MENU_PREFERRED_LINK', '1cf698d64d1aa4b83907cf6ed55db3a7f8e92c91'); * actually exists. This list of 'masks' is built in menu_rebuild(). * * @param $parts - * An array of path parts; for the above example, + * An array of path parts; for the above example, * array('node', '12345', 'edit'). * * @return @@ -2773,8 +2773,9 @@ function menu_rebuild() { try { list($menu, $masks) = menu_router_build(); - _menu_router_save($menu, $masks); - _menu_navigation_links_rebuild($menu); + $menu_needs_rebuild = _menu_router_save($menu, $masks); + _menu_navigation_links_rebuild($menu_needs_rebuild); + _menu_navigation_links_cleanup($menu); // Clear the menu, page and block caches. menu_cache_clear_all(); _menu_clear_page_cache(); @@ -2925,6 +2926,14 @@ function _menu_navigation_links_rebuild($menu) { } } } +} + +/** + * Find new router paths where necessary and delete obsolete links. + * + * @param $menu + */ +function _menu_navigation_links_cleanup($menu) { $paths = array_keys($menu); // Updated and customized items whose router paths are gone need new ones. $result = db_select('menu_links', NULL, array('fetch' => PDO::FETCH_ASSOC)) @@ -3831,6 +3840,7 @@ function _menu_router_build($callbacks) { */ function _menu_router_save($menu, $masks) { // Delete the existing router since we have some data to replace it. + $table_name = db_query_temporary('SELECT * FROM {menu_router}'); db_truncate('menu_router')->execute(); // Prepare insert object. @@ -3902,8 +3912,17 @@ function _menu_router_save($menu, $masks) { $insert->execute(); // Store the masks. variable_set('menu_masks', $masks); - - return $menu; + $query = db_select('menu_router', 'new', array('fetch' => PDO::FETCH_ASSOC)); + // Weight is not necessary but we need path in the key of the resulting array + // and using fetchAllKeyed() is the cheapest way to do it. + $query->fields('new', array('path', 'weight')); + $query->leftJoin($table_name, 'old', 'new.path = old.path'); + $or = db_or()->isNull('old.path'); + foreach (array('load_functions', 'to_arg_functions', 'access_callback', 'access_arguments', 'page_callback', 'page_arguments', 'delivery_callback', 'fit', 'number_parts', 'context', 'tab_parent', 'tab_root', 'title', 'title_callback', 'title_arguments', 'theme_callback', 'theme_arguments', 'type', 'description', 'position', 'weight', 'include_file') as $field) { + $or->where("new.$field != old.$field"); + } + $query->condition($or); + return array_intersect_key($menu, $query->execute()->fetchAllKeyed()); } /**