Index: admin_menu.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/admin_menu/admin_menu.inc,v retrieving revision 1.9 diff -u -p -r1.9 admin_menu.inc --- admin_menu.inc 24 Feb 2008 03:56:09 -0000 1.9 +++ admin_menu.inc 13 Mar 2008 18:29:18 -0000 @@ -19,42 +19,89 @@ function admin_menu_build($mid_admin) { global $_menu; $_admin_menu = array(); - // Temporary access permission fix for root menu items until #126621 is - // committed to Drupal core. - foreach ($_menu['items'][$mid_admin]['children'] as $key => $parent) { - if ($_menu['items'][$parent]['access'] != FALSE || !isset($_menu['items'][$parent]['children'])) { - continue; - } - $is_accessible = FALSE; - foreach ($_menu['items'][$parent]['children'] as $key => $child) { - if ($_menu['items'][$child]['access'] == TRUE) { - $is_accessible = TRUE; - } - } - if ($is_accessible) { - $_menu['items'][$parent]['access'] = TRUE; - } - } - - // Copy admin menu items into a new menu tree. - $_admin_menu['index'] = $_menu['path index']; - $_admin_menu[$mid_admin] = $_menu['items'][$mid_admin]; - admin_menu_item_url($_admin_menu, $mid_admin); - _admin_menu_get_children($_admin_menu, $_admin_menu[$mid_admin]); + // Retrieve the full menu structure. + $_admin_menu = admin_menu_tree_all_data(); // Adjust some menu items for better user experience. - admin_menu_adjust_items($_admin_menu); + #admin_menu_adjust_items($_admin_menu); // Allow other modules to integrate with admin_menu. foreach (module_implements('admin_menu') as $module) { $function = $module .'_admin_menu'; - $function($_admin_menu, TRUE); + #$function($_admin_menu, TRUE); } return $_admin_menu; } /** + * Get the data structure representing the administrative menu tree. + * + * @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')); +// $data['tree'] = menu_tree_all_data('navigation', $item_admin); +// return $data['tree']; + + $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')); + + $args = $parents = array($item_admin['mlid']); + $placeholders = implode(', ', array_fill(0, count($args), '%d')); + + // Collect all links as well as all of their children. + 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']); + + // 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.* + 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); + + $data['node_links'] = array(); + menu_tree_collect_node_links($data['tree'], $data['node_links']); + + // Check access for the current user to each item in the tree. + menu_tree_check_access($data['tree'], $data['node_links']); + + return $data['tree']; +} + +/** * Recursively adds items to the administration menu. * * Any accessible menu items are added, including local tasks. @@ -130,7 +177,7 @@ function admin_menu_adjust_items(&$_admi $_admin_menu['index']['admin_menu_icon'] = $mid_icon; // Add 'administer' item to the icon menu. - $mid_icon_admin = admin_menu_add_item($_admin_menu, $mid_icon, array('title' => t('Administer'), 'path' => 'admin', 'weight' => 10)); + $mid_icon_admin = admin_menu_add_item($_admin_menu, $mid_icon, array('title' => 'Administer', 'path' => 'admin', 'weight' => 10)); // ...and reset 'administer' menu item id in path index. $_admin_menu['index']['admin'] = $mid_admin; @@ -147,19 +194,19 @@ function admin_menu_adjust_items(&$_admi admin_menu_remove_item($_admin_menu, 'admin/by-task'); // Add system update links. - admin_menu_add_item($_admin_menu, $mid_icon, array('title' => t('Run cron'), 'path' => 'admin/logs/status/run-cron', 'weight' => 50, 'query' => drupal_get_destination())); + admin_menu_add_item($_admin_menu, $mid_icon, array('title' => 'Run cron', 'path' => 'admin/reports/status/run-cron', 'weight' => 50, 'query' => drupal_get_destination())); if ($user->uid == 1) { - admin_menu_add_item($_admin_menu, $mid_icon, array('title' => t('Run updates'), 'path' => $base_url .'/update.php', 'weight' => 50)); + admin_menu_add_item($_admin_menu, $mid_icon, array('title' => 'Run updates', 'path' => $base_url .'/update.php', 'weight' => 50)); } // Add links to drupal.org. if (user_access('display drupal links')) { - $mid_drupal = admin_menu_add_item($_admin_menu, $mid_icon, array('title' => t('Drupal.org'), 'path' => 'http://drupal.org', 'weight' => 100)); - admin_menu_add_item($_admin_menu, $mid_drupal, array('title' => t('Drupal issue queue'), 'path' => 'http://drupal.org/project/issues/drupal')); + $mid_drupal = admin_menu_add_item($_admin_menu, $mid_icon, array('title' => 'Drupal.org', 'path' => 'http://drupal.org', 'weight' => 100)); + admin_menu_add_item($_admin_menu, $mid_drupal, array('title' => 'Drupal issue queue', 'path' => 'http://drupal.org/project/issues/drupal')); // Add links to project issue queues. foreach (module_list(FALSE, FALSE, TRUE) as $module) { - $info = _module_parse_info_file(drupal_get_path('module', $module) .'/'. $module .'.info'); + $info = drupal_parse_info_file(drupal_get_path('module', $module) .'/'. $module .'.info'); if (isset($info['project']) && $info['project'] == 'drupal') { continue; } @@ -167,7 +214,7 @@ function admin_menu_adjust_items(&$_admi // Filter project versions via query string not yet supported. // @see http://drupal.org/node/97569 // $url .= !empty($info['version']) ? '/'. $info['version'] : ''; - admin_menu_add_item($_admin_menu, $mid_drupal, array('title' => t('@title issue queue', array('@title' => $info['name'])), 'path' => $url)); + admin_menu_add_item($_admin_menu, $mid_drupal, array('title' => '@title issue queue', 'title arguments' => array('@title' => $info['name']), 'path' => $url)); } } @@ -175,7 +222,8 @@ function admin_menu_adjust_items(&$_admi if ($user->uid > 0) { $mid_logout = $_menu['path index']['logout']; admin_menu_add_item($_admin_menu, $mid_admin, array( - 'title' => t('Logout @name', array('@name' => $user->name)), + 'title' => 'Logout @name', + 'title arguments' => array('@name' => $user->name), 'path' => $_menu['items'][$mid_logout]['path'], 'weight' => -100, 'class' => 'admin-menu-action admin-menu-logout', @@ -197,7 +245,7 @@ function admin_menu_adjust_items(&$_admi $mid_content = $_admin_menu['index']['admin/content/node']; } $mid_node_add = $_menu['path index']['node/add']; - admin_menu_copy_items($_admin_menu, $mid_node_add, $mid_content, t('Add !title')); + admin_menu_copy_items($_admin_menu, $mid_node_add, $mid_content, 'Add @title'); } /** @@ -228,7 +276,8 @@ function admin_menu_copy_items(&$_admin_ continue; } if (isset($title)) { - $item['title'] = check_plain(strtr($title, array('!title' => $_menu['items'][$mid]['title']))); + $item['title'] = $title; + $item['title arguments'] = array('@title' => $_menu['items'][$mid]['title']); } // Only add child to target if it does not already exist. if (!in_array($mid, $_admin_menu[$target_pid]['children'])) { Index: admin_menu.info =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/admin_menu/admin_menu.info,v retrieving revision 1.4 diff -u -p -r1.4 admin_menu.info --- admin_menu.info 2 Dec 2007 07:39:17 -0000 1.4 +++ admin_menu.info 9 Dec 2007 00:42:29 -0000 @@ -2,3 +2,4 @@ name = "Administration Menu" description = "Renders a menu tree for administrative purposes as dropdown menu at the top of the window." package = "Administration" +core = 6.x Index: admin_menu.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/admin_menu/admin_menu.module,v retrieving revision 1.40 diff -u -p -r1.40 admin_menu.module --- admin_menu.module 24 Feb 2008 03:56:09 -0000 1.40 +++ admin_menu.module 13 Mar 2008 18:26:33 -0000 @@ -14,8 +14,8 @@ /** * Implementation of hook_help(). */ -function admin_menu_help($section) { - switch ($section) { +function admin_menu_help($path, $arg) { + switch ($path) { case 'admin/modules#description': return t('Renders the administer menu tree as dropdown menu at the top of the window.'); case 'admin/settings/admin_menu': @@ -48,31 +48,45 @@ function admin_menu_perm() { } /** - * Implementation of hook_menu(). + * Implementation of hook_theme(). + */ +function admin_menu_theme() { + return array( + 'admin_menu_item' => array( + 'arguments' => array('link' => '', 'has_children' => FALSE, 'menu' => '', 'in_active_trail' => FALSE, 'extra_class' => ''), + ), + 'admin_menu_icon' => array( + 'arguments' => array(), + ), + ); +} + +/** + * Implementation of hook_init(). * * We can't move this into admin_menu_footer(), because PHP-only based themes * like chameleon load and output scripts and stylesheets in front of * theme_closure(), so we ensure Admin menu's styles and scripts are loaded on * all pages via hook_menu(). */ -function admin_menu_menu($may_cache) { - $items = array(); - if ($may_cache) { - $items[] = array( - 'path' => 'admin/settings/admin_menu', - 'title' => t('Administration Menu'), - 'description' => t('Adjust settings for the dropdown Administration Menu.'), - 'callback' => 'drupal_get_form', - 'callback arguments' => array('admin_menu_theme_settings'), - 'access' => user_access('administer site configuration'), - ); - } - elseif (!$may_cache && user_access('access administration menu')) { +function admin_menu_init() { + if (user_access('access administration menu')) { $path = drupal_get_path('module', 'admin_menu'); drupal_add_css($path .'/admin_menu.css', 'module', 'screen', FALSE); drupal_add_js($path .'/admin_menu.js'); drupal_add_js(array('admin_menu_margin_top' => variable_get('admin_menu_margin_top', 1)), 'setting'); } +} + +function admin_menu_menu() { + $items = array(); + $items['admin/settings/admin_menu'] = array( + 'title' => 'Administration Menu', + 'description' => t('Adjust settings for the dropdown Administration Menu.'), + 'page callback' => 'drupal_get_form', + 'page arguments' => array('admin_menu_theme_settings'), + 'access arguments' => array('administer site configuration'), + ); return $items; } @@ -102,18 +116,19 @@ function admin_menu_footer($main = 0) { } global $_menu; - // Get item id of /q=admin, which we suppose to be the root for admin menu. - $mid_admin = $_menu['path index']['admin']; - $_admin_menu =& admin_menu_get_menu($mid_admin); + // Get the menu item of /q=admin, which is the root for admin menu. + #$mid_admin = $_menu['path index']['admin']; + $_admin_menu =& admin_menu_get_menu(); // Allow other modules to integrate with admin_menu (uncached). foreach (module_implements('admin_menu') as $module) { $function = $module .'_admin_menu'; - $function($_admin_menu, FALSE); + #$function($_admin_menu, FALSE); } $content = '
'; - $content .= theme_admin_menu_tree($mid_admin); + $content .= admin_menu_tree_output($_admin_menu); + #$content .= menu_tree_output($_admin_menu); $content .= '
'; return $content; } @@ -128,94 +143,97 @@ function admin_menu_footer($main = 0) { * An array containing a complete menu structure of all cached administration * menu items. */ -function &admin_menu_get_menu($mid_admin = 5) { +function &admin_menu_get_menu($mid_admin = 2) { static $_admin_menu; if (isset($_admin_menu)) { return $_admin_menu; } - global $user, $locale; + global $user, $language; - $cid = $user->uid .':'. $locale .':admin_menu'; - $cache = cache_get($cid, 'cache_menu'); - // Check if cache is an array needed to distinguish between v5.x-1.2 and later - // versions. - if ($cache && substr($cache->data, 0, 1) == 'a') { - $_admin_menu = unserialize($cache->data); + $cid = 'links:admin_menu:all:admin:'. $user->uid .':'. $language->language; + $cache = 0; #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, 'cache_menu', serialize($_admin_menu), time() + (60 * 60 * 24)); + #cache_set($cid, $_admin_menu, 'cache_menu', 0); } return $_admin_menu; } /** - * Generate the HTML for a menu tree. + * Returns a rendered menu tree. * - * @param int $pid - * The menu item id to use for the administration menu. + * @param $tree + * A data structure representing the tree as returned from menu_tree_data. * * @return string * The complete, rendered administration menu. */ -function theme_admin_menu_tree($pid = 1) { - $_admin_menu = admin_menu_get_menu(); +function admin_menu_tree_output($tree) { $output = ''; - - if (isset($_admin_menu[$pid]) && $_admin_menu[$pid]['children']) { - // Since we allow other modules to add items to admin menu, we need to sort - // all items (again). - usort($_admin_menu[$pid]['children'], '_admin_menu_sort'); - foreach ($_admin_menu[$pid]['children'] as $mid) { - $children = isset($_admin_menu[$mid]['children']) ? $_admin_menu[$mid]['children'] : NULL; - $output .= theme_admin_menu_item($mid, theme_admin_menu_tree($mid), count($children) == 0); + $items = array(); + + // 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) { + #echo "
"; var_dump($data); echo "
\n"; + if (!$data['link']['hidden']) { + $items[] = $data; + } + } + + // Since we allow other modules to add items to admin menu, we need to sort + // all items (again). + #usort($_admin_menu[$pid]['children'], '_admin_menu_sort'); + + foreach ($items as $i => $data) { + $extra_class = NULL; + // Allow HTML and omit alias lookups. + $data['link']['options']['html'] = TRUE; + $data['link']['options']['alias'] = TRUE; + + $link = theme('menu_item_link', $data['link']); + if ($data['below']) { + $output .= theme('admin_menu_item', $link, $data['link']['has_children'], admin_menu_tree_output($data['below']), $data['link']['in_active_trail'], $extra_class); + } + else { + $output .= theme('admin_menu_item', $link, $data['link']['has_children'], '', $data['link']['in_active_trail'], $extra_class); } } return $output ? "\n' : ''; } /** - * Generate the HTML output for a single menu item. + * Generate the HTML output for a single menu item and submenu. * - * @param int $mid - * The menu id of the item. - * @param string $children - * A string containing any rendered child items of this menu. - * @param bool $leaf - * A boolean indicating whether this menu item is a leaf. - */ -function theme_admin_menu_item($mid, $children = '', $leaf = TRUE) { - static $display_option; - - $_admin_menu = admin_menu_get_menu(); - $item = $_admin_menu[$mid]; - - if (!isset($display_option)) { - $display_option = variable_get('admin_menu_display', 0); + * @param string $link + * A rendered menu item link. + * @param bool $has_children + * Whether this item has children. + * @param string $menu + * A string containing any rendered children of this item. + * @param bool $in_active_trail + * Whether this item is in the active menu trail. + * @param string $extra_class + * An additional CSS class to set for this item. + * + * @see theme_menu_item() + * @ingroup themeable + */ +function theme_admin_menu_item($link, $has_children, $menu = '', $in_active_trail = FALSE, $extra_class = NULL) { + $class = ($menu || $has_children ? 'expandable' : ''); + if (!empty($extra_class)) { + $class .= ' '. $extra_class; } - // Display extra information about menu items if enabled (devel). - if ($display_option) { - if ($display_option == 'mid') { - $item['title'] = $item['title'] .' ('. $mid .')'; - } - else if (isset($item[$display_option])) { - $item['title'] = $item['title'] .' ('. $item[$display_option] .')'; - } + if ($in_active_trail) { + $class .= ' active-trail'; } - - $class = array(); - if (!$leaf) { - $class[] = 'expandable'; - } - if (isset($item['class'])) { - $class[] = $item['class']; - } - $output = ''; - $output .= ''. filter_xss_admin($item['title']) .''. $children .''; - return $output; + return ''. $link . $menu .''; } /** @@ -316,10 +334,10 @@ function admin_menu_admin_menu(&$admin_m $mid_admin = $admin_menu['index']['admin']; $count_anon = db_result(db_query("SELECT COUNT(uid) FROM {sessions} WHERE uid = 0 AND timestamp >= %d", time() - 30 * 60)); $count_auth = db_result(db_query("SELECT COUNT(DISTINCT uid) FROM {sessions} WHERE uid > 0 AND timestamp >= %d", time() - 30 * 60)); - $title = t('Current anonymous / authenticated users'); - $icon_users = ''. $title .''; + $icon_users = '@title'; admin_menu_add_item($admin_menu, $mid_admin, array( 'title' => $count_anon .' / '. $count_auth .' '. $icon_users, + 'title arguments' => array('@title' => 'Current anonymous / authenticated users'), 'path' => user_access('administer users') ? 'admin/user/user' : drupal_get_normal_path(variable_get('site_frontpage', 'node')), 'weight' => -90, 'class' => 'admin-menu-action admin-menu-icon admin-menu-users', @@ -332,7 +350,7 @@ function admin_menu_admin_menu(&$admin_m * * Extends Devel module with Administration Menu developer settings. */ -function admin_menu_form_alter($form_id, &$form) { +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']; @@ -381,13 +399,13 @@ if (module_exists('devel') && !function_ if ($may_cache) { // Add variable editor. if ($access_devel) { - admin_menu_add_item($admin_menu, $mid_icon, array('title' => t('Variable editor'), 'path' => 'devel/variable', 'weight' => 20)); + admin_menu_add_item($admin_menu, $mid_icon, array('title' => 'Variable editor', 'path' => 'devel/variable', 'weight' => 20)); } } else { // Add clear-cache. if ($access_devel) { - admin_menu_add_item($admin_menu, $mid_icon, array('title' => t('Empty cache'), 'path' => 'devel/cache/clear', 'weight' => 20, 'query' => drupal_get_destination())); + admin_menu_add_item($admin_menu, $mid_icon, array('title' => 'Empty cache', 'path' => 'devel/cache/clear', 'weight' => 20, 'query' => drupal_get_destination())); } // Add switch_user items. if ($access_switch && $devel_user_links = module_invoke('devel', 'switch_user_list')) {