summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.txt1
-rw-r--r--admin_menu.api.php38
-rw-r--r--admin_menu.inc114
-rw-r--r--admin_menu.install9
-rw-r--r--admin_menu.map.inc32
5 files changed, 106 insertions, 88 deletions
diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index d3216df..2e8a402 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -6,6 +6,7 @@ Admin Menu x.x-x.x, xxxx-xx-xx
Admin Menu 7.x-3.x, xxxx-xx-xx
------------------------------
+#420816 by sun, smk-ka: Improved on-demand loading of dynamic paths.
#420816 by tim.plunkett: Fixed dynamic Field UI paths for vocabularies.
#871774 by swentel: Fixed developer modules toggle still uses referer_uri().
#671760 by sun: Updated for new preprocess defaults.
diff --git a/admin_menu.api.php b/admin_menu.api.php
index ed8e476..098a604 100644
--- a/admin_menu.api.php
+++ b/admin_menu.api.php
@@ -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;
diff --git a/admin_menu.inc b/admin_menu.inc
index 9c90ab0..fd2b6cf 100644
--- a/admin_menu.inc
+++ b/admin_menu.inc
@@ -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 $expand_map) {
// 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 $expand_map) {
* @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 &$tree, array $tree_dynamic, array $expand_
$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);
-
- // 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;
+ }
+ $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.
+ 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 &$tree, array $tree_dynamic, array $expand_
}
/**
- * 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_item, $map) {
// 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,
diff --git a/admin_menu.install b/admin_menu.install
index 3102bd7..7c9bb65 100644
--- a/admin_menu.install
+++ b/admin_menu.install
@@ -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();
}
diff --git a/admin_menu.map.inc b/admin_menu.map.inc
index ca6edf0..2a3cdc3 100644
--- a/admin_menu.map.inc
+++ b/admin_menu.map.inc
@@ -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',
@@ -61,6 +70,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) {
@@ -105,6 +131,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_machine_name'] = array(
'parent' => 'admin/structure/taxonomy',
'hide' => 'admin/structure/taxonomy/list',
@@ -119,6 +148,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',