Index: admin_menu.api.php =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/admin_menu/admin_menu.api.php,v retrieving revision 1.5 diff -u -p -r1.5 admin_menu.api.php --- admin_menu.api.php 17 Mar 2010 20:49:40 -0000 1.5 +++ admin_menu.api.php 17 Mar 2010 21:02:45 -0000 @@ -7,36 +7,38 @@ */ /** - * Provide expansion arguments for dynamic menu items, i.e. menu paths - * containing one or more %placeholders. - * - * The map items must be keyed by the dynamic path to expand. Each map item may - * have the following properties: + * Provide expansion arguments for dynamic menu items. * + * The map items must be keyed by the dynamic path to expand, i.e. a menu path + * containing one or more '%' placeholders. Each map item may have the following + * properties: * - parent: The parent menu path to link the expanded items to. - * - arguments: An array of argument sets that will be used in the - * expansion. Each set consists of an array of one or more placeholders with - * an array of possible expansions as value. Upon expansion, each argument - * is combined with every other argument from the set (ie., the cartesian - * product of all arguments is created). The expansion values may be empty, - * that is, you don't need to insert logic to skip map items for which no - * values exist, since admin menu will take care of that. - * - hide: (optional) Used to hide another menu item, usually a superfluous + * - arguments: An array of argument sets that will be used in the expansion. + * Each set consists of an array of one or more placeholders, which again is + * an array of possible expansion values. Upon expansion, each argument is + * combined with every other argument from the set (technically, the cartesian + * product of all arguments). The expansion values may be empty; that is, you + * do not need to insert logic to skip map items for which no values exist, + * since Administration menu will take care of that. + * - hide: (optional) Used to hide another menu path, usually a superfluous * "List" item. * * @see admin_menu.map.inc */ function hook_admin_menu_map() { - // Expand content types in Structure >> Content types. + // Expand content types below Structure > Content types. // The key denotes the dynamic path to expand to multiple menu items. $map['admin/structure/types/manage/%node_type'] = array( - // Link generated items directly to the "Content types" item, and hide the - // "List" item. + // Link generated items directly to the "Content types" item. 'parent' => 'admin/structure/types', + // Hide the "List" item, as this expansion will expose all available + // options. 'hide' => 'admin/structure/types/list', - // Create expansion arguments for the %node_type placeholder. + // Create expansion arguments for the '%node_type' placeholder. 'arguments' => array( - array('%node_type' => array_keys(node_type_get_types())), + array( + '%node_type' => array_keys(node_type_get_types()), + ), ), ); return $map; Index: admin_menu.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/admin_menu/admin_menu.inc,v retrieving revision 1.75 diff -u -p -r1.75 admin_menu.inc --- admin_menu.inc 17 Mar 2010 20:49:40 -0000 1.75 +++ admin_menu.inc 17 Mar 2010 21:38:02 -0000 @@ -25,7 +25,6 @@ function admin_menu_tree($menu_name) { foreach ($expand_map as $path => $data) { // Convert named placeholders to anonymous placeholders, since the menu // system stores paths using anonymous placeholders. - // @todo Why specify named placeholders in the first place then? $replacements = array_fill_keys(array_keys($data['arguments'][0]), '%'); $data['parent'] = strtr($data['parent'], $replacements); $new_map[strtr($path, $replacements)] = $data; @@ -91,7 +90,6 @@ function admin_menu_tree_dynamic(array $ // The retrieved menu link trees have to be ordered by depth, so parents // always come before their children for the storage logic below. - // @todo Order by 'fit' or 'depth' instead for parent path handling below? foreach ($p_columns as $column) { $query->orderBy($column, 'ASC'); } @@ -141,14 +139,14 @@ function admin_menu_tree_dynamic(array $ * @param $tree_dynamic * A dynamic menu tree structure as returned by admin_menu_tree_dynamic(). * @param $expand_map - * @todo Rename this argument, it's not the same $expand_map like elsewhere. - * Placeholder expansion arguments. + * An array containing menu router path placeholder expansion argument + * mappings. * @param $hidden * An array containing links to hide, keyed by path. * * @see hook_admin_menu_map() - * @see menu_tree_all_data() * @see admin_menu_tree_dynamic() + * @see menu_tree_all_data() */ function admin_menu_merge_tree(array &$tree, array $tree_dynamic, array $expand_map, array $hidden) { foreach ($tree as $key => $data) { @@ -200,63 +198,51 @@ function admin_menu_merge_tree(array &$t $current_expand_map = $expand_map; } - // Set up path arguments map; depends on whether the item is dynamic - // (contains placeholders) or not. - if (strpos($link['path'], '%') === FALSE) { - // Build static item and subtree. - $map = explode('/', $link['path']); - $item = admin_menu_translate($link, $map); - admin_menu_merge_tree($item, $tree_dynamic, $current_expand_map, $hidden); - $tree[$key]['below'] += $item; + // Skip dynamic items without expansion parameters. + if (empty($current_expand_map)) { + continue; } - else { - // Drop dynamic items without required expansion parameters. - if (empty($current_expand_map)) { - continue; - } - // Expand anonymous to named placeholders. - // @see _menu_load_objects() - $path_args = explode('/', $link['path']); - $load_functions = unserialize($link['load_functions']); - foreach ($load_functions as $index => $function) { - if ($function) { - if (is_array($function)) { - list($function,) = each($function); - } - // Add the loader function name minus "_load". - $placeholder = '%' . substr($function, 0, -5); - $path_args[$index] = $placeholder; + // Expand anonymous to named placeholders. + // @see _menu_load_objects() + $path_args = explode('/', $link['path']); + $load_functions = unserialize($link['load_functions']); + foreach ($load_functions as $index => $function) { + if ($function) { + if (is_array($function)) { + list($function,) = each($function); } + // Add the loader function name minus "_load". + $placeholder = '%' . substr($function, 0, -5); + $path_args[$index] = $placeholder; } - $path_dynamic = implode('/', $path_args); + } + $path_dynamic = implode('/', $path_args); - // Create new menu items using expansion arguments. - foreach ($current_expand_map as $arguments) { - // Create the cartesian product for all arguments and create new - // menu items for each generated combination thereof. - $expanded_args = admin_menu_expand_args($arguments); - foreach ($expanded_args as $replacements) { - $newpath = strtr($path_dynamic, $replacements); - // If any placeholder couldn't be replaced, skip this item. - if (strpos($newpath, '%') !== FALSE) { - continue; - } - $map = explode('/', $newpath); - $item = admin_menu_translate($link, $map); - // No access. - if (empty($item)) { - continue; - } - // Build subtree using current replacement arguments. - // @todo Avoid rebuilding this for each item. - $new_expand_map = array(); - foreach ($replacements as $placeholder => $value) { - $new_expand_map[$placeholder] = array($value); - } - admin_menu_merge_tree($item, $tree_dynamic, array($new_expand_map), $hidden); - $tree[$key]['below'] += $item; + // Create new menu items using expansion arguments. + foreach ($current_expand_map as $arguments) { + // Create the cartesian product for all arguments and create new + // menu items for each generated combination thereof. + foreach (admin_menu_expand_args($arguments) as $replacements) { + $newpath = strtr($path_dynamic, $replacements); + // Skip this item, if any placeholder could not be replaced. + // Faster than trying to invoke _menu_translate(). + if (strpos($newpath, '%') !== FALSE) { + continue; } + $map = explode('/', $newpath); + $item = admin_menu_translate($link, $map); + // Skip this item, if the current user does not have access. + if (empty($item)) { + continue; + } + // Build subtree using current replacement arguments. + $new_expand_map = array(); + foreach ($replacements as $placeholder => $value) { + $new_expand_map[$placeholder] = array($value); + } + admin_menu_merge_tree($item, $tree_dynamic, array($new_expand_map), $hidden); + $tree[$key]['below'] += $item; } } } @@ -266,14 +252,12 @@ function admin_menu_merge_tree(array &$t } /** - * Create a menu item suitable for rendering. + * Translate an expanded router item into a menu link suitable for rendering. * * @param $router_item * A menu router item. * @param $map * A path map with placeholders replaced. - * - * @todo We have links. Consider forking menu_link_translate() instead. */ function admin_menu_translate($router_item, $map) { _menu_translate($router_item, $map, TRUE); @@ -281,21 +265,23 @@ function admin_menu_translate($router_it // Run through hook_translated_menu_link_alter() to add devel information, // if configured. $router_item['menu_name'] = 'management'; + // @todo Invoke as usual like _menu_link_translate(). admin_menu_translated_menu_link_alter($router_item, NULL); if ($router_item['access']) { // Override mlid to make this item unique; since these items are expanded // from dynamic items, the mlid is always the same, so each item would // replace any other. + // @todo Doing this instead leads to plenty of duplicate links below + // admin/structure/menu; likely a hidden recursion problem. + // $router_item['mlid'] = $router_item['href'] . $router_item['mlid']; $router_item['mlid'] = $router_item['href']; - // Turn local task menu callbacks into regular menu items, otherwise they - // won't be visible. + // Turn menu callbacks into regular menu items to make them visible. if ($router_item['type'] == MENU_CALLBACK) { $router_item['type'] = MENU_NORMAL_ITEM; } - // @todo Strip potential HTML from titles? - $router_item['title'] = strip_tags($router_item['title']); + // @see _menu_tree_check_access() $key = (50000 + $router_item['weight']) . ' ' . $router_item['title'] . ' ' . $router_item['mlid']; return array($key => array( 'link' => $router_item, Index: admin_menu.install =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/admin_menu/admin_menu.install,v retrieving revision 1.24 diff -u -p -r1.24 admin_menu.install --- admin_menu.install 17 Mar 2010 20:49:40 -0000 1.24 +++ admin_menu.install 17 Mar 2010 21:16:47 -0000 @@ -92,12 +92,9 @@ function admin_menu_update_7302() { * Remove local tasks from {menu_links} table. */ function admin_menu_update_7303() { - $paths = db_query('SELECT path FROM {menu_router} WHERE path LIKE :prefix AND type & :type', array( - ':prefix' => 'admin/%', - ':type' => MENU_IS_LOCAL_TASK, - ))->fetchCol(); - db_delete('menu_links') - ->condition('router_path', $paths, 'IN') + db_delete('menu_router') + ->condition('path', 'admin/%', 'LIKE') + ->condition('type', MENU_IS_LOCAL_TASK, '&') ->execute(); } Index: admin_menu.map.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/admin_menu/admin_menu.map.inc,v retrieving revision 1.1 diff -u -p -r1.1 admin_menu.map.inc --- admin_menu.map.inc 17 Mar 2010 20:49:40 -0000 1.1 +++ admin_menu.map.inc 17 Mar 2010 21:44:18 -0000 @@ -13,6 +13,9 @@ * Implements hook_admin_menu_map() on behalf of Filter module. */ function filter_admin_menu_map() { + if (!user_access('administer filters')) { + return; + } $map['admin/config/content/formats/%filter_format'] = array( 'parent' => 'admin/config/content/formats', 'hide' => 'admin/config/content/formats/list', @@ -27,6 +30,9 @@ function filter_admin_menu_map() { * Implements hook_admin_menu_map() on behalf of Menu module. */ function menu_admin_menu_map() { + if (!user_access('administer menu')) { + return; + } $map['admin/structure/menu/manage/%menu'] = array( 'parent' => 'admin/structure/menu', 'hide' => 'admin/structure/menu/list', @@ -41,6 +47,9 @@ function menu_admin_menu_map() { * Implements hook_admin_menu_map() on behalf of Node module. */ function node_admin_menu_map() { + if (!user_access('administer content types')) { + return; + } $map['admin/structure/types/manage/%node_type'] = array( 'parent' => 'admin/structure/types', 'hide' => 'admin/structure/types/list', @@ -56,7 +65,7 @@ function node_admin_menu_map() { */ function field_ui_admin_menu_map() { // @todo D7: Taxonomy still uses vid instead of machine name in administrative - // paths. + // paths. http://drupal.org/node/744258 if (module_exists('taxonomy')) { $vocabularies = taxonomy_vocabulary_get_names(); } @@ -67,6 +76,23 @@ function field_ui_admin_menu_map() { if (isset($bundle_info['admin'])) { $arguments = array(); switch ($obj_type) { + case 'comment': + $fields = array(); + foreach (field_info_instances($obj_type, $bundle_name) as $field) { + $fields[] = $field['field_name']; + } + // @todo Make Comment module expose the original node type bundle, + // pretty please. + if (drupal_substr($bundle_name, 0, 13) == 'comment_node_') { + $bundle_name = drupal_substr($bundle_name, 13); + } + // @todo Doesn't work yet. Why? + $arguments = array( + '%comment_node_type' => array($bundle_name), + '%field_ui_menu' => $fields, + ); + break; + case 'node': $fields = array(); foreach (field_info_instances($obj_type, $bundle_name) as $field) { @@ -112,6 +138,9 @@ function field_ui_admin_menu_map() { * Implements hook_admin_menu_map() on behalf of Taxonomy module. */ function taxonomy_admin_menu_map() { + if (!user_access('administer taxonomy')) { + return; + } $map['admin/structure/taxonomy/%taxonomy_vocabulary'] = array( 'parent' => 'admin/structure/taxonomy', 'hide' => 'admin/structure/taxonomy/list', @@ -126,6 +155,9 @@ function taxonomy_admin_menu_map() { * Implements hook_admin_menu_map() on behalf of Views UI module. */ function views_ui_admin_menu_map() { + if (!user_access('administer views')) { + return; + } // @todo Requires patch to views_ui. $map['admin/structure/views/edit/%views_ui_cache'] = array( 'parent' => 'admin/structure/views',