[ Index ]

PHP Cross Reference of Drupal 6 (gatewave)

title

Body

[close]

/sites/all/modules/admin_menu/ -> admin_menu.inc (source)

   1  <?php
   2  // $Id: admin_menu.inc,v 1.11.2.26 2009/12/24 15:45:50 sun Exp $
   3  
   4  /**
   5   * The key function that builds the menu links whenever there is a menu rebuild.
   6   */
   7  function _admin_menu_rebuild_links() {
   8    // Get the newly rebuilt menu.
   9    $menu = menu_router_build();
  10    // Add normal and suggested items as links.
  11    $menu_links = array();
  12    foreach ($menu as $path => $item) {
  13      // Exclude menu callbacks, include items below admin/* and node/add/*.
  14      if ($item['type'] != MENU_CALLBACK && (($item['_parts'][0] == 'admin' && count($item['_parts']) > 1) || (strpos($path, 'node/add') === 0))) {
  15        // TODO: handle local tasks with wildcards
  16        if (!strpos($path, '%')) {
  17          $item = admin_menu_link_build($item);
  18          $menu_links[$path] = $item;
  19          $sort[$path] = $item['_number_parts'];
  20        }
  21      }
  22    }
  23    $deleted = admin_menu_adjust_items($menu_links, $sort);
  24    if ($menu_links) {
  25      // Make sure no child comes before its parent.
  26      array_multisort($sort, SORT_NUMERIC, $menu_links);
  27  
  28      foreach ($menu_links as $item) {
  29        admin_menu_link_save($item);
  30      }
  31    }
  32    // Allow modules to add more links. If you want to alter links saved by
  33    // admin_menu, use hook_menu_link_alter() and look for
  34    // $item['module'] == 'admin_menu'
  35    $links = array();
  36    foreach (module_implements('admin_menu') as $module) {
  37      $function = $module . '_admin_menu';
  38      $links = array_merge_recursive($links, $function($deleted));
  39    }
  40    foreach ($links as $item) {
  41      admin_menu_link_save($item);
  42    }
  43  }
  44  
  45  /**
  46   * Prepare a menu link from basic information formatted for a router item.
  47   */
  48  function admin_menu_link_build($item) {
  49    $item['module'] = 'admin_menu';
  50    $item['menu_name'] = 'admin_menu';
  51    $item += array(
  52      'link_title' => $item['title'],
  53      'link_path' => $item['path'],
  54      'hidden' => 0,
  55      'options' => array(),
  56    );
  57    $item['options']['alter'] = TRUE;
  58    // DAM does not output item descriptions to prevent mouseover clashes and
  59    // increase page loading performance.  However, the following code shows how
  60    // link attributes can be added (for ajaxified DAM functionality later).
  61    /*
  62    if (!empty($item['description'])) {
  63      $item['options']['attributes']['title'] = $item['description'];
  64    }
  65    */
  66    if (!empty($item['query'])) {
  67      $item['options']['query'] = $item['query'];
  68    }
  69    return $item;
  70  }
  71  
  72  /**
  73   * Convenience function that looks up the plid if $item['parent_path'] is set.
  74   */
  75  function admin_menu_link_save($item) {
  76    $item = admin_menu_link_build($item);
  77  
  78    // Check whether we are able to update an existing item.
  79    $existing_item = db_fetch_array(db_query("SELECT mlid, plid, has_children FROM {menu_links} WHERE link_path = '%s' AND menu_name = '%s'", $item['link_path'], 'admin_menu'));
  80    if ($existing_item) {
  81      $item['mlid'] = $existing_item['mlid'];
  82      $item['plid'] = $existing_item['plid'];
  83      $item['has_children'] = $existing_item['has_children'];
  84    }
  85  
  86    // Look up the parent path for both new and existing links, since the parent
  87    // may change.
  88    if (isset($item['parent_path'])) {
  89      if ($item['parent_path'] == '<root>') {
  90        // <root> means that we want the link at the top level.
  91        $item['plid'] = 0;
  92      }
  93      else {
  94        $plid = db_result(db_query("SELECT mlid from {menu_links} WHERE link_path = '%s' AND menu_name = '%s'", $item['parent_path'], 'admin_menu'));
  95        if ($plid) {
  96          $item['plid'] = $plid;
  97        }
  98      }
  99    }
 100  
 101    menu_link_save($item);
 102  }
 103  
 104  /**
 105   * Implementation of hook_admin_menu().
 106   *
 107   * @param &$deleted
 108   *   Array of links under admin/* that were removed by admin_menu_adjust_items().
 109   *   If one of these links is added back, it should be removed from the array.
 110   */
 111  function admin_menu_admin_menu(&$deleted) {
 112    $links = array();
 113    $icon_path = '<front>';
 114  
 115    // Add link to manually run cron.
 116    $links[] = array(
 117      'title' => 'Run cron',
 118      'path' => 'admin/reports/status/run-cron',
 119      'weight' => 50,
 120      'parent_path' => $icon_path,
 121    );
 122    // Add link to run update.php.
 123    $links[] = array(
 124      'title' => 'Run updates',
 125      'path' => 'update.php',
 126      'weight' => 50,
 127      'parent_path' => $icon_path,
 128      'options' => array('external' => TRUE),
 129    );
 130  
 131    // Move 'By module' item into Site configuration.
 132    if (isset($deleted['admin/by-module'])) {
 133      $deleted['admin/by-module']['parent_path'] = 'admin/settings';
 134      $deleted['admin/by-module']['weight'] = -10;
 135      $links[] = $deleted['admin/by-module'];
 136      unset($deleted['admin/by-module']);
 137    }
 138  
 139    // Add link to drupal.org.
 140    $links[] = array(
 141      'title' => 'Drupal.org',
 142      'path' => 'http://drupal.org',
 143      'weight' => 100,
 144      'parent_path' => $icon_path,
 145    );
 146    // Add links to project issue queues.
 147    $links[] = array(
 148      'title' => 'Drupal issue queue',
 149      'path' => 'http://drupal.org/project/issues/drupal',
 150      'weight' => -10,
 151      'parent_path' => 'http://drupal.org',
 152    );
 153    $projects = array();
 154    foreach (module_list(FALSE, FALSE, TRUE) as $module) {
 155      $info = drupal_parse_info_file(drupal_get_path('module', $module) .'/'. $module .'.info');
 156      if (!isset($info['project']) || (isset($info['project']) && ($info['project'] == 'drupal' || isset($projects[$info['project']])))) {
 157        continue;
 158      }
 159      $projects[$info['project']] = 1;
 160      $url = 'http://drupal.org/project/issues/'. $info['project'];
 161      // Filtering project versions via query string is not yet supported.
 162      // @see http://drupal.org/node/97569
 163      // $url .= !empty($info['version']) ? '/'. $info['version'] : '';
 164      $links[] = array(
 165        'title' => check_plain($info['name']) . ' issue queue',
 166        'path' => $url,
 167        'parent_path' => 'http://drupal.org',
 168      );
 169    }
 170  
 171    // Add 'Create <content-type>' items to Content management menu.
 172    if (isset($deleted['node/add'])) {
 173      $deleted['node/add']['parent_path'] = 'admin/content';
 174      $deleted['node/add']['weight'] = 0;
 175      $links[] = $deleted['node/add'];
 176      unset($deleted['node/add']);
 177    }
 178    foreach($deleted as $path => $item) {
 179      if (strpos($path, 'node/add') !== FALSE) {
 180        $links[] = $deleted[$path];
 181        unset($deleted[$path]);
 182      }
 183    }
 184    // Make sure longer paths are after shorter ones
 185    ksort($deleted);
 186    foreach (node_get_types('types', NULL, TRUE) as $type) {
 187      $type_url_str = str_replace('_', '-', $type->type);
 188      $type_path = 'admin/content/node-type/' . $type_url_str;
 189      $links[$type_path] = array(
 190        'title' => 'Edit !content-type',
 191        'path' => $type_path,
 192        'parent_path' => 'admin/content/types',
 193        'options' => array('t' => array('!content-type' => $type->name)),
 194      );
 195      unset($deleted[$type_path . '/edit']);
 196      // CCK and other modules adding to node types handled here.
 197      foreach($deleted as $path => $item) {
 198        // Precise test needed to account for multiple content-types having the
 199        // same prefix in their name.
 200        if ($path === $type_path || strpos($path, $type_path . '/') === 0) {
 201          // Logically, parent path can never go shorter than $type_path.
 202          $i = $item['_number_parts'] - 1;
 203          do {
 204            $parent_path = implode('/', array_slice($item['_parts'], 0, $i));
 205            --$i;
 206          } while (!isset($links[$parent_path]) && $i);
 207          $item['parent_path'] = $parent_path;
 208          $links[$path] = $item;
 209          unset($deleted[$path]);
 210        }
 211      }
 212    }
 213  
 214    // Add clear-cache.
 215    $links[] = array(
 216      'title' => 'Flush all caches',
 217      'path' => 'admin_menu/flush-cache',
 218      'query' => 'destination',
 219      'weight' => 20,
 220      'parent_path' => $icon_path,
 221    );
 222    $caches = array(
 223      'admin_menu' => 'Administration menu',
 224      'cache' => 'Cache tables',
 225      'menu' => 'Menu',
 226      'requisites' => 'Page requisites',
 227      'theme' => 'Theme registry',
 228    );
 229    foreach ($caches as $name => $title) {
 230      $links[] = array(
 231        'title' => $title,
 232        'path' => 'admin_menu/flush-cache/' . $name,
 233        'query' => 'destination',
 234        'parent_path' => 'admin_menu/flush-cache',
 235      );
 236    }
 237  
 238    // Add devel module links
 239    if (module_exists('devel')) {
 240      // Add variable editor.
 241      $links[] = array(
 242        'title' => 'Variable editor',
 243        'path' => 'devel/variable',
 244        'weight' => 20,
 245        'parent_path' => $icon_path,
 246      );
 247      // Add switch_user items.
 248      if ($devel_user_links = module_invoke('devel', 'switch_user_list')) {
 249        foreach ($devel_user_links as $link) {
 250          if (is_array($link)) {
 251            $links[] = array(
 252              'title' => $link['title'],
 253              'description' => $link['attributes']['title'],
 254              'path' => $link['href'],
 255              'options' => array(
 256                'query' => $link['query'],
 257                'html' => !empty($link['html']),
 258              ),
 259              'parent_path' => 'logout',
 260            );
 261          }
 262          // @todo Remove when Devel 6.x-1.16 has been released.
 263          elseif (preg_match('!href="' . base_path() . '([^\?]+)\?([^"]+)" title="([^"]+)">((<em>)?[^<]+(</em>)?)!', $link, $match)) {
 264            $links[] = array(
 265              'title' => $match[4],
 266              'description' => $match[3],
 267              'path' => urldecode($match[1]),
 268              'weight' => 20,
 269              'query' => 'destination',
 270              'parent_path' => 'logout',
 271              'options' => array('html' => TRUE),
 272            );
 273          }
 274        }
 275      }
 276    }
 277    // Add developer modules toggle link.
 278    $saved_state = variable_get('admin_menu_devel_modules_enabled', NULL);
 279    $links[] = array(
 280      'title' => isset($saved_state) ? t('Enable developer modules') : t('Disable developer modules'),
 281      'path' => 'admin_menu/toggle-modules',
 282      'weight' => 88,
 283      'parent_path' => $icon_path,
 284      'options' => array('query' => 'destination'),
 285    );
 286  
 287    return $links;
 288  }
 289  
 290  /**
 291   * Add some hard-coded features for better user experience.
 292   *
 293   * @param array $menu_links
 294   *   An array containing the complete administration menu structure, passed by
 295   *   reference.
 296   * @param array $sort
 297   *   An array containing the # parts of each link - must be updated if a link
 298   *   is added.
 299   * @return
 300   *   An array of links that were removed from $menu_links.
 301   */
 302  function admin_menu_adjust_items(&$menu_links, &$sort) {
 303    global $user;
 304    $links = array();
 305    $deleted = array();
 306  
 307    // Change or remove items, or add new top-level items.
 308    $deleted['admin/by-module'] = $menu_links['admin/by-module'];
 309    unset($menu_links['admin/by-module'], $sort['admin/by-module']);
 310    $deleted['admin/by-task'] = $menu_links['admin/by-task'];
 311    unset($menu_links['admin/by-task'], $sort['admin/by-task']);
 312  
 313    // Remove certain links to re-position them in admin_menu_admin_menu().
 314    foreach ($menu_links as $path => $link) {
 315      // Remove links below
 316      // - admin/content/node-type/*
 317      // - node/add*
 318      if (strpos($path, 'admin/content/node-type/') !== FALSE || strpos($path, 'node/add') !== FALSE) {
 319        $deleted[$path] = $link;
 320        unset($menu_links[$path], $sort[$path]);
 321      }
 322    }
 323    // Add the icon containing special links.
 324    $links[] = array(
 325      'title' => theme('admin_menu_icon'),
 326      'path' => '<front>',
 327      'weight' => -100,
 328      'parent_path' => '<root>',
 329      'options' => array('extra class' => 'admin-menu-icon', 'html' => TRUE),
 330    );
 331    // Add link to show current authenticated/anonymous users - we will add the
 332    // data dynamically in the _alter hook.
 333    $links[] = array(
 334      'title' => 'icon_users',
 335      'path' => 'user',
 336      'weight' => -90,
 337      'parent_path' => '<root>',
 338      'options' => array('extra class' => 'admin-menu-action admin-menu-icon admin-menu-users', 'html' => TRUE),
 339    );
 340    $links[] = array(
 341      'title' => 'Log out @username',
 342      'path' => 'logout',
 343      'weight' => -100,
 344      'parent_path' => '<root>',
 345      // Note: @username is dynamically replaced by default, we just invoke
 346      // replacement by setting the 't' key here.
 347      'options' => array('extra class' => 'admin-menu-action admin-menu-logout', 't' => array()),
 348    );
 349    foreach ($links as $item) {
 350      $path = $item['path'];
 351      $item = admin_menu_link_build($item);
 352      $menu_links[$path] = $item;
 353      $sort[$path] = 1;
 354    }
 355  
 356    return $deleted;
 357  }
 358  
 359  /**
 360   * Form builder function for module settings.
 361   */
 362  function admin_menu_theme_settings() {
 363    $form['admin_menu_margin_top'] = array(
 364      '#type' => 'checkbox',
 365      '#title' => t('Adjust top margin'),
 366      '#default_value' => variable_get('admin_menu_margin_top', 1),
 367      '#description' => t('If enabled, the site output is shifted down approximately 20 pixels from the top of the viewport to display the administration menu. If disabled, some absolute- or fixed-positioned page elements may be covered by the administration menu.'),
 368    );
 369    $form['admin_menu_position_fixed'] = array(
 370      '#type' => 'checkbox',
 371      '#title' => t('Keep menu at top of page'),
 372      '#default_value' => variable_get('admin_menu_position_fixed', 0),
 373      '#description' => t('If enabled, the administration menu is always displayed at the top of the browser viewport (even after the page is scrolled). <strong>Note: In some browsers, this setting results in a malformed page, an invisible cursor, non-selectable elements in forms, or other issues. Disable this option if these issues occur.</strong>'),
 374    );
 375    $form['tweaks'] = array(
 376      '#type' => 'fieldset',
 377      '#title' => t('Advanced settings'),
 378    );
 379    $form['tweaks']['admin_menu_tweak_modules'] = array(
 380      '#type' => 'checkbox',
 381      '#title' => t('Collapse fieldsets on modules page'),
 382      '#default_value' => variable_get('admin_menu_tweak_modules', 0),
 383      '#description' => t('If enabled, fieldsets on the <a href="!modules-url">modules</a> page are automatically collapsed when loading the page.', array('!modules-url' => url('admin/build/modules'))),
 384    );
 385    if (module_exists('util')) {
 386      $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>';
 387    }
 388    $form['tweaks']['admin_menu_tweak_tabs'] = array(
 389      '#type' => 'checkbox',
 390      '#title' => t('Move local tasks into menu'),
 391      '#default_value' => variable_get('admin_menu_tweak_tabs', 0),
 392      '#description' => t('If enabled, the tabs on the current page are moved into the administration menu. This feature is only available in themes that use the CSS classes <code>tabs primary</code> and <code>tabs secondary</code> for tabs.'),
 393    );
 394    $form = system_settings_form($form);
 395    $form['wipe description'] = array(
 396      '#type' => 'item',
 397      '#value' => t('If the administration menu displays duplicate menu items, you may need to rebuild your menu items using the <em>Wipe and rebuild</em> button.'),
 398    );
 399    $form['wipe'] = array(
 400      '#type' => 'submit',
 401      '#value' => t('Wipe and rebuild'),
 402      '#submit' => array('admin_menu_wipe'),
 403    );
 404  
 405    return $form;
 406  }
 407  
 408  /**
 409   * Wipe the menu so it can be rebuilt from scratch.
 410   */
 411  function admin_menu_wipe() {
 412    db_query("DELETE FROM {menu_links} WHERE menu_name = 'admin_menu'");
 413    menu_cache_clear('admin_menu');
 414    variable_set('admin_menu_rebuild_links', TRUE);
 415  }
 416  
 417  /**
 418   * Helper function for admin_menu_form_devel_admin_settings_alter().
 419   *
 420   * Extends Devel module with Administration Menu developer settings.
 421   */
 422  function _admin_menu_devel_settings_form_alter(&$form, $form_state) {
 423    // Shift system_settings_form buttons.
 424    $weight = isset($form['buttons']['#weight']) ? $form['buttons']['#weight'] : 0;
 425    $form['buttons']['#weight'] = $weight + 1;
 426  
 427    $form['admin_menu'] = array(
 428      '#type' => 'fieldset',
 429      '#title' => t('Administration menu settings'),
 430      '#collapsible' => TRUE,
 431      '#collapsed' => TRUE,
 432    );
 433    $display_options = array('mid', 'weight', 'pid');
 434    $display_options = array(0 => t('None'), 'mlid' => t('Menu link ID'), 'weight' => t('Weight'), 'plid' => t('Parent link ID'));
 435    $form['admin_menu']['admin_menu_display'] = array(
 436      '#type' => 'radios',
 437      '#title' => t('Display additional data for each menu item'),
 438      '#default_value' => variable_get('admin_menu_display', 0),
 439      '#options' => $display_options,
 440      '#description' => t('Display the selected items next to each menu item link.'),
 441    );
 442    $form['admin_menu']['admin_menu_show_all'] = array(
 443      '#type' => 'checkbox',
 444      '#title' => t('Display all menu items'),
 445      '#default_value' => variable_get('admin_menu_show_all', 0),
 446      '#description' => t('If enabled, all menu items are displayed regardless of your site permissions. <em>Note: Do not enable on a production site.</em>'),
 447    );
 448  }
 449  
 450  /**
 451   * Menu callback to enable/disable developer modules.
 452   *
 453   * This saves up to 150ms on each uncached page request. Not much, but
 454   * on larger Drupal sites this is actually a 10% performance increase.
 455   */
 456  function admin_menu_toggle_modules() {
 457    $rebuild = FALSE;
 458    $saved_state = variable_get('admin_menu_devel_modules_enabled', NULL);
 459    if (isset($saved_state)) {
 460      // Re-enable modules that were enabled before.
 461      module_enable($saved_state);
 462      variable_del('admin_menu_devel_modules_enabled');
 463      drupal_set_message(t('Enabled these modules: !module-list.', array('!module-list' => implode(', ', $saved_state))));
 464      $rebuild = TRUE;
 465    }
 466    else {
 467      // Allow site admins to override this variable via settings.php.
 468      $devel_modules = variable_get('admin_menu_devel_modules', array('cache_disable', 'coder', 'content_copy', 'debug', 'delete_all', 'demo', 'devel', 'devel_node_access', 'devel_themer', 'macro', 'form_controller', 'imagecache_ui', 'journal', 'trace', 'upgrade_status', 'user_display_ui', 'util', 'views_ui', 'views_theme_wizard'));
 469      // Store currently enabled modules in a variable.
 470      $devel_modules = array_intersect(module_list(FALSE, FALSE), $devel_modules);
 471      if (!empty($devel_modules)) {
 472        variable_set('admin_menu_devel_modules_enabled', $devel_modules);
 473        // Disable developer modules.
 474        module_disable($devel_modules);
 475        drupal_set_message(t('Disabled these modules: !module-list.', array('!module-list' => implode(', ', $devel_modules))));
 476        $rebuild = TRUE;
 477      }
 478      else {
 479        drupal_set_message(t('No developer modules are enabled.'));
 480      }
 481    }
 482    if ($rebuild) {
 483      // Make sure everything is rebuilt, basically a combination of the calls
 484      // from system_modules() and system_modules_submit().
 485      drupal_rebuild_theme_registry();
 486      menu_rebuild();
 487      cache_clear_all('schema', 'cache');
 488      cache_clear_all();
 489      drupal_clear_css_cache();
 490      drupal_clear_js_cache();
 491      // Synchronize to catch any actions that were added or removed.
 492      actions_synchronize();
 493    }
 494    drupal_goto('');
 495  }
 496  
 497  /**
 498   * Flush all caches or a specific one.
 499   *
 500   * @param $name
 501   *   (optional) Name of cache to flush.
 502   */
 503  function admin_menu_flush_cache($name = NULL) {
 504    switch ($name) {
 505      case 'admin_menu':
 506        admin_menu_wipe();
 507        break;
 508  
 509      case 'cache':
 510        // Don't clear cache_form - in-progress form submissions may break.
 511        // Ordered so clearing the page cache will always be the last action.
 512        $core = array('cache', 'cache_block', 'cache_filter', 'cache_page');
 513        $cache_tables = array_merge(module_invoke_all('flush_caches'), $core);
 514        foreach ($cache_tables as $table) {
 515          cache_clear_all('*', $table, TRUE);
 516        }
 517        break;
 518  
 519      case 'menu':
 520        module_invoke('menu', 'rebuild');
 521        break;
 522  
 523      case 'requisites':
 524        // Change query-strings on css/js files to enforce reload for all users.
 525        _drupal_flush_css_js();
 526  
 527        drupal_clear_css_cache();
 528        drupal_clear_js_cache();
 529        break;
 530  
 531      case 'theme':
 532        module_invoke('system', 'theme_data');
 533        drupal_rebuild_theme_registry();
 534        break;
 535  
 536      default:
 537        // Flush all caches; no need to re-implement this.
 538        module_load_include('inc', 'system', 'system.admin');
 539        $form = $form_state = array();
 540        system_clear_cache_submit($form, $form_state);
 541        break;
 542    }
 543    drupal_goto();
 544  }
 545  


Generated: Thu Mar 24 11:18:33 2011 Cross-referenced by PHPXref 0.7