Index: admin_menu.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/admin_menu/admin_menu.inc,v retrieving revision 1.11 diff -u -p -r1.11 admin_menu.inc --- admin_menu.inc 26 Apr 2008 16:10:09 -0000 1.11 +++ admin_menu.inc 9 May 2008 19:13:43 -0000 @@ -40,57 +40,86 @@ function admin_menu_build($mid_admin) { * @see menu_tree_all_data() */ function admin_menu_tree_all_data() { - // chx way. 13/03/2008 sun - // $item_admin = db_fetch_array(db_query("SELECT * FROM {menu_links} WHERE link_path = 'admin' AND menu_name = 'navigation'")); $item_admin = db_fetch_array(db_query("SELECT * FROM {menu_links} WHERE router_path = 'admin'")); $item_admin = array_merge_recursive($item_admin, menu_get_item('admin')); - - // chx way. 13/03/2008 sun - // $data['tree'] = menu_tree_all_data('navigation', $item_admin); - // return $data['tree']; - - $args = $parents = array($item_admin['mlid']); - $placeholders = implode(', ', array_fill(0, count($args), '%d')); - - // Collect all links as well as all of their children. + $args = $where = array(); + $p = 1; do { - $result = db_query("SELECT mlid FROM {menu_links} WHERE menu_name = '%s' AND has_children = 1 AND plid IN (". $placeholders .') AND mlid NOT IN ('. $placeholders .')', array_merge(array($item_admin['menu_name']), $args, $args)); - $num_rows = FALSE; - while ($item = db_fetch_array($result)) { - $args[] = $item['mlid']; - $num_rows = TRUE; - } - $placeholders = implode(', ', array_fill(0, count($args), '%d')); - } while ($num_rows); - - // Build db_query arguments array. - array_unshift($args, $item_admin['menu_name']); + $where[] = "ml.p$p = %d"; + $args[] = $item_admin["p$p"]; + $p++; + } while ($p < 9 && $item_admin["p$p"] != 0); + $where[] = "ml.p$p != 0"; + $where = implode(' AND ', $where); // Until now, everything seems to be a wanted behaviour of the new menu system // in Drupal 6. However, {menu_links} does not contain any local tasks, and // because of that, it's getting crude now. - - // Select the links from the table, and recursively build the tree. We - // LEFT JOIN since there is no match in {menu_router} for an external - // link. - // Union select all local tasks from {menu_router} - // - that start with 'admin/', - // - using the mlid of the corresponding tab_parent path in {menu_links} as plid, - // - using the depth of the tab_parent path in {menu_links} + 1 as depth. - $types = array(MENU_LOCAL_TASK, MENU_DEFAULT_LOCAL_TASK); - $args = array_merge($args, $types); - $data['tree'] = menu_tree_data(db_query("( - SELECT m.load_functions, m.to_arg_functions, m.access_callback, m.access_arguments, m.page_callback, m.page_arguments, m.title, m.title_callback, m.title_arguments, m.type, ml.* + + // Poor man's locking. + if ($lock = variable_get('admin_menu_lock', 0)) { + while ($lock < time() + 10) { + sleep(1); + } + } + variable_set('admin_menu_lock', time()); + + // Clear old data. + db_query('DELETE FROM {admin_menu}'); + + // Fetch the regular, visible menu tree below 'admin/'. + // @todo Figure out which fields are actually needed for menu building and/or + // theming. Everything else can probably be ignored (doesn't need to be queried). + db_query("INSERT INTO {admin_menu} SELECT m.load_functions, m.to_arg_functions, m.access_callback, m.access_arguments, m.page_callback, m.page_arguments, m.title, m.title_callback, m.title_arguments, m.type, + ml.menu_name, ml.mlid, ml.plid, ml.link_path, ml.router_path, ml.link_title, ml.options, ml.module, ml.hidden, ml.external, ml.has_children, ml.expanded, ml.weight, ml.depth, ml.customized, ml.p1, ml.p2, ml.p3, ml.p4, ml.p5, ml.p6, ml.p7, ml.p8, ml.p9, ml.updated FROM {menu_links} ml LEFT JOIN {menu_router} m ON m.path = ml.router_path - WHERE ml.menu_name = '%s' AND ml.plid IN (". $placeholders .") - ) UNION ( - SELECT m.load_functions, m.to_arg_functions, m.access_callback, m.access_arguments, m.page_callback, m.page_arguments, m.title, m.title_callback, m.title_arguments, m.type, - ml.menu_name, ml.mlid + 100000 as mlid, ml.plid, ml.link_path, ml.router_path, m.title as link_title, ml.options, ml.module, ml.hidden, ml.external, ml.has_children, ml.expanded, ml.weight, ml.depth + 1 as depth, ml.customized, ml.p1, ml.p2, ml.p3, ml.p4, ml.p5, ml.p6, ml.p7, ml.p8, ml.p9, ml.updated - FROM {menu_router} m LEFT JOIN {menu_links} ml ON ml.router_path = m.tab_parent - WHERE ml.router_path REGEXP '[^%%]*' AND m.path LIKE 'admin/%%' AND m.type IN (". db_placeholders($types) .") - ) - ORDER BY p1 ASC, p2 ASC, p3 ASC, p4 ASC, p5 ASC, p6 ASC, p7 ASC, p8 ASC, p9 ASC", $args), $parents); - + WHERE $where", $args); + + // Fetch all local tasks from all administrative menu items using the depth + // of the tab_parent path in {menu_links} + 1 as depth. + $types = array(MENU_LOCAL_TASK, MENU_DEFAULT_LOCAL_TASK); + $result = db_query("SELECT m.load_functions, m.to_arg_functions, m.access_callback, m.access_arguments, m.page_callback, m.page_arguments, m.title, m.title_callback, m.title_arguments, m.type, + ml.menu_name, 0 AS mlid, ml.mlid AS plid, m.path as link_path, m.path as router_path, m.title as link_title, ml.options, ml.module, ml.hidden, ml.external, 0 as has_children, ml.expanded, m.weight, ml.depth + 1 as depth, ml.customized, ml.p1, ml.p2, ml.p3, ml.p4, ml.p5, ml.p6, ml.p7, ml.p8, ml.p9, ml.updated + FROM {menu_router} m + INNER JOIN {menu_links} ml ON ml.router_path = m.tab_parent + WHERE ml.hidden <> -1 AND m.type IN (". db_placeholders($types) .") AND $where", array_merge($types, $args)); + // Assign unique mlids to local tasks, and add them to the previously queried + // menu tree. + $mlid = 100000; + while ($item = db_fetch_array($result)) { + $item['mlid'] = $mlid++; + // Adjust parent id. + $item['p'. $item['depth']] = $item['mlid']; + db_query("INSERT INTO {admin_menu} VALUES ('". implode("','", array_fill(0, count($item), '%s')) ."')", $item); + } + + // Fetch secondary level local tasks. These have its parent in the + // {menu_router} table, which means we have to join the table with itself. + // The parent of the parent item is the link item from the {menu_links} table. + // The item's parent id (plid) needs to be looked up from the {admin_menu} table. + $result = db_query("SELECT m.load_functions, m.to_arg_functions, m.access_callback, m.access_arguments, m.page_callback, m.page_arguments, m.title, m.title_callback, m.title_arguments, m.type, + ml.menu_name, 0 AS mlid, am.mlid AS plid, m.path as link_path, m.path as router_path, m.title as link_title, ml.options, ml.module, ml.hidden, ml.external, 0 as has_children, ml.expanded, m.weight, am.depth + 1 as depth, ml.customized, ml.p1, ml.p2, ml.p3, ml.p4, ml.p5, ml.p6, ml.p7, ml.p8, ml.p9, ml.updated + FROM {menu_router} m + INNER JOIN {menu_router} mp ON (mp.path = m.tab_parent) + INNER JOIN {menu_links} ml ON (ml.router_path = mp.tab_parent) + INNER JOIN {admin_menu} am ON (am.link_path = m.tab_parent) + WHERE ml.hidden <> -1 AND m.type IN (". db_placeholders($types) .") AND $where", array_merge($types, $args)); + while ($item = db_fetch_array($result)) { + $item['mlid'] = $mlid++; + // Adjust parent id of the local task and its parent item. + $item['p'. ($item['depth'] - 1)] = $item['plid']; + $item['p'. $item['depth']] = $item['mlid']; + db_query("INSERT INTO {admin_menu} VALUES ('". implode("','", array_fill(0, count($item), '%s')) ."')", $item); + } + + // @todo Make adjustments to the menu tree here.... + + // Fetch all items, ordered by parent items. + $result = db_query("SELECT * FROM {admin_menu} ORDER BY p1 ASC, p2 ASC, p3 ASC, p4 ASC, p5 ASC, p6 ASC, p7 ASC, p8 ASC, p9 ASC"); + $data['tree'] = menu_tree_data($result); + + variable_del('admin_menu_lock'); + $data['node_links'] = array(); menu_tree_collect_node_links($data['tree'], $data['node_links']); Index: admin_menu.install =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/admin_menu/admin_menu.install,v retrieving revision 1.4 diff -u -p -r1.4 admin_menu.install --- admin_menu.install 24 Feb 2008 17:32:47 -0000 1.4 +++ admin_menu.install 9 May 2008 20:13:02 -0000 @@ -1,6 +1,52 @@ uid:$language->language should be sufficient $cid = 'links:admin_menu:all:admin:'. $user->uid .':'. $language->language; - $cache = 0; // cache_get($cid, 'cache_menu'); + $cache = cache_get($cid, 'cache_menu'); if ($cache && isset($cache->data)) { $_admin_menu = $cache->data; } else { require_once drupal_get_path('module', 'admin_menu') .'/admin_menu.inc'; $_admin_menu = admin_menu_build($mid_admin); - // cache_set($cid, $_admin_menu, 'cache_menu', 0); + cache_set($cid, $_admin_menu, 'cache_menu', 0); } return $_admin_menu; @@ -181,7 +182,7 @@ function admin_menu_tree_output($tree) { // Pull out just the menu items we are going to render so that we // get an accurate count for the first/last classes. foreach ($tree as $data) { - if (!$data['link']['hidden']) { + if ($data['link']['hidden'] != -1) { $items[] = $data; } } @@ -356,7 +357,7 @@ function admin_menu_admin_menu(&$admin_m function admin_menu_form_alter(&$form, $form_state, $form_id) { if ($form_id == 'devel_admin_settings') { // Shift system_settings_form buttons. - $weight = $form['buttons']['#weight']; + $weight = isset($form['buttons']['#weight']) ? $form['buttons']['#weight'] : 0; $form['buttons']['#weight'] = $weight + 1; $form['admin_menu'] = array(