diff options
Diffstat (limited to 'includes')
-rw-r--r-- | includes/install.inc | 26 | ||||
-rw-r--r-- | includes/menu.inc | 65 |
2 files changed, 68 insertions, 23 deletions
diff --git a/includes/install.inc b/includes/install.inc index 6d273bac8..8676b03bc 100644 --- a/includes/install.inc +++ b/includes/install.inc @@ -353,6 +353,32 @@ function drupal_install_modules($module_list = array()) { function drupal_uninstall_module($module) { module_load_install($module); module_invoke($module, 'uninstall'); + + // Remove menu links for paths declared by this module. + drupal_load('module', $module); + $paths = module_invoke($module, 'menu'); + if (!empty($paths)) { + $paths = array_keys($paths); + // Clean out the names of load functions. + foreach($paths as $index => $path) { + $parts = explode('/', $path, MENU_MAX_PARTS); + foreach ($parts as $k => $part) { + if (preg_match('/^%[a-z_]*$/', $part)) { + $parts[$k] = '%'; + } + } + $paths[$index] = implode('/', $parts); + } + $placeholders = implode(', ', array_fill(0, count($paths), "'%s'")); + + $result = db_query('SELECT * FROM {menu_links} WHERE router_path IN ('. $placeholders .') AND external = 0 ORDER BY depth DESC', $paths); + // Remove all such items. Starting from those with the greatest depth will + // minimize the amount of re-parenting done by menu_link_delete(). + while ($item = db_fetch_array($result)) { + _menu_delete_item($item, TRUE); + } + } + drupal_set_installed_schema_version($module, SCHEMA_UNINSTALLED); } diff --git a/includes/menu.inc b/includes/menu.inc index 0c7a2a928..087fa793f 100644 --- a/includes/menu.inc +++ b/includes/menu.inc @@ -363,10 +363,10 @@ function _menu_load_objects($item, &$map) { function _menu_check_access(&$item, $map) { // Determine access callback, which will decide whether or not the current // user has access to this path. - $callback = trim($item['access_callback']); + $callback = empty($item['access_callback']) ? 0 : trim($item['access_callback']); // Check for a TRUE or FALSE value. if (is_numeric($callback)) { - $item['access'] = $callback; + $item['access'] = (bool)$callback; } else { $arguments = menu_unserialize($item['access_arguments'], $map); @@ -1457,13 +1457,12 @@ function _menu_navigation_links_rebuild($menu) { } } } - $placeholders = implode(', ', array_fill(0, count($menu), "'%s'")); - // Find any items where their router path does not exist any more. - $result = db_query('SELECT * FROM {menu_links} WHERE router_path NOT IN ('. $placeholders .') AND external = 0 ORDER BY depth DESC', array_keys($menu)); - // Remove all such items. Starting from those with the greatest depth will - // minimize the amount of re-parenting done by menu_link_delete(). + $result = db_query("SELECT ml.link_path, ml.mlid, ml.router_path FROM {menu_links} ml WHERE ml.updated = 1"); while ($item = db_fetch_array($result)) { - _menu_delete_item($item, TRUE); + $router_path = _menu_find_router_path($menu, $item['link_path']); + if (!empty($router_path) && $router_path != $item['router_path']) { + db_query("UPDATE {menu_links} SET router_path = '%s' WHERE mlid = %d", $router_path, $item['mlid']); + } } } @@ -1548,6 +1547,7 @@ function menu_link_save(&$item) { 'options' => array(), 'module' => 'menu', 'customized' => 0, + 'updated' => 0, ); $menu_name = $item['menu_name']; $existing_item = FALSE; @@ -1580,15 +1580,17 @@ function menu_link_save(&$item) { menu_name, plid, link_path, hidden, external, has_children, expanded, weight, - module, link_title, options, customized) VALUES ( + module, link_title, options, + customized, updated) VALUES ( '%s', %d, '%s', %d, %d, %d, %d, %d, - '%s', '%s', '%s', %d)", + '%s', '%s', '%s', %d, %d)", $item['menu_name'], $item['plid'], $item['link_path'], $item['hidden'], $item['_external'], $item['has_children'], $item['expanded'], $item['weight'], - $item['module'], $item['link_title'], serialize($item['options']), $item['customized']); + $item['module'], $item['link_title'], serialize($item['options']), + $item['customized'], $item['updated']); $item['mlid'] = db_last_insert_id('menu_links', 'mlid'); } @@ -1617,24 +1619,16 @@ function menu_link_save(&$item) { if ($existing_item && ($item['plid'] != $existing_item['plid'] || $menu_name != $existing_item['menu_name'])) { _menu_link_move_children($item, $existing_item); } - // Find the callback. - if (empty($item['router_path']) || !$existing_item || ($existing_item['link_path'] != $item['link_path'])) { + // Find the callback. During the menu update we store empty paths to be + // fixed later, so we skip this. + if (!isset($_SESSION['system_update_6021']) && (empty($item['router_path']) || !$existing_item || ($existing_item['link_path'] != $item['link_path']))) { if ($item['_external']) { $item['router_path'] = ''; } else { // Find the router path which will serve this path. $item['parts'] = explode('/', $item['link_path'], MENU_MAX_PARTS); - $item['router_path'] = $item['link_path']; - if (!isset($menu[$item['router_path']])) { - list($ancestors) = menu_get_ancestors($item['parts']); - while ($ancestors && (empty($menu[$item['router_path']]))) { - $item['router_path'] = array_shift($ancestors); - } - } - if (empty($item['router_path'])) { - return FALSE; - } + $item['router_path'] = _menu_find_router_path($menu, $item['link_path']); } } db_query("UPDATE {menu_links} SET menu_name = '%s', plid = %d, link_path = '%s', @@ -1664,6 +1658,31 @@ function menu_link_save(&$item) { } /** + * Find the router path which will serve this path. + * + * @param $menu + * The full built menu. + * @param $link_path + * The path for we are looking up its router path. + * @return + * A path from $menu keys or empty if $link_path points to a nonexisting + * place. + */ + function _menu_find_router_path($menu, $link_path) { + $parts = explode('/', $link_path, MENU_MAX_PARTS); + $router_path = $link_path; + if (!isset($menu[$router_path])) { + list($ancestors) = menu_get_ancestors($parts); + $ancestors[] = ''; + while ($ancestors && (empty($menu[$router_path]))) { + $router_path = array_shift($ancestors); + } + } + return $router_path; +} + + +/** * Find the depth of an item's children relative to its depth. * * For example, if the item has a depth of 2, and the maximum of any child in |