[ Index ]

PHP Cross Reference of Drupal 6 (gatewave)

title

Body

[close]

/sites/all/modules/admin/ -> admin.module (source)

   1  <?php
   2  // $Id: admin.module,v 1.1.2.23 2009/07/30 14:41:34 yhahn Exp $
   3  
   4  /**
   5   * Implementation of hook_init().
   6   */
   7  function admin_init() {
   8    // Don't do anything if the user has no access.
   9    if (!user_access('admin menu') && !user_access('admin inline')) {
  10      return;
  11    }
  12  
  13    $path = drupal_get_path('module', 'admin');
  14    drupal_add_js($path .'/toolbar/admin_toolbar.js');
  15    drupal_add_css($path .'/toolbar/admin_toolbar.css');
  16  
  17    if (arg(0) == 'admin') {
  18      // Set the active menu
  19      menu_set_active_menu_name('admin');
  20  
  21      // Conditionally include admin functions (form alters, etc.)
  22      module_load_include('inc', 'admin', 'admin.admin');
  23    }
  24    
  25    $admin_theme = variable_get('admin_theme', 'slate');
  26  
  27    // Initialize the slate theme. Bypass the theme system entirely so we can load our own theme into place.
  28    if (variable_get('node_admin_theme', 0) && (strpos($_GET['q'], 'node/add') === 0 || strpos($_GET['q'], 'admin/content/add') === 0 || (arg(0) == 'node' && arg(2) == 'edit'))) {
  29      _admin_init_theme();
  30    }
  31    else if (arg(0) == 'admin' && ($admin_theme == 'slate' || empty($admin_theme))) {
  32      if (strpos($_GET['q'], 'admin/build/block') === 0) {
  33        if (in_array(arg(3), array('configure', 'delete', 'add'), TRUE)) {
  34          _admin_init_theme();
  35        }
  36      }
  37      else {
  38        _admin_init_theme();
  39      }
  40    }
  41    else if (function_exists('admin_theme_init') && $GLOBALS['custom_theme'] == 'slate') {
  42      _admin_init_theme();
  43    }
  44  }
  45  
  46  /**
  47   * Menu access callback for admin landing pages.
  48   */
  49  function admin_landing_page_access($path) {
  50    static $paths;
  51    if (!isset($paths)) {
  52      $cache = cache_get('admin_paths');
  53      $paths = ($cache && !empty($cache->data)) ? $cache->data : array();
  54    }
  55    if (!isset($paths[$path])) {
  56      $item = db_fetch_array(db_query("SELECT mlid, menu_name FROM {menu_links} ml WHERE ml.router_path = '%s' AND module = 'system'", $path));
  57      $result = db_query("
  58        SELECT m.load_functions, m.to_arg_functions, m.access_callback, m.access_arguments, m.page_callback, m.page_arguments, m.title, m.title_callback, m.title_arguments, m.type, m.description, ml.*
  59        FROM {menu_links} ml
  60        LEFT JOIN {menu_router} m ON ml.router_path = m.path
  61        WHERE ml.plid = %d AND ml.menu_name = '%s' AND hidden = 0", $item['mlid'], $item['menu_name']);
  62      $paths[$path] = FALSE;
  63      while ($item = db_fetch_array($result)) {
  64        $item['options'] = unserialize($item['options']);
  65        if ($item['external']) {
  66          if (!empty($item['options']['alter'])) {
  67            drupal_alter('translated_menu_link', $item, $map);
  68          }
  69          if ($item['access']) {
  70            $paths[$path] = TRUE;
  71            break;
  72          }
  73        }
  74        else {
  75          $map = explode('/', $item['link_path']);
  76          _menu_link_map_translate($map, $item['to_arg_functions']);
  77          $item['href'] = implode('/', $map);
  78          if (strpos($item['href'], '%') !== FALSE) {
  79            continue;
  80          }
  81          if (!isset($item['access'])) {
  82            if (!_menu_load_objects($item, $map)) {
  83              continue;
  84            }
  85            _menu_check_access($item, $map);
  86          }
  87          if (!$item['access']) {
  88            continue;
  89          }
  90          $paths[$path] = TRUE;
  91          break;
  92        }
  93      }
  94      cache_set('admin_paths', $paths);
  95    }
  96    return $paths[$path];
  97  }
  98  
  99  /**
 100   * Implementation of hook_menu_alter().
 101   */
 102  function admin_menu_alter(&$items) {
 103    foreach ($items as $path => $item) {
 104      $args = explode('/', $path);
 105      // Move all admin/* items to admin menu links.
 106      if ($args && $args[0] === 'admin') {
 107        $items[$path]['menu_name'] = 'admin';
 108      }
 109      // Smarter access callback for poorly checked landing pages
 110      if (!empty($item['access arguments']) && !empty($item['page callback']) && $item['access arguments'] === array('access administration pages') && in_array($item['page callback'], array('system_admin_menu_block_page', 'system_settings_overview'))) {
 111        $items[$path]['access callback'] = 'admin_landing_page_access';
 112        $items[$path]['access arguments'] = array($path);
 113      }
 114    }
 115  
 116    // Move admin theme settings to theme local task.
 117    $items['admin/build/themes/admin'] = $items['admin/settings/admin'];
 118    $items['admin/build/themes/admin']['type'] = MENU_LOCAL_TASK;
 119    $items['admin/build/themes/admin']['weight'] = 10;
 120    unset($items['admin/settings/admin']);
 121  
 122    // Add in a routing item for admin/content/add
 123    $items['admin/content/add'] = $items['node/add'];
 124    $items['admin/content/add']['page callback'] = 'drupal_goto';
 125    $items['admin/content/add']['page arguments'] = array('node/add');
 126    $items['admin/content/add']['description'] = 'Create new content on your site.';
 127    $items['admin/content/add']['weight'] = -20;
 128    $items['admin/content/node']['weight'] = -19;
 129  
 130    $items = array_merge($items, admin_menu_clone_items('admin/build/themes', 'admin/themes', $items));
 131    $items = array_merge($items, admin_menu_clone_items('admin/build/modules', 'admin/modules', $items));
 132  
 133    // Expose a small subset of the most usable core admin pages.
 134    // Other pages can be exposed simply by adding ['options']['admin'] = TRUE
 135    // to items in hook_menu().
 136    $include = array(
 137      'admin/content' => 'Content',
 138      'admin/content/add' => 'Add',
 139      'admin/content/node' => 'Edit',
 140  
 141      'admin/build' => 'Structure',
 142      'admin/build/views' => '',
 143      'admin/build/block' => '',
 144      'admin/build/menu' => '',
 145  
 146      'admin/user' => 'People',
 147      'admin/user/permissions' => '',
 148      'admin/user/user' => '',
 149  
 150      'admin/settings' => 'Configuration',
 151      'admin/settings/date-time' => '',
 152      'admin/settings/filters' => '',
 153      'admin/settings/language' => '',
 154      'admin/settings/performance' => '',
 155      'admin/settings/site-information' => '',
 156  
 157      'admin/themes' => 'Appearance',
 158      'admin/modules' => '',
 159    );
 160  
 161    foreach ($include as $path => $title) {
 162      if (!empty($items[$path])) {
 163        $items[$path]['title'] = !empty($title) ? $title : $items[$path]['title'];
 164        $items[$path]['options']['admin'] = TRUE;
 165      }
 166    }
 167    cache_clear_all('admin_paths', 'cache');
 168  }
 169  
 170  /**
 171   * Helper to clone portions of the menu tree to a duplicate location.
 172   */
 173  function admin_menu_clone_items($search, $replace, $items) {
 174    $offset = count(explode('/', $replace)) - count(explode('/', $search));
 175  
 176    $clone = array();
 177    foreach ($items as $path => $item) {
 178      if (strpos($path, $search) === 0) {
 179        $clone_path = str_replace($search, $replace, $path);
 180  
 181        // Adjust argument offsets if the search and replace paths have a
 182        // different arg counts.
 183        if ($offset != 0) {
 184          foreach (array('page arguments', 'access arguments', 'load arguments', 'title arguments') as $arg_key) {
 185            if (!empty($item[$arg_key])) {
 186              foreach ($item[$arg_key] as $k => $v) {
 187                if (is_numeric($v)) {
 188                  $item[$arg_key][$k] = $v + $offset;
 189                }
 190              }
 191            }
 192          }
 193        }
 194  
 195        $clone[$clone_path] = $item;
 196      }
 197    }
 198    return $clone;
 199  }
 200  
 201  /**
 202   * Implementation of hook_flush_caches().
 203   */
 204  function admin_flush_caches() {
 205    // Reinsert admin theme when caches are cleared.
 206    _admin_theme_rebuild(TRUE);
 207  }
 208  
 209  /**
 210   * Implementation of hook_system_info_alter().
 211   * Throw a flag that tells us we need to reinstantiate the admin theme.
 212   */
 213  function admin_system_info_alter(&$info, &$theme) {
 214    static $once;
 215    if (!isset($once)) {
 216      $once = TRUE;
 217      variable_set('admin_theme_invalidated', TRUE);
 218    }
 219  }
 220  
 221  /**
 222   * Implementation of hook_help().
 223   */
 224  function admin_help($path, $arg) {
 225    // Fool node help to think we are on node/add
 226    if ($arg[0] == 'admin' && $arg[1] == 'content' && $arg[2] == 'add' && $arg[3]) {
 227      $path = 'node/add/'. $arg[3];
 228      $arg = array('node', 'add', $arg[3]);
 229      return module_invoke('node', 'help', $path, $arg);
 230    }
 231  }
 232  
 233  /**
 234   * Implementation of hook_perm().
 235   */
 236  function admin_perm() {
 237    return array('admin menu', 'admin inline');
 238  }
 239  
 240  /**
 241   * Implementation of hook_theme().
 242   */
 243  function admin_theme($cache, $type, $theme, $path) {
 244    $path = drupal_get_path('module', 'admin');
 245    $items['admin_menu_overview_form'] = array(
 246      'arguments' => array('form' => array()),
 247    );
 248    $items['admin_toolbar'] = array(
 249      'arguments' => array('tree' => array()),
 250      'template' => 'admin-toolbar',
 251      'path' => $path . '/toolbar',
 252      'file' => 'theme.inc',
 253    );
 254    $items['admin_links'] = array(
 255      'arguments' => array('links' => array()),
 256      'template' => 'admin-links',
 257      'path' => $path . '/toolbar',
 258      'file' => 'theme.inc',
 259    );
 260    $items['admin_manage_options'] = array(
 261      'arguments' => array('form' => array()),
 262      'path' => $path . '/theme',
 263      'file' => 'template.php',
 264    );
 265    return $items;
 266  }
 267  
 268  /**
 269   * Wrapper to check whether various admin features are accessible to the
 270   * current user and compatible with the current theme.
 271   */
 272  function admin_is_enabled($op = 'admin menu') {
 273    if (user_access($op)) {
 274      global $theme_info;
 275      // If the theme does not specify some flag for this feature, assume
 276      // it is compatible.
 277      if (!isset($theme_info->info['admin'][$op]) || (isset($theme_info->info['admin'][$op]) && !empty($theme_info->info['admin'][$op]))) {
 278        return TRUE;
 279      }
 280    }
 281    return FALSE;
 282  }
 283  
 284  /**
 285   * Retrieve the admin links for a given object.
 286   */
 287  function admin_get_links($type, $object) {
 288    $links = array();
 289    if (admin_is_enabled('admin inline')) {
 290      $links = module_invoke_all('admin_link', $type, $object);
 291      drupal_alter('admin_link', $links, $type, $object);
 292    }
 293    return $links;
 294  }
 295  
 296  /**
 297   * Implementation of hook_admin_link() on behalf of the node module.
 298   */
 299  function node_admin_link($type, $object) {
 300    $links = array();
 301    if ($type == 'node') {
 302      if (node_access('update', $object)) {
 303        $links['node-edit'] = array(
 304          'title' => t('Edit'),
 305          'href' => "node/{$object->nid}/edit",
 306          'attributes' => array('class' => 'icon-edit'),
 307          'query' => array('destination' => $_GET['q']),
 308        );
 309      }
 310      if (node_access('delete', $object)) {
 311        $links['node-delete'] = array(
 312          'title' => t('Delete'),
 313          'href' => "node/{$object->nid}/delete",
 314          'attributes' => array('class' => 'icon-delete'),
 315          'query' => array('destination' => $_GET['q']),
 316        );
 317      }
 318    }
 319    return $links;
 320  }
 321  
 322  /**
 323   * Implementation of hook_admin_link() on behalf of the block module.
 324   */
 325  function block_admin_link($type, $object) {
 326    $links = array();
 327    if ($type == 'block') {
 328      if (user_access('administer blocks')) {
 329        $links['block-configure'] = array(
 330          'title' => t('Configure'),
 331          'href' => "admin/build/block/configure/{$object->module}/{$object->delta}",
 332          'attributes' => array('class' => 'icon-configure'),
 333          'query' => array('destination' => $_GET['q']),
 334        );
 335      }
 336    }
 337    return $links;
 338  }
 339  
 340  /**
 341   * Implementation of hook_admin_link() on behalf of the views module.
 342   */
 343  function views_admin_link($type, $object) {
 344    $links = array();
 345    $view_name = '';
 346    if (user_access('administer views')) {
 347      switch ($type) {
 348        case 'block':
 349          // If this is a Views block and not a special (exposed filter, etc.) block...
 350          if ($object->module == 'views' && strpos($object->delta, '-') !== 0) {
 351            $split = explode('-', $object->delta);
 352            $view_name = array_shift($split);
 353          }
 354          break;
 355        case 'views':
 356          // Bail on block/attachment views or views using the node row plugin to prevent collisions.
 357          if ($object->display_handler->get_option('row_plugin') != 'node' && !in_array(get_class($object->display_handler), array('views_plugin_display_attachment', 'views_plugin_display_block'))) {
 358            $view_name = $object->name;
 359          }
 360          break;
 361      }
 362      if (!empty($view_name)) {
 363        $links['views-edit'] = array(
 364          'title' => t('Edit view'),
 365          'href' => "admin/build/views/edit/{$view_name}",
 366          'attributes' => array('class' => 'icon-edit'),
 367          'query' => array('destination' => $_GET['q']),
 368        );
 369      }
 370    }
 371    return $links;
 372  }
 373  
 374  /**
 375   * Implementation of hook_theme_registry_alter().
 376   */
 377  function admin_theme_registry_alter(&$theme_registry) {
 378    $hooks = array(
 379      'page',
 380      'block',
 381      'views_view',
 382      'node',
 383    );
 384    foreach ($hooks as $hook) {
 385      if (empty($theme_registry[$hook]['preprocess functions']) || !in_array('admin_preprocess_'. $hook, $theme_registry[$hook]['preprocess functions'])) {
 386        $theme_registry[$hook]['preprocess functions'][] = 'admin_preprocess_'. $hook;
 387      }
 388    }
 389    // If the slate theme has been inited, do some additional work.
 390    global $theme;
 391    if ($theme == 'slate') {
 392      // Slap a preprocessor on at the very front of the stack for rebuilding the admin theme.
 393      if (!in_array('admin_page_alter', $theme_registry['page']['preprocess functions'])) {
 394        array_unshift($theme_registry['page']['preprocess functions'], 'admin_page_alter');
 395      }
 396      $overrides = array('fieldset', 'node_form', 'system_settings_form', 'admin_block_content');
 397      foreach ($overrides as $hook) {
 398        $theme_registry[$hook]['function'] = 'slate_'. $hook;
 399        $theme_registry[$hook]['theme path'] = drupal_get_path('module', 'admin') . '/theme';
 400      }
 401    }
 402  }
 403  
 404  /**
 405   * Page preprocessor that runs before any others (including template_preprocess_page()).
 406   * Check the theme rebuild flag and do so if necessary.
 407   */
 408  function admin_page_alter(&$vars) {
 409    _admin_theme_rebuild();
 410  }
 411  
 412  /**
 413   * Implementation of hook_preprocess_page().
 414   */
 415  function admin_preprocess_page(&$vars) {
 416    $vars['admin'] = '';
 417    if (admin_is_enabled('admin menu')) {
 418      $links = admin_menu_tree();
 419      $links = theme('admin_toolbar', $links);
 420      $vars['admin'] = $links;
 421    }
 422  }
 423  
 424  /**
 425   * Implementation of hook_preprocess_views_view().
 426   */
 427  function admin_preprocess_views_view(&$vars) {
 428    $admin_links = theme('admin_links', admin_get_links('views', $vars['view']));
 429    if ($admin_links) {
 430      $vars['pager'] .= $admin_links;
 431    }
 432  
 433    // Disable the Views admin links stack to prevent clutter.
 434    $vars['admin_links'] = '';
 435    $vars['admin_links_raw'] = '';
 436  }
 437  
 438  /**
 439   * Implementation of hook_preprocess_block().
 440   */
 441  function admin_preprocess_block(&$vars) {
 442    $vars['block']->content .= theme('admin_links', admin_get_links('block', $vars['block']));
 443  }
 444  
 445  /**
 446   * Implementation of hook_preprocess_node().
 447   */
 448  function admin_preprocess_node(&$vars) {
 449    $vars['content'] .= theme('admin_links', admin_get_links('node', $vars['node']));
 450  }
 451  
 452  /**
 453   * Helper for returning a selectively flattened version of the admin menu.
 454   */
 455  function admin_get_menu_tree($method = 'all', $reset = FALSE) {
 456    $tree = ($method == 'all' ? menu_tree_all_data('admin') : menu_tree_page_data('admin'));
 457    foreach ($tree as $k => $item) {
 458      if ($item['link']['link_path'] == 'admin' && !empty($item['below'])) {
 459        unset($tree[$k]);
 460        $tree = array_merge($tree, $item['below']);
 461      }
 462    }
 463    return $tree;
 464  }
 465  
 466  /**
 467   * Retrieve a hierarchy of links representing select portions of the
 468   * 'admin' branch of the navigation menu.
 469   */
 470  function admin_menu_tree() {
 471    $links = array();
 472    // Retrieve the admin menu from the database.
 473    $tree = admin_get_menu_tree();
 474    admin_menu_tree_links($tree, $links);
 475  
 476    // Add user-specific links
 477    global $user;
 478    $user_links = array();
 479    if (empty($user->uid)) {
 480      $user_links[] = array(
 481        'title' => t('Login'),
 482        'href' => 'user',
 483        'html' => TRUE
 484      );
 485      $user_links[] = array(
 486        'title' => t('Register'),
 487        'href' => 'user/register',
 488        'html' => TRUE
 489      );
 490    }
 491    else {
 492      $user_links[] = array(
 493        'title' => t('Hello <strong>!username</strong>', array('!username' => $user->name)),
 494        'href' => 'user',
 495        'html' => TRUE
 496      );
 497      $user_links[] = array('title' => t('Logout'), 'href' => "logout");
 498    }
 499    $links[0]['user'] = $user_links;
 500  
 501    return $links;
 502  }
 503  
 504  /**
 505   * Generate a links array from a menu tree array.
 506   */
 507  function admin_menu_navigation_links($tree, $admin_only = FALSE) {
 508    $links = array();
 509    foreach ($tree as $item) {
 510      if (!$item['link']['hidden'] && (!$admin_only || !empty($item['link']['options']['admin']))) {
 511        $class = '';
 512        $id = str_replace('/', '-', $item['link']['href']);
 513  
 514        $l = $item['link']['localized_options'];
 515        $l['href'] = $item['link']['href'];
 516        $l['title'] = "<span class='icon'></span>". $item['link']['title'];
 517        $l['attributes'] = array('id' => 'admin-link-'. $id);
 518        $l['html'] = TRUE;
 519  
 520        $class = ' path-'. $id;
 521        if (admin_in_active_trail($item['link']['href'])) {
 522          $class .= ' active-trail';
 523        }
 524        // Keyed with the unique mlid to generate classes in theme_links().
 525        $links['menu-'. $item['link']['mlid'] . $class] = $l;
 526      }
 527    }
 528    return $links;
 529  }
 530  
 531  /**
 532   * Build a hierarchy of $links arrays suitable for theme_links() from a
 533   * menu tree.
 534   */
 535  function admin_menu_tree_links($tree, &$links, $parent = 'admin', $depth = 0) {
 536    // Create a single level of links.
 537    $links[$depth][$parent] = array();
 538    $l = admin_menu_navigation_links($tree, TRUE);
 539    if (!empty($l)) {
 540      $links[$depth][$parent] = $l;
 541    }
 542  
 543    // Recurse
 544    foreach ($tree as $item) {
 545      if (!$item['link']['hidden'] && !empty($item['link']['options']['admin'])) {
 546        if (!empty($item['below'])) {
 547          admin_menu_tree_links($item['below'], $links, $item['link']['href'], $depth + 1);
 548        }
 549      }
 550    }
 551  }
 552  
 553  /**
 554   * Checks whether an item is in the active trail. Useful when using
 555   * a menu generated by menu_tree_all_data() which does not set the
 556   * 'in_active_trail' flag on items.
 557   */
 558  function admin_in_active_trail($path, $reset = FALSE) {
 559    // Gather active paths
 560    static $active_paths;
 561    if (!isset($active_paths) || $reset) {
 562      $active_paths = array();
 563      $trail = menu_get_active_trail();
 564      foreach ($trail as $item) {
 565        if (!empty($item['href'])) {
 566          $active_paths[] = $item['href'];
 567        }
 568      }
 569    }
 570    return in_array($path, $active_paths);
 571  }
 572  
 573  /**
 574   * Rebuild the admin theme entry in the database.
 575   */
 576  function _admin_theme_rebuild($force = FALSE) {
 577    static $exists;
 578    if (!isset($exists) && arg(0) == 'admin') {
 579      $exists = db_result(db_query("SELECT count(*) FROM {system} WHERE name = 'slate' AND type = 'theme'"));
 580      $force = !$exists ? TRUE : $force;
 581    }
 582    if ($force || variable_get('admin_theme_invalidated', FALSE)) {
 583      $path = drupal_get_path('module', 'admin') .'/theme';
 584  
 585      $theme = new StdClass();
 586      $theme->name = 'slate';
 587      $theme->filename = "{$path}/slate.info";
 588      $theme->engine = 'phptemplate';
 589      $theme->owner = drupal_get_path('theme_engine', 'phptemplate') .'/phptemplate.engine';
 590      $theme->info = system_theme_default();
 591      $theme->info['name'] = 'Slate';
 592  
 593      db_query("DELETE FROM {system} WHERE name = 'slate' AND type = 'theme'");
 594      db_query("INSERT INTO {system} (name, owner, info, type, filename, status, throttle, bootstrap) VALUES ('%s', '%s', '%s', '%s', '%s', %d, %d, %d)", $theme->name, $theme->owner, serialize($theme->info), 'theme', $theme->filename, isset($theme->status) ? $theme->status : 0, 0, 0);
 595    
 596      variable_set('admin_theme_invalidated', FALSE);
 597    }
 598  }
 599  
 600  /**
 601   * Initialize the admin "theme".
 602   */
 603  function _admin_init_theme() {
 604    global $theme, $theme_key;
 605    if (empty($theme)) {
 606      _admin_theme_rebuild();
 607  
 608      $theme = $theme_key = 'slate';
 609  
 610      $path = drupal_get_path('module', 'admin') .'/theme';
 611  
 612      $theme_info = new StdClass();
 613      $theme_info->name = 'slate';
 614      $theme_info->filename = "{$path}/slate.info";
 615      $theme_info->engine = 'phptemplate';
 616      $theme_info->owner = drupal_get_path('theme_engine', 'phptemplate') .'/phptemplate.engine';
 617  
 618      $theme_info->stylesheets = array();
 619      $theme_info->stylesheets['screen'][] = "{$path}/reset.css";
 620      $theme_info->stylesheets['screen'][] = "{$path}/style.css";
 621  
 622      $theme_info->scripts = array();
 623      $theme_info->scripts[] = "{$path}/theme.js";
 624  
 625      _init_theme($theme_info);
 626      return TRUE;
 627    }
 628  }
 629  
 630  /**
 631   * Generate the 1st level of navigation links under 'admin'.
 632   */
 633  function admin_navigation_primary() {
 634    $tree = admin_get_menu_tree();
 635    return admin_menu_navigation_links($tree);
 636  }
 637  
 638  /**
 639   * Generate the 2nd level of navigation links under 'admin/*'.
 640   */
 641  function admin_navigation_secondary() {
 642    $is_duplicated = theme('admin_block_content', NULL, TRUE);
 643    if (!$is_duplicated) {
 644      $tree = admin_get_menu_tree('page');
 645      foreach ($tree as $item) {
 646        if (admin_in_active_trail($item['link']['href']) && !empty($item['below'])) {
 647          return admin_menu_navigation_links($item['below']);
 648        }
 649      }
 650    }
 651    return NULL;
 652  }


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