[ PHPXref.com ] [ Generated: Sun Jul 20 17:22:00 2008 ] [ Drupal 5.0 ]
[ Index ]     [ Variables ]     [ Functions ]     [ Classes ]     [ Constants ]     [ Statistics ]

title

Body

[close]

/modules/system/ -> system.module (source)

   1  <?php
   2  // $Id: system.module,v 1.440.2.1 2007/01/15 12:04:14 unconed Exp $
   3  
   4  /**
   5   * @file
   6   * Configuration system that lets administrators modify the workings of the site.
   7   */
   8  
   9  define('VERSION', '5.0');
  10  
  11  /**
  12   * Implementation of hook_help().
  13   */
  14  function system_help($section) {
  15    global $base_url;
  16  
  17    switch ($section) {
  18      case 'admin/help#system':
  19        $output = '<p>'. t('The system module provides system-wide defaults such as running jobs at a particular time, and storing web pages to improve efficiency. The ability to run scheduled jobs makes administering the web site more usable, as administrators do not have to manually start jobs. The storing of web pages, or caching, allows the site to efficiently re-use web pages and improve web site performance. The settings module provides control over preferences, behaviours including visual and operational settings.') .'</p>';
  20        $output .= '<p>'. t('Some modules require regularly scheduled actions, such as cleaning up logfiles. Cron, which stands for chronograph, is a periodic command scheduler executing commands at intervals specified in seconds. It can be used to control the execution of daily, weekly and monthly jobs (or anything with a period measured in seconds). The aggregator module periodically updates feeds using cron. Ping periodically notifies services of new content on your site. Search periodically indexes the content on your site. Automating tasks is one of the best ways to keep a system running smoothly, and if most of your administration does not require your direct involvement, cron is an ideal solution. Cron can, if necessary, also be run manually.') .'</p>';
  21        $output .= '<p>'. t("There is a caching mechanism which stores dynamically generated web pages in a database. By caching a web page, the system module does not have to create the page each time someone wants to view it, instead it takes only one SQL query to display it, reducing response time and the server's load. Only pages requested by <em>anonymous</em> users are cached. In order to reduce server load and save bandwidth, the system module stores and sends cached pages compressed.") .'</p>';
  22        $output .= '<p>'. t('For more information please read the configuration and customization handbook <a href="@system">System page</a>.', array('@system' => 'http://drupal.org/handbook/modules/system/')) .'</p>';
  23        return $output;
  24      case 'admin':
  25        return '<p>'. t('Welcome to the administration section. Here you may control how your site functions.') .'</p>';
  26      case 'admin/by-module':
  27        return '<p>'. t('This page shows you all available administration tasks for each module.') .'</p>';
  28      case 'admin/build/themes':
  29        return '<p>'. t('Select which themes are available to your users and specify the default theme. To configure site-wide display settings, click the "configure" task above. Alternately, to override these settings in a specific theme, click the "configure" link for the corresponding theme. Note that different themes may have different regions available for rendering content like blocks. If you want consistency in what your users see, you may wish to enable only one theme.') .'</p>';
  30      case 'admin/build/themes/settings':
  31        return '<p>'. t('These options control the default display settings for your entire site, across all themes. Unless they have been overridden by a specific theme, these settings will be used.') .'</p>';
  32      case 'admin/build/themes/settings/'. arg(3):
  33        $reference = explode('.', arg(3), 2);
  34        $theme = array_pop($reference);
  35        return '<p>'. t('These options control the display settings for the <code>%template</code> theme. When your site is displayed using this theme, these settings will be used. By clicking "Reset to defaults," you can choose to use the <a href="@global">global settings</a> for this theme.', array('%template' => $theme, '@global' => url('admin/build/themes/settings'))) .'</p>';
  36      case 'admin/build/modules':
  37        return t('<p>Modules are plugins for Drupal that extend its core functionality. Here you can select which modules are enabled. Click on the name of the module in the navigation menu for their individual configuration pages. Once a module is enabled, new <a href="@permissions">permissions</a> might be made available. Modules can automatically be temporarily disabled to reduce server load when your site becomes extremely busy by enabling the throttle.module and checking throttle. The auto-throttle functionality must be enabled on the <a href="@throttle">throttle configuration page</a> after having enabled the throttle module.</p>
  38  <p>It is important that <a href="@update-php">update.php</a> is run every time a module is updated to a newer version.</p><p>You can find all administration tasks belonging to a particular module on the <a href="@by-module">administration by module page</a>.</p>', array('@permissions' => url('admin/user/access'), '@throttle' => url('admin/settings/throttle'), '@update-php' => $base_url .'/update.php', '@by-module' => url('admin/by-module')));
  39      case 'admin/build/modules/uninstall':
  40        return '<p>'. t('The uninstall process removes all data related to a module. To uninstall a module, you must first disable it. Not all modules support this feature.') .'</p>';
  41      case 'admin/logs/status':
  42        return '<p>'. t("Here you can find a short overview of your Drupal site's parameters as well as any problems detected with your installation. It is useful to copy/paste this information when you need support.") .'</p>';
  43    }
  44  }
  45  
  46  /**
  47   * Implementation of hook_perm().
  48   */
  49  function system_perm() {
  50    return array('administer site configuration', 'access administration pages', 'select different theme');
  51  }
  52  
  53  /**
  54   * Implementation of hook_elements().
  55   */
  56  function system_elements() {
  57    // Top level form
  58    $type['form'] = array('#method' => 'post', '#action' => request_uri());
  59  
  60    // Inputs
  61    $type['checkbox'] = array('#input' => TRUE, '#return_value' => 1);
  62    $type['submit'] = array('#input' => TRUE, '#name' => 'op', '#button_type' => 'submit', '#executes_submit_callback' => TRUE);
  63    $type['button'] = array('#input' => TRUE, '#name' => 'op', '#button_type' => 'submit', '#executes_submit_callback' => FALSE);
  64    $type['textfield'] = array('#input' => TRUE, '#size' => 60, '#maxlength' => 128, '#autocomplete_path' => FALSE);
  65    $type['password'] = array('#input' => TRUE, '#size' => 60);
  66    $type['password_confirm'] = array('#input' => TRUE, '#process' => array('expand_password_confirm' => array()));
  67    $type['textarea'] = array('#input' => TRUE, '#cols' => 60, '#rows' => 5);
  68    $type['radios'] = array('#input' => TRUE, '#process' => array('expand_radios' => array()));
  69    $type['radio'] = array('#input' => TRUE);
  70    $type['checkboxes'] = array('#input' => TRUE, '#process' => array('expand_checkboxes' => array()), '#tree' => TRUE);
  71    $type['select'] = array('#input' => TRUE);
  72    $type['weight'] = array('#input' => TRUE, '#delta' => 10, '#default_value' => 0, '#process' => array('process_weight' => array()));
  73    $type['date'] = array('#input' => TRUE, '#process' => array('expand_date' => array()), '#validate' => array('date_validate' => array()));
  74    $type['file'] = array('#input' => TRUE, '#size' => 60);
  75  
  76    // Form structure
  77    $type['item'] = array();
  78    $type['hidden'] = array('#input' => TRUE);
  79    $type['value'] = array('#input' => TRUE);
  80    $type['markup'] = array('#prefix' => '', '#suffix' => '');
  81    $type['fieldset'] = array('#collapsible' => FALSE, '#collapsed' => FALSE);
  82    $type['token'] = array('#input'=> TRUE);
  83    return $type;
  84  }
  85  
  86  /**
  87   * Implementation of hook_menu().
  88   */
  89  function system_menu($may_cache) {
  90    $items = array();
  91  
  92    if ($may_cache) {
  93      $items[] = array('path' => 'system/files', 'title' => t('File download'),
  94        'callback' => 'file_download',
  95        'access' => TRUE,
  96        'type' => MENU_CALLBACK);
  97  
  98      $access = user_access('administer site configuration');
  99  
 100      $items[] = array('path' => 'admin', 'title' => t('Administer'),
 101        'access' => user_access('access administration pages'),
 102        'callback' => 'system_main_admin_page',
 103        'weight' => 9);
 104      $items[] = array('path' => 'admin/compact', 'title' => t('Compact mode'),
 105        'access' => user_access('access administration pages'),
 106        'callback' => 'system_admin_compact_page',
 107        'type' => MENU_CALLBACK);
 108      $items[] = array('path' => 'admin/by-task', 'title' => t('By task'),
 109        'callback' => 'system_main_admin_page',
 110        'type' => MENU_DEFAULT_LOCAL_TASK);
 111      $items[] = array('path' => 'admin/by-module', 'title' => t('By module'),
 112        'callback' => 'system_admin_by_module',
 113        'type' => MENU_LOCAL_TASK,
 114        'weight' => 2);
 115  
 116      // menu items that are basically just menu blocks
 117      $items[] = array(
 118        'path' => 'admin/settings',
 119        'title' => t('Site configuration'),
 120        'description' => t('Adjust basic site configuration options.'),
 121        'position' => 'right',
 122        'weight' => -5,
 123        'callback' => 'system_settings_overview',
 124        'access' => $access);
 125  
 126      $items[] = array('path' => 'admin/build',
 127        'title' => t('Site building'),
 128        'description' => t('Control how your site looks and feels.'),
 129        'position' => 'right',
 130        'weight' => -10,
 131        'callback' => 'system_admin_menu_block_page',
 132        'access' => $access);
 133  
 134      $items[] = array(
 135        'path' => 'admin/settings/admin',
 136        'title' => t('Administration theme'),
 137        'description' => t('Settings for how your administrative pages should look.'),
 138        'position' => 'left',
 139        'callback' => 'drupal_get_form',
 140        'callback arguments' => array('system_admin_theme_settings'),
 141        'block callback' => 'system_admin_theme_settings',
 142        'access' => $access);
 143  
 144      // Themes:
 145      $items[] = array(
 146        'path' => 'admin/build/themes',
 147        'title' => t('Themes'),
 148        'description' => t('Change which theme your site uses or allows users to set.'),
 149        'callback' => 'drupal_get_form',
 150        'callback arguments' => array('system_themes'),
 151        'access' => $access);
 152  
 153      $items[] = array(
 154        'path' => 'admin/build/themes/select',
 155        'title' => t('List'),
 156        'description' => t('Select the default theme.'),
 157        'callback' => 'drupal_get_form',
 158        'callback arguments' => array('system_themes'),
 159        'access' => $access,
 160        'type' => MENU_DEFAULT_LOCAL_TASK,
 161        'weight' => -1);
 162  
 163      $items[] = array('path' => 'admin/build/themes/settings',
 164        'title' => t('Configure'),
 165        'callback' => 'drupal_get_form',
 166        'callback arguments' => array('system_theme_settings'),
 167        'access' => $access,
 168        'type' => MENU_LOCAL_TASK);
 169  
 170      // Theme configuration subtabs
 171      $items[] = array('path' => 'admin/build/themes/settings/global', 'title' => t('Global settings'),
 172        'callback' => 'drupal_get_form',
 173        'callback arguments' => array('system_theme_settings'),
 174        'access' => $access,
 175        'type' => MENU_DEFAULT_LOCAL_TASK,
 176        'weight' => -1);
 177  
 178      foreach (list_themes() as $theme) {
 179        if ($theme->status) {
 180          $items[] = array('path' => 'admin/build/themes/settings/'. $theme->name, 'title' => $theme->name,
 181          'callback' => 'drupal_get_form', 'callback arguments' => array('system_theme_settings', $theme->name),
 182          'access' => $access, 'type' => MENU_LOCAL_TASK);
 183        }
 184      }
 185  
 186      // Modules:
 187      $items[] = array('path' => 'admin/build/modules',
 188        'title' => t('Modules'),
 189        'description' => t('Enable or disable add-on modules for your site.'),
 190        'callback' => 'drupal_get_form',
 191        'callback arguments' => array('system_modules'),
 192        'access' => $access);
 193      $items[] = array('path' => 'admin/build/modules/list',
 194        'title' => t('List'),
 195        'type' => MENU_DEFAULT_LOCAL_TASK,
 196        'access' => $access);
 197      $items[] = array('path' => 'admin/build/modules/list/confirm',
 198        'title' => t('List'),
 199        'callback' => 'drupal_get_form',
 200        'callback arguments' => array('system_modules'),
 201        'type' => MENU_CALLBACK,
 202        'access' => $access);
 203      $items[] = array('path' => 'admin/build/modules/uninstall',
 204        'title' => t('Uninstall'),
 205        'callback' => 'drupal_get_form',
 206        'callback arguments' => array('system_modules_uninstall'),
 207        'type' => MENU_LOCAL_TASK,
 208        'access' => $access);
 209      $items[] = array('path' => 'admin/build/modules/uninstall/confirm',
 210        'title' => t('Uninstall'),
 211        'callback' => 'drupal_get_form',
 212        'callback arguments' => array('system_modules_uninstall'),
 213        'type' => MENU_CALLBACK,
 214        'access' => $access);
 215  
 216      // Settings:
 217      $items[] = array(
 218        'path' => 'admin/settings/site-information',
 219        'title' => t('Site information'),
 220        'description' => t('Change basic site information, such as the site name, slogan, e-mail address, mission, front page and more.'),
 221        'callback' => 'drupal_get_form',
 222        'callback arguments' => array('system_site_information_settings'));
 223      $items[] = array(
 224        'path' => 'admin/settings/error-reporting',
 225        'title' => t('Error reporting'),
 226        'description' => t('Control how Drupal deals with errors including 403/404 errors as well as PHP error reporting.'),
 227        'callback' => 'drupal_get_form',
 228        'callback arguments' => array('system_error_reporting_settings'));
 229      $items[] = array(
 230        'path' => 'admin/settings/performance',
 231        'title' => t('Performance'),
 232        'description' => t('Enable or disable page caching for anonymous users, and enable or disable CSS preprocessor.'),
 233        'callback' => 'drupal_get_form',
 234        'callback arguments' => array('system_performance_settings'));
 235      $items[] = array(
 236        'path' => 'admin/settings/file-system',
 237        'title' => t('File system'),
 238        'description' => t('Tell Drupal where to store uploaded files and how they are accessed.'),
 239        'callback' => 'drupal_get_form',
 240        'callback arguments' => array('system_file_system_settings'));
 241      $items[] = array(
 242        'path' => 'admin/settings/image-toolkit',
 243        'title' => t('Image toolkit'),
 244        'description' => t('Choose which image toolkit to use if you have installed optional toolkits.'),
 245        'callback' => 'drupal_get_form',
 246        'callback arguments' => array('system_image_toolkit_settings'));
 247      $items[] = array(
 248        'path' => 'admin/content/rss-publishing',
 249        'title' => t('RSS publishing'),
 250        'description' => t('Configure the number of items per feed and whether feeds should be titles/teasers/full-text.'),
 251        'callback' => 'drupal_get_form',
 252        'callback arguments' => array('system_rss_feeds_settings'));
 253      $items[] = array(
 254        'path' => 'admin/settings/date-time',
 255        'title' => t('Date and time'),
 256        'description' => t("Settings for how Drupal displays date and time, as well as the system's default timezone."),
 257        'callback' => 'drupal_get_form',
 258        'callback arguments' => array('system_date_time_settings'));
 259      $items[] = array(
 260        'path' => 'admin/settings/site-maintenance',
 261        'title' => t('Site maintenance'),
 262        'description' => t('Take the site off-line for maintenance or bring it back online.'),
 263        'callback' => 'drupal_get_form',
 264        'callback arguments' => array('system_site_maintenance_settings'));
 265      $items[] = array(
 266        'path' => 'admin/settings/clean-urls',
 267        'title' => t('Clean URLs'),
 268        'description' => t('Enable or disable clean URLs for your site.'),
 269        'callback' => 'drupal_get_form',
 270        'callback arguments' => array('system_clean_url_settings'));
 271  
 272  
 273      // Logs:
 274      $items[] = array(
 275        'path' => 'admin/logs',
 276        'title' => t('Logs'),
 277        'description' => t('View system logs and other status information.'),
 278        'callback' => 'system_admin_menu_block_page',
 279        'weight' => 5,
 280        'position' => 'left');
 281      $items[] = array(
 282        'path' => 'admin/logs/status',
 283        'title' => t('Status report'),
 284        'description' => t("Get a status report about your site's operation and any detected problems."),
 285        'callback' => 'system_status',
 286        'weight' => 10,
 287        'access' => $access);
 288      $items[] = array(
 289        'path' => 'admin/logs/status/run-cron',
 290        'title' => t('Run cron'),
 291        'callback' => 'system_run_cron',
 292        'type' => MENU_CALLBACK);
 293      $items[] = array(
 294        'path' => 'admin/logs/status/php',
 295        'title' => t('PHP'),
 296        'callback' => 'system_php',
 297        'type' => MENU_CALLBACK);
 298      $items[] = array(
 299        'path' => 'admin/logs/status/sql',
 300        'title' => t('SQL'),
 301        'callback' => 'system_sql',
 302        'type' => MENU_CALLBACK);
 303    }
 304    else {
 305      /**
 306       * Use the administrative theme if the user is looking at a page in the admin/* path.
 307       */
 308      if (arg(0) == 'admin') {
 309        global $custom_theme;
 310        $custom_theme = variable_get('admin_theme', '0');
 311        drupal_add_css(drupal_get_path('module', 'system') .'/admin.css', 'module');
 312      }
 313  
 314      // Add the CSS for this module. We put this in !$may_cache so it is only
 315      // added once per request.
 316      drupal_add_css(drupal_get_path('module', 'system') .'/defaults.css', 'module');
 317      drupal_add_css(drupal_get_path('module', 'system') .'/system.css', 'module');
 318    }
 319  
 320    return $items;
 321  }
 322  
 323  /**
 324   * Implementation of hook_user().
 325   *
 326   * Allows users to individually set their theme and time zone.
 327   */
 328  function system_user($type, $edit, &$user, $category = NULL) {
 329    if ($type == 'form' && $category == 'account') {
 330      $form['theme_select'] = system_theme_select_form(t('Selecting a different theme will change the look and feel of the site.'), $edit['theme'], 2);
 331  
 332      if (variable_get('configurable_timezones', 1)) {
 333        $zones = _system_zonelist();
 334        $form['timezone'] = array(
 335          '#type'=>'fieldset',
 336          '#title' => t('Locale settings'),
 337          '#weight' => 6,
 338          '#collapsible' => TRUE,
 339        );
 340        $form['timezone']['timezone'] = array(
 341          '#type' => 'select',
 342          '#title' => t('Time zone'),
 343          '#default_value' => strlen($edit['timezone']) ? $edit['timezone'] : variable_get('date_default_timezone', 0),
 344          '#options' => $zones,
 345          '#description' => t('Select your current local time. Dates and times throughout this site will be displayed using this time zone.'),
 346        );
 347      }
 348  
 349      return $form;
 350    }
 351  }
 352  
 353  /**
 354   * Provide the administration overview page.
 355   */
 356  function system_main_admin_page($arg = NULL) {
 357    // If we received an argument, they probably meant some other page.
 358    // Let's 404 them since the menu system cannot be told we do not
 359    // accept arguments.
 360    if (isset($arg) && substr($arg, 0, 3) != 'by-') {
 361      return drupal_not_found();
 362    }
 363  
 364    // Check for status report errors.
 365    if (system_status(TRUE)) {
 366      drupal_set_message(t('One or more problems were detected with your Drupal installation. Check the <a href="@status">status report</a> for more information.', array('@status' => url('admin/logs/status'))), 'error');
 367    }
 368  
 369  
 370    $menu = menu_get_item(NULL, 'admin');
 371    usort($menu['children'], '_menu_sort');
 372    foreach ($menu['children'] as $mid) {
 373      $block = menu_get_item($mid);
 374      if ($block['block callback'] && function_exists($block['block callback'])) {
 375        $arguments = isset($block['block arguments']) ? $block['block arguments'] : array();
 376        $block['content'] .= call_user_func_array($block['block callback'], $arguments);
 377      }
 378      $block['content'] .= theme('admin_block_content', system_admin_menu_block($block));
 379      $blocks[] = $block;
 380    }
 381  
 382    return theme('admin_page', $blocks);
 383  }
 384  
 385  /**
 386   * Provide a single block on the administration overview page.
 387   */
 388  function system_admin_menu_block($block) {
 389    $content = array();
 390    if (is_array($block['children'])) {
 391      usort($block['children'], '_menu_sort');
 392      foreach ($block['children'] as $mid) {
 393        $item = menu_get_item($mid);
 394        if (($item['type'] & MENU_VISIBLE_IN_TREE) && _menu_item_is_accessible($mid)) {
 395          $content[] = $item;
 396        }
 397      }
 398    }
 399    return $content;
 400  }
 401  
 402  /**
 403   * Provide a single block from the administration menu as a page.
 404   * This function is often a destination for these blocks.
 405   * For example, 'admin/content/types' needs to have a destination to be valid
 406   * in the Drupal menu system, but too much information there might be
 407   * hidden, so we supply the contents of the block.
 408   */
 409  function system_admin_menu_block_page() {
 410    $menu = menu_get_item(NULL, $_GET['q']);
 411    $content = system_admin_menu_block($menu);
 412  
 413    $output = theme('admin_block_content', $content);
 414    return $output;
 415  }
 416  
 417  function system_admin_compact_page($mode = 'off') {
 418    global $user;
 419    user_save($user, array('admin_compact_mode' => ($mode == 'on')));
 420    drupal_goto('admin');
 421  }
 422  
 423  /**
 424   * This function allows selection of the theme to show in administration sections.
 425   */
 426  function system_admin_theme_settings() {
 427    $themes = system_theme_data();
 428    ksort($themes);
 429    $options[0] = t('System default');
 430    foreach ($themes as $theme) {
 431      $options[$theme->name] = $theme->name;
 432    }
 433  
 434    $form['admin_theme'] = array(
 435      '#type' => 'select',
 436      '#options' => $options,
 437      '#title' => t('Administration theme'),
 438      '#description' => t('Choose which theme the administration pages should display in. If you choose "System default" the administration pages will use the same theme as the rest of the site.'),
 439      '#default_value' => variable_get('admin_theme', '0'),
 440    );
 441  
 442    // In order to give it our own submit, we have to give it the default submit
 443    // too because the presence of a #submit will prevent the default #submit
 444    // from being used. Also we want ours first.
 445    $form['#submit']['system_admin_theme_submit'] = array();
 446    $form['#submit']['system_settings_form_submit'] = array();
 447    return system_settings_form($form);
 448  }
 449  
 450  
 451  function system_admin_theme_submit($form_id, $form_values) {
 452    // If we're changing themes, make sure the theme has its blocks initialized.
 453    if ($form_values['admin_theme'] != variable_get('admin_theme', '0')) {
 454      $result = db_query("SELECT status FROM {blocks} WHERE theme = '%s'", $form_values['admin_theme']);
 455      if (!db_num_rows($result)) {
 456        system_initialize_theme_blocks($form_values['admin_theme']);
 457      }
 458    }
 459  }
 460  
 461  /*
 462   * Returns a fieldset containing the theme select form.
 463   *
 464   * @param $description
 465   *    description of the fieldset
 466   * @param $default_value
 467   *    default value of theme radios
 468   * @param $weight
 469   *    weight of the fieldset
 470   * @return
 471   *    a form array
 472   */
 473  function system_theme_select_form($description = '', $default_value = '', $weight = 0) {
 474    if (user_access('select different theme')) {
 475      foreach (list_themes() as $theme) {
 476        if ($theme->status) {
 477          $enabled[] = $theme;
 478        }
 479      }
 480  
 481      if (count($enabled) > 1) {
 482        ksort($enabled);
 483  
 484        $form['themes'] = array(
 485          '#type' => 'fieldset',
 486          '#title' => t('Theme configuration'),
 487          '#description' => $description,
 488          '#collapsible' => TRUE,
 489          '#theme' => 'system_theme_select_form'
 490        );
 491  
 492        foreach ($enabled as $info) {
 493          // For the default theme, revert to an empty string so the user's theme updates when the site theme is changed.
 494          $info->key = $info->name == variable_get('theme_default', 'garland') ? '' : $info->name;
 495  
 496          $info->screenshot = dirname($info->filename) . '/screenshot.png';
 497          $screenshot = file_exists($info->screenshot) ? theme('image', $info->screenshot, t('Screenshot for %theme theme', array('%theme' => $info->name)), '', array('class' => 'screenshot'), FALSE) : t('no screenshot');
 498  
 499          $form['themes'][$info->key]['screenshot'] = array('#value' => $screenshot);
 500          $form['themes'][$info->key]['description'] = array('#type' => 'item', '#title' => $info->name,  '#value' => dirname($info->filename) . ($info->name == variable_get('theme_default', 'garland') ? '<br /> <em>'. t('(site default theme)') .'</em>' : ''));
 501          $options[$info->key] = '';
 502        }
 503  
 504        $form['themes']['theme'] = array('#type' => 'radios', '#options' => $options, '#default_value' => $default_value ? $default_value : '');
 505        $form['#weight'] = $weight;
 506        return $form;
 507      }
 508    }
 509  }
 510  
 511  function theme_system_theme_select_form($form) {
 512    foreach (element_children($form) as $key) {
 513      $row = array();
 514      if (is_array($form[$key]['description'])) {
 515        $row[] = drupal_render($form[$key]['screenshot']);
 516        $row[] = drupal_render($form[$key]['description']);
 517        $row[] = drupal_render($form['theme'][$key]);
 518      }
 519      $rows[] = $row;
 520    }
 521  
 522    $header = array(t('Screenshot'), t('Name'), t('Selected'));
 523    $output = theme('table', $header, $rows);
 524    return $output;
 525  }
 526  
 527  function _system_zonelist() {
 528    $timestamp = time();
 529    $zonelist = array(-11, -10, -9.5, -9, -8, -7, -6, -5, -4, -3.5, -3, -2, -1, 0, 1, 2, 3, 3.5, 4, 5, 5.5, 5.75, 6, 6.5, 7, 8, 9, 9.5, 10, 10.5, 11, 11.5, 12, 12.75, 13, 14);
 530    $zones = array();
 531    foreach ($zonelist as $offset) {
 532      $zone = $offset * 3600;
 533      $zones[$zone] = format_date($timestamp, 'custom', variable_get('date_format_long', 'l, F j, Y - H:i') . ' O', $zone);
 534    }
 535    return $zones;
 536  }
 537  
 538  function system_site_information_settings() {
 539    $form['site_name'] = array(
 540      '#type' => 'textfield',
 541      '#title' => t('Name'),
 542      '#default_value' => variable_get('site_name', 'Drupal'),
 543      '#description' => t('The name of this web site.'),
 544      '#required' => TRUE
 545    );
 546    $form['site_mail'] = array(
 547      '#type' => 'textfield',
 548      '#title' => t('E-mail address'),
 549      '#default_value' => variable_get('site_mail', ini_get('sendmail_from')),
 550      '#description' => t('A valid e-mail address for this website, used by the auto-mailer during registration, new password requests, notifications, etc.')
 551    );
 552    $form['site_slogan'] = array(
 553      '#type' => 'textfield',
 554      '#title' => t('Slogan'),
 555      '#default_value' => variable_get('site_slogan', ''),
 556      '#description' => t('The slogan of this website. Some themes display a slogan when available.')
 557    );
 558  
 559    $form['site_mission'] = array(
 560      '#type' => 'textarea',
 561      '#title' => t('Mission'),
 562      '#default_value' => variable_get('site_mission', ''),
 563      '#description' => t('Your site\'s mission statement or focus.')
 564    );
 565    $form['site_footer'] = array(
 566      '#type' => 'textarea',
 567      '#title' => t('Footer message'),
 568      '#default_value' => variable_get('site_footer', ''),
 569      '#description' => t('This text will be displayed at the bottom of each page. Useful for adding a copyright notice to your pages.')
 570    );
 571    $form['anonymous'] = array(
 572      '#type' => 'textfield',
 573      '#title' => t('Anonymous user'),
 574      '#default_value' => variable_get('anonymous', t('Anonymous')),
 575      '#description' => t('The name used to indicate anonymous users.')
 576    );
 577    $form['site_frontpage'] = array(
 578      '#type' => 'textfield',
 579      '#title' => t('Default front page'),
 580      '#default_value' => variable_get('site_frontpage', 'node'),
 581      '#size' => 40,
 582      '#description' => t('The home page displays content from this relative URL. If unsure, specify "node".'),
 583      '#field_prefix' => url(NULL, NULL, NULL, TRUE) . (variable_get('clean_url', 0) ? '' : '?q=')
 584    );
 585  
 586    return system_settings_form($form);
 587  }
 588  
 589  function system_clean_url_settings() {
 590    // We check for clean URL support using an image on the client side.
 591    $form['clean_url'] = array(
 592      '#type' => 'radios',
 593      '#title' => t('Clean URLs'),
 594      '#default_value' => variable_get('clean_url', 0),
 595      '#options' => array(t('Disabled'), t('Enabled')),
 596      '#description' => t('This option makes Drupal emit "clean" URLs (i.e. without <code>?q=</code> in the URL.)'),
 597    );
 598  
 599    if (!variable_get('clean_url', 0)) {
 600      if (strpos(request_uri(), '?q=') !== FALSE) {
 601        $form['clean_url']['#description'] .= t(' Before enabling clean URLs, you must perform a test to determine if your server is properly configured. If you are able to see this page again after clicking the "Run the clean URL test" link, the test has succeeded and the radio buttons above will be available. If instead you are directed to a "Page not found" error, you will need to change the configuration of your server. The <a href="@handbook">handbook page on Clean URLs</a> has additional troubleshooting information. !run-test', array('@handbook' => 'http://drupal.org/node/15365', '!run-test' => '<a href ="'. base_path() . 'admin/settings/clean-urls">'. t('Run the clean URL test') .'</a>'));
 602        $form['clean_url']['#disabled'] = TRUE;
 603      }
 604      else {
 605        $form['clean_url']['#description'] .= t(' You have successfully demonstrated that clean URLs work on your server. You may enable/disable them as you wish.');
 606        $form['#collapsed'] = FALSE;
 607      }
 608    }
 609  
 610    return system_settings_form($form);
 611  }
 612  
 613  function system_error_reporting_settings() {
 614  
 615    $form['site_403'] = array(
 616      '#type' => 'textfield',
 617      '#title' => t('Default 403 (access denied) page'),
 618      '#default_value' => variable_get('site_403', ''),
 619      '#size' => 40,
 620      '#description' => t('This page is displayed when the requested document is denied to the current user. If unsure, specify nothing.'),
 621      '#field_prefix' => url(NULL, NULL, NULL, TRUE) . (variable_get('clean_url', 0) ? '' : '?q=')
 622    );
 623  
 624    $form['site_404'] = array(
 625      '#type' => 'textfield',
 626      '#title' => t('Default 404 (not found) page'),
 627      '#default_value' =>  variable_get('site_404', ''),
 628      '#size' => 40,
 629      '#description' => t('This page is displayed when no other content matches the requested document. If unsure, specify nothing.'),
 630      '#field_prefix' => url(NULL, NULL, NULL, TRUE) . (variable_get('clean_url', 0) ? '' : '?q=')
 631    );
 632  
 633    $form['error_level'] = array(
 634      '#type' => 'select', '#title' => t('Error reporting'), '#default_value' => variable_get('error_level', 1),
 635      '#options' => array(t('Write errors to the log'), t('Write errors to the log and to the screen')),
 636      '#description' =>  t('Where Drupal, PHP and SQL errors are logged. On a production server it is recommended that errors are only written to the error log. On a test server it can be helpful to write logs to the screen.')
 637    );
 638  
 639    $period = drupal_map_assoc(array(3600, 10800, 21600, 32400, 43200, 86400, 172800, 259200, 604800, 1209600, 2419200), 'format_interval');
 640    $period['1000000000'] = t('Never');
 641    $form['watchdog_clear'] = array(
 642      '#type' => 'select',
 643      '#title' => t('Discard log entries older than'),
 644      '#default_value' => variable_get('watchdog_clear', 604800),
 645      '#options' => $period,
 646      '#description' => t('The time log entries should be kept. Older entries will be automatically discarded. Requires crontab.')
 647    );
 648  
 649    return system_settings_form($form);
 650  }
 651  
 652  function system_performance_settings() {
 653  
 654    $description = '<p>'. t("The normal cache mode is suitable for most sites and does not cause any side effects. The aggressive cache mode causes Drupal to skip the loading (init) and unloading (exit) of enabled modules when serving a cached page. This results in an additional performance boost but can cause unwanted side effects.") .'</p>';
 655  
 656    $problem_modules = array_unique(array_merge(module_implements('init'), module_implements('exit')));
 657    sort($problem_modules);
 658  
 659    if (count($problem_modules) > 0) {
 660      $description .= '<p>'. t('<strong class="error">The following enabled modules are incompatible with aggressive mode caching and will not function properly: %modules</strong>', array('%modules' => implode(', ', $problem_modules))) .'.</p>';
 661    }
 662    else {
 663      $description .= '<p>'. t('<strong class="ok">Currently, all enabled modules are compatible with the aggressive caching policy.</strong> Please note, if you use aggressive caching and enable new modules, you will need to check this page again to ensure compatibility.') .'</p>';
 664    }
 665    $form['page_cache'] = array(
 666      '#type' => 'fieldset',
 667      '#title' => t('Page cache'),
 668      '#description' => t('Enabling the cache will offer a significant performance boost. Drupal can store and send compressed cached pages requested by <em>anonymous</em> users. By caching a web page, Drupal does not have to construct the page each time someone wants to view it.'),
 669    );
 670  
 671    $form['page_cache']['cache'] = array(
 672      '#type' => 'radios',
 673      '#title' => t('Caching mode'),
 674      '#default_value' => variable_get('cache', CACHE_DISABLED),
 675      '#options' => array(CACHE_DISABLED => t('Disabled'), CACHE_NORMAL => t('Normal (recommended, no side effects)'), CACHE_AGGRESSIVE => t('Aggressive (experts only, possible side effects)')),
 676      '#description' => $description
 677    );
 678  
 679    $period = drupal_map_assoc(array(0, 60, 180, 300, 600, 900, 1800, 2700, 3600, 10800, 21600, 32400, 43200, 86400), 'format_interval');
 680    $period[0] = t('none');
 681    $form['page_cache']['cache_lifetime'] = array(
 682      '#type' => 'select',
 683      '#title' => t('Minimum cache lifetime'),
 684      '#default_value' => variable_get('cache_lifetime', 0),
 685      '#options' => $period,
 686      '#description' => t('On high-traffic sites it can become necessary to enforce a minimum cache lifetime. The minimum cache lifetime is the minimum amount of time that will go by before the cache is emptied and recreated. A larger minimum cache lifetime offers better performance, but users will not see new content for a longer period of time.')
 687    );
 688  
 689    $form['bandwidth_optimizations'] = array(
 690      '#type' => 'fieldset',
 691      '#title' => t('Bandwidth optimizations'),
 692      '#description' => t('These options can help reduce both the size and number of requests made to your website. This can reduce the server load, the bandwidth used, and the average page loading time for your visitors.')
 693    );
 694  
 695    $directory = file_directory_path();
 696    $is_writable = is_dir($directory) && is_writable($directory) && (variable_get('file_downloads', FILE_DOWNLOADS_PUBLIC) == FILE_DOWNLOADS_PUBLIC);
 697    $form['bandwidth_optimizations']['preprocess_css'] = array(
 698      '#type' => 'radios',
 699      '#title' => t('Aggregate and compress CSS files'),
 700      '#default_value' => variable_get('preprocess_css', FALSE) && $is_writable,
 701      '#disabled' => !$is_writable,
 702      '#options' => array(t('Disabled'), t('Enabled')),
 703      '#description' => t("Some Drupal modules include their own CSS files. When these modules are enabled, each module's CSS file adds an additional HTTP request to the page, which can increase the load time of each page. These HTTP requests can also slightly increase server load. It is recommended to only turn this option on when your site is in production, as it can interfere with theme development. This option is disabled if you have not set up your files directory, or if your download method is set to private."),
 704    );
 705  
 706    $form['#submit']['system_settings_form_submit'] = array();
 707    $form['#submit']['drupal_clear_css_cache'] = array();
 708  
 709    return system_settings_form($form);
 710  }
 711  
 712  function system_file_system_settings() {
 713  
 714    $form['file_directory_path'] = array(
 715      '#type' => 'textfield',
 716      '#title' => t('File system path'),
 717      '#default_value' => file_directory_path(),
 718      '#maxlength' => 255,
 719      '#description' => t('A file system path where the files will be stored. This directory has to exist and be writable by Drupal. If the download method is set to public this directory has to be relative to the Drupal installation directory, and be accessible over the web. When download method is set to private this directory should not be accessible over the web. Changing this location after the site has been in use will cause problems so only change this setting on an existing site if you know what you are doing.'),
 720      '#after_build' => array('system_check_directory'),
 721    );
 722  
 723    $form['file_directory_temp'] = array(
 724      '#type' => 'textfield',
 725      '#title' => t('Temporary directory'),
 726      '#default_value' => file_directory_temp(),
 727      '#maxlength' => 255,
 728      '#description' => t('Location where uploaded files will be kept during previews. Relative paths will be resolved relative to the Drupal installation directory.'),
 729      '#after_build' => array('system_check_directory'),
 730    );
 731  
 732    $form['file_downloads'] = array(
 733      '#type' => 'radios',
 734      '#title' => t('Download method'),
 735      '#default_value' => variable_get('file_downloads', FILE_DOWNLOADS_PUBLIC),
 736      '#options' => array(FILE_DOWNLOADS_PUBLIC => t('Public - files are available using HTTP directly.'), FILE_DOWNLOADS_PRIVATE => t('Private - files are transferred by Drupal.')),
 737      '#description' => t('If you want any sort of access control on the downloading of files, this needs to be set to <em>private</em>. You can change this at any time, however all download URLs will change and there may be unexpected problems so it is not recommended.')
 738    );
 739  
 740    return system_settings_form($form);
 741  }
 742  
 743  function system_image_toolkit_settings() {
 744    $toolkits_available = image_get_available_toolkits();
 745    if (count($toolkits_available) > 1) {
 746      $form['image_toolkit'] = array(
 747        '#type' => 'radios',
 748        '#title' => t('Select an image processing toolkit'),
 749        '#default_value' => variable_get('image_toolkit', image_get_toolkit()),
 750        '#options' => $toolkits_available
 751      );
 752    }
 753    else {
 754      $form['image_toolkit'] = array('#value' => '<p>'. t("No image toolkits found. Drupal will use PHP's built-in GD library for image handling.") .'</p>');
 755    }
 756    $form['image_toolkit_settings'] = image_toolkit_invoke('settings');
 757    return system_settings_form($form);
 758  }
 759  
 760  function system_rss_feeds_settings() {
 761  
 762    $form['feed_default_items'] = array(
 763      '#type' => 'select',
 764      '#title' => t('Number of items per feed'),
 765      '#default_value' => variable_get('feed_default_items', 10),
 766      '#options' => drupal_map_assoc(array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20, 25, 30)),
 767      '#description' => t('The default number of items to include in a feed.')
 768    );
 769    $form['feed_item_length'] = array(
 770      '#type' => 'select',
 771      '#title' => t('Display of XML feed items'),
 772      '#default_value' => variable_get('feed_item_length','teaser'),
 773      '#options' => array('title' => t('Titles only'), 'teaser' => t('Titles plus teaser'), 'fulltext' => t('Full text')),
 774      '#description' => t('Global setting for the length of XML feed items that are output by default.')
 775    );
 776  
 777    return system_settings_form($form);
 778  }
 779  
 780  function system_date_time_settings() {
 781    // Date settings:
 782    $zones = _system_zonelist();
 783  
 784    // Date settings: possible date formats
 785    $dateshort = array('Y-m-d H:i', 'm/d/Y - H:i', 'd/m/Y - H:i', 'Y/m/d - H:i',
 786             'd.m.Y - H:i', 'm/d/Y - g:ia', 'd/m/Y - g:ia', 'Y/m/d - g:ia',
 787             'M j Y - H:i', 'j M Y - H:i', 'Y M j - H:i',
 788             'M j Y - g:ia', 'j M Y - g:ia', 'Y M j - g:ia');
 789    $datemedium = array('D, Y-m-d H:i', 'D, m/d/Y - H:i', 'D, d/m/Y - H:i',
 790            'D, Y/m/d - H:i', 'F j, Y - H:i', 'j F, Y - H:i', 'Y, F j - H:i',
 791            'D, m/d/Y - g:ia', 'D, d/m/Y - g:ia', 'D, Y/m/d - g:ia',
 792            'F j, Y - g:ia', 'j F Y - g:ia', 'Y, F j - g:ia', 'j. F Y - G:i');
 793    $datelong = array('l, F j, Y - H:i', 'l, j F, Y - H:i', 'l, Y,  F j - H:i',
 794          'l, F j, Y - g:ia', 'l, j F Y - g:ia', 'l, Y,  F j - g:ia', 'l, j. F Y - G:i');
 795  
 796    // Date settings: construct choices for user
 797    foreach ($dateshort as $f) {
 798      $dateshortchoices[$f] = format_date(time(), 'custom', $f);
 799    }
 800    foreach ($datemedium as $f) {
 801      $datemediumchoices[$f] = format_date(time(), 'custom', $f);
 802    }
 803    foreach ($datelong as $f) {
 804      $datelongchoices[$f] = format_date(time(), 'custom', $f);
 805    }
 806  
 807    $form['date_default_timezone'] = array(
 808      '#type' => 'select',
 809      '#title' => t('Default time zone'),
 810      '#default_value' => variable_get('date_default_timezone', 0),
 811      '#options' => $zones,
 812      '#description' => t('Select the default site time zone.')
 813    );
 814  
 815    $form['configurable_timezones'] = array(
 816      '#type' => 'radios',
 817      '#title' => t('Configurable time zones'),
 818      '#default_value' => variable_get('configurable_timezones', 1),
 819      '#options' => array(t('Disabled'), t('Enabled')),
 820      '#description' => t('Enable or disable user-configurable time zones. When enabled, users can set their own time zone and dates will be updated accordingly.')
 821    );
 822  
 823    $form['date_format_short'] = array(
 824      '#type' => 'select',
 825      '#title' => t('Short date format'),
 826      '#default_value' => variable_get('date_format_short', $dateshort[1]),
 827      '#options' => $dateshortchoices,
 828      '#description' => t('The short format of date display.')
 829    );
 830  
 831    $form['date_format_medium'] = array(
 832      '#type' => 'select',
 833      '#title' => t('Medium date format'),
 834      '#default_value' => variable_get('date_format_medium', $datemedium[1]),
 835      '#options' => $datemediumchoices,
 836      '#description' => t('The medium sized date display.')
 837    );
 838  
 839    $form['date_format_long'] = array(
 840      '#type' => 'select',
 841      '#title' => t('Long date format'),
 842      '#default_value' => variable_get('date_format_long', $datelong[0]),
 843      '#options' => $datelongchoices,
 844      '#description' => t('Longer date format used for detailed display.')
 845    );
 846  
 847    $form['date_first_day'] = array(
 848      '#type' => 'select',
 849      '#title' => t('First day of week'),
 850      '#default_value' => variable_get('date_first_day', 0),
 851      '#options' => array(0 => t('Sunday'), 1 => t('Monday'), 2 => t('Tuesday'), 3 => t('Wednesday'), 4 => t('Thursday'), 5 => t('Friday'), 6 => t('Saturday')),
 852      '#description' => t('The first day of the week for calendar views.')
 853    );
 854  
 855    return system_settings_form($form);
 856  }
 857  
 858  function system_site_maintenance_settings() {
 859  
 860    $form['site_offline'] = array(
 861      '#type' => 'radios',
 862      '#title' => t('Site status'),
 863      '#default_value' => variable_get('site_offline', 0),
 864      '#options' => array(t('Online'), t('Off-line')),
 865      '#description' => t('When set to "Online", all visitors will be able to browse your site normally. When set to "Off-line", only users with the "administer site configuration" permission will be able to access your site to perform maintenance; all other visitors will see the site off-line message configured below. Authorized users can log in during "Off-line" mode directly via the <a href="@user-login">user login</a> page.', array('@user-login' => url('user'))),
 866    );
 867  
 868    $form['site_offline_message'] = array(
 869      '#type' => 'textarea',
 870      '#title' => t('Site off-line message'),
 871      '#default_value' => variable_get('site_offline_message', t('@site is currently under maintenance. We should be back shortly. Thank you for your patience.', array('@site' => variable_get('site_name', 'Drupal')))),
 872      '#description' => t('Message to show visitors when the site is in off-line mode.')
 873    );
 874  
 875    return system_settings_form($form);
 876  }
 877  
 878  /**
 879   * Checks the existence of the directory specified in $form_element. This
 880   * function is called from the system_settings form to check both the
 881   * file_directory_path and file_directory_temp directories. If validation
 882   * fails, the form element is flagged with an error from within the
 883   * file_check_directory function.
 884   *
 885   * @param $form_element
 886   *   The form element containing the name of the directory to check.
 887   */
 888  function system_check_directory($form_element) {
 889    file_check_directory($form_element['#value'], FILE_CREATE_DIRECTORY, $form_element['#parents'][0]);
 890    return $form_element;
 891  }
 892  
 893  /**
 894   * Retrieves the current status of an array of files in the system table.
 895   */
 896  function system_get_files_database(&$files, $type) {
 897    // Extract current files from database.
 898    $result = db_query("SELECT filename, name, type, status, throttle, schema_version FROM {system} WHERE type = '%s'", $type);
 899    while ($file = db_fetch_object($result)) {
 900      if (isset($files[$file->name]) && is_object($files[$file->name])) {
 901        $file->old_filename = $file->filename;
 902        foreach ($file as $key => $value) {
 903          if (!isset($files[$file->name]) || !isset($files[$file->name]->$key)) {
 904            $files[$file->name]->$key = $value;
 905          }
 906        }
 907      }
 908    }
 909  }
 910  
 911  /**
 912   * Collect data about all currently available themes
 913   */
 914  function system_theme_data() {
 915    include_once  './includes/install.inc';
 916  
 917    // Find themes
 918    $themes = drupal_system_listing('\.theme$', 'themes');
 919  
 920    // Find theme engines
 921    $engines = drupal_system_listing('\.engine$', 'themes/engines');
 922  
 923    // can't iterate over array itself as it uses a copy of the array items
 924    foreach (array_keys($themes) as $key) {
 925      drupal_get_filename('theme', $themes[$key]->name, $themes[$key]->filename);
 926      drupal_load('theme', $themes[$key]->name);
 927      $themes[$key]->owner = $themes[$key]->filename;
 928      $themes[$key]->prefix = $key;
 929    }
 930  
 931    // Remove all theme engines from the system table
 932    db_query("DELETE FROM {system} WHERE type = 'theme_engine'");
 933  
 934    foreach ($engines as $engine) {
 935      // Insert theme engine into system table
 936      drupal_get_filename('theme_engine', $engine->name, $engine->filename);
 937      drupal_load('theme_engine', $engine->name);
 938      db_query("INSERT INTO {system} (name, type, filename, status, throttle, bootstrap) VALUES ('%s', '%s', '%s', %d, %d, %d)", $engine->name, 'theme_engine', $engine->filename, 1, 0, 0);
 939  
 940      // Add templates to the site listing
 941      foreach (call_user_func($engine->name . '_templates') as $template) {
 942        // Do not double-insert templates with theme files in their directory,
 943        // but do register their engine data.
 944        if (array_key_exists($template->name, $themes)) {
 945          $themes[$template->name]->template = TRUE;
 946          $themes[$template->name]->owner = $engine->filename;
 947          $themes[$template->name]->prefix = $engine->name;
 948        }
 949        else {
 950          $template->template = TRUE;
 951          $template->name = basename(dirname($template->filename));
 952          $template->owner = $engine->filename;
 953          $template->prefix = $engine->name;
 954  
 955          $themes[$template->name] = $template;
 956        }
 957      }
 958    }
 959  
 960    // Find styles in each theme's directory.
 961    foreach ($themes as $theme) {
 962      foreach (file_scan_directory(dirname($theme->filename), 'style.css$') as $style) {
 963        $style->style = TRUE;
 964        $style->template = isset($theme->template) ? $theme->template : FALSE;
 965        $style->name = basename(dirname($style->filename));
 966        $style->owner = $theme->filename;
 967        $style->prefix = $theme->template ? $theme->prefix : $theme->name;
 968        // do not double-insert styles with theme files in their directory
 969        if (array_key_exists($style->name, $themes)) {
 970          continue;
 971        }
 972        $themes[$style->name] = $style;
 973      }
 974    }
 975  
 976    // Extract current files from database.
 977    system_get_files_database($themes, 'theme');
 978  
 979    db_query("DELETE FROM {system} WHERE type = 'theme'");
 980  
 981    foreach ($themes as $theme) {
 982      db_query("INSERT INTO {system} (name, description, type, filename, status, throttle, bootstrap) VALUES ('%s', '%s', '%s', '%s', %d, %d, %d)", $theme->name, $theme->owner, 'theme', $theme->filename, $theme->status, 0, 0);
 983    }
 984  
 985    return $themes;
 986  }
 987  
 988  /**
 989   * Get a list of available regions from a specified theme.
 990   *
 991   * @param $theme_key
 992   *   The name of a theme.
 993   * @return
 994   *   An array of regions in the form $region['name'] = 'description'.
 995   */
 996  function system_region_list($theme_key) {
 997    static $list = array();
 998  
 999    if (!array_key_exists($theme_key, $list)) {
1000      $theme = db_fetch_object(db_query("SELECT * FROM {system} WHERE type = 'theme' AND name = '%s'", $theme_key));
1001  
1002      // Stylesheets can't have regions; use its theme.
1003      if (strpos($theme->filename, '.css')) {
1004        return system_region_list(basename(dirname($theme->description)));
1005      }
1006  
1007      // If this is a custom theme, load it in before moving on.
1008      if (file_exists($file = dirname($theme->filename) .'/' . $theme_key . '.theme')) {
1009        include_once "./$file";
1010      }
1011  
1012      $regions = array();
1013  
1014      // This theme has defined its own regions.
1015      if (function_exists($theme_key . '_regions')) {
1016        $regions = call_user_func($theme_key . '_regions');
1017      }
1018      // File is an engine; include its regions.
1019      else if (strpos($theme->description, '.engine')) {
1020        include_once './' . $theme->description;
1021        $theme_engine = basename($theme->description, '.engine');
1022        $regions = function_exists($theme_engine . '_regions') ? call_user_func($theme_engine . '_regions') : array();
1023      }
1024  
1025      $list[$theme_key] = $regions;
1026    }
1027  
1028    return $list[$theme_key];
1029  }
1030  
1031  /**
1032   * Get the name of the default region for a given theme.
1033   *
1034   * @param $theme
1035   *   The name of a theme.
1036   * @return
1037   *   A string that is the region name.
1038   */
1039  function system_default_region($theme) {
1040    $regions = array_keys(system_region_list($theme));
1041    return $regions[0];
1042  }
1043  
1044  /**
1045   * Assign an initial, default set of blocks for a theme.
1046   *
1047   * This function is called the first time a new theme is enabled. The new theme
1048   * gets a copy of the default theme's blocks, with the difference that if a
1049   * particular region isn't available in the new theme, the block is assigned
1050   * to the new theme's default region.
1051   *
1052   * @param $theme
1053   *   The name of a theme.
1054   */
1055  function system_initialize_theme_blocks($theme) {
1056    // Initialize theme's blocks if none already registered.
1057    if (!(db_num_rows(db_query("SELECT module FROM {blocks} WHERE theme = '%s'", $theme)))) {
1058      $default_theme = variable_get('theme_default', 'garland');
1059      $regions = system_region_list($theme);
1060      $result = db_query("SELECT * FROM {blocks} WHERE theme = '%s'", $default_theme);
1061      while ($block = db_fetch_array($result)) {
1062        // If the region isn't supported by the theme, assign the block to the theme's default region.
1063        if (!array_key_exists($block['region'], $regions)) {
1064          $block['region'] = system_default_region($theme);
1065        }
1066        db_query("INSERT INTO {blocks} (module, delta, theme, status, weight, region, visibility, pages, custom, throttle) VALUES ('%s', '%s', '%s', %d, %d, '%s', %d, '%s', %d, %d)",
1067            $block['module'], $block['delta'], $theme, $block['status'], $block['weight'], $block['region'], $block['visibility'], $block['pages'], $block['custom'], $block['throttle']);
1068      }
1069    }
1070  }
1071  
1072  /**
1073   * Add default buttons to a form and set its prefix
1074   */
1075  function system_settings_form($form) {
1076    $form['buttons']['submit'] = array('#type' => 'submit', '#value' => t('Save configuration') );
1077    $form['buttons']['reset'] = array('#type' => 'submit', '#value' => t('Reset to defaults') );
1078  
1079    if (!empty($_POST) && form_get_errors()) {
1080      drupal_set_message(t('The settings have not been saved because of the errors.'), 'error');
1081    }
1082    $form['#base'] = 'system_settings_form';
1083    return $form;
1084  }
1085  
1086  function system_theme_settings_submit($form_id, $form_values) {
1087    $op = isset($_POST['op']) ? $_POST['op'] : '';
1088    $key = $form_values['var'];
1089  
1090    // Exclude unnecessary elements.
1091    unset($form_values['var'], $form_values['submit'], $form_values['reset'], $form_values['form_id']);
1092  
1093    if ($op == t('Reset to defaults')) {
1094      variable_del($key);
1095      drupal_set_message(t('The configuration options have been reset to their default values.'));
1096    }
1097    else {
1098      variable_set($key, $form_values);
1099      drupal_set_message(t('The configuration options have been saved.'));
1100    }
1101  
1102    cache_clear_all();
1103  }
1104  
1105  /**
1106   * Execute the system_settings_form.
1107   *
1108   * If you want node type configure style handling of your checkboxes,
1109   * add an array_filter value to your form.
1110   *
1111   */
1112  function system_settings_form_submit($form_id, $form_values) {
1113    $op = isset($form_values['op']) ? $form_values['op'] : '';
1114  
1115    // Exclude unnecessary elements.
1116    unset($form_values['submit'], $form_values['reset'], $form_values['form_id'], $form_values['op'], $form_values['form_token']);
1117  
1118    foreach ($form_values as $key => $value) {
1119      if ($op == t('Reset to defaults')) {
1120        variable_del($key);
1121      }
1122      else {
1123        if (is_array($value) && isset($form_values['array_filter'])) {
1124          $value = array_keys(array_filter($value));
1125        }
1126        variable_set($key, $value);
1127      }
1128    }
1129    if ($op == t('Reset to defaults')) {
1130      drupal_set_message(t('The configuration options have been reset to their default values.'));
1131    }
1132    else {
1133      drupal_set_message(t('The configuration options have been saved.'));
1134    }
1135  
1136    menu_rebuild();
1137  }
1138  
1139  /**
1140   * Menu callback; displays a listing of all themes.
1141   */
1142  function system_themes() {
1143  
1144    drupal_clear_css_cache();
1145    $themes = system_theme_data();
1146    ksort($themes);
1147  
1148    foreach ($themes as $info) {
1149      $info->screenshot = dirname($info->filename) . '/screenshot.png';
1150      $screenshot = file_exists($info->screenshot) ? theme('image', $info->screenshot, t('Screenshot for %theme theme', array('%theme' => $info->name)), '', array('class' => 'screenshot'), FALSE) : t('no screenshot');
1151  
1152      $form[$info->name]['screenshot'] = array('#value' => $screenshot);
1153      $form[$info->name]['description'] = array('#type' => 'item', '#title' => $info->name,  '#value' => dirname($info->filename));
1154      $options[$info->name] = '';
1155      if ($info->status) {
1156        $status[] = $info->name;
1157      }
1158      if ($info->status && (function_exists($info->prefix . '_settings') || function_exists($info->prefix . '_features'))) {
1159        $form[$info->name]['operations'] = array('#value' => l(t('configure'), 'admin/build/themes/settings/' . $info->name) );
1160      }
1161      else {
1162        // Dummy element for drupal_render. Cleaner than adding a check in the theme function.
1163        $form[$info->name]['operations'] = array();
1164      }
1165    }
1166  
1167    $form['status'] = array('#type' => 'checkboxes', '#options' => $options, '#default_value' => $status);
1168    $form['theme_default'] = array('#type' => 'radios', '#options' => $options, '#default_value' => variable_get('theme_default', 'garland'));
1169    $form['buttons']['submit'] = array('#type' => 'submit', '#value' => t('Save configuration') );
1170    $form['buttons']['reset'] = array('#type' => 'submit', '#value' => t('Reset to defaults') );
1171  
1172    return $form;
1173  }
1174  
1175  function theme_system_themes($form) {
1176    foreach (element_children($form) as $key) {
1177      $row = array();
1178      if (is_array($form[$key]['description'])) {
1179        $row[] = drupal_render($form[$key]['screenshot']);
1180        $row[] = drupal_render($form[$key]['description']);
1181        $row[] = array('data' => drupal_render($form['status'][$key]), 'align' => 'center');
1182        if ($form['theme_default']) {
1183          $row[] = array('data' => drupal_render($form['theme_default'][$key]), 'align' => 'center');
1184          $row[] = array('data' => drupal_render($form[$key]['operations']), 'align' => 'center');
1185        }
1186      }
1187      $rows[] = $row;
1188    }
1189  
1190    $header = array(t('Screenshot'), t('Name'), t('Enabled'), t('Default'), t('Operations'));
1191    $output = theme('table', $header, $rows);
1192    $output .= drupal_render($form);
1193    return $output;
1194  }
1195  
1196  
1197  function system_themes_submit($form_id, $form_values) {
1198  
1199    db_query("UPDATE {system} SET status = 0 WHERE type = 'theme'");
1200  
1201    if ($form_values['op'] == t('Save configuration')) {
1202      if (is_array($form_values['status'])) {
1203        foreach ($form_values['status'] as $key => $choice) {
1204          // Always enable the default theme, despite its status checkbox being checked:
1205          if ($choice || $form_values['theme_default'] == $key) {
1206            system_initialize_theme_blocks($key);
1207            db_query("UPDATE {system} SET status = 1 WHERE type = 'theme' and name = '%s'", $key);
1208          }
1209        }
1210      }
1211      if (($admin_theme = variable_get('admin_theme', '0')) != '0' && $admin_theme != $form_values['theme_default']) {
1212        drupal_set_message(t('Please note that the <a href="!admin_theme_page">administration theme</a> is still set to the %admin_theme theme; consequently, the theme on this page remains unchanged. All non-administrative sections of the site, however, will show the selected %selected_theme theme by default.', array(
1213          '!admin_theme_page' => url('admin/settings/admin'),
1214          '%admin_theme' => $admin_theme,
1215          '%selected_theme' => $form_values['theme_default'],
1216        )));
1217      }
1218      variable_set('theme_default', $form_values['theme_default']);
1219    }
1220    else {
1221      variable_del('theme_default');
1222      db_query("UPDATE {system} SET status = 1 WHERE type = 'theme' AND name = 'garland'");
1223    }
1224  
1225    menu_rebuild();
1226    drupal_set_message(t('The configuration options have been saved.'));
1227    return 'admin/build/themes';
1228  }
1229  
1230  /**
1231   * Menu callback; provides module enable/disable interface.
1232   *
1233   * Modules can be enabled or disabled and set for throttling if the throttle module is enabled.
1234   * The list of modules gets populated by module.info files, which contain each module's name,
1235   * description and dependencies.
1236   * @sa _module_parse_info_file for information on module.info descriptors.
1237   *
1238   * Dependency checking is performed to ensure that a module cannot be enabled if the module has
1239   * disabled dependencies and also to ensure that the module cannot be disabled if the module has
1240   * enabled dependents.
1241   *
1242   * @return
1243   *   The form array.
1244   */
1245  function system_modules($form_values = NULL) {
1246    // Get current list of modules.
1247    $files = module_rebuild_cache();
1248    if ($confirm_form = system_modules_confirm_form($files, $form_values)) {
1249      return $confirm_form;
1250    }
1251  
1252    // Store module list for validation callback.
1253    $form['validation_modules'] = array('#type' => 'value', '#value' => $files);
1254  
1255    // Create storage for disabled modules as browser will disable checkboxes.
1256    $form['disabled_modules'] = array('#type' => 'value', '#value' => array());
1257  
1258    // Array for disabling checkboxes in callback system_module_disable.
1259    $disabled = array();
1260    // Traverse the files retrieved and build the form.
1261    foreach ($files as $filename => $file) {
1262      $form['name'][$filename] = array('#value' => $file->info['name']);
1263      $form['version'][$filename] = array('#value' => $file->info['version']);
1264      $form['description'][$filename] = array('#value' => t($file->info['description']));
1265      $options[$filename] = '';
1266      if ($file->status) {
1267        $status[] = $file->name;
1268      }
1269      if ($file->throttle) {
1270        $throttle[] = $file->name;
1271      }
1272  
1273      $dependencies = array();
1274      // Check for missing dependencies.
1275      if (is_array($file->info['dependencies'])) {
1276        foreach ($file->info['dependencies'] as $dependency) {
1277          if (!isset($files[$dependency]) || !$files[$dependency]->status) {
1278            if (isset($files[$dependency])) {
1279              $dependencies[] = $files[$dependency]->info['name'] . t(' (<span class="admin-disabled">disabled</span>)');
1280            }
1281            else {
1282              $dependencies[] = drupal_ucfirst($dependency) . t(' (<span class="admin-missing">missing</span>)');
1283              $disabled[] = $filename;
1284              $form['disabled_modules']['#value'][$filename] = FALSE;
1285            }
1286          }
1287          else {
1288            $dependencies[] = $files[$dependency]->info['name'] . t(' (<span class="admin-enabled">enabled</span>)');
1289          }
1290        }
1291  
1292        // Add text for dependencies.
1293        if (!empty($dependencies)) {
1294          $form['description'][$filename]['dependencies'] = array(
1295            '#value' => t('Depends on: !dependencies', array('!dependencies' => implode(', ', $dependencies))),
1296            '#prefix' => '<div class="admin-dependencies">',
1297            '#suffix' => '</div>',
1298          );
1299        }
1300      }
1301  
1302      // Mark dependents disabled so user can not remove modules being depended on.
1303      $dependents = array();
1304      if (is_array($file->info['dependents'])) {
1305        foreach ($file->info['dependents'] as $dependent) {
1306          if ($files[$dependent]->status == 1) {
1307            $dependents[] = $files[$dependent]->info['name'] . t(' (<span class="admin-enabled">enabled</span>)');
1308            $disabled[] = $filename;
1309            $form['disabled_modules']['#value'][$filename] = TRUE;
1310          }
1311          else {
1312            $dependents[] = $files[$dependent]->info['name'] . t(' (<span class="admin-disabled">disabled</span>)');
1313          }
1314        }
1315      }
1316  
1317      // Add text for enabled dependents.
1318      if (!empty($dependents)){
1319        $form['description'][$filename]['required'] = array(
1320          '#value' => t('Required by: !required', array('!required' => implode(', ', $dependents))),
1321          '#prefix' => '<div class="admin-required">',
1322          '#suffix' => '</div>',
1323        );
1324      }
1325    }
1326  
1327    // Merge in required modules.
1328    $modules_required = array('block', 'filter', 'node', 'system', 'user', 'watchdog');
1329    foreach ($modules_required as $required) {
1330      $disabled[] = $required;
1331      $form['disabled_modules']['#value'][$required] = TRUE;
1332    }
1333  
1334    // Handle status checkboxes, including overriding
1335    // the generated checkboxes for required modules.
1336    $form['status'] = array(
1337      '#type' => 'checkboxes',
1338      '#default_value' => $status,
1339      '#options' => $options,
1340      '#process' => array(
1341        'expand_checkboxes' => array(),
1342        'system_modules_disable' => array($disabled),
1343      ),
1344    );
1345  
1346    // Handle throttle checkboxes, including overriding the
1347    // generated checkboxes for required modules.
1348    if (module_exists('throttle')) {
1349      $form['throttle'] = array(
1350        '#type' => 'checkboxes',
1351        '#default_value' => $throttle,
1352        '#options' => $options,
1353        '#process' => array(
1354          'expand_checkboxes' => array(),
1355          'system_modules_disable' => array(array_merge($modules_required, array('throttle'))),
1356        ),
1357      );
1358    }
1359  
1360    $form['buttons']['submit'] = array(
1361      '#type' => 'submit',
1362      '#value' => t('Save configuration'),
1363    );
1364    $form['#multistep'] = TRUE;
1365    $form['#action'] = url('admin/build/modules/list/confirm');
1366  
1367    return $form;
1368  }
1369  
1370  /**
1371   * Form process callback function to disable check boxes.
1372   */
1373  function system_modules_disable($form, $edit, $disabled) {
1374    foreach ($disabled as $key) {
1375      $form[$key]['#attributes']['disabled'] = 'disabled';
1376    }
1377    return $form;
1378  }
1379  
1380  function system_modules_confirm_form($modules, $form_values = array()) {
1381    $form = array();
1382    $items = array();
1383  
1384    // Check values for submitted dependency errors.
1385    if ($dependencies = system_module_build_dependencies($modules, $form_values)) {
1386      // preserve the already switched on modules
1387      foreach ($modules as $name => $module) {
1388        if ($module->status) {
1389          $form['status'][$name] = array('#type' => 'hidden', '#value' => 1);
1390        }
1391      }
1392  
1393      $form['validation_modules'] = array('#type' => 'value', '#value' => $modules);
1394      $form['status']['#tree'] = TRUE;
1395      foreach ($dependencies as $name => $missing_dependencies) {
1396        $form['status'][$name] = array('#type' => 'hidden', '#value' => 1);
1397        foreach ($missing_dependencies as $k => $dependency) {
1398          $form['status'][$dependency] = array('#type' => 'hidden', '#value' => 1);
1399          $info = $modules[$dependency]->info;
1400          $missing_dependencies[$k] = $info['name'] ? $info['name'] : drupal_ucfirst($dependency);
1401        }
1402        $t_argument = array(
1403          '%module' => $modules[$name]->info['name'],
1404          '%dependencies' => implode(', ', $missing_dependencies),
1405        );
1406        $items[] = strtr(format_plural(count($missing_dependencies), 'You must enable the %dependencies module to install %module.', 'You must enable the %dependencies modules to install %module.'), $t_argument);
1407      }
1408      $form['text'] = array('#value' => theme('item_list', $items));
1409    }
1410  
1411    if ($form) {
1412      // Set some default form values
1413      $form = confirm_form(
1414        $form,
1415        t('Some required modules must be enabled'),
1416        'admin/build/modules',
1417        t('Would you like to continue with enabling the above?'),
1418        t('Continue'),
1419        t('Cancel'));
1420      return $form;
1421    }
1422  }
1423  
1424  function system_module_build_dependencies($modules, $form_values) {
1425    static $dependencies;
1426  
1427    if (!isset($dependencies) && isset($form_values)) {
1428      $dependencies = array();
1429      foreach ($modules as $name => $module) {
1430        // If the module is disabled, will be switched on and it has dependencies.
1431        if (!$module->status && $form_values['status'][$name] && isset($module->info['dependencies'])) {
1432          foreach ($module->info['dependencies'] as $dependency) {
1433            if (!$form_values['status'][$dependency] && isset($modules[$dependency])) {
1434              if (!isset($dependencies[$name])) {
1435                $dependencies[$name] = array();
1436              }
1437              $dependencies[$name][] = $dependency;
1438            }
1439          }
1440        }
1441      }
1442    }
1443    return $dependencies;
1444  }
1445  
1446  /**
1447   * Submit callback; handles modules form submission.
1448   */
1449  function system_modules_submit($form_id, $form_values) {
1450    include_once  './includes/install.inc';
1451    $new_modules = array();
1452  
1453    // Merge in disabled active modules since they should be enabled.
1454    // They don't appear because disabled checkboxes are not submitted
1455    // by browsers.
1456    $form_values['status'] = array_merge($form_values['status'], $form_values['disabled_modules']);
1457  
1458    // Check values for dependency that we can't install.
1459    if ($dependencies = system_module_build_dependencies($form_values['validation_modules'], $form_values)) {
1460      // These are the modules that depend on existing modules.
1461      foreach (array_keys($dependencies) as $name) {
1462        $form_values['status'][$name] = 0;
1463      }
1464    }
1465  
1466    $enable_modules = array();
1467    $disable_modules = array();
1468    foreach ($form_values['status'] as $key => $choice) {
1469      if ($choice) {
1470        if (drupal_get_installed_schema_version($key) == SCHEMA_UNINSTALLED) {
1471          $new_modules[] = $key;
1472        }
1473        else {
1474          $enable_modules[] = $key;
1475        }
1476      }
1477      else {
1478        $disable_modules[] = $key;
1479      }
1480    }
1481  
1482    $old_module_list = module_list();
1483  
1484    if (!empty($enable_modules)) {
1485      module_enable($enable_modules);
1486    }
1487    if (!empty($disable_modules)) {
1488      module_disable($disable_modules);
1489    }
1490  
1491    // Install new modules.
1492    foreach ($new_modules as $key => $module) {
1493      if (!drupal_check_module($module)) {
1494        unset($new_modules[$key]);
1495      }
1496    }
1497    drupal_install_modules($new_modules);
1498  
1499    $current_module_list = module_list(TRUE, FALSE);
1500  
1501    if (is_array($form_values['throttle'])) {
1502      foreach ($form_values['throttle'] as $key => $choice) {
1503        db_query("UPDATE {system} SET throttle = %d WHERE type = 'module' and name = '%s'", $choice ? 1 : 0, $key);
1504      }
1505    }
1506  
1507    if ($old_module_list != $current_module_list) {
1508      menu_rebuild();
1509      node_types_rebuild();
1510      drupal_set_message(t('The configuration options have been saved.'));
1511    }
1512  
1513    // If there where unmet dependencies and they haven't confirmed don't redirect.
1514    if ($dependencies && !isset($form_values['confirm'])) {
1515      return FALSE;
1516    }
1517  
1518    drupal_clear_css_cache();
1519  
1520    return 'admin/build/modules';
1521  }
1522  
1523  /**
1524   * Theme call back for the modules form.
1525   */
1526  function theme_system_modules($form) {
1527    if (isset($form['confirm'])) {
1528      return drupal_render($form);
1529    }
1530  
1531    // Individual table headers.
1532    $header = array(t('Enabled'));
1533    if (module_exists('throttle')) {
1534      $header[] = t('Throttle');
1535    }
1536    $header[] = t('Name');
1537    $header[] = t('Version');
1538    $header[] = t('Description');
1539  
1540    // Pull package information from module list and start grouping modules.
1541    $modules = $form['validation_modules']['#value'];
1542    foreach ($modules as $module) {
1543      if (!isset($module->info['package']) || !$module->info['package']) {
1544        $module->info['package'] = 'Other';
1545      }
1546      $packages[$module->info['package']][$module->name] = $module->info;
1547    }
1548    ksort($packages);
1549  
1550    // Display packages.
1551    $output = '';
1552    foreach ($packages as $package => $modules) {
1553      $rows = array();
1554      foreach ($modules as $key => $module) {
1555        $row = array();
1556        $row[] = array('data' => drupal_render($form['status'][$key]), 'align' => 'center');
1557  
1558        if (module_exists('throttle')) {
1559          $row[] = array('data' => drupal_render($form['throttle'][$key]), 'align' => 'center');
1560        }
1561        $row[] = '<strong>'. drupal_render($form['name'][$key]) .'</strong>';
1562        $row[] = drupal_render($form['version'][$key]);
1563        $row[] = array('data' => drupal_render($form['description'][$key]), 'class' => 'description');
1564        $rows[] = $row;
1565      }
1566      $fieldset = array(
1567        '#title' => t($package),
1568        '#collapsible' => TRUE,
1569        '#collapsed' => ($package == 'Core - required'),
1570        '#value' => theme('table', $header, $rows, array('class' => 'package')),
1571      );
1572      $output .= theme('fieldset', $fieldset);
1573    }
1574  
1575    $output .= drupal_render($form);
1576    return $output;
1577  }
1578  
1579  /**
1580   * Uninstall functions
1581   */
1582  
1583  /**
1584   * Builds a form of currently disabled modules.
1585   *
1586   * @param
1587   *   $form_values Submitted form values.
1588   * @return
1589   *   A form array representing the currently disabled modules.
1590   */
1591  function system_modules_uninstall($form_values = NULL) {
1592    // Make sure the install API is available.
1593    include_once  './includes/install.inc';
1594  
1595    // Display the confirm form if any modules have been submitted.
1596    if ($confirm_form = system_modules_uninstall_confirm_form($form_values)) {
1597      return $confirm_form;
1598    }
1599  
1600    $form = array();
1601  
1602    // Pull all disabled modules from the system table.
1603    $disabled_modules = db_query("SELECT name, filename FROM {system} WHERE type = 'module' AND status = 0 AND schema_version > %d ORDER BY name", SCHEMA_UNINSTALLED);
1604    while ($module = db_fetch_object($disabled_modules)) {
1605  
1606      // Grab the .info file and set name and description.
1607      $info = _module_parse_info_file(dirname($module->filename) .'/'. $module->name .'.info');
1608  
1609      // Load the .install file, and check for an uninstall hook.
1610      // If the hook exists, the module can be uninstalled.
1611      module_load_install($module->name);
1612      if (module_hook($module->name, 'uninstall')) {
1613        $form['modules'][$module->name]['name'] = array('#value' => $info['name'] ? $info['name'] : $module->name);
1614        $form['modules'][$module->name]['description'] = array('#value' => t($info['description']));
1615        $options[$module->name] = '';
1616      }
1617    }
1618  
1619    // Only build the rest of the form if there are any modules available to uninstall.
1620    if (count($options)) {
1621      $form['uninstall'] = array(
1622        '#type' => 'checkboxes',
1623        '#options' => $options,
1624      );
1625      $form['buttons']['submit'] = array(
1626        '#type' => 'button',
1627        '#value' => t('Uninstall'),
1628      );
1629      $form['#multistep'] = TRUE;
1630      $form['#action'] = url('admin/build/modules/uninstall/confirm');
1631    }
1632  
1633    return $form;
1634  }
1635  
1636  /**
1637   * Confirm uninstall of selected modules.
1638   *
1639   * @param
1640   *   $form_values Submitted form values.
1641   * @return
1642   *   A form array representing modules to confirm.
1643   */
1644  function system_modules_uninstall_confirm_form($form_values) {
1645    // Nothing to build.
1646    if (!isset($form_values)) {
1647      return;
1648    }
1649  
1650    // Construct the hidden form elements and list items.
1651    foreach (array_filter($form_values['uninstall']) as $module => $value) {
1652      $info = _module_parse_info_file(dirname(drupal_get_filename('module', $module)) .'/'. $module .'.info');
1653      $uninstall[] = $info['name'];
1654      $form['uninstall'][$module] = array('#type' => 'hidden',
1655        '#value' => 1,
1656      );
1657    }
1658  
1659    // Display a confirm form if modules have been selected.
1660    if (isset($uninstall)) {
1661      $form['uninstall']['#tree'] = TRUE;
1662      $form['#multistep'] = TRUE;
1663      $form['modules'] = array('#value' => '<p>'. t('The following modules will be completely uninstalled from your site, and <em>all data from these modules will be lost</em>!') .'</p>'. theme('item_list', $uninstall));
1664      $form = confirm_form(
1665        $form,
1666        t('Confirm uninstall'),
1667        'admin/build/modules/uninstall',
1668        t('Would you like to continue with uninstalling the above?'),
1669        t('Uninstall'),
1670        t('Cancel'));
1671      return $form;
1672    }
1673  }
1674  
1675  /**
1676   * Themes a table of currently disabled modules.
1677   *
1678   * @param
1679   *   $form The form array representing the currently disabled modules.
1680   * @return
1681   *   An HTML string representing the table.
1682   */
1683  function theme_system_modules_uninstall($form) {
1684    // No theming for the confirm form.
1685    if (isset($form['confirm'])) {
1686      return drupal_render($form);
1687    }
1688  
1689    // Table headers.
1690    $header = array(t('Uninstall'),
1691      t('Name'),
1692      t('Description'),
1693    );
1694  
1695    // Display table.
1696    $rows = array();
1697    foreach (element_children($form['modules']) as $module) {
1698      $rows[] = array(
1699        array('data' => drupal_render($form['uninstall'][$module]), 'align' => 'center'),
1700        '<strong>'. drupal_render($form['modules'][$module]['name']) .'</strong>',
1701        array('data' => drupal_render($form['modules'][$module]['description']), 'class' => 'description'),
1702      );
1703    }
1704  
1705    // Only display table if there are modules that can be uninstalled.
1706    if (!count($rows)) {
1707      $rows[] = array(array('data' => t('No modules are available to uninstall.'), 'colspan' => '3', 'align' => 'center', 'class' => 'message'));
1708    }
1709  
1710    $output  = theme('table', $header, $rows);
1711    $output .= drupal_render($form);
1712  
1713    return $output;
1714  }
1715  
1716  /**
1717   * Validates the submitted uninstall form.
1718   *
1719   * @param
1720   *   $form_id The form ID.
1721   * @param
1722   *   $form_values Submitted form values.
1723   */
1724  function system_modules_uninstall_validate($form_id, $form_values) {
1725    // Form submitted, but no modules selected.
1726    if (!count(array_filter($form_values['uninstall']))) {
1727      drupal_set_message(t('No modules selected.'), 'error');
1728      drupal_goto('admin/build/modules/uninstall');
1729    }
1730  }
1731  
1732  /**
1733   * Processes the submitted uninstall form.
1734   *
1735   * @param
1736   *   $form_id The form ID.
1737   * @param
1738   *   $form_values Submitted form values.
1739   */
1740  function system_modules_uninstall_submit($form_id, $form_values) {
1741    // Make sure the install API is available.
1742    include_once  './includes/install.inc';
1743  
1744    // Call the uninstall routine for each selected module.
1745    foreach (array_filter($form_values['uninstall']) as $module => $value) {
1746      drupal_uninstall_module($module);
1747    }
1748    drupal_set_message(t('The selected modules have been uninstalled.'));
1749    drupal_goto('admin/build/modules/uninstall');
1750  }
1751  
1752  /**
1753   * Menu callback: run cron manually.
1754   */
1755  function system_run_cron() {
1756     // Run cron manually
1757     if (drupal_cron_run()) {
1758       drupal_set_message(t('Cron ran successfully'));
1759     }
1760     else {
1761       drupal_set_message(t('Cron run failed'));
1762     }
1763  
1764     drupal_goto('admin/logs/status');
1765  }
1766  
1767  /**
1768   * Menu callback: return information about PHP.
1769   */
1770  function system_php() {
1771    phpinfo(INFO_GENERAL | INFO_CONFIGURATION);
1772    exit();
1773  }
1774  
1775  function _system_sql($data, $keys) {
1776    $rows = array();
1777    foreach ($keys as $key => $explanation) {
1778      if (isset($data[$key])) {
1779        $rows[] = array(check_plain($key), check_plain($data[$key]), $explanation);
1780      }
1781    }
1782  
1783    return theme('table', array(t('Variable'), t('Value'), t('Description')), $rows);
1784  }
1785  
1786  /**
1787   * Menu callback: return information about PHP.
1788   */
1789  function system_sql() {
1790  
1791    $result = db_query("SHOW STATUS");
1792    while ($entry = db_fetch_object($result)) {
1793     $data[$entry->Variable_name] = $entry->Value;
1794    }
1795  
1796    $output  = '<h2>'. t('Command counters') .'</h2>';
1797    $output .= _system_sql($data, array(
1798     'Com_select' => t('The number of <code>SELECT</code>-statements.'),
1799     'Com_insert' => t('The number of <code>INSERT</code>-statements.'),
1800     'Com_update' => t('The number of <code>UPDATE</code>-statements.'),
1801     'Com_delete' => t('The number of <code>DELETE</code>-statements.'),
1802     'Com_lock_tables' => t('The number of table locks.'),
1803     'Com_unlock_tables' => t('The number of table unlocks.')
1804    ));
1805  
1806    $output .= '<h2>'. t('Query performance') .'</h2>';
1807    $output .= _system_sql($data, array(
1808     'Select_full_join' => t('The number of joins without an index; should be zero.'),
1809     'Select_range_check' => t('The number of joins without an index; should be zero.'),
1810     'Sort_scan' => t('The number of sorts done without using an index; should be zero.'),
1811     'Table_locks_immediate' => t('The number of times a lock could be acquired immediately.'),
1812     'Table_locks_waited' => t('The number of times the server had to wait for a lock.')
1813    ));
1814  
1815    $output .= '<h2>'. t('Query cache information') .'</h2>';
1816    $output .= '<p>'. t('The MySQL query cache can improve performance of your site by storing the result of queries.  Then, if an identical query is received later, the MySQL server retrieves the result from the query cache rather than parsing and executing the statement again.') .'</p>';
1817    $output .= _system_sql($data, array(
1818     'Qcache_queries_in_cache' => t('The number of queries in the query cache.'),
1819     'Qcache_hits' => t('The number of times that MySQL found previous results in the cache.'),
1820     'Qcache_inserts' => t('The number of times that MySQL added a query to the cache (misses).'),
1821     'Qcache_lowmem_prunes' => t('The number of times that MySQL had to remove queries from the cache because it ran out of memory.  Ideally should be zero.')
1822    ));
1823  
1824    return $output;
1825  }
1826  
1827  /**
1828   * Menu callback: displays the site status report. Can also be used as a pure check.
1829   *
1830   * @param $check
1831   *   If true, only returns a boolean whether there are system status errors.
1832   */
1833  function system_status($check = FALSE) {
1834    // Load .install files
1835    include_once  './includes/install.inc';
1836    drupal_load_updates();
1837  
1838    // Check run-time requirements and status information
1839    $requirements = module_invoke_all('requirements', 'runtime');
1840    usort($requirements, '_system_sort_requirements');
1841  
1842    if ($check) {
1843      return drupal_requirements_severity($requirements) == REQUIREMENT_ERROR;
1844    }
1845  
1846    return theme('status_report', $requirements);
1847  }
1848  
1849  /**
1850   * Helper function to sort requirements.
1851   */
1852  function _system_sort_requirements($a, $b) {
1853    return (isset($a['weight']) || isset($b['weight'])) ? $a['weight'] - $b['weight'] : strcmp($a['title'], $b['title']);
1854  }
1855  
1856  /**
1857   * Theme status report
1858   */
1859  function theme_status_report(&$requirements) {
1860    $i = 0;
1861    $output = '<table class="system-status-report">';
1862    foreach ($requirements as $requirement) {
1863      if ($requirement['#type'] == '') {
1864        $class = ++$i % 2 == 0 ? 'even' : 'odd';
1865  
1866        $classes = array(
1867          REQUIREMENT_INFO => 'info',
1868          REQUIREMENT_OK => 'ok',
1869          REQUIREMENT_WARNING => 'warning',
1870          REQUIREMENT_ERROR => 'error',
1871        );
1872        $class = $classes[(int)$requirement['severity']] .' '. $class;
1873  
1874        // Output table row(s)
1875        if ($requirement['description']) {
1876          $output .= '<tr class="'. $class .' merge-down"><th>'. $requirement['title'] .'</th><td>'. $requirement['value'] .'</td></tr>';
1877          $output .= '<tr class="'. $class .' merge-up"><td colspan="2">'. $requirement['description'] .'</td></tr>';
1878        }
1879        else {
1880          $output .= '<tr class="'. $class .'"><th>'. $requirement['title'] .'</th><td>'. $requirement['value'] .'</td></tr>';
1881        }
1882      }
1883    }
1884  
1885    $output .= '</table>';
1886    return $output;
1887  }
1888  
1889  /**
1890   * Menu callback; displays a module's settings page.
1891   */
1892  function system_settings_overview() {
1893  
1894    // Check database setup if necessary
1895    if (function_exists('db_check_setup') && empty($_POST)) {
1896      db_check_setup();
1897    }
1898  
1899    $menu = menu_get_item(NULL, 'admin/settings');
1900    $content = system_admin_menu_block($menu);
1901  
1902    $output = theme('admin_block_content', $content);
1903  
1904    return $output;
1905  }
1906  
1907  /**
1908   * Menu callback; display theme configuration for entire site and individual themes.
1909   */
1910  function system_theme_settings($key = '') {
1911    $directory_path = file_directory_path();
1912    file_check_directory($directory_path, FILE_CREATE_DIRECTORY, 'file_directory_path');
1913  
1914    // Default settings are defined in theme_get_settings() in includes/theme.inc
1915    if ($key) {
1916      $settings = theme_get_settings($key);
1917      $var = str_replace('/', '_', 'theme_'. $key .'_settings');
1918      $themes = system_theme_data();
1919      $features = function_exists($themes[$key]->prefix . '_features') ? call_user_func($themes[$key]->prefix . '_features') : array();
1920    }
1921    else {
1922      $settings = theme_get_settings('');
1923      $var = 'theme_settings';
1924    }
1925  
1926    $form['var'] = array('#type' => 'hidden', '#value' => $var);
1927  
1928    // Check for a new uploaded logo, and use that instead.
1929    if ($file = file_check_upload('logo_upload')) {
1930      if ($info = image_get_info($file->filepath)) {
1931        $parts = pathinfo($file->filename);
1932        $filename = ($key) ? str_replace('/', '_', $key) . '_logo.' . $parts['extension'] : 'logo.' . $parts['extension'];
1933  
1934        if ($file = file_save_upload('logo_upload', $filename, 1)) {
1935          $_POST['default_logo'] = 0;
1936          $_POST['logo_path'] = $file->filepath;
1937          $_POST['toggle_logo'] = 1;
1938        }
1939      }
1940      else {
1941        form_set_error('file_upload', t('Only JPEG, PNG and GIF images are allowed to be used as logos.'));
1942      }
1943    }
1944  
1945    // Check for a new uploaded favicon, and use that instead.
1946    if ($file = file_check_upload('favicon_upload')) {
1947      $parts = pathinfo($file->filename);
1948      $filename = ($key) ? str_replace('/', '_', $key) . '_favicon.' . $parts['extension'] : 'favicon.' . $parts['extension'];
1949  
1950      if ($file = file_save_upload('favicon_upload', $filename, 1)) {
1951        $_POST['default_favicon'] = 0;
1952        $_POST['favicon_path'] = $file->filepath;
1953        $_POST['toggle_favicon'] = 1;
1954      }
1955    }
1956  
1957    // Toggle settings
1958    $toggles = array(
1959      'toggle_logo'                 => t('Logo'),
1960      'toggle_name'                 => t('Site name'),
1961      'toggle_slogan'               => t('Site slogan'),
1962      'toggle_mission'              => t('Mission statement'),
1963      'toggle_node_user_picture'    => t('User pictures in posts'),
1964      'toggle_comment_user_picture' => t('User pictures in comments'),
1965      'toggle_search'               => t('Search box'),
1966      'toggle_favicon'              => t('Shortcut icon')
1967    );
1968  
1969    // Some features are not always available
1970    $disabled = array();
1971    if (!variable_get('user_pictures', 0)) {
1972      $disabled['toggle_node_user_picture'] = TRUE;
1973      $disabled['toggle_comment_user_picture'] = TRUE;
1974    }
1975    if (!module_exists('search')) {
1976      $disabled['toggle_search'] = TRUE;
1977    }
1978  
1979    $form['theme_settings'] = array(
1980      '#type' => 'fieldset',
1981      '#title' => t('Toggle display'),
1982      '#description' => t('Enable or disable the display of certain page elements.'),
1983    );
1984    foreach ($toggles as $name => $title) {
1985      if ((!$key) || in_array($name, $features)) {
1986        // disable search box if search.module is disabled
1987        $form['theme_settings'][$name] = array('#type' => 'checkbox', '#title' => $title, '#default_value' => $settings[$name]);
1988        if (isset($disabled[$name])) {
1989          $form['theme_settings'][$name]['#disabled'] = TRUE;
1990        }
1991      }
1992    }
1993  
1994    // System wide only settings.
1995    if (!$key) {
1996      // Create neat 2-column layout for the toggles
1997      $form['theme_settings'] += array(
1998        '#prefix' => '<div class="theme-settings-left">',
1999        '#suffix' => '</div>',
2000      );
2001  
2002      // Toggle node display.
2003      $node_types = node_get_types('names');
2004      if ($node_types) {
2005        $form['node_info'] = array(
2006          '#type' => 'fieldset',
2007          '#title' => t('Display post information on'),
2008          '#description' =>  t('Enable or disable the <em>submitted by Username on date</em> text when displaying posts of the following type.'),
2009          '#prefix' => '<div class="theme-settings-right">',
2010          '#suffix' => '</div>',
2011        );
2012        foreach ($node_types as $type => $name) {
2013          $form['node_info']["toggle_node_info_$type"] = array('#type' => 'checkbox', '#title' => $name, '#default_value' => $settings["toggle_node_info_$type"]);
2014        }
2015      }
2016    }
2017  
2018    // Logo settings
2019    if ((!$key) || in_array('toggle_logo', $features)) {
2020      $form['logo'] = array(
2021        '#type' => 'fieldset',
2022        '#title' => t('Logo image settings'),
2023        '#description' => t('If toggled on, the following logo will be displayed.'),
2024        '#attributes' => array('class' => 'theme-settings-bottom'),
2025      );
2026      $form['logo']["default_logo"] = array(
2027        '#type' => 'checkbox',
2028        '#title' => t('Use the default logo'),
2029        '#default_value' => $settings['default_logo'],
2030        '#tree' => FALSE,
2031        '#description' => t('Check here if you want the theme to use the logo supplied with it.')
2032      );
2033      $form['logo']['logo_path'] = array(
2034        '#type' => 'textfield',
2035        '#title' => t('Path to custom logo'),
2036        '#default_value' => $settings['logo_path'],
2037        '#description' => t('The path to the file you would like to use as your logo file instead of the default logo.'));
2038  
2039      $form['logo']['logo_upload'] = array(
2040        '#type' => 'file',
2041        '#title' => t('Upload logo image'),
2042        '#maxlength' => 40,
2043        '#description' => t("If you don't have direct file access to the server, use this field to upload your logo.")
2044      );
2045    }
2046  
2047    // Icon settings
2048    if ((!$key) || in_array('toggle_favicon', $features)) {
2049      $form['favicon'] = array('#type' => 'fieldset', '#title' => t('Shortcut icon settings'));
2050      $form['favicon']['text'] = array('#value' => t('Your shortcut icon or \'favicon\' is displayed in the address bar and bookmarks of most browsers.'));
2051      $form['favicon']['default_favicon'] = array(
2052        '#type' => 'checkbox',
2053        '#title' => t('Use the default shortcut icon.'),
2054        '#default_value' => $settings['default_favicon'],
2055        '#description' => t('Check here if you want the theme to use the default shortcut icon.')
2056      );
2057      $form['favicon']['favicon_path'] = array(
2058        '#type' => 'textfield',
2059        '#title' => t('Path to custom icon'),
2060        '#default_value' =>  $settings['favicon_path'],
2061        '#description' => t('The path to the image file you would like to use as your custom shortcut icon.')
2062      );
2063  
2064      $form['favicon']['favicon_upload'] = array(
2065        '#type' => 'file',
2066        '#title' => t('Upload icon image'),
2067        '#description' => t("If you don't have direct file access to the server, use this field to upload your shortcut icon.")
2068      );
2069    }
2070  
2071    if ($key) {
2072      // Template-specific settings
2073      $function = $themes[$key]->prefix .'_settings';
2074      if (function_exists($function)) {
2075        if ($themes[$key]->template) {
2076          // file is a template or a style of a template
2077          $form['specific'] = array('#type' => 'fieldset', '#title' => t('Engine-specific settings'), '#description' => t('These settings only exist for all the templates and styles based on the %engine theme engine.', array('%engine' => $themes[$key]->prefix)));
2078        }
2079        else {
2080          // file is a theme or a style of a theme
2081          $form['specific'] = array('#type' => 'fieldset', '#title' => t('Theme-specific settings'), '#description' => t('These settings only exist for the %theme theme and all the styles based on it.', array('%theme' => $themes[$key]->prefix)));
2082        }
2083        $group = $function();
2084        $form['specific'] = array_merge($form['specific'], (is_array($group) ? $group : array()));
2085      }
2086    }
2087    $form['#attributes'] = array('enctype' => 'multipart/form-data');
2088  
2089    return system_settings_form($form);
2090  }
2091  
2092  /**
2093   * Implementation of hook_node_type().
2094   *
2095   * Updates theme settings after a node type change.
2096   */
2097  function system_node_type($op, $info) {
2098    if ($op == 'update' && !empty($info->old_type) && $info->type != $info->old_type) {
2099      $old = 'toggle_node_info_'. $info->old_type;
2100      $new = 'toggle_node_info_'. $info->type;
2101  
2102      $theme_settings = variable_get('theme_settings', array());
2103      if (isset($theme_settings[$old])) {
2104        $theme_settings[$new] = $theme_settings[$old];
2105        unset($theme_settings[$old]);
2106        variable_set('theme_settings', $theme_settings);
2107      }
2108    }
2109  }
2110  
2111  /**
2112   * Output a confirmation form
2113   *
2114   * This function returns a complete form for confirming an action. A link is
2115   * offered to go back to the item that is being changed in case the user changes
2116   * his/her mind.
2117   *
2118   * You can check for the existence of $_POST[$name] (where $name
2119   * is usually 'confirm') to check if the confirmation was successful or
2120   * use the regular submit model.
2121   *
2122   * @param $form
2123   *   Additional elements to inject into the form, for example hidden elements.
2124   * @param $question
2125   *   The question to ask the user (e.g. "Are you sure you want to delete the
2126   *   block <em>foo</em>?").
2127   * @param $path
2128   *   The page to go to if the user denies the action.
2129   *   Can be either a drupal path, or an array with the keys 'path', 'query', 'fragment'.
2130   * @param $description
2131   *   Additional text to display (defaults to "This action cannot be undone.").
2132   * @param $yes
2133   *   A caption for the button which confirms the action (e.g. "Delete",
2134   *   "Replace", ...).
2135   * @param $no
2136   *   A caption for the link which denies the action (e.g. "Cancel").
2137   * @param $name
2138   *   The internal name used to refer to the confirmation item.
2139   * @return
2140   *   The form.
2141   */
2142  function confirm_form($form, $question, $path, $description = NULL, $yes = NULL, $no = NULL, $name = 'confirm') {
2143    $description = isset($description) ? $description : t('This action cannot be undone.');
2144  
2145    // Prepare cancel link
2146    $query = $fragment = NULL;
2147    if (is_array($path)) {
2148      $query = isset($path['query']) ? $path['query'] : NULL;
2149      $fragment = isset($path['fragment']) ? $path['fragment'] : NULL;
2150      $path = isset($path['path']) ? $path['path'] : NULL;
2151    }
2152    $cancel = l($no ? $no : t('Cancel'), $path, array(), $query, $fragment);
2153  
2154    drupal_set_title($question);
2155    $form['#attributes'] = array('class' => 'confirmation');
2156    $form['description'] = array('#value' => $description);
2157    $form[$name] = array('#type' => 'hidden', '#value' => 1);
2158  
2159    $form['actions'] = array('#prefix' => '<div class="container-inline">', '#suffix' => '</div>');
2160    $form['actions']['submit'] = array('#type' => 'submit', '#value' => $yes ? $yes : t('Confirm'));
2161    $form['actions']['cancel'] = array('#value' => $cancel);
2162    $form['#base'] = 'confirm_form';
2163    return $form;
2164  }
2165  
2166  /**
2167   * Determine if a user is in compact mode.
2168   */
2169  function system_admin_compact_mode() {
2170    global $user;
2171    return (isset($user->admin_compact_mode)) ? $user->admin_compact_mode : variable_get('admin_compact_mode', FALSE);
2172  }
2173  
2174  /**
2175   * This function formats an administrative page for viewing.
2176   *
2177   * @param $blocks
2178   *   An array of blocks to display. Each array should include a
2179   *   'title', a 'description', a formatted 'content' and a
2180   *   'position' which will control which container it will be
2181   *   in. This is usually 'left' or 'right'.
2182   * @themeable
2183   */
2184  function theme_admin_page($blocks) {
2185    $stripe = 0;
2186    $container = array();
2187  
2188    foreach ($blocks as $block) {
2189      if ($block_output = theme('admin_block', $block)) {
2190        if (!$block['position']) {
2191          // perform automatic striping.
2192          $block['position'] = $stripe++ % 2 ? 'left' : 'right';
2193        }
2194        $container[$block['position']] .= $block_output;
2195      }
2196    }
2197  
2198    $output = '<div class="admin clear-block">';
2199    $output .= '<div class="compact-link">';
2200    if (system_admin_compact_mode()) {
2201      $output .= l(t('Show descriptions'), 'admin/compact/off', array('title' => t('Produce a less compact layout that includes descriptions.')));
2202    }
2203    else {
2204      $output .= l(t('Hide descriptions'), 'admin/compact/on', array('title' => t("Produce a more compact layout that doesn't include descriptions.")));
2205    }
2206    $output .= '</div>';
2207  
2208    foreach ($container as $id => $data) {
2209      $output .= '<div class="'. $id .' clear-block">';
2210      $output .= $data;
2211      $output .= '</div>';
2212    }
2213    $output .= '</div>';
2214    return $output;
2215  }
2216  
2217  /**
2218   * This function formats an administrative block for display.
2219   *
2220   * @param $block
2221   *   An array containing information about the block. It should
2222   *   include a 'title', a 'description' and a formatted 'content'.
2223   * @themeable
2224   */
2225  function theme_admin_block($block) {
2226    // Don't display the block if it has no content to display.
2227    if (!$block['content']) {
2228      return '';
2229    }
2230  
2231    $output = <<< EOT
2232    <div class="admin-panel">
2233      <h3>
2234        $block[title]
2235      </h3>
2236      <div class="body">
2237        <p class="description">
2238          $block[description]
2239        </p>
2240        $block[content]
2241      </div>
2242    </div>
2243  EOT;
2244    return $output;
2245  }
2246  
2247  /**
2248   * This function formats the content of an administrative block.
2249   *
2250   * @param $block
2251   *   An array containing information about the block. It should
2252   *   include a 'title', a 'description' and a formatted 'content'.
2253   * @themeable
2254   */
2255  function theme_admin_block_content($content) {
2256    if (!$content) {
2257      return '';
2258    }
2259  
2260    if (system_admin_compact_mode()) {
2261      $output = '<ul class="menu">';
2262      foreach ($content as $item) {
2263        $output .= '<li class="leaf">'. l($item['title'], $item['path'], array('title' => $item['description'])) .'</li>';
2264      }
2265      $output .= '</ul>';
2266    }
2267    else {
2268      $output = '<dl class="admin-list">';
2269      foreach ($content as $item) {
2270        $output .= '<dt>'. l($item['title'], $item['path']) .'</dt>';
2271        $output .= '<dd>'. $item['description'] .'</dd>';
2272      }
2273      $output .= '</dl>';
2274    }
2275    return $output;
2276  }
2277  
2278  /**
2279   * Menu callback; prints a listing of admin tasks for each installed module.
2280   */
2281  function system_admin_by_module() {
2282    $modules = module_rebuild_cache();
2283    $menu_items = array();
2284    foreach ($modules as $file) {
2285      $module = $file->name;
2286      if ($module == 'help') {
2287        continue;
2288      }
2289  
2290      $admin_tasks = system_get_module_admin_tasks($module);
2291  
2292      // Only display a section if there are any available tasks.
2293      if (count($admin_tasks)) {
2294  
2295        // Check for help links.
2296        if (module_invoke($module, 'help', "admin/help#$module")) {
2297          $admin_tasks[100] = l(t('Get help'), "admin/help/$module");
2298        }
2299  
2300        // Sort.
2301        ksort($admin_tasks);
2302  
2303        $menu_items[$file->info['name']] = array($file->info['description'], $admin_tasks);
2304      }
2305    }
2306    return theme('system_admin_by_module', $menu_items);
2307  }
2308  
2309  function system_get_module_admin_tasks($module) {
2310    $admin_access = user_access('administer access control');
2311    $menu = menu_get_menu();
2312    $admin_tasks = array();
2313  
2314    // Check for permissions.
2315    if (module_hook($module, 'perm') && $admin_access) {
2316      $admin_tasks[-1] = l(t('Configure permissions'), 'admin/user/access', NULL, NULL, 'module-'. $module);
2317    }
2318  
2319    // Check for menu items that are admin links.
2320    if ($items = module_invoke($module, 'menu', TRUE)) {
2321      foreach ($items as $item) {
2322        $parts = explode('/', $item['path']);
2323        $n = count($parts);
2324        if ((!isset($item['type']) || ($item['type'] & MENU_VISIBLE_IN_TREE)) && ($parts[0] == 'admin') && ($n >= 3) && _menu_item_is_accessible($menu['path index'][$item['path']])) {
2325          $admin_tasks[$item['title']] = l($item['title'], $item['path']);
2326        }
2327      }
2328    }
2329  
2330    return $admin_tasks;
2331  }
2332  
2333  /**
2334   * Theme output of the dashboard page.
2335   */
2336  function theme_system_admin_by_module($menu_items) {
2337    $stripe = 0;
2338    $output = '';
2339    $container = array();
2340  
2341    // Iterate over all modules
2342    foreach ($menu_items as $module => $block) {
2343      list($description, $items) = $block;
2344  
2345      // Output links
2346      if (count($items)) {
2347        $block = array();
2348        $block['title'] = $module;
2349        $block['content'] = theme('item_list', $items);
2350        $block['description'] = t($description);
2351  
2352        if ($block_output = theme('admin_block', $block)) {
2353          if (!$block['position']) {
2354            // Perform automatic striping.
2355            $block['position'] = ++$stripe % 2 ? 'left' : 'right';
2356          }
2357          $container[$block['position']] .= $block_output;
2358        }
2359      }
2360    }
2361  
2362    $output = '<div class="admin">';
2363    foreach ($container as $id => $data) {
2364      $output .= '<div class="'. $id .' clear-block">';
2365      $output .= $data;
2366      $output .= '</div>';
2367    }
2368    $output .= '</div>';
2369  
2370    return $output;
2371  }


[ Powered by PHPXref - Served by Debian GNU/Linux ]