system.module 103 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.
 */

Steven Wittens's avatar
Steven Wittens committed
9
define('VERSION', '6.0-dev');
10

11
12
13
14
15
define('DRUPAL_MINIMUM_PHP',    '4.3.3');
define('DRUPAL_MINIMUM_MYSQL',  '4.1.0'); // If using MySQL
define('DRUPAL_MINIMUM_PGSQL',  '7.4');   // If using PostgreSQL
define('DRUPAL_MINIMUM_APACHE', '1.3');   // If using Apache

Dries's avatar
   
Dries committed
16
17
18
19
/**
 * Implementation of hook_help().
 */
function system_help($section) {
20
21
  global $base_url;

22
  switch ($section) {
23
    case 'admin/help#system':
24
      $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 website 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 website performance. The settings module provides control over preferences, behaviours including visual and operational settings.') .'</p>';
25
      $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>';
26
      $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>';
27
      $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>';
28
      return $output;
29
    case 'admin':
30
      return '<p>'. t('Welcome to the administration section. Here you may control how your site functions.') .'</p>';
31
    case 'admin/by-module':
32
      return '<p>'. t('This page shows you all available administration tasks for each module.') .'</p>';
33
    case 'admin/build/themes':
34
      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>';
35
    case 'admin/build/themes/settings':
36
      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>';
37
38
    case 'admin/build/themes/settings/'. arg(4):
      $reference = explode('.', arg(4), 2);
39
      $theme = array_pop($reference);
40
      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>';
41
    case 'admin/build/modules':
42
      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>
43
<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')));
44
    case 'admin/build/modules/uninstall':
45
      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>';
46
    case 'admin/logs/status':
47
      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>';
48
  }
Dries's avatar
   
Dries committed
49
50
}

51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
function system_theme() {
  return array_merge(drupal_common_themes(), array(
    'system_theme_select_form' => array(
      'arguments' => array('form' => NULL),
    ),
    'system_themes_form' => array(
      'arguments' => array('form' => NULL),
    ),
    'system_modules' => array(
      'arguments' => array('form' => NULL),
    ),
    'system_modules_uninstall' => array(
      'arguments' => array('form' => NULL),
    ),
    'status_report' => array(
      'arguments' => array('requirements' => NULL),
    ),
    'admin_page' => array(
      'arguments' => array('blocks' => NULL),
    ),
    'admin_block' => array(
      'arguments' => array('block' => NULL),
    ),
    'admin_block_content' => array(
      'arguments' => array('content' => NULL),
    ),
    'system_admin_by_module' => array(
      'arguments' => array('menu_items' => NULL),
    ),
  ));
}
Dries's avatar
   
Dries committed
82
83
84
/**
 * Implementation of hook_perm().
 */
Dries's avatar
 
Dries committed
85
function system_perm() {
86
  return array('administer site configuration', 'access administration pages', 'select different theme');
Dries's avatar
   
Dries committed
87
88
}

89
90
91
92
93
/**
 * Implementation of hook_elements().
 */
function system_elements() {
  // Top level form
94
  $type['form'] = array('#method' => 'post', '#action' => request_uri());
95
96

  // Inputs
97
  $type['checkbox'] = array('#input' => TRUE, '#return_value' => 1);
98
99
  $type['submit'] = array('#input' => TRUE, '#name' => 'op', '#button_type' => 'submit', '#executes_submit_callback' => TRUE);
  $type['button'] = array('#input' => TRUE, '#name' => 'op', '#button_type' => 'submit', '#executes_submit_callback' => FALSE);
100
  $type['textfield'] = array('#input' => TRUE, '#size' => 60, '#maxlength' => 128, '#autocomplete_path' => FALSE);
101
  $type['password'] = array('#input' => TRUE, '#size' => 60, '#maxlength' => 128);
102
  $type['password_confirm'] = array('#input' => TRUE, '#process' => array('expand_password_confirm'));
103
  $type['textarea'] = array('#input' => TRUE, '#cols' => 60, '#rows' => 5, '#resizable' => TRUE);
104
  $type['radios'] = array('#input' => TRUE, '#process' => array('expand_radios'));
105
  $type['radio'] = array('#input' => TRUE, '#default_value' => NULL);
106
  $type['checkboxes'] = array('#input' => TRUE, '#process' => array('expand_checkboxes'), '#tree' => TRUE);
107
  $type['select'] = array('#input' => TRUE, '#size' => 0, '#multiple' => FALSE);
108
109
  $type['weight'] = array('#input' => TRUE, '#delta' => 10, '#default_value' => 0, '#process' => array('process_weight'));
  $type['date'] = array('#input' => TRUE, '#process' => array('expand_date' => array()), '#element_validate' => array('date_validate'));
110
  $type['file'] = array('#input' => TRUE, '#size' => 60);
111
112

  // Form structure
113
  $type['item'] = array('#value' => '');
114
115
116
  $type['hidden'] = array('#input' => TRUE);
  $type['value'] = array('#input' => TRUE);
  $type['markup'] = array('#prefix' => '', '#suffix' => '');
117
  $type['fieldset'] = array('#collapsible' => FALSE, '#collapsed' => FALSE, '#value' => NULL);
Dries's avatar
Dries committed
118
  $type['token'] = array('#input' => TRUE);
119
120
121
  return $type;
}

Dries's avatar
   
Dries committed
122
/**
Dries's avatar
   
Dries committed
123
 * Implementation of hook_menu().
Dries's avatar
   
Dries committed
124
 */
125
126
function system_menu() {
  $items['system/files'] = array(
127
    'title' => 'File download',
128
129
130
131
132
    'page callback' => 'file_download',
    'access callback' => TRUE,
    'type' => MENU_CALLBACK,
  );
  $items['admin'] = array(
133
    'title' => 'Administer',
134
135
136
137
138
    'access arguments' => array('access administration pages'),
    'page callback' => 'system_main_admin_page',
    'weight' => 9,
  );
  $items['admin/compact'] = array(
139
    'title' => 'Compact mode',
140
141
142
143
    'page callback' => 'system_admin_compact_page',
    'type' => MENU_CALLBACK,
  );
  $items['admin/by-task'] = array(
144
    'title' => 'By task',
145
146
147
148
    'page callback' => 'system_main_admin_page',
    'type' => MENU_DEFAULT_LOCAL_TASK,
  );
  $items['admin/by-module'] = array(
149
    'title' => 'By module',
150
151
152
153
154
155
    'page callback' => 'system_admin_by_module',
    'type' => MENU_LOCAL_TASK,
    'weight' => 2,
  );
  // menu items that are basically just menu blocks
  $items['admin/settings'] = array(
156
157
    'title' => 'Site configuration',
    'description' => 'Adjust basic site configuration options.',
158
159
160
161
162
163
    'position' => 'right',
    'weight' => -5,
    'page callback' => 'system_settings_overview',
    'access arguments' => array('administer site configuration'),
  );
  $items['admin/build'] = array(
164
165
    'title' => 'Site building',
    'description' => 'Control how your site looks and feels.',
166
167
168
169
170
171
    'position' => 'right',
    'weight' => -10,
    'page callback' => 'system_admin_menu_block_page',
    'access arguments' => array('administer site configuration'),
  );
  $items['admin/settings/admin'] = array(
172
173
    'title' => 'Administration theme',
    'description' => 'Settings for how your administrative pages should look.',
174
175
176
177
178
179
180
    'position' => 'left',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('system_admin_theme_settings'),
    'block callback' => 'system_admin_theme_settings',
  );
  // Themes:
  $items['admin/build/themes'] = array(
181
182
    'title' => 'Themes',
    'description' => 'Change which theme your site uses or allows users to set.',
183
    'page callback' => 'drupal_get_form',
184
    'page arguments' => array('system_themes_form'),
185
186
  );
  $items['admin/build/themes/select'] = array(
187
188
    'title' => 'List',
    'description' => 'Select the default theme.',
189
190
191
192
    'type' => MENU_DEFAULT_LOCAL_TASK,
    'weight' => -1,
  );
  $items['admin/build/themes/settings'] = array(
193
    'title' => 'Configure',
194
195
196
197
198
    'page arguments' => array('system_theme_settings'),
    'type' => MENU_LOCAL_TASK,
  );
  // Theme configuration subtabs
  $items['admin/build/themes/settings/global'] = array(
199
    'title' => 'Global settings',
200
201
202
    'type' => MENU_DEFAULT_LOCAL_TASK,
    'weight' => -1,
  );
Dries's avatar
   
Dries committed
203

204
205
206
  foreach (list_themes() as $theme) {
    if ($theme->status) {
      $items['admin/build/themes/settings/'. $theme->name] = array(
207
        'title' => $theme->info['name'],
208
209
210
        'page arguments' => array('system_theme_settings', $theme->name),
        'type' => MENU_LOCAL_TASK,
      );
Dries's avatar
   
Dries committed
211
    }
Dries's avatar
   
Dries committed
212
  }
drumm's avatar
drumm committed
213

214
215
  // Modules:
  $items['admin/build/modules'] = array(
216
217
    'title' => 'Modules',
    'description' => 'Enable or disable add-on modules for your site.',
218
219
220
221
    'page callback' => 'drupal_get_form',
    'page arguments' => array('system_modules'),
  );
  $items['admin/build/modules/list'] = array(
222
    'title' => 'List',
223
224
225
    'type' => MENU_DEFAULT_LOCAL_TASK,
  );
  $items['admin/build/modules/list/confirm'] = array(
226
    'title' => 'List',
227
228
229
    'type' => MENU_CALLBACK,
  );
  $items['admin/build/modules/uninstall'] = array(
230
    'title' => 'Uninstall',
231
232
233
234
    'page arguments' => array('system_modules_uninstall'),
    'type' => MENU_LOCAL_TASK,
  );
  $items['admin/build/modules/uninstall/confirm'] = array(
235
    'title' => 'Uninstall',
236
237
    'type' => MENU_CALLBACK,
  );
Dries's avatar
   
Dries committed
238

239
240
  // Settings:
  $items['admin/settings/site-information'] = array(
241
242
    'title' => 'Site information',
    'description' => 'Change basic site information, such as the site name, slogan, e-mail address, mission, front page and more.',
243
244
245
246
    'page callback' => 'drupal_get_form',
    'page arguments' => array('system_site_information_settings'),
  );
  $items['admin/settings/error-reporting'] = array(
247
248
    'title' => 'Error reporting',
    'description' => 'Control how Drupal deals with errors including 403/404 errors as well as PHP error reporting.',
249
250
251
    'page callback' => 'drupal_get_form',
    'page arguments' => array('system_error_reporting_settings'),
  );
252
  $items['admin/settings/logging'] = array(
253
254
    '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.",
255
256
    'page callback' => 'system_logging_overview',
  );
257
  $items['admin/settings/performance'] = array(
258
259
    'title' => 'Performance',
    'description' => 'Enable or disable page caching for anonymous users, and enable or disable CSS preprocessor.',
260
261
262
263
    'page callback' => 'drupal_get_form',
    'page arguments' => array('system_performance_settings'),
  );
  $items['admin/settings/file-system'] = array(
264
265
    'title' => 'File system',
    'description' => 'Tell Drupal where to store uploaded files and how they are accessed.',
266
267
268
269
    'page callback' => 'drupal_get_form',
    'page arguments' => array('system_file_system_settings'),
  );
  $items['admin/settings/image-toolkit'] = array(
270
271
    'title' => 'Image toolkit',
    'description' => 'Choose which image toolkit to use if you have installed optional toolkits.',
272
273
274
275
    'page callback' => 'drupal_get_form',
    'page arguments' => array('system_image_toolkit_settings'),
  );
  $items['admin/content/rss-publishing'] = array(
276
277
    'title' => 'RSS publishing',
    'description' => 'Configure the number of items per feed and whether feeds should be titles/teasers/full-text.',
278
279
280
281
    'page callback' => 'drupal_get_form',
    'page arguments' => array('system_rss_feeds_settings'),
  );
  $items['admin/settings/date-time'] = array(
282
283
    'title' => 'Date and time',
    'description' => "Settings for how Drupal displays date and time, as well as the system's default timezone.",
284
285
286
    'page callback' => 'drupal_get_form',
    'page arguments' => array('system_date_time_settings'),
  );
287
288
289
290
291
  $items['admin/settings/date-time/lookup'] = array(
    'title' => t('Date and time lookup'),
    'type' => MENU_CALLBACK,
    'page callback' => 'system_date_time_lookup',
  );
292
  $items['admin/settings/site-maintenance'] = array(
293
294
    'title' => 'Site maintenance',
    'description' => 'Take the site off-line for maintenance or bring it back online.',
295
296
297
298
    'page callback' => 'drupal_get_form',
    'page arguments' => array('system_site_maintenance_settings'),
  );
  $items['admin/settings/clean-urls'] = array(
299
300
    'title' => 'Clean URLs',
    'description' => 'Enable or disable clean URLs for your site.',
301
302
303
304
305
306
    'page callback' => 'drupal_get_form',
    'page arguments' => array('system_clean_url_settings'),
  );

  // Logs:
  $items['admin/logs'] = array(
307
308
    'title' => 'Logs',
    'description' => 'View system logs and other status information.',
309
310
311
312
313
    'page callback' => 'system_admin_menu_block_page',
    'weight' => 5,
    'position' => 'left',
  );
  $items['admin/logs/status'] = array(
314
315
    'title' => 'Status report',
    'description' => "Get a status report about your site's operation and any detected problems.",
316
317
318
319
320
    'page callback' => 'system_status',
    'weight' => 10,
    'access arguments' => array('administer site configuration'),
  );
  $items['admin/logs/status/run-cron'] = array(
321
    'title' => 'Run cron',
322
323
324
325
    'page callback' => 'system_run_cron',
    'type' => MENU_CALLBACK,
  );
  $items['admin/logs/status/php'] = array(
326
    'title' => 'PHP',
327
328
329
330
    'page callback' => 'system_php',
    'type' => MENU_CALLBACK,
  );
  $items['admin/logs/status/sql'] = array(
331
    'title' => 'SQL',
332
333
334
    'page callback' => 'system_sql',
    'type' => MENU_CALLBACK,
  );
335
336
337
338
339
340
  // Default page for batch operations
  $items['batch'] = array(
    'page callback' => 'system_batch_page',
    'access callback' => TRUE,
    'type' => MENU_CALLBACK,
  );
Dries's avatar
   
Dries committed
341
  return $items;
Dries's avatar
 
Dries committed
342
343
}

344
345
346
347
348
349
350
351
352
353
354
355
356
function system_init() {
  // Use the administrative theme if the user is looking at a page in the admin/* path.
  if (arg(0) == 'admin') {
    global $custom_theme;
    $custom_theme = variable_get('admin_theme', '0');
    drupal_add_css(drupal_get_path('module', 'system') .'/admin.css', 'module');
  }

  // Add the CSS for this module.
  drupal_add_css(drupal_get_path('module', 'system') .'/defaults.css', 'module');
  drupal_add_css(drupal_get_path('module', 'system') .'/system.css', 'module');
}

Dries's avatar
   
Dries committed
357
358
359
360
361
/**
 * Implementation of hook_user().
 *
 * Allows users to individually set their theme and time zone.
 */
362
function system_user($type, $edit, &$user, $category = NULL) {
Dries's avatar
Dries committed
363
  if ($type == 'form' && $category == 'account') {
364
    $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);
Dries's avatar
Dries committed
365

366
    if (variable_get('configurable_timezones', 1)) {
Steven Wittens's avatar
Steven Wittens committed
367
      $zones = _system_zonelist();
368
      $form['timezone'] = array(
369
        '#type' => 'fieldset',
370
371
372
373
        '#title' => t('Locale settings'),
        '#weight' => 6,
        '#collapsible' => TRUE,
      );
374
      $form['timezone']['timezone'] = array(
375
376
377
378
379
        '#type' => 'select',
        '#title' => t('Time zone'),
        '#default_value' => strlen($edit['timezone']) ? $edit['timezone'] : variable_get('date_default_timezone', 0),
        '#options' => $zones,
        '#description' => t('Select your current local time. Dates and times throughout this site will be displayed using this time zone.'),
380
      );
Dries's avatar
   
Dries committed
381
    }
Dries's avatar
Dries committed
382

383
    return $form;
Dries's avatar
   
Dries committed
384
  }
Dries's avatar
   
Dries committed
385
386
}

387
388
389
390
391
392
393
/**
 * Provide the administration overview page.
 */
function system_main_admin_page($arg = NULL) {
  // If we received an argument, they probably meant some other page.
  // Let's 404 them since the menu system cannot be told we do not
  // accept arguments.
394
  if (isset($arg) && substr($arg, 0, 3) != 'by-') {
395
396
397
    return drupal_not_found();
  }

398
399
400
401
  // Check for status report errors.
  if (system_status(TRUE)) {
    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');
  }
402
403
404
  $result = db_query("SELECT * FROM {menu_links} ml INNER JOIN {menu_router} m ON ml.router_path = m.path
                      WHERE ml.href like 'admin/%' AND ml.href != 'admin/help' AND ml.depth = 2 AND ml.menu_name = 'navigation'
                      ORDER BY p1 ASC, p2 ASC, p3 ASC");
405
  while ($item = db_fetch_object($result)) {
406
    _menu_link_translate($item);
407
408
    if (!$item->access) {
      continue;
409
    }
410
411
412
413
414
415
416
    $block = (array)$item;
    $block['content'] = '';
    if ($item->block_callback && function_exists($item->block_callback)) {
      $function = $item->block_callback;
      $block['content'] .= $function();
    }
    $block['content'] .= theme('admin_block_content', system_admin_menu_block($item));
417
418
419
420
421
422
423
424
    $blocks[] = $block;
  }
  return theme('admin_page', $blocks);
}

/**
 * Provide a single block on the administration overview page.
 */
425
function system_admin_menu_block($item) {
426
  $content = array();
427
428
429
430
431
  if (!isset($item->mlid)) {
    $item->mlid = db_result(db_query("SELECT mlid FROM {menu_links} ml WHERE ml.router_path = '%s' AND menu_name = 'navigation'", $item->path));
  }
  $result = db_query("SELECT * FROM {menu_links} ml INNER JOIN {menu_router} m ON ml.router_path = m.path
                      WHERE ml.plid = '%s' AND ml.menu_name = 'navigation' ORDER BY m.weight, m.title", $item->mlid);
432
  while ($item = db_fetch_object($result)) {
433
    _menu_link_translate($item);
434
435
    if (!$item->access) {
      continue;
436
    }
437
    $content[] = (array)$item;
438
439
440
441
442
443
444
  }
  return $content;
}

/**
 * Provide a single block from the administration menu as a page.
 * This function is often a destination for these blocks.
445
 * For example, 'admin/content/types' needs to have a destination to be valid
446
447
448
449
 * in the Drupal menu system, but too much information there might be
 * hidden, so we supply the contents of the block.
 */
function system_admin_menu_block_page() {
450
451
  $item = menu_get_item();
  $content = system_admin_menu_block($item);
452
453
454
455
456
457
458
459
460
461

  $output = theme('admin_block_content', $content);
  return $output;
}

function system_admin_compact_page($mode = 'off') {
  global $user;
  user_save($user, array('admin_compact_mode' => ($mode == 'on')));
  drupal_goto('admin');
}
462

463
/**
464
 * This function allows selection of the theme to show in administration sections.
465
 */
466
function system_admin_theme_settings() {
467
468
469
470
  $themes = system_theme_data();
  ksort($themes);
  $options[0] = t('System default');
  foreach ($themes as $theme) {
471
    $options[$theme->name] = $theme->info['name'];
472
473
474
475
476
477
  }

  $form['admin_theme'] = array(
    '#type' => 'select',
    '#options' => $options,
    '#title' => t('Administration theme'),
478
    '#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.'),
479
    '#default_value' => variable_get('admin_theme', '0'),
480
481
482
483
484
  );

  // In order to give it our own submit, we have to give it the default submit
  // too because the presence of a #submit will prevent the default #submit
  // from being used. Also we want ours first.
485
486
  $form['#submit'][] = 'system_admin_theme_submit';
  $form['#submit'][] = 'system_settings_form_submit';
487
  return system_settings_form($form);
488
489
490
}


491
function system_admin_theme_submit($form_values, $form, &$form_state) {
492
  // If we're changing themes, make sure the theme has its blocks initialized.
493
  if ($form_values['admin_theme'] != variable_get('admin_theme', '0')) {
494
495
496
497
498
499
500
    $result = db_query("SELECT status FROM {blocks} WHERE theme = '%s'", $form_values['admin_theme']);
    if (!db_num_rows($result)) {
      system_initialize_theme_blocks($form_values['admin_theme']);
    }
  }
}

501
502
503
504
505
506
507
508
509
510
511
512
513
514
/*
 * 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
 */
function system_theme_select_form($description = '', $default_value = '', $weight = 0) {
  if (user_access('select different theme')) {
515
    $enabled = array();
516
517
518
    $themes = list_themes();

    foreach ($themes as $theme) {
519
520
521
522
523
524
525
526
527
      if ($theme->status) {
        $enabled[] = $theme;
      }
    }

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

      $form['themes'] = array(
Dries's avatar
Dries committed
528
529
530
531
        '#type' => 'fieldset',
        '#title' => t('Theme configuration'),
        '#description' => $description,
        '#collapsible' => TRUE,
532
533
534
535
536
        '#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.
537
        $info->key = $info->name == variable_get('theme_default', 'garland') ? '' : $info->name;
538

539
540
541
542
543
544
545
546
547
548
549
        $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');
550

551
        $form['themes'][$info->key]['screenshot'] = array('#value' => $screenshot);
552
        $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>' : ''));
553
554
555
556
557
558
559
560
561
562
563
        $options[$info->key] = '';
      }

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

function theme_system_theme_select_form($form) {
564
565
  foreach (element_children($form) as $key) {
    $row = array();
566
    if (isset($form[$key]['description']) && is_array($form[$key]['description'])) {
567
568
569
      $row[] = drupal_render($form[$key]['screenshot']);
      $row[] = drupal_render($form[$key]['description']);
      $row[] = drupal_render($form['theme'][$key]);
570
571
572
573
    }
    $rows[] = $row;
  }

574
  $header = array(t('Screenshot'), t('Name'), t('Selected'));
575
576
577
578
  $output = theme('table', $header, $rows);
  return $output;
}

Steven Wittens's avatar
Steven Wittens committed
579
580
581
582
583
584
function _system_zonelist() {
  $timestamp = time();
  $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);
  $zones = array();
  foreach ($zonelist as $offset) {
    $zone = $offset * 3600;
Dries's avatar
Dries committed
585
    $zones[$zone] = format_date($timestamp, 'custom', variable_get('date_format_long', 'l, F j, Y - H:i') .' O', $zone);
Steven Wittens's avatar
Steven Wittens committed
586
587
588
589
  }
  return $zones;
}

Dries's avatar
Dries committed
590
591
592
593
function system_site_information_settings() {
  $form['site_name'] = array(
    '#type' => 'textfield',
    '#title' => t('Name'),
594
    '#default_value' => variable_get('site_name', 'Drupal'),
595
    '#description' => t('The name of this website.'),
Dries's avatar
Dries committed
596
    '#required' => TRUE
597
  );
Dries's avatar
Dries committed
598
599
600
601
  $form['site_mail'] = array(
    '#type' => 'textfield',
    '#title' => t('E-mail address'),
    '#default_value' => variable_get('site_mail', ini_get('sendmail_from')),
602
603
    '#description' => t('A valid e-mail address to be used as the "From" address by the auto-mailer during registration, new password requests, notifications, etc.  To lessen the likelihood of e-mail being marked as spam, this e-mail address should use the same domain as the website.'),
    '#required' => TRUE,
604
  );
Dries's avatar
Dries committed
605
606
607
608
  $form['site_slogan'] = array(
    '#type' => 'textfield',
    '#title' => t('Slogan'),
    '#default_value' => variable_get('site_slogan', ''),
609
    '#description' => t('The slogan of this website. Some themes display a slogan when available.')
610
611
  );

Dries's avatar
Dries committed
612
613
614
615
  $form['site_mission'] = array(
    '#type' => 'textarea',
    '#title' => t('Mission'),
    '#default_value' => variable_get('site_mission', ''),
616
    '#description' => t('Your site\'s mission statement or focus.')
617
  );
Dries's avatar
Dries committed
618
619
620
621
  $form['site_footer'] = array(
    '#type' => 'textarea',
    '#title' => t('Footer message'),
    '#default_value' => variable_get('site_footer', ''),
622
    '#description' => t('This text will be displayed at the bottom of each page. Useful for adding a copyright notice to your pages.')
623
  );
Dries's avatar
Dries committed
624
625
626
  $form['anonymous'] = array(
    '#type' => 'textfield',
    '#title' => t('Anonymous user'),
627
    '#default_value' => variable_get('anonymous', t('Anonymous')),
628
    '#description' => t('The name used to indicate anonymous users.')
629
  );
Dries's avatar
Dries committed
630
631
632
633
  $form['site_frontpage'] = array(
    '#type' => 'textfield',
    '#title' => t('Default front page'),
    '#default_value' => variable_get('site_frontpage', 'node'),
634
635
    '#size' => 40,
    '#description' => t('The home page displays content from this relative URL. If unsure, specify "node".'),
636
    '#field_prefix' => url(NULL, array('absolute' => TRUE)) . (variable_get('clean_url', 0) ? '' : '?q=')
637
  );
638

639
  return system_settings_form($form);
Dries's avatar
Dries committed
640
641
642
643
}

function system_clean_url_settings() {
  $form['clean_url'] = array(
644
645
646
647
    '#type' => 'radios',
    '#title' => t('Clean URLs'),
    '#default_value' => variable_get('clean_url', 0),
    '#options' => array(t('Disabled'), t('Enabled')),
648
    '#description' => t('This option makes Drupal emit "clean" URLs (i.e. without <code>?q=</code> in the URL).'),
649
  );
650

651
652
  if (!variable_get('clean_url', 0)) {
    if (strpos(request_uri(), '?q=') !== FALSE) {
653
654
655
656
657
658
659
660
661
662
663
664
      drupal_add_js(array('cleanURL' => array('success' => t('Your server has been successfully tested to support this feature.'), 'failure' => t('Your system configuration does not currently support this feature. The <a href="http://drupal.org/node/15365">handbook page on Clean URLs</a> has additional troubleshooting information.'), 'testing' => t('Testing clean URLs...'))), 'setting');
      drupal_add_js(drupal_get_path('module', 'system') .'/system.js', 'module');
      drupal_add_js('
// Global Killswitch
if (Drupal.jsEnabled) {
  $(document).ready(function() {
    Drupal.cleanURLsSettingsCheck();
  });
}', 'inline');

      $form['clean_url']['#description'] .= ' <span>'. 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.', array('@handbook' => 'http://drupal.org/node/15365')) .'</span>';

665
      $form['clean_url']['#disabled'] = TRUE;
666
667
      $form['clean_url']['#prefix'] = '<div id="clean-url">';
      $form['clean_url']['#suffix'] = '<p>'. t('<a href="@clean_url">Run the clean url test</a>.', array('@clean_url' => base_path() .'admin/settings/clean-urls')) .'</p></div>';
668
669
    }
    else {
670
      $form['clean_url']['#description'] .= ' '. t('Your server has been successfully tested to support this feature.');
671
672
    }
  }
Dries's avatar
   
Dries committed
673

674
  return system_settings_form($form);
Dries's avatar
Dries committed
675
676
677
}

function system_error_reporting_settings() {
drumm's avatar
drumm committed
678
679

  $form['site_403'] = array(
Dries's avatar
Dries committed
680
    '#type' => 'textfield',
drumm's avatar
drumm committed
681
    '#title' => t('Default 403 (access denied) page'),
Dries's avatar
Dries committed
682
    '#default_value' => variable_get('site_403', ''),
683
684
    '#size' => 40,
    '#description' => t('This page is displayed when the requested document is denied to the current user. If unsure, specify nothing.'),
685
    '#field_prefix' => url(NULL, array('absolute' => TRUE)) . (variable_get('clean_url', 0) ? '' : '?q=')
686
  );
drumm's avatar
drumm committed
687
688

  $form['site_404'] = array(
Dries's avatar
Dries committed
689
    '#type' => 'textfield',
drumm's avatar
drumm committed
690
    '#title' => t('Default 404 (not found) page'),
Dries's avatar
Dries committed
691
    '#default_value' =>  variable_get('site_404', ''),
692
693
    '#size' => 40,
    '#description' => t('This page is displayed when no other content matches the requested document. If unsure, specify nothing.'),
694
    '#field_prefix' => url(NULL, array('absolute' => TRUE)) . (variable_get('clean_url', 0) ? '' : '?q=')
695
  );
drumm's avatar
drumm committed
696
697

  $form['error_level'] = array(
698
699
    '#type' => 'select', '#title' => t('Error reporting'), '#default_value' => variable_get('error_level', 1),
    '#options' => array(t('Write errors to the log'), t('Write errors to the log and to the screen')),
drumm's avatar
drumm committed
700
    '#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.')
701
  );
drumm's avatar
drumm committed
702

703
  return system_settings_form($form);
Dries's avatar
Dries committed
704
}
Dries's avatar
 
Dries committed
705

706
function system_performance_settings() {
707

708
709
710
711
712
713
  $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>';

  $problem_modules = array_unique(array_merge(module_implements('init'), module_implements('exit')));
  sort($problem_modules);

  if (count($problem_modules) > 0) {
714
    $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>';
715
716
  }
  else {
717
    $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>';
718
  }
719
720
721
722
723
  $form['page_cache'] = array(
    '#type' => 'fieldset',
    '#title' => t('Page cache'),
    '#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.'),
  );
724

725
  $form['page_cache']['cache'] = array(
Dries's avatar
Dries committed
726
    '#type' => 'radios',
727
    '#title' => t('Caching mode'),
Dries's avatar
Dries committed
728
    '#default_value' => variable_get('cache', CACHE_DISABLED),
729
730
    '#options' => array(CACHE_DISABLED => t('Disabled'), CACHE_NORMAL => t('Normal (recommended, no side effects)'), CACHE_AGGRESSIVE => t('Aggressive (experts only, possible side effects)')),
    '#description' => $description
731
732
  );

733
734
  $period = drupal_map_assoc(array(0, 60, 180, 300, 600, 900, 1800, 2700, 3600, 10800, 21600, 32400, 43200, 86400), 'format_interval');
  $period[0] = t('none');
735
  $form['page_cache']['cache_lifetime'] = array(
Dries's avatar
Dries committed
736
737
738
739
    '#type' => 'select',
    '#title' => t('Minimum cache lifetime'),
    '#default_value' => variable_get('cache_lifetime', 0),
    '#options' => $period,
740
    '#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.')
741
  );
742

743
744
745
746
747
  $form['bandwidth_optimizations'] = array(
    '#type' => 'fieldset',
    '#title' => t('Bandwidth optimizations'),
    '#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.')
  );
748

749
  $directory = file_directory_path();
750
  $is_writable = is_dir($directory) && is_writable($directory) && (variable_get('file_downloads', FILE_DOWNLOADS_PUBLIC) == FILE_DOWNLOADS_PUBLIC);
751
752
753
754
755
756
757
758
759
  $form['bandwidth_optimizations']['preprocess_css'] = array(
    '#type' => 'radios',
    '#title' => t('Aggregate and compress CSS files'),
    '#default_value' => variable_get('preprocess_css', FALSE) && $is_writable,
    '#disabled' => !$is_writable,
    '#options' => array(t('Disabled'), t('Enabled')),
    '#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."),
  );

760
761
  $form['#submit'][] = 'system_settings_form_submit';
  $form['#submit'][] = 'drupal_clear_css_cache';
Dries's avatar
   
Dries committed
762

763
  return system_settings_form($form);
Dries's avatar
Dries committed
764
}
Dries's avatar
   
Dries committed
765

Dries's avatar
Dries committed
766
function system_file_system_settings() {
767

Dries's avatar
Dries committed
768
  $form['file_directory_path'] = array(
769
770
771
772
    '#type' => 'textfield',
    '#title' => t('File system path'),
    '#default_value' => file_directory_path(),
    '#maxlength' => 255,
773
    '#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.'),
774
    '#after_build' => array('system_check_directory'),
775
776
  );

Dries's avatar
Dries committed
777
  $form['file_directory_temp'] = array(
778
779
780
781
782
    '#type' => 'textfield',
    '#title' => t('Temporary directory'),
    '#default_value' => file_directory_temp(),
    '#maxlength' => 255,
    '#description' => t('Location where uploaded files will be kept during previews. Relative paths will be resolved relative to the Drupal installation directory.'),
783
    '#after_build' => array('system_check_directory'),
784
785
  );

Dries's avatar
Dries committed
786
787
788
789
  $form['file_downloads'] = array(
    '#type' => 'radios',
    '#title' => t('Download method'),
    '#default_value' => variable_get('file_downloads', FILE_DOWNLOADS_PUBLIC),
790
    '#options' => array(FILE_DOWNLOADS_PUBLIC => t('Public - files are available using HTTP directly.'), FILE_DOWNLOADS_PRIVATE => t('Private - files are transferred by Drupal.')),
791
    '#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.')
792
  );
Dries's avatar
   
Dries committed
793

794
  return system_settings_form($form);
Dries's avatar
Dries committed
795
796
797
}

function system_image_toolkit_settings() {
798
799
  $toolkits_available = image_get_available_toolkits();
  if (count($toolkits_available) > 1) {
Dries's avatar
Dries committed
800
801
802
803
804
    $form['image_toolkit'] = array(
      '#type' => 'radios',
      '#title' => t('Select an image processing toolkit'),
      '#default_value' => variable_get('image_toolkit', image_get_toolkit()),
      '#options' => $toolkits_available
805
    );
806
  }
Dries's avatar
Dries committed
807
  else {
808
    $form['image_toolkit'] = array('#value' => '<p>'. t("No image toolkits found. Drupal will use PHP's built-in GD library for image handling.") .'</p>');
Dries's avatar
Dries committed
809
  }
810
811
  $form['image_toolkit_settings'] = image_toolkit_invoke('settings');
  return system_settings_form($form);
Dries's avatar
Dries committed
812
813
814
}

function system_rss_feeds_settings() {
815

Dries's avatar
Dries committed
816
817
818
819
  $form['feed_default_items'] = array(
    '#type' => 'select',
    '#title' => t('Number of items per feed'),
    '#default_value' => variable_get('feed_default_items', 10),
820
821
    '#options' => drupal_map_assoc(array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20, 25, 30)),
    '#description' => t('The default number of items to include in a feed.')
822
  );
Dries's avatar
Dries committed
823
824
825
  $form['feed_item_length'] = array(
    '#type' => 'select',
    '#title' => t('Display of XML feed items'),
Dries's avatar
Dries committed
826
    '#default_value' => variable_get('feed_item_length', 'teaser'),
827
828
    '#options' => array('title' => t('Titles only'), 'teaser' => t('Titles plus teaser'), 'fulltext' => t('Full text')),
    '#description' => t('Global setting for the length of XML feed items that are output by default.')
829
  );
830

831
  return system_settings_form($form);
Dries's avatar
Dries committed
832
833
834
}

function system_date_time_settings() {
835
836
837
838
839
840
841
  drupal_add_js(drupal_get_path('module', 'system') .'/system.js', 'module');
  drupal_add_js(array('dateTime' => array('lookup' => url('admin/settings/date-time/lookup'))), 'setting');
  drupal_add_js('
// Global Killswitch
if (Drupal.jsEnabled) {
  $(document).ready(Drupal.dateTimeAutoAttach);
}', 'inline');
842
  // Date settings:
Steven Wittens's avatar
Steven Wittens committed
843
  $zones = _system_zonelist();
844

845
  // Date settings: possible date formats
846
  $date_short = array('Y-m-d H:i', 'm/d/Y - H:i', 'd/m/Y - H:i', 'Y/m/d - H:i',
847
           'd.m.Y - H:i', 'm/d/Y - g:ia', 'd/m/Y - g:ia', 'Y/m/d - g:ia',
Dries's avatar
   
Dries committed
848
849
           'M j Y - H:i', 'j M Y - H:i', 'Y M j - H:i',
           'M j Y - g:ia', 'j M Y - g:ia', 'Y M j - g:ia');
850
  $date_medium = array('D, Y-m-d H:i', 'D, m/d/Y - H:i', 'D, d/m/Y - H:i',
Dries's avatar
   
Dries committed
851
          'D, Y/m/d - H:i', 'F j, Y - H:i', 'j F, Y - H:i', 'Y, F j - H:i',
Dries's avatar
   
Dries committed
852
          'D, m/d/Y - g:ia', 'D, d/m/Y - g:ia', 'D, Y/m/d - g:ia',
853
          'F j, Y - g:ia', 'j F Y - g:ia', 'Y, F j - g:ia', 'j. F Y - G:i');
854
  $date_long = array('l, F j, Y - H:i', 'l, j F, Y - H:i', 'l, Y,  F j - H:i',
855
        'l, F j, Y - g:ia', 'l, j F Y - g:ia', 'l, Y,  F j - g:ia', 'l, j. F Y - G:i');
Dries's avatar
   
Dries committed
856

857
  // Date settings: construct choices for user
858
859
  foreach ($date_short as $f) {
    $date_short_choices[$f] = format_date(time(), 'custom', $f);
Dries's avatar
   
Dries committed
860
  }
861
862
  foreach ($date_medium as $f) {
    $date_medium_choices[$f] = format_date(time(), 'custom', $f);
Dries's avatar
   
Dries committed
863
  }
864
865
  foreach ($date_long as $f) {
    $date_long_choices[$f] = format_date(time(), 'custom', $f);
Dries's avatar
   
Dries committed
866
867
  }

868
869
  $date_long_choices['custom'] = $date_medium_choices['custom'] = $date_short_choices['custom'] = t('Custom format');

870
871
872
873
874
875
  $form['locale'] = array(
    '#type' => 'fieldset',
    '#title' => t('Locale settings'),
  );

  $form['locale']['date_default_timezone'] = array(
Dries's avatar
Dries committed
876
877
878
879
880
    '#type' => 'select',
    '#title' => t('Default time zone'),
    '#default_value' => variable_get('date_default_timezone', 0),
    '#options' => $zones,
    '#description' => t('Select the default site time zone.')
881
882
  );

883
  $form['locale']['configurable_timezones'] = array(
Dries's avatar
Dries committed
884
    '#type' => 'radios',
885
    '#title' => t('User-configurable time zones'),
Dries's avatar
Dries committed
886
887
    '#default_value' => variable_get('configurable_timezones', 1),
    '#options' => array(t('Disabled'), t('Enabled')),
888
889
890
891
892
893
894
895
896
897
898
899
900
901
    '#description' => t('When enabled, users can set their own time zone and dates will be displayed accordingly.')
  );

  $form['locale']['date_first_day'] = array(
    '#type' => 'select',
    '#title' => t('First day of week'),
    '#default_value' => variable_get('date_first_day', 0),
    '#options' => array(0 => t('Sunday'), 1 => t('Monday'), 2 => t('Tuesday'), 3 => t('Wednesday'), 4 => t('Thursday'), 5 => t('Friday'), 6 => t('Saturday')),
    '#description' => t('The first day of the week for calendar views.')
  );

  $form['date_formats'] = array(
    '#type' => 'fieldset',
    '#title' => t('Formatting'),
902
903
  );

904
  $date_format_short = variable_get('date_format_short', $date_short[1]);
905
  $form['date_formats']['date_format_short'] = array(
906
907
    '#prefix' => '<div class="date-container"><div>',
    '#suffix' => '</div>',
Dries's avatar
Dries committed
908
909
    '#type' => 'select',
    '#title' => t('Short date format'),
910
911
912
913
    '#attributes' => array('class' => 'date-format'),
    '#default_value' => (isset($date_short_choices[$date_format_short]) ? $date_format_short : 'custom'),
    '#options' => $date_short_choices,
    '#description' => t('The short format of date display.'),
914
915
  );

916
  $default_short_custom = variable_get('date_format_short_custom', (isset($date_short_choices[$date_format_short]) ? $date_format_short : ''));
917
  $form['date_formats']['date_format_short_custom'] = array(
918
919
920
921
922
923
924
925
926
927
    '#prefix' => '<div class="custom-container">',
    '#suffix' => '</div></div>',
    '#type' => 'textfield',
    '#title' => t('Custom short date format'),
    '#attributes' => array('class' => 'custom-format'),
    '#default_value' => $default_short_custom,
    '#description' => t('A user-defined short date format. See the <a href="@url">PHP manual</a> for available options. This format is currently set to display as <span>%date</span>.', array('@url' => 'http://php.net/manual/function.date.php', '%date' => format_date(time(), 'custom', $default_short_custom))),
  );

  $date_format_medium = variable_get('date_format_medium', $date_medium[1]);
928
  $form['date_formats']['date_format_medium'] = array(
929
930
    '#prefix' => '<div class="date-container"><div>',
    '#suffix' => '</div>',
Dries's avatar
Dries committed
931
932
    '#type' => 'select',
    '#title' => t('Medium date format'),
933
934
935
936
937
938
939
    '#attributes' => array('class' => 'date-format'),
    '#default_value' => (isset($date_medium_choices[$date_format_medium]) ? $date_format_medium : 'custom'),
    '#options' => $date_medium_choices,
    '#description' => t('The medium sized date display.'),
  );

  $default_medium_custom = variable_get('date_format_medium_custom', (isset($date_medium_choices[$date_format_medium]) ? $date_format_medium : ''));
940
  $form['date_formats']['date_format_medium_custom'] = array(
941
942
943
944
945
946
947
    '#prefix' => '<div class="custom-container">',
    '#suffix' => '</div></div>',
    '#type' => 'textfield',
    '#title' => t('Custom medium date format'),
    '#attributes' => array('class' => 'custom-format'),
    '#default_value' => $default_medium_custom,
    '#description' => t('A user-defined medium date format. See the <a href="@url">PHP manual</a> for available options. This format is currently set to display as <span>%date</span>.', array('@url' => 'http://php.net/manual/function.date.php', '%date' => format_date(time(), 'custom', $default_medium_custom))),
948
949
  );

950
  $date_format_long = variable_get('date_format_long', $date_long[0]);
951
  $form['date_formats']['date_format_long'] = array(
952
953
    '#prefix' => '<div class="date-container"><div>',
    '#suffix' => '</div>',
Dries's avatar
Dries committed
954
955
    '#type' => 'select',
    '#title' => t('Long date format'),