annotate modules/admin_menu/admin_menu.inc @ 13:134d4b2e75f6

updated quicktabs and google analytics modules
author danieleb <danielebarchiesi@me.com>
date Tue, 29 Oct 2013 13:48:59 +0000
parents a75ead649730
children
rev   line source
danielebarchiesi@6 1 <?php
danielebarchiesi@6 2
danielebarchiesi@6 3 /**
danielebarchiesi@6 4 * @file
danielebarchiesi@6 5 * Menu builder functions for Administration menu.
danielebarchiesi@6 6 */
danielebarchiesi@6 7
danielebarchiesi@6 8 /**
danielebarchiesi@6 9 * Build the full administration menu tree from static and expanded dynamic items.
danielebarchiesi@6 10 *
danielebarchiesi@6 11 * @param $menu_name
danielebarchiesi@6 12 * The menu name to use as base for the tree.
danielebarchiesi@6 13 */
danielebarchiesi@6 14 function admin_menu_tree($menu_name) {
danielebarchiesi@6 15 // Get placeholder expansion arguments from hook_admin_menu_map()
danielebarchiesi@6 16 // implementations.
danielebarchiesi@6 17 module_load_include('inc', 'admin_menu', 'admin_menu.map');
danielebarchiesi@6 18 $expand_map = module_invoke_all('admin_menu_map');
danielebarchiesi@6 19 // Allow modules to alter the expansion map.
danielebarchiesi@6 20 drupal_alter('admin_menu_map', $expand_map);
danielebarchiesi@6 21
danielebarchiesi@6 22 $new_map = array();
danielebarchiesi@6 23 foreach ($expand_map as $path => $data) {
danielebarchiesi@6 24 // Convert named placeholders to anonymous placeholders, since the menu
danielebarchiesi@6 25 // system stores paths using anonymous placeholders.
danielebarchiesi@6 26 $replacements = array_fill_keys(array_keys($data['arguments'][0]), '%');
danielebarchiesi@6 27 $data['parent'] = strtr($data['parent'], $replacements);
danielebarchiesi@6 28 $new_map[strtr($path, $replacements)] = $data;
danielebarchiesi@6 29 }
danielebarchiesi@6 30 $expand_map = $new_map;
danielebarchiesi@6 31 unset($new_map);
danielebarchiesi@6 32
danielebarchiesi@6 33 // Retrieve dynamic menu link tree for the expansion mappings.
danielebarchiesi@6 34 // @todo Skip entire processing if initial $expand_map is empty and directly
danielebarchiesi@6 35 // return $tree?
danielebarchiesi@6 36 if (!empty($expand_map)) {
danielebarchiesi@6 37 $tree_dynamic = admin_menu_tree_dynamic($expand_map);
danielebarchiesi@6 38 }
danielebarchiesi@6 39 else {
danielebarchiesi@6 40 $tree_dynamic = array();
danielebarchiesi@6 41 }
danielebarchiesi@6 42
danielebarchiesi@6 43 // Merge local tasks with static menu tree.
danielebarchiesi@6 44 $tree = menu_tree_all_data($menu_name);
danielebarchiesi@6 45 admin_menu_merge_tree($tree, $tree_dynamic, array());
danielebarchiesi@6 46
danielebarchiesi@6 47 return $tree;
danielebarchiesi@6 48 }
danielebarchiesi@6 49
danielebarchiesi@6 50 /**
danielebarchiesi@6 51 * Load menu link trees for router paths containing dynamic arguments.
danielebarchiesi@6 52 *
danielebarchiesi@6 53 * @param $expand_map
danielebarchiesi@6 54 * An array containing menu router path placeholder expansion argument
danielebarchiesi@6 55 * mappings.
danielebarchiesi@6 56 *
danielebarchiesi@6 57 * @return
danielebarchiesi@6 58 * An associative array whose keys are the parent paths of the menu router
danielebarchiesi@6 59 * paths given in $expand_map as well as the parent paths of any child link
danielebarchiesi@6 60 * deeper down the tree. The parent paths are used in admin_menu_merge_tree()
danielebarchiesi@6 61 * to check whether anything needs to be merged.
danielebarchiesi@6 62 *
danielebarchiesi@6 63 * @see hook_admin_menu_map()
danielebarchiesi@6 64 */
danielebarchiesi@6 65 function admin_menu_tree_dynamic(array $expand_map) {
danielebarchiesi@6 66 $p_columns = array();
danielebarchiesi@6 67 for ($i = 1; $i <= MENU_MAX_DEPTH; $i++) {
danielebarchiesi@6 68 $p_columns[] = 'p' . $i;
danielebarchiesi@6 69 }
danielebarchiesi@6 70
danielebarchiesi@6 71 // Fetch p* columns for all router paths to expand.
danielebarchiesi@6 72 $router_paths = array_keys($expand_map);
danielebarchiesi@6 73 $plids = db_select('menu_links', 'ml')
danielebarchiesi@6 74 ->fields('ml', $p_columns)
danielebarchiesi@6 75 ->condition('router_path', $router_paths)
danielebarchiesi@6 76 ->execute()
danielebarchiesi@6 77 ->fetchAll(PDO::FETCH_ASSOC);
danielebarchiesi@6 78
danielebarchiesi@6 79 // Unlikely, but possible.
danielebarchiesi@6 80 if (empty($plids)) {
danielebarchiesi@6 81 return array();
danielebarchiesi@6 82 }
danielebarchiesi@6 83
danielebarchiesi@6 84 // Use queried plid columns to query sub-trees for the router paths.
danielebarchiesi@6 85 $query = db_select('menu_links', 'ml');
danielebarchiesi@6 86 $query->join('menu_router', 'm', 'ml.router_path = m.path');
danielebarchiesi@6 87 $query
danielebarchiesi@6 88 ->fields('ml')
danielebarchiesi@6 89 ->fields('m', array_diff(drupal_schema_fields_sql('menu_router'), drupal_schema_fields_sql('menu_links')));
danielebarchiesi@6 90
danielebarchiesi@6 91 // The retrieved menu link trees have to be ordered by depth, so parents
danielebarchiesi@6 92 // always come before their children for the storage logic below.
danielebarchiesi@6 93 foreach ($p_columns as $column) {
danielebarchiesi@6 94 $query->orderBy($column, 'ASC');
danielebarchiesi@6 95 }
danielebarchiesi@6 96
danielebarchiesi@6 97 $db_or = db_or();
danielebarchiesi@6 98 foreach ($plids as $path_plids) {
danielebarchiesi@6 99 $db_and = db_and();
danielebarchiesi@6 100 // plids with value 0 may be ignored.
danielebarchiesi@6 101 foreach (array_filter($path_plids) as $column => $plid) {
danielebarchiesi@6 102 $db_and->condition($column, $plid);
danielebarchiesi@6 103 }
danielebarchiesi@6 104 $db_or->condition($db_and);
danielebarchiesi@6 105 }
danielebarchiesi@6 106 $query->condition($db_or);
danielebarchiesi@6 107 $result = $query
danielebarchiesi@6 108 ->execute()
danielebarchiesi@6 109 ->fetchAllAssoc('mlid', PDO::FETCH_ASSOC);
danielebarchiesi@6 110
danielebarchiesi@6 111 // Store dynamic links grouped by parent path for later merging and assign
danielebarchiesi@6 112 // placeholder expansion arguments.
danielebarchiesi@6 113 $tree_dynamic = array();
danielebarchiesi@6 114 foreach ($result as $mlid => $link) {
danielebarchiesi@6 115 // If contained in $expand_map, then this is a (first) parent, and we need
danielebarchiesi@6 116 // to store by the defined 'parent' path for later merging, as well as
danielebarchiesi@6 117 // provide the expansion map arguments to apply to the dynamic tree.
danielebarchiesi@6 118 if (isset($expand_map[$link['path']])) {
danielebarchiesi@6 119 $parent_path = $expand_map[$link['path']]['parent'];
danielebarchiesi@6 120 $link['expand_map'] = $expand_map[$link['path']]['arguments'];
danielebarchiesi@6 121 }
danielebarchiesi@6 122 // Otherwise, just store this link keyed by its parent path; the expand_map
danielebarchiesi@6 123 // is automatically derived from parent paths.
danielebarchiesi@6 124 else {
danielebarchiesi@6 125 $parent_path = $result[$link['plid']]['path'];
danielebarchiesi@6 126 }
danielebarchiesi@6 127
danielebarchiesi@6 128 $tree_dynamic[$parent_path][] = $link;
danielebarchiesi@6 129 }
danielebarchiesi@6 130
danielebarchiesi@6 131 return $tree_dynamic;
danielebarchiesi@6 132 }
danielebarchiesi@6 133
danielebarchiesi@6 134 /**
danielebarchiesi@6 135 * Walk through the entire menu tree and merge in expanded dynamic menu links.
danielebarchiesi@6 136 *
danielebarchiesi@6 137 * @param &$tree
danielebarchiesi@6 138 * A menu tree structure as returned by menu_tree_all_data().
danielebarchiesi@6 139 * @param $tree_dynamic
danielebarchiesi@6 140 * A dynamic menu tree structure as returned by admin_menu_tree_dynamic().
danielebarchiesi@6 141 * @param $expand_map
danielebarchiesi@6 142 * An array containing menu router path placeholder expansion argument
danielebarchiesi@6 143 * mappings.
danielebarchiesi@6 144 *
danielebarchiesi@6 145 * @see hook_admin_menu_map()
danielebarchiesi@6 146 * @see admin_menu_tree_dynamic()
danielebarchiesi@6 147 * @see menu_tree_all_data()
danielebarchiesi@6 148 */
danielebarchiesi@6 149 function admin_menu_merge_tree(array &$tree, array $tree_dynamic, array $expand_map) {
danielebarchiesi@6 150 foreach ($tree as $key => $data) {
danielebarchiesi@6 151 $path = $data['link']['router_path'];
danielebarchiesi@6 152
danielebarchiesi@6 153 // Recurse into regular menu tree.
danielebarchiesi@6 154 if ($tree[$key]['below']) {
danielebarchiesi@6 155 admin_menu_merge_tree($tree[$key]['below'], $tree_dynamic, $expand_map);
danielebarchiesi@6 156 }
danielebarchiesi@6 157 // Nothing to merge, if this parent path is not in our dynamic tree.
danielebarchiesi@6 158 if (!isset($tree_dynamic[$path])) {
danielebarchiesi@6 159 continue;
danielebarchiesi@6 160 }
danielebarchiesi@6 161
danielebarchiesi@6 162 // Add expanded dynamic items.
danielebarchiesi@6 163 foreach ($tree_dynamic[$path] as $link) {
danielebarchiesi@6 164 // If the dynamic item has custom placeholder expansion parameters set,
danielebarchiesi@6 165 // use them, otherwise keep current.
danielebarchiesi@6 166 if (isset($link['expand_map'])) {
danielebarchiesi@6 167 // If there are currently no expansion parameters, we may use the new
danielebarchiesi@6 168 // set immediately.
danielebarchiesi@6 169 if (empty($expand_map)) {
danielebarchiesi@6 170 $current_expand_map = $link['expand_map'];
danielebarchiesi@6 171 }
danielebarchiesi@6 172 else {
danielebarchiesi@6 173 // Otherwise we need to filter out elements that differ from the
danielebarchiesi@6 174 // current set, i.e. that are not in the same path.
danielebarchiesi@6 175 $current_expand_map = array();
danielebarchiesi@6 176 foreach ($expand_map as $arguments) {
danielebarchiesi@6 177 foreach ($arguments as $placeholder => $value) {
danielebarchiesi@6 178 foreach ($link['expand_map'] as $new_arguments) {
danielebarchiesi@6 179 // Skip the new argument if it doesn't contain the current
danielebarchiesi@6 180 // replacement placeholders or if their values differ.
danielebarchiesi@6 181 if (!isset($new_arguments[$placeholder]) || $new_arguments[$placeholder] != $value) {
danielebarchiesi@6 182 continue;
danielebarchiesi@6 183 }
danielebarchiesi@6 184 $current_expand_map[] = $new_arguments;
danielebarchiesi@6 185 }
danielebarchiesi@6 186 }
danielebarchiesi@6 187 }
danielebarchiesi@6 188 }
danielebarchiesi@6 189 }
danielebarchiesi@6 190 else {
danielebarchiesi@6 191 $current_expand_map = $expand_map;
danielebarchiesi@6 192 }
danielebarchiesi@6 193
danielebarchiesi@6 194 // Skip dynamic items without expansion parameters.
danielebarchiesi@6 195 if (empty($current_expand_map)) {
danielebarchiesi@6 196 continue;
danielebarchiesi@6 197 }
danielebarchiesi@6 198
danielebarchiesi@6 199 // Expand anonymous to named placeholders.
danielebarchiesi@6 200 // @see _menu_load_objects()
danielebarchiesi@6 201 $path_args = explode('/', $link['path']);
danielebarchiesi@6 202 $load_functions = unserialize($link['load_functions']);
danielebarchiesi@6 203 if (is_array($load_functions)) {
danielebarchiesi@6 204 foreach ($load_functions as $index => $function) {
danielebarchiesi@6 205 if ($function) {
danielebarchiesi@6 206 if (is_array($function)) {
danielebarchiesi@6 207 list($function,) = each($function);
danielebarchiesi@6 208 }
danielebarchiesi@6 209 // Add the loader function name minus "_load".
danielebarchiesi@6 210 $placeholder = '%' . substr($function, 0, -5);
danielebarchiesi@6 211 $path_args[$index] = $placeholder;
danielebarchiesi@6 212 }
danielebarchiesi@6 213 }
danielebarchiesi@6 214 }
danielebarchiesi@6 215 $path_dynamic = implode('/', $path_args);
danielebarchiesi@6 216
danielebarchiesi@6 217 // Create new menu items using expansion arguments.
danielebarchiesi@6 218 foreach ($current_expand_map as $arguments) {
danielebarchiesi@6 219 // Create the cartesian product for all arguments and create new
danielebarchiesi@6 220 // menu items for each generated combination thereof.
danielebarchiesi@6 221 foreach (admin_menu_expand_args($arguments) as $replacements) {
danielebarchiesi@6 222 $newpath = strtr($path_dynamic, $replacements);
danielebarchiesi@6 223 // Skip this item, if any placeholder could not be replaced.
danielebarchiesi@6 224 // Faster than trying to invoke _menu_translate().
danielebarchiesi@6 225 if (strpos($newpath, '%') !== FALSE) {
danielebarchiesi@6 226 continue;
danielebarchiesi@6 227 }
danielebarchiesi@6 228 $map = explode('/', $newpath);
danielebarchiesi@6 229 $item = admin_menu_translate($link, $map);
danielebarchiesi@6 230 // Skip this item, if the current user does not have access.
danielebarchiesi@6 231 if (empty($item)) {
danielebarchiesi@6 232 continue;
danielebarchiesi@6 233 }
danielebarchiesi@6 234 // Build subtree using current replacement arguments.
danielebarchiesi@6 235 $new_expand_map = array();
danielebarchiesi@6 236 foreach ($replacements as $placeholder => $value) {
danielebarchiesi@6 237 $new_expand_map[$placeholder] = array($value);
danielebarchiesi@6 238 }
danielebarchiesi@6 239 admin_menu_merge_tree($item, $tree_dynamic, array($new_expand_map));
danielebarchiesi@6 240 $tree[$key]['below'] += $item;
danielebarchiesi@6 241 }
danielebarchiesi@6 242 }
danielebarchiesi@6 243 }
danielebarchiesi@6 244 // Sort new subtree items.
danielebarchiesi@6 245 ksort($tree[$key]['below']);
danielebarchiesi@6 246 }
danielebarchiesi@6 247 }
danielebarchiesi@6 248
danielebarchiesi@6 249 /**
danielebarchiesi@6 250 * Translate an expanded router item into a menu link suitable for rendering.
danielebarchiesi@6 251 *
danielebarchiesi@6 252 * @param $router_item
danielebarchiesi@6 253 * A menu router item.
danielebarchiesi@6 254 * @param $map
danielebarchiesi@6 255 * A path map with placeholders replaced.
danielebarchiesi@6 256 */
danielebarchiesi@6 257 function admin_menu_translate($router_item, $map) {
danielebarchiesi@6 258 _menu_translate($router_item, $map, TRUE);
danielebarchiesi@6 259
danielebarchiesi@6 260 // Run through hook_translated_menu_link_alter() to add devel information,
danielebarchiesi@6 261 // if configured.
danielebarchiesi@6 262 $router_item['menu_name'] = 'management';
danielebarchiesi@6 263 // @todo Invoke as usual like _menu_link_translate().
danielebarchiesi@6 264 admin_menu_translated_menu_link_alter($router_item, NULL);
danielebarchiesi@6 265
danielebarchiesi@6 266 if ($router_item['access']) {
danielebarchiesi@6 267 // Override mlid to make this item unique; since these items are expanded
danielebarchiesi@6 268 // from dynamic items, the mlid is always the same, so each item would
danielebarchiesi@6 269 // replace any other.
danielebarchiesi@6 270 // @todo Doing this instead leads to plenty of duplicate links below
danielebarchiesi@6 271 // admin/structure/menu; likely a hidden recursion problem.
danielebarchiesi@6 272 // $router_item['mlid'] = $router_item['href'] . $router_item['mlid'];
danielebarchiesi@6 273 $router_item['mlid'] = $router_item['href'];
danielebarchiesi@6 274 // Turn menu callbacks into regular menu items to make them visible.
danielebarchiesi@6 275 if ($router_item['type'] == MENU_CALLBACK) {
danielebarchiesi@6 276 $router_item['type'] = MENU_NORMAL_ITEM;
danielebarchiesi@6 277 }
danielebarchiesi@6 278
danielebarchiesi@6 279 // @see _menu_tree_check_access()
danielebarchiesi@6 280 $key = (50000 + $router_item['weight']) . ' ' . $router_item['title'] . ' ' . $router_item['mlid'];
danielebarchiesi@6 281 return array($key => array(
danielebarchiesi@6 282 'link' => $router_item,
danielebarchiesi@6 283 'below' => array(),
danielebarchiesi@6 284 ));
danielebarchiesi@6 285 }
danielebarchiesi@6 286
danielebarchiesi@6 287 return array();
danielebarchiesi@6 288 }
danielebarchiesi@6 289
danielebarchiesi@6 290 /**
danielebarchiesi@6 291 * Create the cartesian product of multiple varying sized argument arrays.
danielebarchiesi@6 292 *
danielebarchiesi@6 293 * @param $arguments
danielebarchiesi@6 294 * A two dimensional array of arguments.
danielebarchiesi@6 295 *
danielebarchiesi@6 296 * @see hook_admin_menu_map()
danielebarchiesi@6 297 */
danielebarchiesi@6 298 function admin_menu_expand_args($arguments) {
danielebarchiesi@6 299 $replacements = array();
danielebarchiesi@6 300
danielebarchiesi@6 301 // Initialize line cursors, move out array keys (placeholders) and assign
danielebarchiesi@6 302 // numeric keys instead.
danielebarchiesi@6 303 $i = 0;
danielebarchiesi@6 304 $placeholders = array();
danielebarchiesi@6 305 $new_arguments = array();
danielebarchiesi@6 306 foreach ($arguments as $placeholder => $values) {
danielebarchiesi@6 307 // Skip empty arguments.
danielebarchiesi@6 308 if (empty($values)) {
danielebarchiesi@6 309 continue;
danielebarchiesi@6 310 }
danielebarchiesi@6 311 $cursor[$i] = 0;
danielebarchiesi@6 312 $placeholders[$i] = $placeholder;
danielebarchiesi@6 313 $new_arguments[$i] = $values;
danielebarchiesi@6 314 $i++;
danielebarchiesi@6 315 }
danielebarchiesi@6 316 $arguments = $new_arguments;
danielebarchiesi@6 317 unset($new_arguments);
danielebarchiesi@6 318
danielebarchiesi@6 319 if ($rows = count($arguments)) {
danielebarchiesi@6 320 do {
danielebarchiesi@6 321 // Collect current argument from each row.
danielebarchiesi@6 322 $row = array();
danielebarchiesi@6 323 for ($i = 0; $i < $rows; ++$i) {
danielebarchiesi@6 324 $row[$placeholders[$i]] = $arguments[$i][$cursor[$i]];
danielebarchiesi@6 325 }
danielebarchiesi@6 326 $replacements[] = $row;
danielebarchiesi@6 327
danielebarchiesi@6 328 // Increment cursor position.
danielebarchiesi@6 329 $j = $rows - 1;
danielebarchiesi@6 330 $cursor[$j]++;
danielebarchiesi@6 331 while (!array_key_exists($cursor[$j], $arguments[$j])) {
danielebarchiesi@6 332 // No more arguments left: reset cursor, go to next line and increment
danielebarchiesi@6 333 // that cursor instead. Repeat until argument found or out of rows.
danielebarchiesi@6 334 $cursor[$j] = 0;
danielebarchiesi@6 335 if (--$j < 0) {
danielebarchiesi@6 336 // We're done.
danielebarchiesi@6 337 break 2;
danielebarchiesi@6 338 }
danielebarchiesi@6 339 $cursor[$j]++;
danielebarchiesi@6 340 }
danielebarchiesi@6 341 } while (1);
danielebarchiesi@6 342 }
danielebarchiesi@6 343
danielebarchiesi@6 344 return $replacements;
danielebarchiesi@6 345 }
danielebarchiesi@6 346
danielebarchiesi@6 347 /**
danielebarchiesi@6 348 * Build the administration menu as renderable menu links.
danielebarchiesi@6 349 *
danielebarchiesi@6 350 * @param $tree
danielebarchiesi@6 351 * A data structure representing the administration menu tree as returned from
danielebarchiesi@6 352 * menu_tree_all_data().
danielebarchiesi@6 353 *
danielebarchiesi@6 354 * @return
danielebarchiesi@6 355 * The complete administration menu, suitable for theme_admin_menu_links().
danielebarchiesi@6 356 *
danielebarchiesi@6 357 * @see theme_admin_menu_links()
danielebarchiesi@6 358 * @see admin_menu_menu_alter()
danielebarchiesi@6 359 */
danielebarchiesi@6 360 function admin_menu_links_menu($tree) {
danielebarchiesi@6 361 $links = array();
danielebarchiesi@6 362 foreach ($tree as $data) {
danielebarchiesi@6 363 // Skip items that are inaccessible, invisible, or link to their parent.
danielebarchiesi@6 364 // (MENU_DEFAULT_LOCAL_TASK), and MENU_CALLBACK-alike items that should only
danielebarchiesi@6 365 // appear in the breadcrumb.
danielebarchiesi@6 366 if (!$data['link']['access'] || $data['link']['type'] & MENU_LINKS_TO_PARENT || $data['link']['type'] == MENU_VISIBLE_IN_BREADCRUMB || $data['link']['hidden'] == 1) {
danielebarchiesi@6 367 continue;
danielebarchiesi@6 368 }
danielebarchiesi@6 369 // Hide 'Administer' and make child links appear on this level.
danielebarchiesi@6 370 // @todo Make this configurable.
danielebarchiesi@6 371 if ($data['link']['router_path'] == 'admin') {
danielebarchiesi@6 372 if ($data['below']) {
danielebarchiesi@6 373 $links = array_merge($links, admin_menu_links_menu($data['below']));
danielebarchiesi@6 374 }
danielebarchiesi@6 375 continue;
danielebarchiesi@6 376 }
danielebarchiesi@6 377 // Omit alias lookups.
danielebarchiesi@6 378 $data['link']['localized_options']['alias'] = TRUE;
danielebarchiesi@6 379 // Remove description to prevent mouseover tooltip clashes.
danielebarchiesi@6 380 unset($data['link']['localized_options']['attributes']['title']);
danielebarchiesi@6 381
danielebarchiesi@6 382 // Make action links (typically "Add ...") appear first in dropdowns.
danielebarchiesi@6 383 // They might appear first already, but only as long as there is no link
danielebarchiesi@6 384 // that comes alphabetically first (e.g., a node type with label "Ad").
danielebarchiesi@6 385 if ($data['link']['type'] & MENU_IS_LOCAL_ACTION) {
danielebarchiesi@6 386 $data['link']['weight'] -= 1000;
danielebarchiesi@6 387 }
danielebarchiesi@6 388
danielebarchiesi@6 389 $links[$data['link']['href']] = array(
danielebarchiesi@6 390 '#title' => $data['link']['title'],
danielebarchiesi@6 391 '#href' => $data['link']['href'],
danielebarchiesi@6 392 '#options' => $data['link']['localized_options'],
danielebarchiesi@6 393 '#weight' => $data['link']['weight'],
danielebarchiesi@6 394 );
danielebarchiesi@6 395
danielebarchiesi@6 396 // Recurse to add any child links.
danielebarchiesi@6 397 $children = array();
danielebarchiesi@6 398 if ($data['below']) {
danielebarchiesi@6 399 $children = admin_menu_links_menu($data['below']);
danielebarchiesi@6 400 $links[$data['link']['href']] += $children;
danielebarchiesi@6 401 }
danielebarchiesi@6 402
danielebarchiesi@6 403 // Handle links pointing to category/overview pages.
danielebarchiesi@6 404 if ($data['link']['page_callback'] == 'system_admin_menu_block_page' || $data['link']['page_callback'] == 'system_admin_config_page') {
danielebarchiesi@6 405 // Apply a marker for others to consume.
danielebarchiesi@6 406 $links[$data['link']['href']]['#is_category'] = TRUE;
danielebarchiesi@6 407 // Automatically hide empty categories.
danielebarchiesi@6 408 // Check for empty children first for performance. Only when non-empty
danielebarchiesi@6 409 // (typically 'admin/config'), check whether children are accessible.
danielebarchiesi@6 410 if (empty($children) || !element_get_visible_children($children)) {
danielebarchiesi@6 411 $links[$data['link']['href']]['#access'] = FALSE;
danielebarchiesi@6 412 }
danielebarchiesi@6 413 }
danielebarchiesi@6 414 }
danielebarchiesi@6 415 return $links;
danielebarchiesi@6 416 }
danielebarchiesi@6 417
danielebarchiesi@6 418 /**
danielebarchiesi@6 419 * Build icon menu links; mostly containing maintenance helpers.
danielebarchiesi@6 420 *
danielebarchiesi@6 421 * @see theme_admin_menu_links()
danielebarchiesi@6 422 */
danielebarchiesi@6 423 function admin_menu_links_icon() {
danielebarchiesi@6 424 $destination = drupal_get_destination();
danielebarchiesi@6 425
danielebarchiesi@6 426 $links = array(
danielebarchiesi@6 427 '#theme' => 'admin_menu_links',
danielebarchiesi@6 428 '#wrapper_attributes' => array('id' => 'admin-menu-icon'),
danielebarchiesi@6 429 '#weight' => -100,
danielebarchiesi@6 430 );
danielebarchiesi@6 431 $links['icon'] = array(
danielebarchiesi@6 432 '#title' => theme('admin_menu_icon'),
danielebarchiesi@6 433 '#attributes' => array('class' => array('admin-menu-icon')),
danielebarchiesi@6 434 '#href' => '<front>',
danielebarchiesi@6 435 '#options' => array(
danielebarchiesi@6 436 'html' => TRUE,
danielebarchiesi@6 437 ),
danielebarchiesi@6 438 );
danielebarchiesi@6 439 // Add link to manually run cron.
danielebarchiesi@6 440 $links['icon']['cron'] = array(
danielebarchiesi@6 441 '#title' => t('Run cron'),
danielebarchiesi@6 442 '#weight' => 50,
danielebarchiesi@6 443 '#access' => user_access('administer site configuration'),
danielebarchiesi@6 444 '#href' => 'admin/reports/status/run-cron',
danielebarchiesi@6 445 );
danielebarchiesi@6 446 // Add link to run update.php.
danielebarchiesi@6 447 $links['icon']['update'] = array(
danielebarchiesi@6 448 '#title' => t('Run updates'),
danielebarchiesi@6 449 '#weight' => 50,
danielebarchiesi@6 450 // @see update_access_allowed()
danielebarchiesi@6 451 '#access' => $GLOBALS['user']->uid == 1 || !empty($GLOBALS['update_free_access']) || user_access('administer software updates'),
danielebarchiesi@6 452 '#href' => base_path() . 'update.php',
danielebarchiesi@6 453 '#options' => array(
danielebarchiesi@6 454 'external' => TRUE,
danielebarchiesi@6 455 ),
danielebarchiesi@6 456 );
danielebarchiesi@6 457 // Add link to drupal.org.
danielebarchiesi@6 458 $links['icon']['drupal.org'] = array(
danielebarchiesi@6 459 '#title' => 'Drupal.org',
danielebarchiesi@6 460 '#weight' => 100,
danielebarchiesi@6 461 '#access' => user_access('display drupal links'),
danielebarchiesi@6 462 '#href' => 'http://drupal.org',
danielebarchiesi@6 463 );
danielebarchiesi@6 464 // Add links to project issue queues.
danielebarchiesi@6 465 foreach (module_list(FALSE, TRUE) as $module) {
danielebarchiesi@6 466 $info = drupal_parse_info_file(drupal_get_path('module', $module) . '/' . $module . '.info');
danielebarchiesi@6 467 if (!isset($info['project']) || isset($links['icon']['drupal.org'][$info['project']])) {
danielebarchiesi@6 468 continue;
danielebarchiesi@6 469 }
danielebarchiesi@6 470 $links['icon']['drupal.org'][$info['project']] = array(
danielebarchiesi@6 471 '#title' => t('@project issue queue', array('@project' => $info['name'])),
danielebarchiesi@6 472 '#weight' => ($info['project'] == 'drupal' ? -10 : 0),
danielebarchiesi@6 473 '#href' => 'http://drupal.org/project/issues/' . $info['project'],
danielebarchiesi@6 474 '#options' => array(
danielebarchiesi@6 475 'query' => array('version' => (isset($info['core']) ? $info['core'] : 'All')),
danielebarchiesi@6 476 ),
danielebarchiesi@6 477 );
danielebarchiesi@6 478 }
danielebarchiesi@6 479 // Add items to flush caches.
danielebarchiesi@6 480 $links['icon']['flush-cache'] = array(
danielebarchiesi@6 481 '#title' => t('Flush all caches'),
danielebarchiesi@6 482 '#weight' => 20,
danielebarchiesi@6 483 '#access' => user_access('flush caches'),
danielebarchiesi@6 484 '#href' => 'admin_menu/flush-cache',
danielebarchiesi@6 485 '#options' => array(
danielebarchiesi@6 486 'query' => $destination + array('token' => drupal_get_token('admin_menu/flush-cache')),
danielebarchiesi@6 487 ),
danielebarchiesi@6 488 );
danielebarchiesi@6 489 $caches = module_invoke_all('admin_menu_cache_info');
danielebarchiesi@6 490 foreach ($caches as $name => $cache) {
danielebarchiesi@6 491 $links['icon']['flush-cache'][$name] = array(
danielebarchiesi@6 492 '#title' => $cache['title'],
danielebarchiesi@6 493 '#href' => 'admin_menu/flush-cache/' . $name,
danielebarchiesi@6 494 '#options' => array(
danielebarchiesi@6 495 'query' => $destination + array('token' => drupal_get_token('admin_menu/flush-cache/' . $name)),
danielebarchiesi@6 496 ),
danielebarchiesi@6 497 );
danielebarchiesi@6 498 }
danielebarchiesi@6 499
danielebarchiesi@6 500 // Add link to toggle developer modules (performance).
danielebarchiesi@6 501 $saved_state = variable_get('admin_menu_devel_modules_enabled', NULL);
danielebarchiesi@6 502 $links['icon']['toggle-modules'] = array(
danielebarchiesi@6 503 '#title' => isset($saved_state) ? t('Enable developer modules') : t('Disable developer modules'),
danielebarchiesi@6 504 '#weight' => 88,
danielebarchiesi@6 505 '#access' => user_access('administer modules'),
danielebarchiesi@6 506 '#href' => 'admin_menu/toggle-modules',
danielebarchiesi@6 507 '#options' => array(
danielebarchiesi@6 508 'query' => $destination + array('token' => drupal_get_token('admin_menu/toggle-modules')),
danielebarchiesi@6 509 ),
danielebarchiesi@6 510 );
danielebarchiesi@6 511
danielebarchiesi@6 512 // Add Devel module menu links.
danielebarchiesi@6 513 if (module_exists('devel')) {
danielebarchiesi@6 514 $devel_tree = menu_build_tree('devel');
danielebarchiesi@6 515 $devel_links = admin_menu_links_menu($devel_tree);
danielebarchiesi@6 516 if (element_get_visible_children($devel_links)) {
danielebarchiesi@6 517 $links['icon']['devel'] = array(
danielebarchiesi@6 518 '#title' => t('Development'),
danielebarchiesi@6 519 '#weight' => 30,
danielebarchiesi@6 520 ) + $devel_links;
danielebarchiesi@6 521 }
danielebarchiesi@6 522 }
danielebarchiesi@6 523
danielebarchiesi@6 524 return $links;
danielebarchiesi@6 525 }
danielebarchiesi@6 526
danielebarchiesi@6 527 /**
danielebarchiesi@6 528 * Builds the account links.
danielebarchiesi@6 529 *
danielebarchiesi@6 530 * @see theme_admin_menu_links()
danielebarchiesi@6 531 */
danielebarchiesi@6 532 function admin_menu_links_account() {
danielebarchiesi@6 533 $links = array(
danielebarchiesi@6 534 '#theme' => 'admin_menu_links',
danielebarchiesi@6 535 '#wrapper_attributes' => array('id' => 'admin-menu-account'),
danielebarchiesi@6 536 '#weight' => 100,
danielebarchiesi@6 537 );
danielebarchiesi@6 538 $links['account'] = array(
danielebarchiesi@6 539 '#title' => format_username($GLOBALS['user']),
danielebarchiesi@6 540 '#weight' => -99,
danielebarchiesi@6 541 '#attributes' => array('class' => array('admin-menu-action', 'admin-menu-account')),
danielebarchiesi@6 542 '#href' => 'user/' . $GLOBALS['user']->uid,
danielebarchiesi@6 543 );
danielebarchiesi@6 544 $links['logout'] = array(
danielebarchiesi@6 545 '#title' => t('Log out'),
danielebarchiesi@6 546 '#weight' => -100,
danielebarchiesi@6 547 '#attributes' => array('class' => array('admin-menu-action')),
danielebarchiesi@6 548 '#href' => 'user/logout',
danielebarchiesi@6 549 );
danielebarchiesi@6 550 // Add Devel module switch user links.
danielebarchiesi@6 551 $switch_links = module_invoke('devel', 'switch_user_list');
danielebarchiesi@6 552 if (!empty($switch_links) && count($switch_links) > 1) {
danielebarchiesi@6 553 foreach ($switch_links as $uid => $link) {
danielebarchiesi@6 554 $links['account'][$link['title']] = array(
danielebarchiesi@6 555 '#title' => $link['title'],
danielebarchiesi@6 556 '#description' => $link['attributes']['title'],
danielebarchiesi@6 557 '#href' => $link['href'],
danielebarchiesi@6 558 '#options' => array(
danielebarchiesi@6 559 'query' => $link['query'],
danielebarchiesi@6 560 'html' => !empty($link['html']),
danielebarchiesi@6 561 ),
danielebarchiesi@6 562 );
danielebarchiesi@6 563 }
danielebarchiesi@6 564 }
danielebarchiesi@6 565 return $links;
danielebarchiesi@6 566 }
danielebarchiesi@6 567
danielebarchiesi@6 568 /**
danielebarchiesi@6 569 * Builds user counter.
danielebarchiesi@6 570 *
danielebarchiesi@6 571 * @see theme_admin_menu_links()
danielebarchiesi@6 572 */
danielebarchiesi@6 573 function admin_menu_links_users() {
danielebarchiesi@6 574 $links = array(
danielebarchiesi@6 575 '#theme' => 'admin_menu_links',
danielebarchiesi@6 576 '#wrapper_attributes' => array('id' => 'admin-menu-users'),
danielebarchiesi@6 577 '#weight' => 150,
danielebarchiesi@6 578 );
danielebarchiesi@6 579 // Add link to show current authenticated/anonymous users.
danielebarchiesi@6 580 $links['user-counter'] = array(
danielebarchiesi@6 581 '#title' => admin_menu_get_user_count(),
danielebarchiesi@6 582 '#description' => t('Current anonymous / authenticated users'),
danielebarchiesi@6 583 '#weight' => -90,
danielebarchiesi@6 584 '#attributes' => array('class' => array('admin-menu-action', 'admin-menu-users')),
danielebarchiesi@6 585 '#href' => (user_access('administer users') ? 'admin/people/people' : 'user'),
danielebarchiesi@6 586 );
danielebarchiesi@6 587 return $links;
danielebarchiesi@6 588 }
danielebarchiesi@6 589
danielebarchiesi@6 590 /**
danielebarchiesi@6 591 * Build search widget.
danielebarchiesi@6 592 *
danielebarchiesi@6 593 * @see theme_admin_menu_links()
danielebarchiesi@6 594 */
danielebarchiesi@6 595 function admin_menu_links_search() {
danielebarchiesi@6 596 $links = array(
danielebarchiesi@6 597 '#theme' => 'admin_menu_links',
danielebarchiesi@6 598 '#wrapper_attributes' => array('id' => 'admin-menu-search'),
danielebarchiesi@6 599 '#weight' => 180,
danielebarchiesi@6 600 );
danielebarchiesi@6 601 $links['search'] = array(
danielebarchiesi@6 602 '#type' => 'textfield',
danielebarchiesi@6 603 '#title' => t('Search'),
danielebarchiesi@6 604 '#title_display' => 'attribute',
danielebarchiesi@6 605 '#attributes' => array(
danielebarchiesi@6 606 'placeholder' => t('Search'),
danielebarchiesi@6 607 'class' => array('admin-menu-search'),
danielebarchiesi@6 608 ),
danielebarchiesi@6 609 );
danielebarchiesi@6 610 return $links;
danielebarchiesi@6 611 }
danielebarchiesi@6 612
danielebarchiesi@6 613 /**
danielebarchiesi@6 614 * Form builder function for module settings.
danielebarchiesi@6 615 */
danielebarchiesi@6 616 function admin_menu_theme_settings() {
danielebarchiesi@6 617 $form['admin_menu_margin_top'] = array(
danielebarchiesi@6 618 '#type' => 'checkbox',
danielebarchiesi@6 619 '#title' => t('Adjust top margin'),
danielebarchiesi@6 620 '#default_value' => variable_get('admin_menu_margin_top', 1),
danielebarchiesi@6 621 '#description' => t('Shifts the site output down by approximately 20 pixels from the top of the viewport. If disabled, absolute- or fixed-positioned page elements may be covered by the administration menu.'),
danielebarchiesi@6 622 );
danielebarchiesi@6 623 $form['admin_menu_position_fixed'] = array(
danielebarchiesi@6 624 '#type' => 'checkbox',
danielebarchiesi@6 625 '#title' => t('Keep menu at top of page'),
danielebarchiesi@6 626 '#default_value' => variable_get('admin_menu_position_fixed', 1),
danielebarchiesi@6 627 '#description' => t('Displays the administration menu always at the top of the browser viewport (even when scrolling the page).'),
danielebarchiesi@6 628 );
danielebarchiesi@6 629 // @todo Re-confirm this with latest browser versions.
danielebarchiesi@6 630 $form['admin_menu_position_fixed']['#description'] .= '<br /><strong>' . t('In some browsers, this setting may result in a malformed page, an invisible cursor, non-selectable elements in forms, or other issues.') . '</strong>';
danielebarchiesi@6 631
danielebarchiesi@6 632 $form['advanced'] = array(
danielebarchiesi@6 633 '#type' => 'vertical_tabs',
danielebarchiesi@6 634 '#title' => t('Advanced settings'),
danielebarchiesi@6 635 );
danielebarchiesi@6 636
danielebarchiesi@6 637 $form['plugins'] = array(
danielebarchiesi@6 638 '#type' => 'fieldset',
danielebarchiesi@6 639 '#title' => t('Plugins'),
danielebarchiesi@6 640 '#group' => 'advanced',
danielebarchiesi@6 641 );
danielebarchiesi@6 642 $form['plugins']['admin_menu_components'] = array(
danielebarchiesi@6 643 '#type' => 'checkboxes',
danielebarchiesi@6 644 '#title' => t('Enabled components'),
danielebarchiesi@6 645 '#options' => array(
danielebarchiesi@6 646 'admin_menu.icon' => t('Icon menu'),
danielebarchiesi@6 647 'admin_menu.menu' => t('Administration menu'),
danielebarchiesi@6 648 'admin_menu.search' => t('Search bar'),
danielebarchiesi@6 649 'admin_menu.users' => t('User counts'),
danielebarchiesi@6 650 'admin_menu.account' => t('Account links'),
danielebarchiesi@6 651 ),
danielebarchiesi@6 652 );
danielebarchiesi@6 653 $form['plugins']['admin_menu_components']['#default_value'] = array_keys(array_filter(variable_get('admin_menu_components', $form['plugins']['admin_menu_components']['#options'])));
danielebarchiesi@6 654
danielebarchiesi@6 655 $process = element_info_property('checkboxes', '#process', array());
danielebarchiesi@6 656 $form['plugins']['admin_menu_components']['#process'] = array_merge(array('admin_menu_settings_process_components'), $process);
danielebarchiesi@6 657 $form['#attached']['js'][] = drupal_get_path('module', 'admin_menu') . '/admin_menu.admin.js';
danielebarchiesi@6 658
danielebarchiesi@6 659 $form['tweaks'] = array(
danielebarchiesi@6 660 '#type' => 'fieldset',
danielebarchiesi@6 661 '#title' => t('System tweaks'),
danielebarchiesi@6 662 '#group' => 'advanced',
danielebarchiesi@6 663 );
danielebarchiesi@6 664 $form['tweaks']['admin_menu_tweak_modules'] = array(
danielebarchiesi@6 665 '#type' => 'checkbox',
danielebarchiesi@6 666 '#title' => t('Collapse module groups on the <a href="!modules-url">%modules</a> page', array(
danielebarchiesi@6 667 '%modules' => t('Modules'),
danielebarchiesi@6 668 '!modules-url' => url('admin/modules'),
danielebarchiesi@6 669 )),
danielebarchiesi@6 670 '#default_value' => variable_get('admin_menu_tweak_modules', 0),
danielebarchiesi@6 671 );
danielebarchiesi@6 672 if (module_exists('util')) {
danielebarchiesi@6 673 $form['tweaks']['admin_menu_tweak_modules']['#description'] .= '<br /><strong>' . t('If the Utility module was installed for this purpose, it can be safely disabled and uninstalled.') . '</strong>';
danielebarchiesi@6 674 }
danielebarchiesi@6 675 $form['tweaks']['admin_menu_tweak_permissions'] = array(
danielebarchiesi@6 676 '#type' => 'checkbox',
danielebarchiesi@6 677 '#title' => t('Collapse module groups on the <a href="@permissions-url">%permissions</a> page', array(
danielebarchiesi@6 678 '%permissions' => t('Permissions'),
danielebarchiesi@6 679 '@permissions-url' => url('admin/people/permissions'),
danielebarchiesi@6 680 )),
danielebarchiesi@6 681 '#default_value' => variable_get('admin_menu_tweak_permissions', 0),
danielebarchiesi@6 682 );
danielebarchiesi@6 683 $form['tweaks']['admin_menu_tweak_tabs'] = array(
danielebarchiesi@6 684 '#type' => 'checkbox',
danielebarchiesi@6 685 '#title' => t('Move local tasks into menu'),
danielebarchiesi@6 686 '#default_value' => variable_get('admin_menu_tweak_tabs', 0),
danielebarchiesi@6 687 '#description' => t('Moves the tabs on all pages into the administration menu. Only possible for themes using the CSS classes <code>tabs primary</code> and <code>tabs secondary</code>.'),
danielebarchiesi@6 688 );
danielebarchiesi@6 689
danielebarchiesi@6 690 $form['performance'] = array(
danielebarchiesi@6 691 '#type' => 'fieldset',
danielebarchiesi@6 692 '#title' => t('Performance'),
danielebarchiesi@6 693 '#group' => 'advanced',
danielebarchiesi@6 694 );
danielebarchiesi@6 695 $form['performance']['admin_menu_cache_client'] = array(
danielebarchiesi@6 696 '#type' => 'checkbox',
danielebarchiesi@6 697 '#title' => t('Cache menu in client-side browser'),
danielebarchiesi@6 698 '#default_value' => variable_get('admin_menu_cache_client', 1),
danielebarchiesi@6 699 );
danielebarchiesi@6 700 // Fetch all available modules manually, since module_list() only returns
danielebarchiesi@6 701 // currently enabled modules, which makes this setting pointless if developer
danielebarchiesi@6 702 // modules are currently disabled.
danielebarchiesi@6 703 $all_modules = array();
danielebarchiesi@6 704 $result = db_query("SELECT name, filename, info FROM {system} WHERE type = 'module' ORDER BY name ASC");
danielebarchiesi@6 705 foreach ($result as $module) {
danielebarchiesi@6 706 if (file_exists($module->filename)) {
danielebarchiesi@6 707 $info = unserialize($module->info);
danielebarchiesi@6 708 $all_modules[$module->name] = $info['name'];
danielebarchiesi@6 709 }
danielebarchiesi@6 710 }
danielebarchiesi@6 711 $devel_modules = variable_get('admin_menu_devel_modules', _admin_menu_developer_modules());
danielebarchiesi@6 712 $devel_modules = array_intersect_key($all_modules, array_flip($devel_modules));
danielebarchiesi@6 713 $form['performance']['admin_menu_devel_modules_skip'] = array(
danielebarchiesi@6 714 '#type' => 'checkboxes',
danielebarchiesi@6 715 '#title' => t('Developer modules to keep enabled'),
danielebarchiesi@6 716 '#default_value' => variable_get('admin_menu_devel_modules_skip', array()),
danielebarchiesi@6 717 '#options' => $devel_modules,
danielebarchiesi@6 718 '#access' => !empty($devel_modules),
danielebarchiesi@6 719 '#description' => t('The selected modules will not be disabled when the link %disable-developer-modules below the icon in the menu is invoked.', array(
danielebarchiesi@6 720 '%disable-developer-modules' => t('Disable developer modules'),
danielebarchiesi@6 721 )),
danielebarchiesi@6 722 );
danielebarchiesi@6 723
danielebarchiesi@6 724 return system_settings_form($form);
danielebarchiesi@6 725 }
danielebarchiesi@6 726
danielebarchiesi@6 727 /**
danielebarchiesi@6 728 * #process callback for component plugin form element in admin_menu_theme_settings().
danielebarchiesi@6 729 */
danielebarchiesi@6 730 function admin_menu_settings_process_components($element) {
danielebarchiesi@6 731 // Assign 'rel' attributes to all options to achieve a live preview.
danielebarchiesi@6 732 // Unfortunately, #states relies on wrapping .form-wrapper classes, so it
danielebarchiesi@6 733 // cannot be used here.
danielebarchiesi@6 734 foreach ($element['#options'] as $key => $label) {
danielebarchiesi@6 735 if (!isset($element[$key]['#attributes']['rel'])) {
danielebarchiesi@6 736 $id = preg_replace('/[^a-z]/', '-', $key);
danielebarchiesi@6 737 $element[$key]['#attributes']['rel'] = '#' . $id;
danielebarchiesi@6 738 }
danielebarchiesi@6 739 }
danielebarchiesi@6 740 return $element;
danielebarchiesi@6 741 }
danielebarchiesi@6 742
danielebarchiesi@6 743 /**
danielebarchiesi@6 744 * Form validation handler for admin_menu_theme_settings().
danielebarchiesi@6 745 */
danielebarchiesi@6 746 function admin_menu_theme_settings_validate(&$form, &$form_state) {
danielebarchiesi@6 747 // Change the configured components to Boolean values.
danielebarchiesi@6 748 foreach ($form_state['values']['admin_menu_components'] as $component => &$enabled) {
danielebarchiesi@6 749 $enabled = (bool) $enabled;
danielebarchiesi@6 750 }
danielebarchiesi@6 751 }
danielebarchiesi@6 752
danielebarchiesi@6 753 /**
danielebarchiesi@6 754 * Implementation of hook_form_FORM_ID_alter().
danielebarchiesi@6 755 *
danielebarchiesi@6 756 * Extends Devel module with Administration menu developer settings.
danielebarchiesi@6 757 */
danielebarchiesi@6 758 function _admin_menu_form_devel_admin_settings_alter(&$form, $form_state) {
danielebarchiesi@6 759 // Shift system_settings_form buttons.
danielebarchiesi@6 760 $weight = isset($form['buttons']['#weight']) ? $form['buttons']['#weight'] : 0;
danielebarchiesi@6 761 $form['buttons']['#weight'] = $weight + 1;
danielebarchiesi@6 762
danielebarchiesi@6 763 $form['admin_menu'] = array(
danielebarchiesi@6 764 '#type' => 'fieldset',
danielebarchiesi@6 765 '#title' => t('Administration menu settings'),
danielebarchiesi@6 766 '#collapsible' => TRUE,
danielebarchiesi@6 767 '#collapsed' => TRUE,
danielebarchiesi@6 768 );
danielebarchiesi@6 769 $display_options = array('mid', 'weight', 'pid');
danielebarchiesi@6 770 $display_options = array(0 => t('None'), 'mlid' => t('Menu link ID'), 'weight' => t('Weight'), 'plid' => t('Parent link ID'));
danielebarchiesi@6 771 $form['admin_menu']['admin_menu_display'] = array(
danielebarchiesi@6 772 '#type' => 'radios',
danielebarchiesi@6 773 '#title' => t('Display additional data for each menu item'),
danielebarchiesi@6 774 '#default_value' => variable_get('admin_menu_display', 0),
danielebarchiesi@6 775 '#options' => $display_options,
danielebarchiesi@6 776 '#description' => t('Display the selected items next to each menu item link.'),
danielebarchiesi@6 777 );
danielebarchiesi@6 778 $form['admin_menu']['admin_menu_show_all'] = array(
danielebarchiesi@6 779 '#type' => 'checkbox',
danielebarchiesi@6 780 '#title' => t('Display all menu items'),
danielebarchiesi@6 781 '#default_value' => variable_get('admin_menu_show_all', 0),
danielebarchiesi@6 782 '#description' => t('If enabled, all menu items are displayed regardless of your site permissions. <em>Note: Do not enable on a production site.</em>'),
danielebarchiesi@6 783 );
danielebarchiesi@6 784 }
danielebarchiesi@6 785
danielebarchiesi@6 786 /**
danielebarchiesi@6 787 * Menu callback; Enable/disable developer modules.
danielebarchiesi@6 788 *
danielebarchiesi@6 789 * This can save up to 150ms on each uncached page request.
danielebarchiesi@6 790 */
danielebarchiesi@6 791 function admin_menu_toggle_modules() {
danielebarchiesi@6 792 if (!isset($_GET['token']) || !drupal_valid_token($_GET['token'], current_path())) {
danielebarchiesi@6 793 return MENU_ACCESS_DENIED;
danielebarchiesi@6 794 }
danielebarchiesi@6 795
danielebarchiesi@6 796 $rebuild = FALSE;
danielebarchiesi@6 797 $saved_state = variable_get('admin_menu_devel_modules_enabled', NULL);
danielebarchiesi@6 798 if (isset($saved_state)) {
danielebarchiesi@6 799 // Re-enable modules that were enabled before.
danielebarchiesi@6 800 module_enable($saved_state);
danielebarchiesi@6 801 variable_del('admin_menu_devel_modules_enabled');
danielebarchiesi@6 802 drupal_set_message(t('Enabled these modules: !module-list.', array('!module-list' => implode(', ', $saved_state))));
danielebarchiesi@6 803 $rebuild = TRUE;
danielebarchiesi@6 804 }
danielebarchiesi@6 805 else {
danielebarchiesi@6 806 // Allow site admins to override this variable via settings.php.
danielebarchiesi@6 807 $devel_modules = variable_get('admin_menu_devel_modules', _admin_menu_developer_modules());
danielebarchiesi@6 808 // Store currently enabled modules in a variable.
danielebarchiesi@6 809 $devel_modules = array_intersect(module_list(FALSE, FALSE), $devel_modules);
danielebarchiesi@6 810 $devel_modules = array_diff($devel_modules, variable_get('admin_menu_devel_modules_skip', array()));
danielebarchiesi@6 811 if (!empty($devel_modules)) {
danielebarchiesi@6 812 variable_set('admin_menu_devel_modules_enabled', $devel_modules);
danielebarchiesi@6 813 // Disable developer modules.
danielebarchiesi@6 814 module_disable($devel_modules);
danielebarchiesi@6 815 drupal_set_message(t('Disabled these modules: !module-list.', array('!module-list' => implode(', ', $devel_modules))));
danielebarchiesi@6 816 $rebuild = TRUE;
danielebarchiesi@6 817 }
danielebarchiesi@6 818 else {
danielebarchiesi@6 819 drupal_set_message(t('No developer modules are enabled.'));
danielebarchiesi@6 820 }
danielebarchiesi@6 821 }
danielebarchiesi@6 822 if ($rebuild) {
danielebarchiesi@6 823 // Make sure everything is rebuilt, basically a combination of the calls
danielebarchiesi@6 824 // from system_modules() and system_modules_submit().
danielebarchiesi@6 825 drupal_theme_rebuild();
danielebarchiesi@6 826 menu_rebuild();
danielebarchiesi@6 827 cache_clear_all('schema', 'cache');
danielebarchiesi@6 828 cache_clear_all();
danielebarchiesi@6 829 drupal_clear_css_cache();
danielebarchiesi@6 830 drupal_clear_js_cache();
danielebarchiesi@6 831 // Synchronize to catch any actions that were added or removed.
danielebarchiesi@6 832 actions_synchronize();
danielebarchiesi@6 833 // Finally, flush admin_menu's cache.
danielebarchiesi@6 834 admin_menu_flush_caches();
danielebarchiesi@6 835 }
danielebarchiesi@6 836 drupal_goto();
danielebarchiesi@6 837 }
danielebarchiesi@6 838
danielebarchiesi@6 839 /**
danielebarchiesi@6 840 * Helper function to return a default list of developer modules.
danielebarchiesi@6 841 */
danielebarchiesi@6 842 function _admin_menu_developer_modules() {
danielebarchiesi@6 843 return array(
danielebarchiesi@6 844 'admin_devel',
danielebarchiesi@6 845 'cache_disable',
danielebarchiesi@6 846 'coder',
danielebarchiesi@6 847 'content_copy',
danielebarchiesi@6 848 'context_ui',
danielebarchiesi@6 849 'debug',
danielebarchiesi@6 850 'delete_all',
danielebarchiesi@6 851 'demo',
danielebarchiesi@6 852 'devel',
danielebarchiesi@6 853 'devel_node_access',
danielebarchiesi@6 854 'devel_themer',
danielebarchiesi@6 855 'field_ui',
danielebarchiesi@6 856 'fontyourface_ui',
danielebarchiesi@6 857 'form_controller',
danielebarchiesi@6 858 'imagecache_ui',
danielebarchiesi@6 859 'journal',
danielebarchiesi@6 860 'l10n_client',
danielebarchiesi@6 861 'l10n_update',
danielebarchiesi@6 862 'macro',
danielebarchiesi@6 863 'rules_admin',
danielebarchiesi@6 864 'stringoverrides',
danielebarchiesi@6 865 'trace',
danielebarchiesi@6 866 'upgrade_status',
danielebarchiesi@6 867 'user_display_ui',
danielebarchiesi@6 868 'util',
danielebarchiesi@6 869 'views_ui',
danielebarchiesi@6 870 'views_theme_wizard',
danielebarchiesi@6 871 );
danielebarchiesi@6 872 }
danielebarchiesi@6 873
danielebarchiesi@6 874 /**
danielebarchiesi@6 875 * Flush all caches or a specific one.
danielebarchiesi@6 876 *
danielebarchiesi@6 877 * @param $name
danielebarchiesi@6 878 * (optional) Name of cache to flush.
danielebarchiesi@6 879 */
danielebarchiesi@6 880 function admin_menu_flush_cache($name = NULL) {
danielebarchiesi@6 881 if (!isset($_GET['token']) || !drupal_valid_token($_GET['token'], current_path())) {
danielebarchiesi@6 882 return MENU_ACCESS_DENIED;
danielebarchiesi@6 883 }
danielebarchiesi@6 884 if (isset($name)) {
danielebarchiesi@6 885 $caches = module_invoke_all('admin_menu_cache_info');
danielebarchiesi@6 886 if (!isset($caches[$name])) {
danielebarchiesi@6 887 return MENU_NOT_FOUND;
danielebarchiesi@6 888 }
danielebarchiesi@6 889 }
danielebarchiesi@6 890 else {
danielebarchiesi@6 891 $caches[$name] = array(
danielebarchiesi@6 892 'title' => t('Every'),
danielebarchiesi@6 893 'callback' => 'drupal_flush_all_caches',
danielebarchiesi@6 894 );
danielebarchiesi@6 895 }
danielebarchiesi@6 896 // Pass the cache to flush forward to the callback.
danielebarchiesi@6 897 $function = $caches[$name]['callback'];
danielebarchiesi@6 898 $function($name);
danielebarchiesi@6 899
danielebarchiesi@6 900 drupal_set_message(t('!title cache cleared.', array('!title' => $caches[$name]['title'])));
danielebarchiesi@6 901
danielebarchiesi@6 902 // The JavaScript injects a destination request parameter pointing to the
danielebarchiesi@6 903 // originating page, so the user is redirected back to that page. Without
danielebarchiesi@6 904 // destination parameter, the redirect ends on the front page.
danielebarchiesi@6 905 drupal_goto();
danielebarchiesi@6 906 }
danielebarchiesi@6 907
danielebarchiesi@6 908 /**
danielebarchiesi@6 909 * Implements hook_admin_menu_cache_info().
danielebarchiesi@6 910 */
danielebarchiesi@6 911 function admin_menu_admin_menu_cache_info() {
danielebarchiesi@6 912 $caches['admin_menu'] = array(
danielebarchiesi@6 913 'title' => t('Administration menu'),
danielebarchiesi@6 914 'callback' => '_admin_menu_flush_cache',
danielebarchiesi@6 915 );
danielebarchiesi@6 916 return $caches;
danielebarchiesi@6 917 }
danielebarchiesi@6 918
danielebarchiesi@6 919 /**
danielebarchiesi@6 920 * Implements hook_admin_menu_cache_info() on behalf of System module.
danielebarchiesi@6 921 */
danielebarchiesi@6 922 function system_admin_menu_cache_info() {
danielebarchiesi@6 923 $caches = array(
danielebarchiesi@6 924 'assets' => t('CSS and JavaScript'),
danielebarchiesi@6 925 'cache' => t('Page and else'),
danielebarchiesi@6 926 'menu' => t('Menu'),
danielebarchiesi@6 927 'registry' => t('Class registry'),
danielebarchiesi@6 928 'theme' => t('Theme registry'),
danielebarchiesi@6 929 );
danielebarchiesi@6 930 foreach ($caches as $name => $cache) {
danielebarchiesi@6 931 $caches[$name] = array(
danielebarchiesi@6 932 'title' => $cache,
danielebarchiesi@6 933 'callback' => '_admin_menu_flush_cache',
danielebarchiesi@6 934 );
danielebarchiesi@6 935 }
danielebarchiesi@6 936 return $caches;
danielebarchiesi@6 937 }
danielebarchiesi@6 938
danielebarchiesi@6 939 /**
danielebarchiesi@6 940 * Implements hook_admin_menu_cache_info() on behalf of Update module.
danielebarchiesi@6 941 */
danielebarchiesi@6 942 function update_admin_menu_cache_info() {
danielebarchiesi@6 943 $caches['update'] = array(
danielebarchiesi@6 944 'title' => t('Update data'),
danielebarchiesi@6 945 'callback' => '_update_cache_clear',
danielebarchiesi@6 946 );
danielebarchiesi@6 947 return $caches;
danielebarchiesi@6 948 }
danielebarchiesi@6 949
danielebarchiesi@6 950 /**
danielebarchiesi@6 951 * Flush all caches or a specific one.
danielebarchiesi@6 952 *
danielebarchiesi@6 953 * @param $name
danielebarchiesi@6 954 * (optional) Name of cache to flush.
danielebarchiesi@6 955 *
danielebarchiesi@6 956 * @see system_admin_menu_cache_info()
danielebarchiesi@6 957 */
danielebarchiesi@6 958 function _admin_menu_flush_cache($name = NULL) {
danielebarchiesi@6 959 switch ($name) {
danielebarchiesi@6 960 case 'admin_menu':
danielebarchiesi@6 961 admin_menu_flush_caches();
danielebarchiesi@6 962 break;
danielebarchiesi@6 963
danielebarchiesi@6 964 case 'menu':
danielebarchiesi@6 965 menu_rebuild();
danielebarchiesi@6 966 break;
danielebarchiesi@6 967
danielebarchiesi@6 968 case 'registry':
danielebarchiesi@6 969 registry_rebuild();
danielebarchiesi@6 970 // Fall-through to clear cache tables, since registry information is
danielebarchiesi@6 971 // usually the base for other data that is cached (e.g. SimpleTests).
danielebarchiesi@6 972 case 'cache':
danielebarchiesi@6 973 // Don't clear cache_form - in-progress form submissions may break.
danielebarchiesi@6 974 // Ordered so clearing the page cache will always be the last action.
danielebarchiesi@6 975 // @see drupal_flush_all_caches()
danielebarchiesi@6 976 $core = array('cache', 'cache_bootstrap', 'cache_filter', 'cache_page');
danielebarchiesi@6 977 $cache_tables = array_merge(module_invoke_all('flush_caches'), $core);
danielebarchiesi@6 978 foreach ($cache_tables as $table) {
danielebarchiesi@6 979 cache_clear_all('*', $table, TRUE);
danielebarchiesi@6 980 }
danielebarchiesi@6 981 break;
danielebarchiesi@6 982
danielebarchiesi@6 983 case 'assets':
danielebarchiesi@6 984 // Change query-strings on css/js files to enforce reload for all users.
danielebarchiesi@6 985 _drupal_flush_css_js();
danielebarchiesi@6 986
danielebarchiesi@6 987 drupal_clear_css_cache();
danielebarchiesi@6 988 drupal_clear_js_cache();
danielebarchiesi@6 989
danielebarchiesi@6 990 // Clear the page cache, since cached HTML pages might link to old CSS and
danielebarchiesi@6 991 // JS aggregates.
danielebarchiesi@6 992 cache_clear_all('*', 'cache_page', TRUE);
danielebarchiesi@6 993 break;
danielebarchiesi@6 994
danielebarchiesi@6 995 case 'theme':
danielebarchiesi@6 996 system_rebuild_theme_data();
danielebarchiesi@6 997 drupal_theme_rebuild();
danielebarchiesi@6 998 break;
danielebarchiesi@6 999 }
danielebarchiesi@6 1000 }
danielebarchiesi@6 1001
danielebarchiesi@6 1002 /**
danielebarchiesi@6 1003 * Preprocesses variables for theme_admin_menu_icon().
danielebarchiesi@6 1004 */
danielebarchiesi@6 1005 function template_preprocess_admin_menu_icon(&$variables) {
danielebarchiesi@6 1006 // Image source might have been passed in as theme variable.
danielebarchiesi@6 1007 if (!isset($variables['src'])) {
danielebarchiesi@6 1008 if (theme_get_setting('toggle_favicon')) {
danielebarchiesi@6 1009 $variables['src'] = theme_get_setting('favicon');
danielebarchiesi@6 1010 }
danielebarchiesi@6 1011 else {
danielebarchiesi@6 1012 $variables['src'] = base_path() . 'misc/favicon.ico';
danielebarchiesi@6 1013 }
danielebarchiesi@6 1014 }
danielebarchiesi@6 1015 // Strip the protocol without delimiters for transient HTTP/HTTPS support.
danielebarchiesi@6 1016 // Since the menu is cached on the server-side and client-side, the cached
danielebarchiesi@6 1017 // version might contain a HTTP link, whereas the actual page is on HTTPS.
danielebarchiesi@6 1018 // Relative paths will work fine, but theme_get_setting() returns an
danielebarchiesi@6 1019 // absolute URI.
danielebarchiesi@6 1020 $variables['src'] = preg_replace('@^https?:@', '', $variables['src']);
danielebarchiesi@6 1021 $variables['src'] = check_plain($variables['src']);
danielebarchiesi@6 1022 $variables['alt'] = t('Home');
danielebarchiesi@6 1023 }
danielebarchiesi@6 1024
danielebarchiesi@6 1025 /**
danielebarchiesi@6 1026 * Renders an icon to display in the administration menu.
danielebarchiesi@6 1027 *
danielebarchiesi@6 1028 * @ingroup themeable
danielebarchiesi@6 1029 */
danielebarchiesi@6 1030 function theme_admin_menu_icon($variables) {
danielebarchiesi@6 1031 return '<img class="admin-menu-icon" src="' . $variables['src'] . '" width="16" height="16" alt="' . $variables['alt'] . '" />';
danielebarchiesi@6 1032 }
danielebarchiesi@6 1033