You are here

admin.module in Admin 6.2

Same filename and directory in other branches
  1. 6 admin.module
  2. 7.2 admin.module

File

admin.module
View source
<?php

/**
 * Implementation of hook_init().
 */
function admin_init() {
  if (arg(0) === 'admin') {
    menu_set_active_menu_name('admin');
  }
  if (user_access('use admin toolbar')) {
    $path = drupal_get_path('module', 'admin');
    drupal_add_js("{$path}/includes/jquery.cookie.js");
    drupal_add_js("{$path}/includes/jquery.drilldown.js");
    drupal_add_js("{$path}/includes/admin.toolbar.js");
    drupal_add_js("{$path}/includes/admin.menu.js");
    drupal_add_css("{$path}/includes/admin.toolbar.base.css");
    drupal_add_css("{$path}/includes/admin.toolbar.css");
    drupal_add_css("{$path}/includes/admin.menu.css");
  }
}

/**
 * Implementation of hook_block().
 */
function admin_block($op = 'list', $delta = 0, $edit = array()) {
  switch ($op) {
    case 'list':
      $blocks = array();
      $blocks['create'] = array(
        'info' => t('Create content'),
        'cache' => BLOCK_NO_CACHE,
        'admin' => TRUE,
      );
      $blocks['theme'] = array(
        'info' => t('Theme switcher'),
        'cache' => BLOCK_CACHE_PER_ROLE,
        'admin' => TRUE,
      );
      $blocks['account'] = array(
        'info' => t('My Account'),
        'cache' => BLOCK_NO_CACHE,
        'admin' => TRUE,
      );
      if (module_exists('menu')) {
        $blocks['menu'] = array(
          'info' => t('Administration menu'),
          'cache' => BLOCK_CACHE_PER_ROLE,
          'admin' => TRUE,
        );
      }
      if (module_exists('devel')) {
        $blocks['devel'] = array(
          'info' => t('Devel'),
          'cache' => BLOCK_NO_CACHE,
          'admin' => TRUE,
        );
      }
      return $blocks;
    case 'view':
      switch ($delta) {
        case 'create':
          $item = menu_get_item('node/add');
          $links = system_admin_menu_block($item);
          if (!empty($links)) {
            $menu = array();
            foreach ($links as $key => $link) {
              $menu[$key] = array(
                'link' => $link,
                'below' => FALSE,
              );
            }
            return array(
              'subject' => !empty($item['title']) ? $item['title'] : t('Create content'),
              'content' => theme('admin_drilldown_menu_tree_output', $menu),
            );
          }
          break;
        case 'theme':
          module_load_include('inc', 'admin', 'includes/admin.theme');
          return admin_block_theme();
        case 'account':
          return admin_account_block();
        case 'menu':
          $item = menu_get_item('admin');
          if ($item && $item['access']) {
            return array(
              'subject' => !empty($item['title']) ? $item['title'] : t('Administer'),
              'content' => theme('admin_drilldown_menu_tree_output', menu_tree_all_data('admin')),
            );
          }
          break;
        case 'devel':
          module_load_include('inc', 'admin', 'includes/admin.devel');
          return admin_block_devel();
      }
      break;
  }
}

/**
 * Implement our own simplified block caching. Because the Drupal core block
 * caching system is so conservative (e.g. disabled when *any* node_access
 * module is enabled), we roll our own solution here. Note that except for
 * the introduction of a user 1 specific cache, the cid generated by this
 * function is compatible with those in Drupal core.
 */
function admin_block_get_cache_id($block) {
  global $theme, $base_root, $user;
  if ($block->cache != BLOCK_NO_CACHE) {
    $cid_parts = array();

    // Start with common sub-patterns: block identification, theme, language.
    $cid_parts[] = $block->module;
    $cid_parts[] = $block->delta;
    $cid_parts[] = $theme;
    if (module_exists('locale')) {
      global $language;
      $cid_parts[] = $language->language;
    }

    // In addition to the Drupal core pattern, allow caching separately for u1.
    if ($user->uid == 1) {
      $cid_parts[] = "u.{$user->uid}";
    }
    else {
      if ($block->cache & BLOCK_CACHE_PER_ROLE) {
        $cid_parts[] = 'r.' . implode(',', array_keys($user->roles));
      }
      elseif ($block->cache & BLOCK_CACHE_PER_USER) {
        $cid_parts[] = "u.{$user->uid}";
      }
    }
    if ($block->cache & BLOCK_CACHE_PER_PAGE) {
      $cid_parts[] = $base_root . request_uri();
    }
    return implode(':', $cid_parts);
  }
}

/**
 * Implementation of hook_elements().
 */
function admin_elements() {
  return array(
    'admin_panes' => array(
      '#value' => '',
    ),
  );
}

/**
 * Implementation of hook_menu_alter().
 */
function admin_menu_alter(&$items) {

  // Move admin theme item under ours as a local task.
  $items['admin/settings/admin/theme'] = $items['admin/settings/admin'];
  $items['admin/settings/admin/theme']['type'] = MENU_LOCAL_TASK;
  $items['admin/settings/admin/theme']['weight'] = 10;

  // Generate our own admin settings page.
  $items['admin/settings/admin'] = $items['admin/settings/admin/settings'] = array(
    'title' => 'Administration tools',
    'description' => 'Settings for site administration tools.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'admin_settings_form',
    ),
    'access callback' => 'user_access',
    'access arguments' => array(
      'administer site configuration',
    ),
    'type' => MENU_NORMAL_ITEM,
    'file' => 'admin.admin.inc',
    'module' => 'admin',
  );
  $items['admin/settings/admin/settings']['title'] = 'Settings';
  $items['admin/settings/admin/settings']['type'] = MENU_DEFAULT_LOCAL_TASK;
  $items['admin/settings/admin/rebuild'] = array(
    'title' => 'Rebuild',
    'description' => 'Wipe and rebuild the administrative menu.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'admin_settings_rebuild',
    ),
    'access callback' => 'user_access',
    'access arguments' => array(
      'administer site configuration',
    ),
    'type' => MENU_LOCAL_TASK,
    'file' => 'admin.admin.inc',
    'module' => 'admin',
    'weight' => 10,
  );
  foreach ($items as $path => $item) {
    $item['type'] = isset($item['type']) ? $item['type'] : MENU_NORMAL_ITEM;

    // Move all admin/* items to admin menu links except local tasks, callbacks.
    $args = explode('/', $path);
    if ($path === 'admin' || $item['type'] & MENU_NORMAL_ITEM && $args && $args[0] === 'admin') {
      $items[$path]['menu_name'] = 'admin';
    }

    // Smarter access callback for poorly checked landing pages
    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',
    ))) {
      $items[$path]['access callback'] = 'admin_landing_page_access';
      $items[$path]['access arguments'] = array(
        $path,
      );
    }
  }
}

/**
 * Menu access callback for admin landing pages.
 *
 * For a given landing page, grant access if the current user has access
 * to any of its child menu items.
 */
function admin_landing_page_access($path) {
  static $paths;
  if (!isset($paths[$path])) {
    $item = db_fetch_array(db_query("SELECT mlid, menu_name FROM {menu_links} ml WHERE ml.router_path = '%s' AND module = 'system'", $path));
    $result = db_query("\n      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.*\n      FROM {menu_links} ml\n      LEFT JOIN {menu_router} m ON ml.link_path = m.path\n      WHERE ml.plid = %d AND ml.menu_name = '%s' AND hidden = 0", $item['mlid'], $item['menu_name']);
    $paths[$path] = FALSE;
    while ($item = db_fetch_array($result)) {
      _menu_link_translate($item);
      if ($item['access']) {
        $paths[$path] = TRUE;
        break;
      }
    }
  }
  return $paths[$path];
}

/**
 * Implementation of hook_perm().
 */
function admin_perm() {
  return array(
    'use admin toolbar',
  );
}

/**
 * Implementation of hook_theme().
 */
function admin_theme($cache, $type, $theme, $path) {
  $path = drupal_get_path('module', 'admin');
  $items['admin_tab'] = array(
    'arguments' => array(
      'tab' => array(),
      'class' => '',
    ),
    'path' => $path . '/theme',
    'file' => 'theme.inc',
  );
  $items['admin_toolbar'] = array(
    'arguments' => array(
      'blocks' => array(),
      'position' => 'ne',
      'layout' => 'horizontal',
      'behavior' => 'df',
    ),
    'template' => 'admin-toolbar',
    'path' => $path . '/theme',
    'file' => 'theme.inc',
  );
  $items['admin_drilldown_menu_tree_output'] = array(
    'arguments' => array(
      'menu' => array(),
    ),
    'path' => $path . '/theme',
    'file' => 'theme.inc',
  );
  $items['admin_drilldown_menu_tree'] = array(
    'arguments' => array(
      'menu' => array(),
    ),
    'path' => $path . '/theme',
    'file' => 'theme.inc',
  );
  $items['admin_drilldown_menu_item'] = array(
    'arguments' => array(
      'link' => NULL,
      'has_children' => NULL,
      'menu' => '',
      'in_active_trail' => FALSE,
      'extra_class' => NULL,
    ),
    'path' => $path . '/theme',
    'file' => 'theme.inc',
  );
  $items['admin_drilldown_menu_item_link'] = array(
    'arguments' => array(
      'item' => array(),
    ),
    'path' => $path . '/theme',
    'file' => 'theme.inc',
  );
  $items['admin_panes'] = array(
    'arguments' => array(
      'element' => array(),
    ),
    'template' => 'admin-panes',
    'path' => $path . '/theme',
    'file' => 'theme.inc',
  );
  $items['admin_settings_form'] = array(
    'arguments' => array(
      'element' => array(),
    ),
    'path' => $path,
    'file' => 'admin.admin.inc',
  );
  return $items;
}

/**
 * Implementation of hook_theme_registry_alter().
 */
function admin_theme_registry_alter(&$theme_registry) {

  // Remove any existing instances of our pre page preprocessor.
  $position = array_search('admin_preprocess_pre_page', $theme_registry['page']['preprocess functions']);
  if ($position !== FALSE) {
    unset($theme_registry['page']['preprocess functions'][$position]);
  }

  // Add an additional page preprocess function prior to template_preprocess_page()
  // so that our blocks can include JS files as needed.
  $position = array_search('template_preprocess_page', $theme_registry['page']['preprocess functions']);
  if ($position !== FALSE) {
    array_splice($theme_registry['page']['preprocess functions'], $position, 0, 'admin_preprocess_pre_page');
  }
}

/**
 * Get variable settings or fallback to defaults.
 */
function admin_get_settings($key = NULL) {
  static $settings;
  if (!isset($settings)) {

    // Try to gather what information we can from the cookie.
    // Note that this information should not be trusted in any
    // way for affecting *anything* but trivial changes to the site.
    $cookie = array();
    if (isset($_REQUEST['DrupalAdminToolbar'])) {
      parse_str($_REQUEST['DrupalAdminToolbar'], $cookie);
    }
    $settings = variable_get('admin_toolbar', array()) + array(
      'layout' => 'vertical',
      'position' => 'nw',
      'behavior' => 'df',
      'blocks' => admin_get_default_blocks(),
      'expanded' => isset($cookie['expanded']) ? check_plain($cookie['expanded']) : 0,
      'active_tab' => isset($cookie['activeTab']) ? check_plain($cookie['activeTab']) : 0,
    );

    // Ensure that if behavior is set to autohide the toolbar is collapsed.
    if ($settings['behavior'] === 'ah') {
      $settings['expanded'] = 0;
    }
  }
  if (isset($key)) {
    return isset($settings[$key]) ? $settings[$key] : FALSE;
  }
  return $settings;
}

/**
 * Get all blocks that have declared themselves visible in the admin toolbar by default.
 */
function admin_get_default_blocks($reset = FALSE) {
  static $defaults;
  if (!isset($defaults) || $reset) {
    $cache = cache_get('admin_default_blocks');
    if ($cache && !$reset) {
      $defaults = $cache->data;
    }
    else {
      $defaults = array();
      foreach (module_implements('block') as $module) {
        $module_blocks = module_invoke($module, 'block', 'list');
        if ($module_blocks) {
          foreach ($module_blocks as $delta => $info) {
            if (isset($info['admin'])) {
              $defaults["{$module}-{$delta}"] = isset($info['cache']) ? $info['cache'] : BLOCK_NO_CACHE;
            }
          }
        }
      }
      cache_set('admin_default_blocks', $defaults);
    }
  }
  return $defaults;
}

/**
 * Set static cache for blocks enabled for the admin toolbar.
 */
function admin_set_admin_blocks($reset = FALSE) {
  static $blocks;
  if (!isset($blocks) || $reset) {
    $blocks = array();
    if (user_access('use admin toolbar') && ($enabled_blocks = admin_get_settings('blocks'))) {
      foreach ($enabled_blocks as $bid => $cache) {
        $block = NULL;
        $split = explode('-', $bid, 2);
        if (count($split) === 2) {
          list($module, $delta) = $split;
          $block = new stdClass();
          $block->module = $module;
          $block->delta = $delta;
          $block->cache = is_numeric($cache) ? $cache : BLOCK_NO_CACHE;
          $block->region = 'admin_toolbar';

          // Fake the block region.
        }
        if (!empty($block)) {
          if ($_SERVER['REQUEST_METHOD'] == 'GET' && ($cid = admin_block_get_cache_id($block))) {
            if ($cache = cache_get($cid, 'cache_block')) {
              $array = $cache->data;
            }
            else {
              $array = module_invoke($block->module, 'block', 'view', $block->delta);
              cache_set($cid, $array, 'cache_block', CACHE_TEMPORARY);
            }
          }
          else {
            $array = module_invoke($block->module, 'block', 'view', $block->delta);
          }
          if (!empty($array['content'])) {
            foreach ($array as $k => $v) {
              $block->{$k} = $v;
            }
            if ($block->module === 'block') {
              global $theme;
              $block->subject = db_result(db_query("SELECT title FROM {blocks} WHERE module = 'block' AND delta = '%s'", $delta));
            }

            // This is here simpy to trigger any preprocess functions that may
            // add javascript, etc. for this block. Note that the output is
            // thrown away.
            theme('block', $block);
            $blocks["{$module}-{$delta}"] = $block;
          }
        }
      }
    }
  }
  return $blocks;
}

/**
 * Get wrapper around admin blocks set.
 */
function admin_get_admin_blocks($reset = FALSE) {
  return admin_set_admin_blocks($reset);
}

/**
 * Preprocessor that runs *before* template_preprocess_page().
 */
function admin_preprocess_pre_page(&$vars) {
  admin_set_admin_blocks();
  if (user_access('use admin toolbar') && ($trail = menu_get_active_trail())) {
    do {
      $last = array_pop($trail);
    } while (count($trail) && !($last['type'] & MENU_VISIBLE_IN_TREE));
    if ($last) {
      drupal_add_js(array(
        'activePath' => url($last['href']),
      ), 'setting');
    }
  }
}

/**
 * Implementation of hook_preprocess_page().
 */
function admin_preprocess_page(&$vars) {
  if (!admin_suppress(FALSE) && ($blocks = admin_get_admin_blocks())) {
    $position = admin_get_settings('position');
    $layout = admin_get_settings('layout');
    $behavior = admin_get_settings('behavior');
    $class = admin_get_settings('expanded') ? 'admin-expanded' : '';
    $vars['body_classes'] .= " admin-{$position} admin-{$layout} admin-{$behavior} {$class} ";
  }
}

/**
 * Implementation of hook_footer().
 */
function admin_footer() {
  if (!admin_suppress(FALSE) && ($blocks = admin_get_admin_blocks())) {
    $position = admin_get_settings('position');
    $layout = admin_get_settings('layout');
    $behavior = admin_get_settings('behavior');
    $class = admin_get_settings('expanded') ? 'admin-expanded' : '';
    return theme('admin_toolbar', $blocks, $position, $layout, $behavior);
  }
}

/**
 * Implementation of hook_suppress().
 *
 * Suppress display of administration toolbar.
 *
 * This function should be called from within another module's page callback
 * preferably using module_invoke_all('suppress') when the menu should not be
 * displayed. This is useful for modules that implement popup pages or other
 * special pages where the menu would be distracting or break the layout.
 *
 * @param $set
 *   Defaults to TRUE. If called before hook_footer(), the menu will not be
 *   displayed. If FALSE is passed, the suppression state is returned.
 */
function admin_suppress($set = TRUE) {
  static $suppress = FALSE;
  if (!empty($set) && $suppress === FALSE) {
    $suppress = TRUE;
  }
  return $suppress;
}

/**
 * My Account block.
 */
function admin_account_block() {
  $block = array(
    'subject' => t('My Account'),
    'content' => '',
  );
  global $user;
  if ($user->uid > 0) {
    $menu = array();
    $menu[] = array(
      'data' => l(t('View my account'), 'user/' . $user->uid),
      'class' => 'leaf',
    );
    $menu[] = array(
      'data' => l(t('Edit my account'), 'user/' . $user->uid . '/edit'),
      'class' => 'leaf',
    );
    $menu[] = array(
      'data' => l(t('Logout'), 'logout'),
      'class' => 'leaf',
    );
    $block['content'] = theme('item_list', $menu, NULL, 'ul', array(
      'class' => 'menu',
    ));
  }
  return $block;
}

Functions

Namesort descending Description
admin_account_block My Account block.
admin_block Implementation of hook_block().
admin_block_get_cache_id Implement our own simplified block caching. Because the Drupal core block caching system is so conservative (e.g. disabled when *any* node_access module is enabled), we roll our own solution here. Note that except for the introduction of a user 1…
admin_elements Implementation of hook_elements().
admin_footer Implementation of hook_footer().
admin_get_admin_blocks Get wrapper around admin blocks set.
admin_get_default_blocks Get all blocks that have declared themselves visible in the admin toolbar by default.
admin_get_settings Get variable settings or fallback to defaults.
admin_init Implementation of hook_init().
admin_landing_page_access Menu access callback for admin landing pages.
admin_menu_alter Implementation of hook_menu_alter().
admin_perm Implementation of hook_perm().
admin_preprocess_page Implementation of hook_preprocess_page().
admin_preprocess_pre_page Preprocessor that runs *before* template_preprocess_page().
admin_set_admin_blocks Set static cache for blocks enabled for the admin toolbar.
admin_suppress Implementation of hook_suppress().
admin_theme Implementation of hook_theme().
admin_theme_registry_alter Implementation of hook_theme_registry_alter().