system.module 81.3 KB
Newer Older
Dries's avatar
   
Dries committed
1
<?php
2
// $Id$
Dries's avatar
   
Dries committed
3

Dries's avatar
   
Dries committed
4
5
6
7
8
/**
 * @file
 * Configuration system that lets administrators modify the workings of the site.
 */

9
10
11
/**
 * The current system version.
 */
12
define('VERSION', '7.0-dev');
13
14
15
16

/**
 * Core API compatibility.
 */
17
define('DRUPAL_CORE_COMPATIBILITY', '7.x');
18

19
20
21
/**
 * Minimum supported version of PHP.
 */
22
define('DRUPAL_MINIMUM_PHP',    '5.2.0');
23

24
25
26
27
28
/**
 * Minimum recommended value of PHP memory_limit.
 */
define('DRUPAL_MINIMUM_PHP_MEMORY_LIMIT',    '16M');

29
30
31
/**
 * Minimum supported version of MySQL, if it is used.
 */
32
define('DRUPAL_MINIMUM_MYSQL',  '5.0');
33
34
35
36

/**
 * Minimum supported version of PostgreSQL, if it is used.
 */
37
define('DRUPAL_MINIMUM_PGSQL',  '8.1');
38
39
40
41

/**
 * Maximum age of temporary files in seconds.
 */
42
define('DRUPAL_MAXIMUM_TEMP_FILE_AGE', 21600);
43

44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
/**
 * New users will be set to the default time zone at registration.
 */
define('DRUPAL_USER_TIMEZONE_DEFAULT', 0);

/**
 * New users will get an empty time zone at registration.
 */
define('DRUPAL_USER_TIMEZONE_EMPTY', 1);

/**
 * New users will select their own timezone at registration.
 */
define('DRUPAL_USER_TIMEZONE_SELECT', 2);

Dries's avatar
   
Dries committed
59
60
61
/**
 * Implementation of hook_help().
 */
62
function system_help($path, $arg) {
63
64
  global $base_url;

65
  switch ($path) {
66
    case 'admin/help#system':
67
68
69
70
71
72
      $output = '<p>' . t('The system module is at the foundation of your Drupal website, and provides basic but extensible functionality for use by other modules and themes. Some integral elements of Drupal are contained in and managed by the system module, including caching, enabling or disabling of modules and themes, preparing and displaying the administrative page, and configuring fundamental site settings. A number of key system maintenance operations are also part of the system module.') . '</p>';
      $output .= '<p>' . t('The system module provides:') . '</p>';
      $output .= '<ul><li>' . t('support for enabling and disabling <a href="@modules">modules</a>. Drupal comes packaged with a number of core modules; each module provides a discrete set of features and may be enabled depending on the needs of your site. A wide array of additional modules contributed by members of the Drupal community are available for download at the <a href="@drupal-modules">Drupal.org module page</a>.', array('@modules' => url('admin/build/modules'), '@drupal-modules' => 'http://drupal.org/project/modules')) . '</li>';
      $output .= '<li>' . t('support for enabling and disabling <a href="@themes">themes</a>, which determine the design and presentation of your site. Drupal comes packaged with several core themes and additional contributed themes are available at the <a href="@drupal-themes">Drupal.org theme page</a>.', array('@themes' => url('admin/build/themes'), '@drupal-themes' => 'http://drupal.org/project/themes')) . '</li>';
      $output .= '<li>' . t('a robust <a href="@cache-settings">caching system</a> that allows the efficient re-use of previously-constructed web pages and web page components. Drupal stores the pages requested by anonymous users in a compressed format; depending on your site configuration and the amount of your web traffic tied to anonymous visitors, Drupal\'s caching system may significantly increase the speed of your site.', array('@cache-settings' => url('admin/settings/performance'))) . '</li>';
      $output .= '<li>' . t('a set of routine administrative operations that rely on a correctly-configured <a href="@cron">cron maintenance task</a> to run automatically. A number of other modules, including the feed aggregator, and search also rely on <a href="@cron">cron maintenance tasks</a>. For more information, see the online handbook entry for <a href="@handbook">configuring cron jobs</a>.', array('@cron' => url('admin/reports/status'), '@handbook' => 'http://drupal.org/cron')) . '</li>';
73
      $output .= '<li>' . t('basic configuration options for your site, including <a href="@date-settings">date and time settings</a>, <a href="@file-system">file system settings</a>, <a href="@clean-url">clean URL support</a>, <a href="@site-info">site name and other information</a>, and a <a href="@site-maintenance">site maintenance</a> function for taking your site temporarily offline.', array('@date-settings' => url('admin/settings/date-time'), '@file-system' => url('admin/settings/file-system'), '@clean-url' => url('admin/settings/clean-urls'), '@site-info' => url('admin/settings/site-information'), '@site-maintenance' => url('admin/settings/site-maintenance'))) . '</li></ul>';
74
      $output .= '<p>' . t('For more information, see the online handbook entry for <a href="@system">System module</a>.', array('@system' => 'http://drupal.org/handbook/modules/system/')) . '</p>';
75
      return $output;
76
    case 'admin/by-module':
77
      return '<p>' . t('This page shows you all available administration tasks for each module.') . '</p>';
78
    case 'admin/build/themes':
79
80
      $output = '<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. Alternatively, to override these settings in a specific theme, click the "configure" link for that theme. Note that different themes may have different regions available for displaying content; for consistency in presentation, you may wish to enable only one theme.') . '</p>';
      $output .= '<p>' . t('To change the appearance of your site, a number of <a href="@themes">contributed themes</a> are available.', array('@themes' => 'http://drupal.org/project/themes')) . '</p>';
81
      return $output;
82
    case 'admin/build/themes/settings/' . $arg[4]:
83
      $reference = explode('.', $arg[4], 2);
84
      $theme = array_pop($reference);
85
      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>';
86
    case 'admin/build/themes/settings':
87
      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>';
88
    case 'admin/build/modules':
89
90
91
      $output = '<p>' . t('Modules are plugins that extend Drupal\'s core functionality. To enable modules, select the <em>Enabled</em> checkboxes below and click the <em>Save configuration</em> button. To further extend your site\'s functionality, a number of <a href="@modules">contributed modules</a> are available for download.', array('@permissions' => url('admin/user/permissions'), '@modules' => 'http://drupal.org/project/modules')) . '</p>';
      $output .= '<p>' . t('Module-related tasks can be located on the <a href="@by-module">administration by module page</a>. New <a href="@permissions">module-related permissions</a> may also become available as new modules are enabled.', array('@by-module' => url('admin/by-module'), '@permissions' => url('admin/user/permissions'))) . '</p>';
      $output .= '<p>' . t('Each time a module is updated, it is important that <a href="@update-php">update.php</a> is run. To help manage the update process, the <em>Update status</em> module, if enabled, provides <a href="@updates">information on new versions of modules (and themes)</a> as they are released. Regular review of the <a href="@updates">available updates page</a> is essential to maintaining a secure and current site.', array('@update-php' => $base_url . '/update.php', '@updates' => url('admin/reports/updates'))) . '</p>';
92
      return $output;
93
    case 'admin/build/modules/uninstall':
94
      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>';
95
96
    case 'admin/build/block/configure':
      if ($arg[4] == 'system' && $arg[5] == 0) {
97
        return '<p>' . t('The <em>Powered by Drupal</em> block is an optional link to the home page of the Drupal project. While there is absolutely no requirement that sites feature this link, it may be used to show support for Drupal.') . '</p>';
98
      }
99
      break;
100
101
    case 'admin/settings/actions':
    case 'admin/settings/actions/manage':
102
103
      $output = '<p>' . t('Actions are individual tasks that the system can do, such as unpublishing a piece of content or banning a user. Modules, such as the trigger module, can fire these actions when certain system events happen; for example, when a new post is added or when a user logs in. Modules may also provide additional actions.') . '</p>';
      $output .= '<p>' . t('There are two types of actions: simple and advanced. Simple actions do not require any additional configuration, and are listed here automatically. Advanced actions can do more than simple actions; for example, send an e-mail to a specified address, or check for certain words within a piece of content. These actions need to be created and configured first before they may be used. To create an advanced action, select the action from the drop-down below and click the <em>Create</em> button.') . '</p>';
104
      if (module_exists('trigger')) {
105
        $output .= '<p>' . t('You may proceed to the <a href="@url">Triggers</a> page to assign these actions to system events.', array('@url' => url('admin/build/trigger'))) . '</p>';
106
      }
107
      return $output;
108
109
    case 'admin/settings/actions/configure':
      return t('An advanced action offers additional configuration options which may be filled out below. Changing the <em>Description</em> field is recommended, in order to better identify the precise action taking place. This description will be displayed in modules such as the trigger module when assigning actions to system events, so it is best if it is as descriptive as possible (for example, "Send e-mail to Moderation Team" rather than simply "Send e-mail").');
110
    case 'admin/settings/ip-blocking':
111
      return '<p>' . t('IP addresses listed here are blocked from your site before any modules are loaded. You may add IP addresses to the list, or delete existing entries.') . '</p>';
112
    case 'admin/reports/status':
113
      return '<p>' . t("Here you can find a short overview of your site's parameters as well as any problems detected with your installation. It may be useful to copy and paste this information into support requests filed on drupal.org's support forums and project issue queues.") . '</p>';
114
  }
Dries's avatar
   
Dries committed
115
116
}

117
118
119
/**
 * Implementation of hook_theme().
 */
120
function system_theme() {
121
  return array_merge(drupal_common_theme(), array(
122
123
    'system_theme_select_form' => array(
      'arguments' => array('form' => NULL),
124
      'file' => 'system.admin.inc',
125
126
127
    ),
    'system_themes_form' => array(
      'arguments' => array('form' => NULL),
128
      'file' => 'system.admin.inc',
129
    ),
130
    'system_modules_fieldset' => array(
131
      'arguments' => array('form' => NULL),
132
      'file' => 'system.admin.inc',
133
    ),
134
135
136
137
    'system_modules_incompatible' => array(
      'arguments' => array('message' => NULL),
      'file' => 'system.admin.inc',
    ),
138
139
    'system_modules_uninstall' => array(
      'arguments' => array('form' => NULL),
140
      'file' => 'system.admin.inc',
141
142
143
    ),
    'status_report' => array(
      'arguments' => array('requirements' => NULL),
144
      'file' => 'system.admin.inc',
145
146
147
    ),
    'admin_page' => array(
      'arguments' => array('blocks' => NULL),
148
      'file' => 'system.admin.inc',
149
150
151
    ),
    'admin_block' => array(
      'arguments' => array('block' => NULL),
152
      'file' => 'system.admin.inc',
153
154
155
    ),
    'admin_block_content' => array(
      'arguments' => array('content' => NULL),
156
      'file' => 'system.admin.inc',
157
158
159
    ),
    'system_admin_by_module' => array(
      'arguments' => array('menu_items' => NULL),
160
      'file' => 'system.admin.inc',
161
    ),
162
163
164
    'system_powered_by' => array(
      'arguments' => array('image_path' => NULL),
    ),
165
166
167
168
169
170
    'meta_generator_html' => array(
      'arguments' => array('version' => NULL),
    ),
    'meta_generator_header' => array(
      'arguments' => array('version' => NULL),
    ),
171
    'system_compact_link' => array(),
172
173
  ));
}
174

Dries's avatar
   
Dries committed
175
176
177
/**
 * Implementation of hook_perm().
 */
Dries's avatar
   
Dries committed
178
function system_perm() {
179
  return array(
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
    'administer site configuration' => array(
      'title' => t('Administer site configuration'),
      'description' => t('Configure site-wide settings such as module or theme administration settings.'),
    ),
    'administer actions' => array(
      'title' => t('Administer actions'),
      'description' => t('Manage the actions defined for your site.'),
    ),
    'administer files' => array(
      'title' => t('Administer files'),
      'description' => t('Manage user-uploaded files.'),
    ),
    'access administration pages' => array(
      'title' => t('Access administration pages'),
      'description' => t('View the administration panel and browse the help system.'),
    ),
    'access site reports' => array(
      'title' => t('Access site reports'),
      'description' => t('View reports from system logs and other status information.'),
    ),
    'select different theme' => array(
      'title' => t('Select different theme'),
      'description' => t('Select a theme other than the default theme set by the site administrator.'),
    ),
    'block IP addresses' => array(
      'title' => t('Block IP addresses'),
      'description' => t('Block IP addresses from accessing your site.'),
    ),
208
  );
Dries's avatar
   
Dries committed
209
210
}

211
/**
212
 * Implementation of hook_rdf_namespaces().
213
214
215
216
217
218
219
220
221
222
223
224
225
 */
function system_rdf_namespaces() {
  return array(
    'admin'    => 'http://webns.net/mvcb/',
    'content'  => 'http://purl.org/rss/1.0/modules/content/',
    'dc'       => 'http://purl.org/dc/elements/1.1/',
    'dcterms'  => 'http://purl.org/dc/terms/',
    'foaf'     => 'http://xmlns.com/foaf/0.1/',
    'owl'      => 'http://www.w3.org/2002/07/owl#',
    'rdf'      => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
    'rdfs'     => 'http://www.w3.org/2000/01/rdf-schema#',
    'rss'      => 'http://purl.org/rss/1.0/',
    'sioc'     => 'http://rdfs.org/sioc/ns#',
226
    'xsd'      => 'http://www.w3.org/2001/XMLSchema',
227
228
229
  );
}

230
231
232
233
234
/**
 * Implementation of hook_elements().
 */
function system_elements() {
  // Top level form
235
236
237
238
239
240
241
242
243
244
245
246
247
  $type['form'] = array(
    '#method' => 'post',
    '#action' => request_uri(),
  );

  /**
   * Input elements.
   */
  $type['submit'] = array(
    '#input' => TRUE,
    '#name' => 'op',
    '#button_type' => 'submit',
    '#executes_submit_callback' => TRUE,
248
    '#process' => array('form_process_ahah'),
249
250
251
252
253
254
255
  );

  $type['button'] = array(
    '#input' => TRUE,
    '#name' => 'op',
    '#button_type' => 'submit',
    '#executes_submit_callback' => FALSE,
256
    '#process' => array('form_process_ahah'),
257
258
259
260
261
262
  );

  $type['image_button'] = array(
    '#input' => TRUE,
    '#button_type' => 'submit',
    '#executes_submit_callback' => TRUE,
263
    '#process' => array('form_process_ahah'),
264
265
266
267
268
269
270
271
272
273
    '#return_value' => TRUE,
    '#has_garbage_value' => TRUE,
    '#src' => NULL,
  );

  $type['textfield'] = array(
    '#input' => TRUE,
    '#size' => 60,
    '#maxlength' => 128,
    '#autocomplete_path' => FALSE,
274
    '#process' => array('form_process_input_format', 'form_process_ahah'),
275
276
277
278
279
280
  );

  $type['password'] = array(
    '#input' => TRUE,
    '#size' => 60,
    '#maxlength' => 128,
281
    '#process' => array('form_process_ahah'),
282
283
284
285
  );

  $type['password_confirm'] = array(
    '#input' => TRUE,
286
    '#process' => array('form_process_password_confirm'),
287
288
289
290
291
292
293
  );

  $type['textarea'] = array(
    '#input' => TRUE,
    '#cols' => 60,
    '#rows' => 5,
    '#resizable' => TRUE,
294
    '#process' => array('form_process_input_format', 'form_process_ahah'),
295
296
297
298
  );

  $type['radios'] = array(
    '#input' => TRUE,
299
    '#process' => array('form_process_radios'),
300
301
302
303
304
  );

  $type['radio'] = array(
    '#input' => TRUE,
    '#default_value' => NULL,
305
    '#process' => array('form_process_ahah'),
306
307
308
309
310
  );

  $type['checkboxes'] = array(
    '#input' => TRUE,
    '#tree' => TRUE,
311
    '#process' => array('form_process_checkboxes'),
312
313
314
315
316
  );

  $type['checkbox'] = array(
    '#input' => TRUE,
    '#return_value' => 1,
317
    '#process' => array('form_process_ahah'),
318
319
320
321
322
323
  );

  $type['select'] = array(
    '#input' => TRUE,
    '#size' => 0,
    '#multiple' => FALSE,
324
    '#process' => array('form_process_ahah'),
325
326
327
328
329
330
  );

  $type['weight'] = array(
    '#input' => TRUE,
    '#delta' => 10,
    '#default_value' => 0,
331
    '#process' => array('form_process_weight', 'form_process_ahah'),
332
333
334
335
336
  );

  $type['date'] = array(
    '#input' => TRUE,
    '#element_validate' => array('date_validate'),
337
    '#process' => array('form_process_date'),
338
339
340
341
342
343
344
345
346
347
348
349
  );

  $type['file'] = array(
    '#input' => TRUE,
    '#size' => 60,
  );


  /**
   * Form structure.
   */
  $type['item'] = array(
350
    '#markup' => '',
351
352
353
354
  );

  $type['hidden'] = array(
    '#input' => TRUE,
355
    '#process' => array('form_process_ahah'),
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
  );

  $type['value'] = array(
    '#input' => TRUE,
  );

  $type['markup'] = array(
    '#prefix' => '',
    '#suffix' => '',
  );

  $type['fieldset'] = array(
    '#collapsible' => FALSE,
    '#collapsed' => FALSE,
    '#value' => NULL,
371
    '#process' => array('form_process_ahah'),
372
373
374
375
376
377
  );

  $type['token'] = array(
    '#input' => TRUE,
  );

378
379
380
  return $type;
}

Dries's avatar
   
Dries committed
381
/**
Dries's avatar
   
Dries committed
382
 * Implementation of hook_menu().
Dries's avatar
   
Dries committed
383
 */
384
385
function system_menu() {
  $items['system/files'] = array(
386
    'title' => 'File download',
387
388
389
390
    'page callback' => 'file_download',
    'access callback' => TRUE,
    'type' => MENU_CALLBACK,
  );
391
392
393
394
395
396
  $items['system/timezone'] = array(
    'title' => 'Time zone',
    'page callback' => 'system_timezone',
    'access callback' => TRUE,
    'type' => MENU_CALLBACK,
  );
397
  $items['admin'] = array(
398
    'title' => 'Administer',
399
400
401
402
403
    'access arguments' => array('access administration pages'),
    'page callback' => 'system_main_admin_page',
    'weight' => 9,
  );
  $items['admin/compact'] = array(
404
    'title' => 'Compact mode',
405
    'page callback' => 'system_admin_compact_page',
406
    'access arguments' => array('access administration pages'),
407
408
409
    'type' => MENU_CALLBACK,
  );
  $items['admin/by-task'] = array(
410
    'title' => 'By task',
411
    'page callback' => 'system_main_admin_page',
412
    'access arguments' => array('access administration pages'),
413
414
415
    'type' => MENU_DEFAULT_LOCAL_TASK,
  );
  $items['admin/by-module'] = array(
416
    'title' => 'By module',
417
    'page callback' => 'system_admin_by_module',
418
    'access arguments' => array('access administration pages'),
419
420
421
    'type' => MENU_LOCAL_TASK,
    'weight' => 2,
  );
422
423
424
425
426
427
  $items['admin/content'] = array(
    'title' => 'Content management',
    'description' => "Manage your site's content.",
    'position' => 'left',
    'weight' => -10,
    'page callback' => 'system_admin_menu_block_page',
428
    'access arguments' => array('access administration pages'),
429
430
  );

431
432
  // menu items that are basically just menu blocks
  $items['admin/settings'] = array(
433
    'title' => 'Site configuration',
434
    'description' => 'Configure site settings.',
435
436
437
    'position' => 'right',
    'weight' => -5,
    'page callback' => 'system_settings_overview',
438
    'access arguments' => array('access administration pages'),
439
440
  );
  $items['admin/build'] = array(
441
442
    'title' => 'Site building',
    'description' => 'Control how your site looks and feels.',
443
444
445
    'position' => 'right',
    'weight' => -10,
    'page callback' => 'system_admin_menu_block_page',
446
    'access arguments' => array('access administration pages'),
447
448
  );
  $items['admin/settings/admin'] = array(
449
450
    'title' => 'Administration theme',
    'description' => 'Settings for how your administrative pages should look.',
451
452
453
    'position' => 'left',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('system_admin_theme_settings'),
454
    'access arguments' => array('administer site configuration'),
455
456
457
458
    'block callback' => 'system_admin_theme_settings',
  );
  // Themes:
  $items['admin/build/themes'] = array(
459
460
    'title' => 'Themes',
    'description' => 'Change which theme your site uses or allows users to set.',
461
    'page callback' => 'drupal_get_form',
462
    'page arguments' => array('system_themes_form', NULL),
463
    'access arguments' => array('administer site configuration'),
464
465
  );
  $items['admin/build/themes/select'] = array(
466
467
    'title' => 'List',
    'description' => 'Select the default theme.',
468
469
470
471
    'type' => MENU_DEFAULT_LOCAL_TASK,
    'weight' => -1,
  );
  $items['admin/build/themes/settings'] = array(
472
    'title' => 'Configure',
473
    'page arguments' => array('system_theme_settings'),
474
    'access arguments' => array('administer site configuration'),
475
476
477
478
    'type' => MENU_LOCAL_TASK,
  );
  // Theme configuration subtabs
  $items['admin/build/themes/settings/global'] = array(
479
    'title' => 'Global settings',
480
481
482
    'type' => MENU_DEFAULT_LOCAL_TASK,
    'weight' => -1,
  );
Dries's avatar
   
Dries committed
483

484
  foreach (list_themes() as $theme) {
485
    $items['admin/build/themes/settings/' . $theme->name] = array(
486
487
488
489
490
491
      'title' => $theme->info['name'],
      'page arguments' => array('system_theme_settings', $theme->name),
      'type' => MENU_LOCAL_TASK,
      'access callback' => '_system_themes_access',
      'access arguments' => array($theme),
    );
Dries's avatar
   
Dries committed
492
  }
drumm's avatar
drumm committed
493

494
495
  // Modules:
  $items['admin/build/modules'] = array(
496
497
    'title' => 'Modules',
    'description' => 'Enable or disable add-on modules for your site.',
498
499
    'page callback' => 'drupal_get_form',
    'page arguments' => array('system_modules'),
500
    'access arguments' => array('administer site configuration'),
501
502
  );
  $items['admin/build/modules/list'] = array(
503
    'title' => 'List',
504
505
506
    'type' => MENU_DEFAULT_LOCAL_TASK,
  );
  $items['admin/build/modules/list/confirm'] = array(
507
    'title' => 'List',
508
    'access arguments' => array('administer site configuration'),
509
510
511
    'type' => MENU_CALLBACK,
  );
  $items['admin/build/modules/uninstall'] = array(
512
    'title' => 'Uninstall',
513
    'page arguments' => array('system_modules_uninstall'),
514
    'access arguments' => array('administer site configuration'),
515
516
517
    'type' => MENU_LOCAL_TASK,
  );
  $items['admin/build/modules/uninstall/confirm'] = array(
518
    'title' => 'Uninstall',
519
    'access arguments' => array('administer site configuration'),
520
521
    'type' => MENU_CALLBACK,
  );
Dries's avatar
   
Dries committed
522

523
  // Actions:
524
  $items['admin/settings/actions'] = array(
525
526
527
528
529
    'title' => 'Actions',
    'description' => 'Manage the actions defined for your site.',
    'access arguments' => array('administer actions'),
    'page callback' => 'system_actions_manage'
  );
530
  $items['admin/settings/actions/manage'] = array(
531
532
533
534
535
536
    'title' => 'Manage actions',
    'description' => 'Manage the actions defined for your site.',
    'page callback' => 'system_actions_manage',
    'type' => MENU_DEFAULT_LOCAL_TASK,
    'weight' => -2,
  );
537
538
  $items['admin/settings/actions/configure'] = array(
    'title' => 'Configure an advanced action',
539
540
    'page callback' => 'drupal_get_form',
    'page arguments' => array('system_actions_configure'),
541
    'access arguments' => array('administer actions'),
542
543
    'type' => MENU_CALLBACK,
  );
544
  $items['admin/settings/actions/delete/%actions'] = array(
545
546
547
548
    'title' => 'Delete action',
    'description' => 'Delete an action.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('system_actions_delete_form', 4),
549
    'access arguments' => array('administer actions'),
550
551
    'type' => MENU_CALLBACK,
  );
552
  $items['admin/settings/actions/orphan'] = array(
553
554
    'title' => 'Remove orphans',
    'page callback' => 'system_actions_remove_orphans',
555
    'access arguments' => array('administer actions'),
556
557
558
    'type' => MENU_CALLBACK,
  );

559
560
561
562
563
564
565
  // IP address blocking.
  $items['admin/settings/ip-blocking'] = array(
    'title' => 'IP address blocking',
    'description' => 'Manage blocked IP addresses.',
    'page callback' => 'system_ip_blocking',
    'access arguments' => array('block IP addresses'),
  );
566
567
568
569
570
571
572
  $items['admin/settings/ip-blocking/%'] = array(
    'title' => 'IP address blocking',
    'description' => 'Manage blocked IP addresses.',
    'page callback' => 'system_ip_blocking',
    'access arguments' => array('block IP addresses'),
    'type' => MENU_CALLBACK,
  );
573
574
575
576
577
578
579
580
  $items['admin/settings/ip-blocking/delete/%blocked_ip'] = array(
    'title' => 'Delete IP address',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('system_ip_blocking_delete', 4),
    'access arguments' => array('block IP addresses'),
    'type' => MENU_CALLBACK,
  );

581
582
  // Settings:
  $items['admin/settings/site-information'] = array(
583
584
    'title' => 'Site information',
    'description' => 'Change basic site information, such as the site name, slogan, e-mail address, mission, front page and more.',
585
586
    'page callback' => 'drupal_get_form',
    'page arguments' => array('system_site_information_settings'),
587
    'access arguments' => array('administer site configuration'),
588
589
  );
  $items['admin/settings/error-reporting'] = array(
590
591
    'title' => 'Error reporting',
    'description' => 'Control how Drupal deals with errors including 403/404 errors as well as PHP error reporting.',
592
593
    'page callback' => 'drupal_get_form',
    'page arguments' => array('system_error_reporting_settings'),
594
    'access arguments' => array('administer site configuration'),
595
  );
596
  $items['admin/settings/logging'] = array(
597
598
    'title' => 'Logging and alerts',
    'description' => "Settings for logging and alerts modules. Various modules can route Drupal's system events to different destination, such as syslog, database, email, ...etc.",
599
    'page callback' => 'system_logging_overview',
600
    'access arguments' => array('administer site configuration'),
601
  );
602
  $items['admin/settings/performance'] = array(
603
    'title' => 'Performance',
604
    'description' => 'Enable or disable page caching for anonymous users and set CSS and JS bandwidth optimization options.',
605
606
    'page callback' => 'drupal_get_form',
    'page arguments' => array('system_performance_settings'),
607
    'access arguments' => array('administer site configuration'),
608
609
  );
  $items['admin/settings/file-system'] = array(
610
611
    'title' => 'File system',
    'description' => 'Tell Drupal where to store uploaded files and how they are accessed.',
612
613
    'page callback' => 'drupal_get_form',
    'page arguments' => array('system_file_system_settings'),
614
    'access arguments' => array('administer site configuration'),
615
616
  );
  $items['admin/settings/image-toolkit'] = array(
617
618
    'title' => 'Image toolkit',
    'description' => 'Choose which image toolkit to use if you have installed optional toolkits.',
619
620
    'page callback' => 'drupal_get_form',
    'page arguments' => array('system_image_toolkit_settings'),
621
    'access arguments' => array('administer site configuration'),
622
623
  );
  $items['admin/content/rss-publishing'] = array(
624
625
    'title' => 'RSS publishing',
    'description' => 'Configure the number of items per feed and whether feeds should be titles/teasers/full-text.',
626
627
    'page callback' => 'drupal_get_form',
    'page arguments' => array('system_rss_feeds_settings'),
628
    'access arguments' => array('administer site configuration'),
629
630
  );
  $items['admin/settings/date-time'] = array(
631
    'title' => 'Date and time',
632
    'description' => "Settings for how Drupal displays date and time, as well as the system's default time zone.",
633
634
    'page callback' => 'drupal_get_form',
    'page arguments' => array('system_date_time_settings'),
635
    'access arguments' => array('administer site configuration'),
636
  );
637
  $items['admin/settings/date-time/lookup'] = array(
638
    'title' => 'Date and time lookup',
639
640
    'type' => MENU_CALLBACK,
    'page callback' => 'system_date_time_lookup',
641
    'access arguments' => array('administer site configuration'),
642
  );
643
  $items['admin/settings/site-maintenance'] = array(
644
    'title' => 'Site maintenance',
645
    'description' => 'Take the site offline for maintenance or bring it back online.',
646
647
    'page callback' => 'drupal_get_form',
    'page arguments' => array('system_site_maintenance_settings'),
648
    'access arguments' => array('administer site configuration'),
649
650
  );
  $items['admin/settings/clean-urls'] = array(
651
652
    'title' => 'Clean URLs',
    'description' => 'Enable or disable clean URLs for your site.',
653
654
    'page callback' => 'drupal_get_form',
    'page arguments' => array('system_clean_url_settings'),
655
    'access arguments' => array('administer site configuration'),
656
  );
657
658
659
660
661
662
663
  $items['admin/settings/clean-urls/check'] = array(
    'title' => 'Clean URL check',
    'page callback' => 'drupal_json',
    'page arguments' => array(array('status' => TRUE)),
    'access callback' => TRUE,
    'type' => MENU_CALLBACK,
  );
664
  // Menu handler to test that drupal_http_request() works locally.
665
  // @see system_check_http_request()
666
667
668
669
670
671
672
  $items['admin/reports/request-test'] = array(
    'title' => 'Request test',
    'page callback' => 'printf',
    'page arguments' => array('request test'),
    'access callback' => TRUE,
    'type' => MENU_CALLBACK,
  );
673

674
675
676
677
  // Reports:
  $items['admin/reports'] = array(
    'title' => 'Reports',
    'description' => 'View reports from system logs and other status information.',
678
    'page callback' => 'system_admin_menu_block_page',
679
    'access arguments' => array('access site reports'),
680
681
682
    'weight' => 5,
    'position' => 'left',
  );
683
  $items['admin/reports/status'] = array(
684
685
    'title' => 'Status report',
    'description' => "Get a status report about your site's operation and any detected problems.",
686
687
688
689
    'page callback' => 'system_status',
    'weight' => 10,
    'access arguments' => array('administer site configuration'),
  );
690
  $items['admin/reports/status/run-cron'] = array(
691
    'title' => 'Run cron',
692
    'page callback' => 'system_run_cron',
693
    'access arguments' => array('administer site configuration'),
694
695
    'type' => MENU_CALLBACK,
  );
696
  $items['admin/reports/status/php'] = array(
697
    'title' => 'PHP',
698
    'page callback' => 'system_php',
699
    'access arguments' => array('administer site configuration'),
700
701
    'type' => MENU_CALLBACK,
  );
702
  $items['admin/reports/status/sql'] = array(
703
    'title' => 'SQL',
704
    'page callback' => 'system_sql',
705
    'access arguments' => array('administer site configuration'),
706
707
    'type' => MENU_CALLBACK,
  );
708
709
710
711
712
713
  // Default page for batch operations
  $items['batch'] = array(
    'page callback' => 'system_batch_page',
    'access callback' => TRUE,
    'type' => MENU_CALLBACK,
  );
Dries's avatar
   
Dries committed
714
  return $items;
Dries's avatar
   
Dries committed
715
716
}

717
718
719
720
721
722
723
724
725
726
727
728
729
730
/**
 * Retrieve a blocked IP address from the database.
 *
 * @param $iid integer
 *   The ID of the blocked IP address to retrieve.
 *
 * @return
 *   The blocked IP address from the database as an array.
 */
function blocked_ip_load($iid) {
  $blocked_ip = db_fetch_array(db_query("SELECT * FROM {blocked_ips} WHERE iid = %d", $iid));
  return $blocked_ip;
}

731
732
733
734
/**
 * Menu item access callback - only admin or enabled themes can be accessed.
 */
function _system_themes_access($theme) {
735
  return user_access('administer site configuration') && ($theme->status || $theme->name == variable_get('admin_theme', '0'));
736
737
}

738
739
740
/**
 * Implementation of hook_init().
 */
741
742
function system_init() {
  // Use the administrative theme if the user is looking at a page in the admin/* path.
743
  if (arg(0) == 'admin' || (variable_get('node_admin_theme', '0') && arg(0) == 'node' && (arg(1) == 'add' || arg(2) == 'edit'))) {
744
745
    global $custom_theme;
    $custom_theme = variable_get('admin_theme', '0');
746
    drupal_add_css(drupal_get_path('module', 'system') . '/admin.css');
747
748
749
  }

  // Add the CSS for this module.
750
751
752
  drupal_add_css(drupal_get_path('module', 'system') . '/defaults.css');
  drupal_add_css(drupal_get_path('module', 'system') . '/system.css');
  drupal_add_css(drupal_get_path('module', 'system') . '/system-menus.css');
753
}
754

755
756
757
/**
 * Implementation of MODULE_preprocess_HOOK().
 */
758
function system_preprocess_page(&$variables) {
759
760
761
762
763
764
765
766
  // Get the major version
  list($version,) = explode('.', VERSION);

  // Emit the META tag in the HTML HEAD section
  theme('meta_generator_html', $version);

  // Emit the HTTP Header too
  theme('meta_generator_header', $version);
767
768

  $variables['head'] = drupal_get_html_head();
769
770
}

Dries's avatar
   
Dries committed
771
/**
772
 * Implementation of hook_user_form().
Dries's avatar
   
Dries committed
773
 */
774
775
function system_user_form(&$edit, &$user, $category = NULL) {
  if ($category == 'account') {
776
    $form['theme_select'] = system_theme_select_form(t('Selecting a different theme will change the look and feel of the site.'), isset($edit['theme']) ? $edit['theme'] : NULL, 2);
777
    if (variable_get('configurable_timezones', 1)) {
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
      system_user_timezone($edit, $form);
    }
    return $form;
  }
}

/**
 * Implementation of hook_user_register().
 */
function system_user_register(&$edit, &$user, $category = NULL) {
  if (variable_get('configurable_timezones', 1)) {
    $form = array();
    if (variable_get('user_default_timezone', DRUPAL_USER_TIMEZONE_DEFAULT) == DRUPAL_USER_TIMEZONE_SELECT) {
      system_user_timezone($edit, $form);
    }
    else {
794
      $form['timezone'] = array(
795
796
        '#type' => 'hidden',
        '#value' => variable_get('user_default_timezone', DRUPAL_USER_TIMEZONE_DEFAULT) ? '' : variable_get('date_default_timezone', ''),
797
      );
Dries's avatar
   
Dries committed
798
    }
799
    return $form;
Dries's avatar
   
Dries committed
800
  }
Dries's avatar
   
Dries committed
801
802
}

803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
/**
 * Implementation of hook_user_login().
 */
function system_user_login(&$edit, &$user, $category = NULL) {
  // If the user has a NULL time zone, notify them to set a time zone.
  if (!$user->timezone && variable_get('configurable_timezones', 1) && variable_get('empty_timezone_message', 0)) {
    drupal_set_message(t('Please configure your <a href="@user-edit">account time zone setting</a>.', array('@user-edit' => url("user/$user->uid/edit", array('query' => drupal_get_destination(), 'fragment' => 'edit-timezone')))));
  }
}

/**
 * Add the time zone field to the user edit and register forms.
 */
function system_user_timezone(&$edit, &$form) {
  global $user;
  $form['timezone'] = array(
    '#type' => 'fieldset',
    '#title' => t('Locale settings'),
    '#weight' => 6,
    '#collapsible' => TRUE,
  );
  $form['timezone']['timezone'] = array(
    '#type' => 'select',
    '#title' => t('Time zone'),
    '#default_value' => $edit['timezone'] ? $edit['timezone'] : ($edit['uid'] == $user->uid ? variable_get('date_default_timezone', '') : ''),
    '#options' => system_time_zones(($edit['uid'] != $user->uid)),
    '#description' => t('Select the desired local time and time zone. Dates and times throughout this site will be displayed using this time zone.'),
  );
  if (!$edit['timezone'] && $edit['uid'] == $user->uid) {
    $form['timezone']['#description'] = t('Your time zone setting will be automatically detected if possible. Please confirm the selection and click save.');
    $form['timezone']['timezone']['#attributes'] = array('class' => 'timezone-detect');
    drupal_add_js('misc/timezone.js');
  }
}

838
/**
839
840
 * Implementation of hook_block().
 *
841
842
 * Generate a block with a promotional link to Drupal.org.
 */
843
function system_block($op = 'list', $delta = '', $edit = NULL) {
844
  $image_path = 'misc/' . variable_get('drupal_badge_color', 'powered-blue') . '-' . variable_get('drupal_badge_size', '80x15') . '.png';
845
  switch ($op) {
846
    case 'list':
847
      $blocks['powered-by'] = array(
848
849
        'info' => t('Powered by Drupal'),
        'weight' => '10',
850
851
         // Not worth caching.
        'cache' => BLOCK_NO_CACHE,
852
853
854
      );
      return $blocks;
    case 'configure':
855
      drupal_add_js(drupal_get_path('module', 'system') .'/system.js');
856
857
858
859
860
861
862
863
864
865
866
867
868
      // Compile a list of fields to show
      $form['wrapper']['color'] = array(
        '#type' => 'select',
        '#title' => t('Badge color'),
        '#default_value' => variable_get('drupal_badge_color', 'powered-blue'),
        '#options' => array('powered-black' => t('Black'), 'powered-blue' => t('Blue'), 'powered-gray' => t('Gray')),
      );
      $form['wrapper']['size'] = array(
        '#type' => 'select',
        '#title' => t('Badge size'),
        '#default_value' => variable_get('drupal_badge_size', '80x15'),
        '#options' => array('80x15' => t('Small'), '88x31' => t('Medium'), '135x42' => t('Large')),
      );
869
870
871
872
873
      $form['wrapper']['preview'] = array(
        '#type' => 'item',
        '#title' => 'Preview',
        '#markup' => theme('image', $image_path, t('Powered by Drupal, an open source content management system'), t('Powered by Drupal, an open source content management system'), array('class' => 'powered-by-preview'), FALSE),
      );
874
875
876
877
878
879
880
881
882
883
884
885
      return $form;
    case 'save':
      variable_set('drupal_badge_color', $edit['color']);
      variable_set('drupal_badge_size', $edit['size']);
      break;
    case 'view':
      $block['subject'] = NULL; // Don't display a title
      $block['content'] = theme('system_powered_by', $image_path);
      return $block;
  }
}

886
887
/**
 * Provide a single block on the administration overview page.
888
889
890
 *
 * @param $item
 *   The menu item to be displayed.
891
 */
892
function system_admin_menu_block($item) {
893
  $content = array();
894
  if (!isset($item['mlid'])) {
895
    $item += db_fetch_array(db_query("SELECT mlid, menu_name FROM {menu_links} ml WHERE ml.router_path = '%s' AND module = 'system'", $item['path']));
896
  }
897
  $result = db_query("
898
    SELECT m.load_functions, m.to_arg_functions, m.access_callback, m.access_arguments, m.page_callback, m.page_arguments, m.title, m.title_callback, m.title_arguments, m.type, m.description, ml.*
899
    FROM {menu_links} ml
900
    LEFT JOIN {menu_router} m ON ml.router_path = m.path
901
    WHERE ml.plid = %d AND ml.menu_name = '%s' AND hidden = 0", $item['mlid'], $item['menu_name']);
902
  while ($item = db_fetch_array($result)) {
903
    _menu_link_translate($item);
904
    if (!$item['access']) {
905
      continue;
906
    }
907
908
    // The link 'description' either derived from the hook_menu 'description' or
    // entered by the user via menu module is saved as the title attribute.
909
910
    if (!empty($item['localized_options']['attributes']['title'])) {
      $item['description'] = $item['localized_options']['attributes']['title'];
911
912
913
    }
    // Prepare for sorting as in function _menu_tree_check_access().
    // The weight is offset so it is always positive, with a uniform 5-digits.
914
    $content[(50000 + $item['weight']) . ' ' . $item['title'] . ' ' . $item['mlid']] = $item;
915
  }
916
  ksort($content);
917
918
919
  return $content;
}

920
921
922
/**
 * Process admin theme form submissions.
 */
923
function system_admin_theme_submit($form, &$form_state) {
924
  // If we're changing themes, make sure the theme has its blocks initialized.
925
  if ($form_state['values']['admin_theme'] && $form_state['values']['admin_theme'] != variable_get('admin_theme', '0')) {
926
    $result = db_result(db_query("SELECT COUNT(*) FROM {block} WHERE theme = '%s'", $form_state['values']['admin_theme']));
927
    if (!$result) {
928
      system_initialize_theme_blocks($form_state['values']['admin_theme']);
929
930
931
932
    }
  }
}

933
/**
934
935
936
937
938
939
940
941
942
943
944
 * Returns a fieldset containing the theme select form.
 *
 * @param $description
 *    description of the fieldset
 * @param $default_value
 *    default value of theme radios
 * @param $weight
 *    weight of the fieldset
 * @return
 *    a form array
 */
945
function system_theme_select_form($description = '', $default_value = '', $weight = 0) {
946
  if (user_access('select different theme')) {
947
    $enabled = array();
948
949
950
    $themes = list_themes();

    foreach ($themes as $theme) {
951
952
953
954
955
956
957
958
959
      if ($theme->status) {
        $enabled[] = $theme;
      }
    }

    if (count($enabled) > 1) {
      ksort($enabled);

      $form['themes'] = array(
Dries's avatar
Dries committed
960
961
962
963
        '#type' => 'fieldset',
        '#title' => t('Theme configuration'),
        '#description' => $description,
        '#collapsible' => TRUE,
964
965
966
967
968
        '#theme' => 'system_theme_select_form'
      );

      foreach ($enabled as $info) {
        // For the default theme, revert to an empty string so the user's theme updates when the site theme is changed.
969
        $info->key = $info->name == variable_get('theme_default', 'garland') ? '' : $info->name;
970

971
972
973
974
975
976
977
978
979
980
981
        $screenshot = NULL;
        $theme_key = $info->name;
        while ($theme_key) {
          if (file_exists($themes[$theme_key]->info['screenshot'])) {
            $screenshot = $themes[$theme_key]->info['screenshot'];
            break;
          }
          $theme_key = isset($themes[$theme_key]->info['base theme']) ? $themes[$theme_key]->info['base theme'] : NULL;
        }

        $screenshot = $screenshot ? theme('image', $screenshot, t('Screenshot for %theme theme', array('%theme' => $info->name)), '', array('class' => 'screenshot'), FALSE) : t('no screenshot');
982

983
984
        $form['themes'][$info->key]['screenshot'] = array('#markup' => $screenshot);
        $form['themes'][$info->key]['description'] = array('#type' => 'item', '#title' => $info->name, '#markup' => dirname($info->filename) . ($info->name == variable_get('theme_default', 'garland') ? '<br /> <em>' . t('(site default theme)') . '</em>' : ''));
985
986
987
988
989
990
991
992
993
994
        $options[$info->key] = '';
      }

      $form['themes']['theme'] = array('#type' => 'radios', '#options' => $options, '#default_value' => $default_value ? $default_value : '');
      $form['#weight'] = $weight;
      return $form;
    }
  }
}

995
996
/**
 * Checks the existence of the directory specified in $form_element. This
Dries's avatar
Dries committed
997
 * function is called from the system_settings form to check both the
998
999
1000
1001
1002
1003
1004
 * file_directory_path and file_directory_temp directories. If validation
 * fails, the form element is flagged with an error from within the
 * file_check_directory function.
 *
 * @param $form_element
 *   The form element containing the name of the directory to check.
 */
1005
function system_check_directory($form_element) {
1006
1007
1008
1009
  file_check_directory($form_element['#value'], FILE_CREATE_DIRECTORY, $form_element['#parents'][0]);
  return $form_element;
}

Dries's avatar
   
Dries committed
1010
1011
/**
 * Retrieves the current status of an array of files in the system table.
1012
1013
1014
1015
1016
 *
 * @param $files
 *   An array of files to check.
 * @param $type
 *   The type of the files.
Dries's avatar
   
Dries committed
1017
1018
 */
function system_get_files_database(&$files, $type) {
Dries's avatar
   
Dries committed
1019
  // Extract current files from database.
1020
  $result = db_query("SELECT filename, name, type, status, schema_version, weight FROM {system} WHERE type = '%s'", $type);
Dries's avatar
   
Dries committed
1021
  while ($file = db_fetch_object($result)) {
1022
    if (isset($files[$file->name]) && is_object($files[$file->name])) {
1023
      $file->old_filename = $file->filename;
Dries's avatar
   
Dries committed
1024
      foreach ($file as $key => $value) {