? multiple_menus_0.patch ? separate_menu_tables_1.patch ? includes/foo_menu.inc ? sites/rosalind.local Index: includes/menu.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/menu.inc,v retrieving revision 1.162 diff -u -p -r1.162 menu.inc --- includes/menu.inc 15 Apr 2007 14:38:16 -0000 1.162 +++ includes/menu.inc 22 Apr 2007 04:33:27 -0000 @@ -313,7 +313,7 @@ function menu_get_item($path = NULL, $it // behaviour. The last parent is always the item itself. $args = explode(',', $item->parents); $placeholders = implode(', ', array_fill(0, count($args), '%d')); - $result = db_query('SELECT * FROM {menu} WHERE mid IN ('. $placeholders .') ORDER BY mleft', $args); + $result = db_query('SELECT * FROM {menu_links} WHERE mid IN ('. $placeholders .') ORDER BY mleft', $args); $item->access = TRUE; while ($item->access && ($parent = db_fetch_object($result))) { $map = _menu_translate($parent, $original_map); @@ -582,6 +582,30 @@ function menu_get_active_help() { return $output; } + +/** + * Build a list of named menus. + */ + +function menu_get_names($reset = FALSE) { + $names = module_invoke_all('menu_info'); + $names['navigation'] = array('customize' => TRUE, 'title' => t('Navigation'), 'title callback' => 'check_plain', 'callback arguments' => array('$user->name')); + + foreach ($names as $key => $data) { + if (!isset($data['customize'])) { + $names[$key]['customize'] = TRUE; + } + if (!isset($data['title callback'])) { + $names[$key]['title callback'] = FALSE; + } + if (!isset($data['callback arguments'])) { + $names[$key]['callback arguments'] = array(); + } + } + return $names; +} + + function menu_path_is_external($path) { $colonpos = strpos($path, ':'); return $colonpos !== FALSE && !preg_match('![/?#]!', substr($path, 0, $colonpos)) && filter_xss_bad_protocol($path, FALSE) == check_plain($path); @@ -593,10 +617,18 @@ function menu_path_is_external($path) { function menu_rebuild() { // TODO: split menu and menu links storage. $menu = module_invoke_all('menu'); + $names = menu_get_names(TRUE); + foreach ($menu as $path => $item) { + if (!isset($item['menu name']) || !isset($names[$item['menu name']])) { + $menu[$path]['menu name'] = 'navigation'; + } + } + // Alter the menu as defined in modules, keys are like user/%user. drupal_alter('menu', $menu, MENU_ALTER_MODULE_DEFINED); db_query('DELETE FROM {menu}'); + db_query('DELETE FROM {menu_links}'); $mid = 1; // First pass: separate callbacks from pathes, making pathes ready for @@ -843,30 +875,39 @@ function menu_rebuild() { $item['_visible'] = FALSE; } db_query("INSERT INTO {menu} ( - mid, pid, path, load_functions, to_arg_functions, + path, load_functions, to_arg_functions, access_callback, access_arguments, page_callback, page_arguments, fit, - number_parts, visible, parents, depth, has_children, tab, title, parent, - type, mleft, mright, block_callback, description, position, - link_path, attributes, query, fragment, absolute, html) - VALUES (%d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, %d, - '%s', %d, %d, %d, '%s', '%s', '%s', %d, %d, '%s', '%s', '%s', - '%s', '%s', '%s', '%s', %d, %d)", - $item['_mid'], $item['_pid'], $path, $item['load_functions'], + number_parts, parent,tab_depth, title, + type, block_callback, description, position) + VALUES ('%s', '%s', '%s', + '%s', '%s', '%s', '%s', %d, + %d, '%s', %d, '%s', + %d, '%s', '%s', '%s')", + $path, $item['load_functions'], $item['to_arg_functions'], $item['access callback'], serialize($item['access arguments']), $item['page callback'], serialize($item['page arguments']), $item['_fit'], - $item['_number_parts'], $item['_visible'], $item['_parents'], - $item['_depth'], $has_children, $item['_tab'], - $item['title'], $item['parent'], $item['type'], $item['_mleft'], - $item['_mright'], $item['block callback'], $item['description'], - $item['position'], $link_path, + $item['_number_parts'], $item['parent'], $item['_tab'] ? $item['_depth'] : 0, + $item['title'],$item['type'], $item['block callback'], $item['description'], $item['position']); + db_query("INSERT INTO {menu_links} ( + menu_name, mid, pid, path, visible, + parents, depth, has_children, + mleft, mright, description, + link_path, attributes, query, fragment, absolute, html) + VALUES ('%s', %d, %d, '%s', %d, + '%s', %d, %d, + %d, %d, '%s', + '%s', '%s', '%s', '%s', %d, %d)", + $item['menu name'], $item['_mid'], $item['_pid'], $path, $item['_visible'], + $item['_parents'], + $item['_depth'], $has_children, + $item['_mleft'], $item['_mright'], $item['description'], + $link_path, $item['attributes'], $item['query'], $item['fragment'], $item['absolute'], $item['html']); } } - - function menu_renumber(&$tree) { foreach ($tree as $key => $element) { if (!isset($tree[$key]['_mleft'])) { @@ -923,20 +964,20 @@ function menu_local_tasks($level = 0) { continue; } // This loads all the tabs. - $result = db_query("SELECT * FROM {menu} WHERE parent = '%s' AND tab = 1 ORDER BY mleft", $parent); + $result = db_query("SELECT * FROM {menu} WHERE parent = '%s' AND tab_depth != 0", $parent); // ORDER BY mleft $tabs_current = ''; while ($item = db_fetch_object($result)) { // This call changes the path from for example user/% to user/123 and // also determines whether we are allowed to access it. _menu_translate($item, $map, MENU_RENDER_LINK); if ($item->access) { - $depth = $item->depth; + $depth = $item->tab_depth; $link = l($item->title, $item->link_path, (array)$item); // We check for the active tab. - if ($item->path == $router_item->path || (!$router_item->tab && $item->type == MENU_DEFAULT_LOCAL_TASK)) { + if ($item->path == $router_item->path || (!$router_item->tab_depth && $item->type == MENU_DEFAULT_LOCAL_TASK)) { $tabs_current .= theme('menu_local_task', $link, TRUE); // Let's try to find the router item one level up. - $next_router_item = db_fetch_object(db_query("SELECT path, tab, parent FROM {menu} WHERE path = '%s'", $item->parent)); + $next_router_item = db_fetch_object(db_query("SELECT path, tab_depth, parent FROM {menu} WHERE path = '%s'", $item->parent)); // We will need to inspect one level down. $parents[] = $item->path; } @@ -1008,7 +1049,7 @@ function menu_get_active_title() { * rendering. */ function menu_get_item_by_mid($mid) { - if ($item = db_fetch_object(db_query('SELECT * FROM {menu} WHERE mid = %d', $mid))) { + if ($item = db_fetch_object(db_query('SELECT * FROM {menu_links} WHERE mid = %d', $mid))) { _menu_translate($item, arg(), MENU_RENDER_LINK); if ($item->access) { return $item; Index: modules/system/system.install =================================================================== RCS file: /cvs/drupal/drupal/modules/system/system.install,v retrieving revision 1.94 diff -u -p -r1.94 system.install --- modules/system/system.install 17 Apr 2007 08:13:11 -0000 1.94 +++ modules/system/system.install 22 Apr 2007 04:33:28 -0000 @@ -324,8 +324,6 @@ function system_install() { ) /*!40100 DEFAULT CHARACTER SET UTF8 */ "); db_query("CREATE TABLE {menu} ( - mid int NOT NULL default 0, - pid int NOT NULL default 0, path varchar(255) NOT NULL default '', load_functions varchar(255) NOT NULL default '', to_arg_functions varchar(255) NOT NULL default '', @@ -335,32 +333,40 @@ function system_install() { page_arguments text, fit int NOT NULL default 0, number_parts int NOT NULL default 0, - mleft int NOT NULL default 0, - mright int NOT NULL default 0, - visible int NOT NULL default 0, - parents varchar(255) NOT NULL default '', - depth int NOT NULL default 0, - has_children int NOT NULL default 0, - tab int NOT NULL default 0, + parent varchar(255) NOT NULL default '', + tab_depth int NOT NULL default 0, title varchar(255) NOT NULL default '', title_callback varchar(255) NOT NULL default '', title_arguments varchar(255) NOT NULL default '', - parent varchar(255) NOT NULL default '', type int NOT NULL default 0, block_callback varchar(255) NOT NULL default '', description varchar(255) NOT NULL default '', position varchar(255) NOT NULL default '', + PRIMARY KEY (path), + KEY fit (fit) + ) /*!40100 DEFAULT CHARACTER SET UTF8 */ "); + + db_query("CREATE TABLE {menu_links} ( + menu_name varchar(64) NOT NULL default '', + mid int NOT NULL default 0, + pid int NOT NULL default 0, + path varchar(255) NOT NULL default '', + visible int NOT NULL default 0, + mleft int NOT NULL default 0, + mright int NOT NULL default 0, + parents varchar(255) NOT NULL default '', + depth int NOT NULL default 0, + has_children int NOT NULL default 0, + description varchar(255) NOT NULL default '', link_path varchar(255) NOT NULL default '', attributes varchar(255) NOT NULL default '', query varchar(255) NOT NULL default '', fragment varchar(255) NOT NULL default '', absolute INT NOT NULL default 0, html INT NOT NULL default 0, - PRIMARY KEY (path), - KEY fit (fit), + PRIMARY KEY (menu_name, path), KEY visible (visible), - KEY pid (pid), - KEY parent (parent) + KEY pid (pid) ) /*!40100 DEFAULT CHARACTER SET UTF8 */ "); db_query("CREATE TABLE {node} (