| [ Index ] |
PHP Cross Reference of Drupal 6 (gatewave) |
[Summary view] [Print] [Text view]
1 <?php 2 // $Id: system.module,v 1.585.2.59 2010/12/15 21:11:23 goba Exp $ 3 4 /** 5 * @file 6 * Configuration system that lets administrators modify the workings of the site. 7 */ 8 9 /** 10 * The current system version. 11 */ 12 define('VERSION', '6.20'); 13 14 /** 15 * Core API compatibility. 16 */ 17 define('DRUPAL_CORE_COMPATIBILITY', '6.x'); 18 19 /** 20 * Minimum supported version of PHP. 21 */ 22 define('DRUPAL_MINIMUM_PHP', '4.3.5'); 23 24 /** 25 * Minimum recommended value of PHP memory_limit. 26 */ 27 define('DRUPAL_MINIMUM_PHP_MEMORY_LIMIT', '16M'); 28 29 /** 30 * Minimum supported version of MySQL, if it is used. 31 */ 32 define('DRUPAL_MINIMUM_MYSQL', '4.1.1'); 33 34 /** 35 * Minimum supported version of PostgreSQL, if it is used. 36 */ 37 define('DRUPAL_MINIMUM_PGSQL', '7.4'); 38 39 /** 40 * Maximum age of temporary files in seconds. 41 */ 42 define('DRUPAL_MAXIMUM_TEMP_FILE_AGE', 21600); 43 44 /** 45 * Implementation of hook_help(). 46 */ 47 function system_help($path, $arg) { 48 global $base_url; 49 50 switch ($path) { 51 case 'admin/help#system': 52 $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>'; 53 $output .= '<p>'. t('The system module provides:') .'</p>'; 54 $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>'; 55 $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>'; 56 $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>'; 57 $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, ping module 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>'; 58 $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 off-line.', 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>'; 59 $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>'; 60 return $output; 61 case 'admin': 62 return '<p>'. t('Welcome to the administration section. Here you may control how your site functions.') .'</p>'; 63 case 'admin/by-module': 64 return '<p>'. t('This page shows you all available administration tasks for each module.') .'</p>'; 65 case 'admin/build/themes': 66 $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>'; 67 $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>'; 68 return $output; 69 case 'admin/build/themes/settings/'. $arg[4]: 70 $reference = explode('.', $arg[4], 2); 71 $theme = array_pop($reference); 72 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>'; 73 case 'admin/build/themes/settings': 74 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>'; 75 case 'admin/build/modules': 76 $output = '<p>'. t('Modules are plugins that extend Drupal\'s core functionality. Enable modules by selecting the <em>Enabled</em> checkboxes below and clicking the <em>Save configuration</em> button. Once a module is enabled, new <a href="@permissions">permissions</a> may be available. To reduce server load, modules with their <em>Throttle</em> checkbox selected are temporarily disabled when your site becomes extremely busy. (Note that the <em>Throttle</em> checkbox is only available if the Throttle module is enabled.)', array('@permissions' => url('admin/user/permissions'))); 77 if (module_exists('throttle')) { 78 $output .= ' '. t('The auto-throttle functionality must be enabled on the <a href="@throttle">throttle configuration page</a> after having enabled the throttle module.', array('@throttle' => url('admin/settings/throttle'))); 79 } 80 $output .= '</p>'; 81 $output .= '<p>'. t('It is important that <a href="@update-php">update.php</a> is run every time a module is updated to a newer version.', array('@update-php' => $base_url .'/update.php')) .'</p>'; 82 $output .= '<p>'. t('You can find all administration tasks belonging to a particular module on the <a href="@by-module">administration by module page</a>.', array('@by-module' => url('admin/by-module'))) .'</p>'; 83 $output .= '<p>'. t('To extend the functionality of your site, a number of <a href="@modules">contributed modules</a> are available.', array('@modules' => 'http://drupal.org/project/modules')) .'</p>'; 84 $output .= '<p>'. t('To clear all caches, click the button on the <a href="@performance">Performance page</a>.', array('@performance' => url('admin/settings/performance', array('fragment' => 'edit-clear')))) .'</p>'; 85 return $output; 86 case 'admin/build/modules/uninstall': 87 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>'; 88 case 'admin/build/block/configure': 89 if ($arg[4] == 'system' && $arg[5] == 0) { 90 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>'; 91 } 92 break; 93 case 'admin/settings/actions': 94 case 'admin/settings/actions/manage': 95 $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>'; 96 $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>'; 97 if (module_exists('trigger')) { 98 $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>'; 99 } 100 return $output; 101 case 'admin/settings/actions/configure': 102 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").'); 103 case 'admin/reports/status': 104 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>'; 105 } 106 } 107 108 /** 109 * Implementation of hook_theme(). 110 */ 111 function system_theme() { 112 return array_merge(drupal_common_theme(), array( 113 'system_theme_select_form' => array( 114 'arguments' => array('form' => NULL), 115 'file' => 'system.admin.inc', 116 ), 117 'system_themes_form' => array( 118 'arguments' => array('form' => NULL), 119 'file' => 'system.admin.inc', 120 ), 121 'system_modules' => array( 122 'arguments' => array('form' => NULL), 123 'file' => 'system.admin.inc', 124 ), 125 'system_modules_uninstall' => array( 126 'arguments' => array('form' => NULL), 127 'file' => 'system.admin.inc', 128 ), 129 'status_report' => array( 130 'arguments' => array('requirements' => NULL), 131 'file' => 'system.admin.inc', 132 ), 133 'admin_page' => array( 134 'arguments' => array('blocks' => NULL), 135 'file' => 'system.admin.inc', 136 ), 137 'admin_block' => array( 138 'arguments' => array('block' => NULL), 139 'file' => 'system.admin.inc', 140 ), 141 'admin_block_content' => array( 142 'arguments' => array('content' => NULL), 143 'file' => 'system.admin.inc', 144 ), 145 'system_admin_by_module' => array( 146 'arguments' => array('menu_items' => NULL), 147 'file' => 'system.admin.inc', 148 ), 149 'system_powered_by' => array( 150 'arguments' => array('image_path' => NULL), 151 ), 152 )); 153 } 154 155 /** 156 * Implementation of hook_perm(). 157 */ 158 function system_perm() { 159 return array('administer site configuration', 'access administration pages', 'administer actions', 'access site reports', 'select different theme', 'administer files'); 160 } 161 162 /** 163 * Implementation of hook_elements(). 164 */ 165 function system_elements() { 166 // Top level form 167 $type['form'] = array('#method' => 'post', '#action' => request_uri()); 168 169 // Inputs 170 $type['submit'] = array('#input' => TRUE, '#name' => 'op', '#button_type' => 'submit', '#executes_submit_callback' => TRUE, '#process' => array('form_expand_ahah')); 171 $type['button'] = array('#input' => TRUE, '#name' => 'op', '#button_type' => 'submit', '#executes_submit_callback' => FALSE, '#process' => array('form_expand_ahah')); 172 $type['image_button'] = array('#input' => TRUE, '#button_type' => 'submit', '#executes_submit_callback' => TRUE, '#process' => array('form_expand_ahah'), '#return_value' => TRUE, '#has_garbage_value' => TRUE, '#src' => NULL); 173 $type['textfield'] = array('#input' => TRUE, '#size' => 60, '#maxlength' => 128, '#autocomplete_path' => FALSE, '#process' => array('form_expand_ahah')); 174 $type['password'] = array('#input' => TRUE, '#size' => 60, '#maxlength' => 128, '#process' => array('form_expand_ahah')); 175 $type['password_confirm'] = array('#input' => TRUE, '#process' => array('expand_password_confirm')); 176 $type['textarea'] = array('#input' => TRUE, '#cols' => 60, '#rows' => 5, '#resizable' => TRUE, '#process' => array('form_expand_ahah')); 177 $type['radios'] = array('#input' => TRUE, '#process' => array('expand_radios')); 178 $type['radio'] = array('#input' => TRUE, '#default_value' => NULL, '#process' => array('form_expand_ahah')); 179 $type['checkboxes'] = array('#input' => TRUE, '#process' => array('expand_checkboxes'), '#tree' => TRUE); 180 $type['checkbox'] = array('#input' => TRUE, '#return_value' => 1, '#process' => array('form_expand_ahah')); 181 $type['select'] = array('#input' => TRUE, '#size' => 0, '#multiple' => FALSE, '#process' => array('form_expand_ahah')); 182 $type['weight'] = array('#input' => TRUE, '#delta' => 10, '#default_value' => 0, '#process' => array('process_weight', 'form_expand_ahah')); 183 $type['date'] = array('#input' => TRUE, '#process' => array('expand_date'), '#element_validate' => array('date_validate')); 184 $type['file'] = array('#input' => TRUE, '#size' => 60); 185 186 // Form structure 187 $type['item'] = array('#value' => ''); 188 $type['hidden'] = array('#input' => TRUE, '#process' => array('form_expand_ahah')); 189 $type['value'] = array('#input' => TRUE); 190 $type['markup'] = array('#prefix' => '', '#suffix' => ''); 191 $type['fieldset'] = array('#collapsible' => FALSE, '#collapsed' => FALSE, '#value' => NULL, '#process' => array('form_expand_ahah')); 192 $type['token'] = array('#input' => TRUE); 193 return $type; 194 } 195 196 /** 197 * Implementation of hook_menu(). 198 */ 199 function system_menu() { 200 $items['system/files'] = array( 201 'title' => 'File download', 202 'page callback' => 'file_download', 203 'access callback' => TRUE, 204 'type' => MENU_CALLBACK, 205 ); 206 $items['admin'] = array( 207 'title' => 'Administer', 208 'access arguments' => array('access administration pages'), 209 'page callback' => 'system_main_admin_page', 210 'weight' => 9, 211 'file' => 'system.admin.inc', 212 ); 213 $items['admin/compact'] = array( 214 'title' => 'Compact mode', 215 'page callback' => 'system_admin_compact_page', 216 'access arguments' => array('access administration pages'), 217 'type' => MENU_CALLBACK, 218 'file' => 'system.admin.inc', 219 ); 220 $items['admin/by-task'] = array( 221 'title' => 'By task', 222 'page callback' => 'system_main_admin_page', 223 'access arguments' => array('access administration pages'), 224 'file' => 'system.admin.inc', 225 'type' => MENU_DEFAULT_LOCAL_TASK, 226 ); 227 $items['admin/by-module'] = array( 228 'title' => 'By module', 229 'page callback' => 'system_admin_by_module', 230 'access arguments' => array('access administration pages'), 231 'file' => 'system.admin.inc', 232 'type' => MENU_LOCAL_TASK, 233 'weight' => 2, 234 ); 235 $items['admin/content'] = array( 236 'title' => 'Content management', 237 'description' => "Manage your site's content.", 238 'position' => 'left', 239 'weight' => -10, 240 'page callback' => 'system_admin_menu_block_page', 241 'access arguments' => array('access administration pages'), 242 'file' => 'system.admin.inc', 243 ); 244 245 // menu items that are basically just menu blocks 246 $items['admin/settings'] = array( 247 'title' => 'Site configuration', 248 'description' => 'Adjust basic site configuration options.', 249 'position' => 'right', 250 'weight' => -5, 251 'page callback' => 'system_settings_overview', 252 'access arguments' => array('access administration pages'), 253 'file' => 'system.admin.inc', 254 ); 255 $items['admin/build'] = array( 256 'title' => 'Site building', 257 'description' => 'Control how your site looks and feels.', 258 'position' => 'right', 259 'weight' => -10, 260 'page callback' => 'system_admin_menu_block_page', 261 'access arguments' => array('access administration pages'), 262 'file' => 'system.admin.inc', 263 ); 264 $items['admin/settings/admin'] = array( 265 'title' => 'Administration theme', 266 'description' => 'Settings for how your administrative pages should look.', 267 'position' => 'left', 268 'page callback' => 'drupal_get_form', 269 'page arguments' => array('system_admin_theme_settings'), 270 'access arguments' => array('administer site configuration'), 271 'block callback' => 'system_admin_theme_settings', 272 'file' => 'system.admin.inc', 273 ); 274 // Themes: 275 $items['admin/build/themes'] = array( 276 'title' => 'Themes', 277 'description' => 'Change which theme your site uses or allows users to set.', 278 'page callback' => 'drupal_get_form', 279 'page arguments' => array('system_themes_form', NULL), 280 'access arguments' => array('administer site configuration'), 281 'file' => 'system.admin.inc', 282 ); 283 $items['admin/build/themes/select'] = array( 284 'title' => 'List', 285 'description' => 'Select the default theme.', 286 'type' => MENU_DEFAULT_LOCAL_TASK, 287 'weight' => -1, 288 ); 289 $items['admin/build/themes/settings'] = array( 290 'title' => 'Configure', 291 'page arguments' => array('system_theme_settings'), 292 'access arguments' => array('administer site configuration'), 293 'type' => MENU_LOCAL_TASK, 294 ); 295 // Theme configuration subtabs 296 $items['admin/build/themes/settings/global'] = array( 297 'title' => 'Global settings', 298 'type' => MENU_DEFAULT_LOCAL_TASK, 299 'weight' => -1, 300 ); 301 302 foreach (list_themes() as $theme) { 303 $items['admin/build/themes/settings/'. $theme->name] = array( 304 'title' => $theme->info['name'], 305 'page arguments' => array('system_theme_settings', $theme->name), 306 'type' => MENU_LOCAL_TASK, 307 'access callback' => '_system_themes_access', 308 'access arguments' => array($theme), 309 ); 310 } 311 312 // Modules: 313 $items['admin/build/modules'] = array( 314 'title' => 'Modules', 315 'description' => 'Enable or disable add-on modules for your site.', 316 'page callback' => 'drupal_get_form', 317 'page arguments' => array('system_modules'), 318 'access arguments' => array('administer site configuration'), 319 'file' => 'system.admin.inc', 320 ); 321 $items['admin/build/modules/list'] = array( 322 'title' => 'List', 323 'type' => MENU_DEFAULT_LOCAL_TASK, 324 ); 325 $items['admin/build/modules/list/confirm'] = array( 326 'title' => 'List', 327 'access arguments' => array('administer site configuration'), 328 'type' => MENU_CALLBACK, 329 ); 330 $items['admin/build/modules/uninstall'] = array( 331 'title' => 'Uninstall', 332 'page arguments' => array('system_modules_uninstall'), 333 'access arguments' => array('administer site configuration'), 334 'type' => MENU_LOCAL_TASK, 335 ); 336 $items['admin/build/modules/uninstall/confirm'] = array( 337 'title' => 'Uninstall', 338 'access arguments' => array('administer site configuration'), 339 'type' => MENU_CALLBACK, 340 ); 341 342 // Actions: 343 $items['admin/settings/actions'] = array( 344 'title' => 'Actions', 345 'description' => 'Manage the actions defined for your site.', 346 'access arguments' => array('administer actions'), 347 'page callback' => 'system_actions_manage' 348 ); 349 $items['admin/settings/actions/manage'] = array( 350 'title' => 'Manage actions', 351 'description' => 'Manage the actions defined for your site.', 352 'page callback' => 'system_actions_manage', 353 'type' => MENU_DEFAULT_LOCAL_TASK, 354 'weight' => -2, 355 ); 356 $items['admin/settings/actions/configure'] = array( 357 'title' => 'Configure an advanced action', 358 'page callback' => 'drupal_get_form', 359 'page arguments' => array('system_actions_configure'), 360 'access arguments' => array('administer actions'), 361 'type' => MENU_CALLBACK, 362 ); 363 $items['admin/settings/actions/delete/%actions'] = array( 364 'title' => 'Delete action', 365 'description' => 'Delete an action.', 366 'page callback' => 'drupal_get_form', 367 'page arguments' => array('system_actions_delete_form', 4), 368 'access arguments' => array('administer actions'), 369 'type' => MENU_CALLBACK, 370 ); 371 $items['admin/settings/actions/orphan'] = array( 372 'title' => 'Remove orphans', 373 'page callback' => 'system_actions_remove_orphans', 374 'access arguments' => array('administer actions'), 375 'type' => MENU_CALLBACK, 376 ); 377 378 // Settings: 379 $items['admin/settings/site-information'] = array( 380 'title' => 'Site information', 381 'description' => 'Change basic site information, such as the site name, slogan, e-mail address, mission, front page and more.', 382 'page callback' => 'drupal_get_form', 383 'page arguments' => array('system_site_information_settings'), 384 'access arguments' => array('administer site configuration'), 385 'file' => 'system.admin.inc', 386 ); 387 $items['admin/settings/error-reporting'] = array( 388 'title' => 'Error reporting', 389 'description' => 'Control how Drupal deals with errors including 403/404 errors as well as PHP error reporting.', 390 'page callback' => 'drupal_get_form', 391 'page arguments' => array('system_error_reporting_settings'), 392 'access arguments' => array('administer site configuration'), 393 'file' => 'system.admin.inc', 394 ); 395 $items['admin/settings/logging'] = array( 396 'title' => 'Logging and alerts', 397 'description' => "Settings for logging and alerts modules. Various modules can route Drupal's system events to different destination, such as syslog, database, email, ...etc.", 398 'page callback' => 'system_logging_overview', 399 'access arguments' => array('administer site configuration'), 400 'file' => 'system.admin.inc', 401 ); 402 $items['admin/settings/performance'] = array( 403 'title' => 'Performance', 404 'description' => 'Enable or disable page caching for anonymous users and set CSS and JS bandwidth optimization options.', 405 'page callback' => 'drupal_get_form', 406 'page arguments' => array('system_performance_settings'), 407 'access arguments' => array('administer site configuration'), 408 'file' => 'system.admin.inc', 409 ); 410 $items['admin/settings/file-system'] = array( 411 'title' => 'File system', 412 'description' => 'Tell Drupal where to store uploaded files and how they are accessed.', 413 'page callback' => 'drupal_get_form', 414 'page arguments' => array('system_file_system_settings'), 415 'access arguments' => array('administer site configuration'), 416 'file' => 'system.admin.inc', 417 ); 418 $items['admin/settings/image-toolkit'] = array( 419 'title' => 'Image toolkit', 420 'description' => 'Choose which image toolkit to use if you have installed optional toolkits.', 421 'page callback' => 'drupal_get_form', 422 'page arguments' => array('system_image_toolkit_settings'), 423 'access arguments' => array('administer site configuration'), 424 'file' => 'system.admin.inc', 425 ); 426 $items['admin/content/rss-publishing'] = array( 427 'title' => 'RSS publishing', 428 'description' => 'Configure the number of items per feed and whether feeds should be titles/teasers/full-text.', 429 'page callback' => 'drupal_get_form', 430 'page arguments' => array('system_rss_feeds_settings'), 431 'access arguments' => array('administer site configuration'), 432 'file' => 'system.admin.inc', 433 ); 434 $items['admin/settings/date-time'] = array( 435 'title' => 'Date and time', 436 'description' => "Settings for how Drupal displays date and time, as well as the system's default timezone.", 437 'page callback' => 'drupal_get_form', 438 'page arguments' => array('system_date_time_settings'), 439 'access arguments' => array('administer site configuration'), 440 'file' => 'system.admin.inc', 441 ); 442 $items['admin/settings/date-time/lookup'] = array( 443 'title' => 'Date and time lookup', 444 'type' => MENU_CALLBACK, 445 'page callback' => 'system_date_time_lookup', 446 'access arguments' => array('administer site configuration'), 447 'file' => 'system.admin.inc', 448 ); 449 $items['admin/settings/site-maintenance'] = array( 450 'title' => 'Site maintenance', 451 'description' => 'Take the site off-line for maintenance or bring it back online.', 452 'page callback' => 'drupal_get_form', 453 'page arguments' => array('system_site_maintenance_settings'), 454 'access arguments' => array('administer site configuration'), 455 'file' => 'system.admin.inc', 456 ); 457 $items['admin/settings/clean-urls'] = array( 458 'title' => 'Clean URLs', 459 'description' => 'Enable or disable clean URLs for your site.', 460 'page callback' => 'drupal_get_form', 461 'page arguments' => array('system_clean_url_settings'), 462 'access arguments' => array('administer site configuration'), 463 'file' => 'system.admin.inc', 464 ); 465 $items['admin/settings/clean-urls/check'] = array( 466 'title' => 'Clean URL check', 467 'page callback' => 'drupal_json', 468 'page arguments' => array(array('status' => TRUE)), 469 'access callback' => TRUE, 470 'type' => MENU_CALLBACK, 471 ); 472 473 // Reports: 474 $items['admin/reports'] = array( 475 'title' => 'Reports', 476 'description' => 'View reports from system logs and other status information.', 477 'page callback' => 'system_admin_menu_block_page', 478 'access arguments' => array('access site reports'), 479 'weight' => 5, 480 'position' => 'left', 481 'file' => 'system.admin.inc', 482 ); 483 $items['admin/reports/status'] = array( 484 'title' => 'Status report', 485 'description' => "Get a status report about your site's operation and any detected problems.", 486 'page callback' => 'system_status', 487 'weight' => 10, 488 'access arguments' => array('administer site configuration'), 489 'file' => 'system.admin.inc', 490 ); 491 $items['admin/reports/status/run-cron'] = array( 492 'title' => 'Run cron', 493 'page callback' => 'system_run_cron', 494 'access arguments' => array('administer site configuration'), 495 'type' => MENU_CALLBACK, 496 'file' => 'system.admin.inc', 497 ); 498 $items['admin/reports/status/php'] = array( 499 'title' => 'PHP', 500 'page callback' => 'system_php', 501 'access arguments' => array('administer site configuration'), 502 'type' => MENU_CALLBACK, 503 'file' => 'system.admin.inc', 504 ); 505 $items['admin/reports/status/sql'] = array( 506 'title' => 'SQL', 507 'page callback' => 'system_sql', 508 'access arguments' => array('administer site configuration'), 509 'type' => MENU_CALLBACK, 510 'file' => 'system.admin.inc', 511 ); 512 // Default page for batch operations 513 $items['batch'] = array( 514 'page callback' => 'system_batch_page', 515 'access callback' => TRUE, 516 'type' => MENU_CALLBACK, 517 'file' => 'system.admin.inc', 518 ); 519 return $items; 520 } 521 522 /** 523 * Menu item access callback - only admin or enabled themes can be accessed. 524 */ 525 function _system_themes_access($theme) { 526 return user_access('administer site configuration') && ($theme->status || $theme->name == variable_get('admin_theme', '0')); 527 } 528 529 /** 530 * Implementation of hook_init(). 531 */ 532 function system_init() { 533 // Use the administrative theme if the user is looking at a page in the admin/* path. 534 if (arg(0) == 'admin' || (variable_get('node_admin_theme', '0') && arg(0) == 'node' && (arg(1) == 'add' || arg(2) == 'edit'))) { 535 global $custom_theme; 536 $custom_theme = variable_get('admin_theme', '0'); 537 drupal_add_css(drupal_get_path('module', 'system') .'/admin.css', 'module'); 538 } 539 540 // Add the CSS for this module. 541 drupal_add_css(drupal_get_path('module', 'system') .'/defaults.css', 'module'); 542 drupal_add_css(drupal_get_path('module', 'system') .'/system.css', 'module'); 543 drupal_add_css(drupal_get_path('module', 'system') .'/system-menus.css', 'module'); 544 } 545 546 /** 547 * Implementation of hook_user(). 548 * 549 * Allows users to individually set their theme and time zone. 550 */ 551 function system_user($type, $edit, &$user, $category = NULL) { 552 if ($type == 'form' && $category == 'account') { 553 $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); 554 555 if (variable_get('configurable_timezones', 1)) { 556 $zones = _system_zonelist(); 557 $form['timezone'] = array( 558 '#type' => 'fieldset', 559 '#title' => t('Locale settings'), 560 '#weight' => 6, 561 '#collapsible' => TRUE, 562 ); 563 $form['timezone']['timezone'] = array( 564 '#type' => 'select', 565 '#title' => t('Time zone'), 566 '#default_value' => strlen($edit['timezone']) ? $edit['timezone'] : variable_get('date_default_timezone', 0), 567 '#options' => $zones, 568 '#description' => t('Select your current local time. Dates and times throughout this site will be displayed using this time zone.'), 569 ); 570 } 571 572 return $form; 573 } 574 } 575 576 /** 577 * Implementation of hook_block(). 578 * 579 * Generate a block with a promotional link to Drupal.org. 580 */ 581 function system_block($op = 'list', $delta = 0, $edit = NULL) { 582 switch ($op) { 583 case 'list': 584 $blocks[0] = array( 585 'info' => t('Powered by Drupal'), 586 'weight' => '10', 587 // Not worth caching. 588 'cache' => BLOCK_NO_CACHE, 589 ); 590 return $blocks; 591 case 'configure': 592 // Compile a list of fields to show 593 $form['wrapper']['color'] = array( 594 '#type' => 'select', 595 '#title' => t('Badge color'), 596 '#default_value' => variable_get('drupal_badge_color', 'powered-blue'), 597 '#options' => array('powered-black' => t('Black'), 'powered-blue' => t('Blue'), 'powered-gray' => t('Gray')), 598 ); 599 $form['wrapper']['size'] = array( 600 '#type' => 'select', 601 '#title' => t('Badge size'), 602 '#default_value' => variable_get('drupal_badge_size', '80x15'), 603 '#options' => array('80x15' => t('Small'), '88x31' => t('Medium'), '135x42' => t('Large')), 604 ); 605 return $form; 606 case 'save': 607 variable_set('drupal_badge_color', $edit['color']); 608 variable_set('drupal_badge_size', $edit['size']); 609 break; 610 case 'view': 611 $image_path = 'misc/'. variable_get('drupal_badge_color', 'powered-blue') .'-'. variable_get('drupal_badge_size', '80x15') .'.png'; 612 $block['subject'] = NULL; // Don't display a title 613 $block['content'] = theme('system_powered_by', $image_path); 614 return $block; 615 } 616 } 617 618 /** 619 * Provide a single block on the administration overview page. 620 * 621 * @param $item 622 * The menu item to be displayed. 623 */ 624 function system_admin_menu_block($item) { 625 $content = array(); 626 if (!isset($item['mlid'])) { 627 $item += db_fetch_array(db_query("SELECT mlid, menu_name FROM {menu_links} ml WHERE ml.router_path = '%s' AND module = 'system'", $item['path'])); 628 } 629 $result = db_query(" 630 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.* 631 FROM {menu_links} ml 632 LEFT JOIN {menu_router} m ON ml.router_path = m.path 633 WHERE ml.plid = %d AND ml.menu_name = '%s' AND hidden = 0", $item['mlid'], $item['menu_name']); 634 while ($item = db_fetch_array($result)) { 635 _menu_link_translate($item); 636 if (!$item['access']) { 637 continue; 638 } 639 // The link 'description' either derived from the hook_menu 'description' or 640 // entered by the user via menu module is saved as the title attribute. 641 if (!empty($item['localized_options']['attributes']['title'])) { 642 $item['description'] = $item['localized_options']['attributes']['title']; 643 } 644 // Prepare for sorting as in function _menu_tree_check_access(). 645 // The weight is offset so it is always positive, with a uniform 5-digits. 646 $content[(50000 + $item['weight']) .' '. drupal_strtolower($item['title']) .' '. $item['mlid']] = $item; 647 } 648 ksort($content); 649 return $content; 650 } 651 652 /** 653 * Process admin theme form submissions. 654 */ 655 function system_admin_theme_submit($form, &$form_state) { 656 // If we're changing themes, make sure the theme has its blocks initialized. 657 if ($form_state['values']['admin_theme'] && $form_state['values']['admin_theme'] != variable_get('admin_theme', '0')) { 658 $result = db_result(db_query("SELECT COUNT(*) FROM {blocks} WHERE theme = '%s'", $form_state['values']['admin_theme'])); 659 if (!$result) { 660 system_initialize_theme_blocks($form_state['values']['admin_theme']); 661 } 662 } 663 } 664 665 /** 666 * Returns a fieldset containing the theme select form. 667 * 668 * @param $description 669 * description of the fieldset 670 * @param $default_value 671 * default value of theme radios 672 * @param $weight 673 * weight of the fieldset 674 * @return 675 * a form array 676 */ 677 function system_theme_select_form($description = '', $default_value = '', $weight = 0) { 678 if (user_access('select different theme')) { 679 $enabled = array(); 680 $themes = list_themes(); 681 682 foreach ($themes as $theme) { 683 if ($theme->status) { 684 $enabled[] = $theme; 685 } 686 } 687 688 if (count($enabled) > 1) { 689 ksort($enabled); 690 691 $form['themes'] = array( 692 '#type' => 'fieldset', 693 '#title' => t('Theme configuration'), 694 '#description' => $description, 695 '#collapsible' => TRUE, 696 '#theme' => 'system_theme_select_form' 697 ); 698 699 foreach ($enabled as $info) { 700 // For the default theme, revert to an empty string so the user's theme updates when the site theme is changed. 701 $info->key = $info->name == variable_get('theme_default', 'garland') ? '' : $info->name; 702 703 $screenshot = NULL; 704 $theme_key = $info->name; 705 while ($theme_key) { 706 if (file_exists($themes[$theme_key]->info['screenshot'])) { 707 $screenshot = $themes[$theme_key]->info['screenshot']; 708 break; 709 } 710 $theme_key = isset($themes[$theme_key]->info['base theme']) ? $themes[$theme_key]->info['base theme'] : NULL; 711 } 712 713 $screenshot = $screenshot ? theme('image', $screenshot, t('Screenshot for %theme theme', array('%theme' => $info->name)), '', array('class' => 'screenshot'), FALSE) : t('no screenshot'); 714 715 $form['themes'][$info->key]['screenshot'] = array('#value' => $screenshot); 716 $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>' : '')); 717 $options[$info->key] = ''; 718 } 719 720 $form['themes']['theme'] = array('#type' => 'radios', '#options' => $options, '#default_value' => $default_value ? $default_value : ''); 721 $form['#weight'] = $weight; 722 return $form; 723 } 724 } 725 } 726 727 /** 728 * Checks the existence of the directory specified in $form_element. This 729 * function is called from the system_settings form to check both the 730 * file_directory_path and file_directory_temp directories. If validation 731 * fails, the form element is flagged with an error from within the 732 * file_check_directory function. 733 * 734 * @param $form_element 735 * The form element containing the name of the directory to check. 736 */ 737 function system_check_directory($form_element) { 738 file_check_directory($form_element['#value'], FILE_CREATE_DIRECTORY, $form_element['#parents'][0]); 739 return $form_element; 740 } 741 742 /** 743 * Retrieves the current status of an array of files in the system table. 744 * 745 * @param $files 746 * An array of files to check. 747 * @param $type 748 * The type of the files. 749 */ 750 function system_get_files_database(&$files, $type) { 751 // Extract current files from database. 752 $result = db_query("SELECT filename, name, type, status, throttle, schema_version FROM {system} WHERE type = '%s'", $type); 753 while ($file = db_fetch_object($result)) { 754 if (isset($files[$file->name]) && is_object($files[$file->name])) { 755 $file->old_filename = $file->filename; 756 foreach ($file as $key => $value) { 757 if (!isset($files[$file->name]) || !isset($files[$file->name]->$key)) { 758 $files[$file->name]->$key = $value; 759 } 760 } 761 } 762 } 763 } 764 765 /** 766 * Prepare defaults for themes. 767 * 768 * @return 769 * An array of default themes settings. 770 */ 771 function system_theme_default() { 772 return array( 773 'regions' => array( 774 'left' => 'Left sidebar', 775 'right' => 'Right sidebar', 776 'content' => 'Content', 777 'header' => 'Header', 778 'footer' => 'Footer', 779 ), 780 'description' => '', 781 'features' => array( 782 'comment_user_picture', 783 'favicon', 784 'mission', 785 'logo', 786 'name', 787 'node_user_picture', 788 'search', 789 'slogan', 790 'primary_links', 791 'secondary_links', 792 ), 793 'stylesheets' => array( 794 'all' => array('style.css') 795 ), 796 'scripts' => array('script.js'), 797 'screenshot' => 'screenshot.png', 798 'php' => DRUPAL_MINIMUM_PHP, 799 ); 800 } 801 802 /** 803 * Collect data about all currently available themes. 804 * 805 * @return 806 * Array of all available themes and their data. 807 */ 808 function system_theme_data() { 809 // Scan the installation theme .info files and their engines. 810 $themes = _system_theme_data(); 811 812 // Extract current files from database. 813 system_get_files_database($themes, 'theme'); 814 815 db_query("DELETE FROM {system} WHERE type = 'theme'"); 816 817 foreach ($themes as $theme) { 818 if (!isset($theme->owner)) { 819 $theme->owner = ''; 820 } 821 822 db_query("INSERT INTO {system} (name, owner, info, type, filename, status, throttle, bootstrap) VALUES ('%s', '%s', '%s', '%s', '%s', %d, %d, %d)", $theme->name, $theme->owner, serialize($theme->info), 'theme', $theme->filename, isset($theme->status) ? $theme->status : 0, 0, 0); 823 } 824 825 return $themes; 826 } 827 828 /** 829 * Helper function to scan and collect theme .info data and their engines. 830 * 831 * @return 832 * An associative array of themes information. 833 */ 834 function _system_theme_data() { 835 static $themes_info = array(); 836 837 if (empty($themes_info)) { 838 // Find themes 839 $themes = drupal_system_listing('\.info$', 'themes'); 840 // Find theme engines 841 $engines = drupal_system_listing('\.engine$', 'themes/engines'); 842 843 $defaults = system_theme_default(); 844 845 $sub_themes = array(); 846 // Read info files for each theme 847 foreach ($themes as $key => $theme) { 848 $themes[$key]->info = drupal_parse_info_file($theme->filename) + $defaults; 849 850 // Invoke hook_system_info_alter() to give installed modules a chance to 851 // modify the data in the .info files if necessary. 852 drupal_alter('system_info', $themes[$key]->info, $themes[$key]); 853 854 if (!empty($themes[$key]->info['base theme'])) { 855 $sub_themes[] = $key; 856 } 857 if (empty($themes[$key]->info['engine'])) { 858 $filename = dirname($themes[$key]->filename) .'/'. $themes[$key]->name .'.theme'; 859 if (file_exists($filename)) { 860 $themes[$key]->owner = $filename; 861 $themes[$key]->prefix = $key; 862 } 863 } 864 else { 865 $engine = $themes[$key]->info['engine']; 866 if (isset($engines[$engine])) { 867 $themes[$key]->owner = $engines[$engine]->filename; 868 $themes[$key]->prefix = $engines[$engine]->name; 869 $themes[$key]->template = TRUE; 870 } 871 } 872 873 // Give the stylesheets proper path information. 874 $pathed_stylesheets = array(); 875 foreach ($themes[$key]->info['stylesheets'] as $media => $stylesheets) { 876 foreach ($stylesheets as $stylesheet) { 877 $pathed_stylesheets[$media][$stylesheet] = dirname($themes[$key]->filename) .'/'. $stylesheet; 878 } 879 } 880 $themes[$key]->info['stylesheets'] = $pathed_stylesheets; 881 882 // Give the scripts proper path information. 883 $scripts = array(); 884 foreach ($themes[$key]->info['scripts'] as $script) { 885 $scripts[$script] = dirname($themes[$key]->filename) .'/'. $script; 886 } 887 $themes[$key]->info['scripts'] = $scripts; 888 // Give the screenshot proper path information. 889 if (!empty($themes[$key]->info['screenshot'])) { 890 $themes[$key]->info['screenshot'] = dirname($themes[$key]->filename) .'/'. $themes[$key]->info['screenshot']; 891 } 892 } 893 894 // Now that we've established all our master themes, go back and fill in 895 // data for subthemes. 896 foreach ($sub_themes as $key) { 897 $themes[$key]->base_themes = system_find_base_themes($themes, $key); 898 // Don't proceed if there was a problem with the root base theme. 899 if (!current($themes[$key]->base_themes)) { 900 continue; 901 } 902 $base_key = key($themes[$key]->base_themes); 903 foreach (array_keys($themes[$key]->base_themes) as $base_theme) { 904 $themes[$base_theme]->sub_themes[$key] = $themes[$key]->info['name']; 905 } 906 // Copy the 'owner' and 'engine' over if the top level theme uses a 907 // theme engine. 908 if (isset($themes[$base_key]->owner)) { 909 if (isset($themes[$base_key]->info['engine'])) { 910 $themes[$key]->info['engine'] = $themes[$base_key]->info['engine']; 911 $themes[$key]->owner = $themes[$base_key]->owner; 912 $themes[$key]->prefix = $themes[$base_key]->prefix; 913 } 914 else { 915 $themes[$key]->prefix = $key; 916 } 917 } 918 } 919 920 $themes_info = $themes; 921 } 922 923 return $themes_info; 924 } 925 926 /** 927 * Find all the base themes for the specified theme. 928 * 929 * Themes can inherit templates and function implementations from earlier themes. 930 * 931 * @param $themes 932 * An array of available themes. 933 * @param $key 934 * The name of the theme whose base we are looking for. 935 * @param $used_keys 936 * A recursion parameter preventing endless loops. 937 * @return 938 * Returns an array of all of the theme's ancestors; the first element's value 939 * will be NULL if an error occurred. 940 */ 941 function system_find_base_themes($themes, $key, $used_keys = array()) { 942 $base_key = $themes[$key]->info['base theme']; 943 // Does the base theme exist? 944 if (!isset($themes[$base_key])) { 945 return array($base_key => NULL); 946 } 947 948 $current_base_theme = array($base_key => $themes[$base_key]->info['name']); 949 950 // Is the base theme itself a child of another theme? 951 if (isset($themes[$base_key]->info['base theme'])) { 952 // Do we already know the base themes of this theme? 953 if (isset($themes[$base_key]->base_themes)) { 954 return $themes[$base_key]->base_themes + $current_base_theme; 955 } 956 // Prevent loops. 957 if (!empty($used_keys[$base_key])) { 958 return array($base_key => NULL); 959 } 960 $used_keys[$base_key] = TRUE; 961 return system_find_base_themes($themes, $base_key, $used_keys) + $current_base_theme; 962 } 963 // If we get here, then this is our parent theme. 964 return $current_base_theme; 965 } 966 967 /** 968 * This function has been deprecated in favor of system_find_base_themes(). 969 * 970 * Recursive function to find the top level base theme. Themes can inherit 971 * templates and function implementations from earlier themes. 972 * 973 * @param $themes 974 * An array of available themes. 975 * @param $key 976 * The name of the theme whose base we are looking for. 977 * @param $used_keys 978 * A recursion parameter preventing endless loops. 979 * @return 980 * Returns the top level parent that has no ancestor or returns NULL if there isn't a valid parent. 981 */ 982 function system_find_base_theme($themes, $key, $used_keys = array()) { 983 $base_key = $themes[$key]->info['base theme']; 984 // Does the base theme exist? 985 if (!isset($themes[$base_key])) { 986 return NULL; 987 } 988 989 // Is the base theme itself a child of another theme? 990 if (isset($themes[$base_key]->info['base theme'])) { 991 // Prevent loops. 992 if (!empty($used_keys[$base_key])) { 993 return NULL; 994 } 995 $used_keys[$base_key] = TRUE; 996 return system_find_base_theme($themes, $base_key, $used_keys); 997 } 998 // If we get here, then this is our parent theme. 999 return $base_key; 1000 } 1001 1002 /** 1003 * Get a list of available regions from a specified theme. 1004 * 1005 * @param $theme_key 1006 * The name of a theme. 1007 * @return 1008 * An array of regions in the form $region['name'] = 'description'. 1009 */ 1010 function system_region_list($theme_key) { 1011 static $list = array(); 1012 1013 if (!array_key_exists($theme_key, $list)) { 1014 $info = unserialize(db_result(db_query("SELECT info FROM {system} WHERE type = 'theme' AND name = '%s'", $theme_key))); 1015 $list[$theme_key] = array_map('t', $info['regions']); 1016 } 1017 1018 return $list[$theme_key]; 1019 } 1020 1021 /** 1022 * Get the name of the default region for a given theme. 1023 * 1024 * @param $theme 1025 * The name of a theme. 1026 * @return 1027 * A string that is the region name. 1028 */ 1029 function system_default_region($theme) { 1030 $regions = array_keys(system_region_list($theme)); 1031 return isset($regions[0]) ? $regions[0] : ''; 1032 } 1033 1034 /** 1035 * Assign an initial, default set of blocks for a theme. 1036 * 1037 * This function is called the first time a new theme is enabled. The new theme 1038 * gets a copy of the default theme's blocks, with the difference that if a 1039 * particular region isn't available in the new theme, the block is assigned 1040 * to the new theme's default region. 1041 * 1042 * @param $theme 1043 * The name of a theme. 1044 */ 1045 function system_initialize_theme_blocks($theme) { 1046 // Initialize theme's blocks if none already registered. 1047 if (!(db_result(db_query("SELECT COUNT(*) FROM {blocks} WHERE theme = '%s'", $theme)))) { 1048 $default_theme = variable_get('theme_default', 'garland'); 1049 $regions = system_region_list($theme); 1050 $result = db_query("SELECT * FROM {blocks} WHERE theme = '%s'", $default_theme); 1051 while ($block = db_fetch_array($result)) { 1052 // If the region isn't supported by the theme, assign the block to the theme's default region. 1053 if (!array_key_exists($block['region'], $regions)) { 1054 $block['region'] = system_default_region($theme); 1055 } 1056 db_query("INSERT INTO {blocks} (module, delta, theme, status, weight, region, visibility, pages, custom, throttle, cache) VALUES ('%s', '%s', '%s', %d, %d, '%s', %d, '%s', %d, %d, %d)", 1057 $block['module'], $block['delta'], $theme, $block['status'], $block['weight'], $block['region'], $block['visibility'], $block['pages'], $block['custom'], $block['throttle'], $block['cache']); 1058 } 1059 } 1060 } 1061 1062 /** 1063 * Add default buttons to a form and set its prefix. 1064 * 1065 * @ingroup forms 1066 * @see system_settings_form_submit() 1067 * @param $form 1068 * An associative array containing the structure of the form. 1069 * @return 1070 * The form structure. 1071 */ 1072 function system_settings_form($form) { 1073 $form['buttons']['submit'] = array('#type' => 'submit', '#value' => t('Save configuration') ); 1074 $form['buttons']['reset'] = array('#type' => 'submit', '#value' => t('Reset to defaults') ); 1075 1076 if (!empty($_POST) && form_get_errors()) { 1077 drupal_set_message(t('The settings have not been saved because of the errors.'), 'error'); 1078 } 1079 $form['#submit'][] = 'system_settings_form_submit'; 1080 $form['#theme'] = 'system_settings_form'; 1081 return $form; 1082 } 1083 1084 /** 1085 * Execute the system_settings_form. 1086 * 1087 * If you want node type configure style handling of your checkboxes, 1088 * add an array_filter value to your form. 1089 */ 1090 function system_settings_form_submit($form, &$form_state) { 1091 $op = isset($form_state['values']['op']) ? $form_state['values']['op'] : ''; 1092 1093 // Exclude unnecessary elements. 1094 unset($form_state['values']['submit'], $form_state['values']['reset'], $form_state['values']['form_id'], $form_state['values']['op'], $form_state['values']['form_token'], $form_state['values']['form_build_id']); 1095 1096 foreach ($form_state['values'] as $key => $value) { 1097 if ($op == t('Reset to defaults')) { 1098 variable_del($key); 1099 } 1100 else { 1101 if (is_array($value) && isset($form_state['values']['array_filter'])) { 1102 $value = array_keys(array_filter($value)); 1103 } 1104 variable_set($key, $value); 1105 } 1106 } 1107 if ($op == t('Reset to defaults')) { 1108 drupal_set_message(t('The configuration options have been reset to their default values.')); 1109 } 1110 else { 1111 drupal_set_message(t('The configuration options have been saved.')); 1112 } 1113 1114 cache_clear_all(); 1115 drupal_rebuild_theme_registry(); 1116 } 1117 1118 /** 1119 * Helper function to sort requirements. 1120 */ 1121 function _system_sort_requirements($a, $b) { 1122 if (!isset($a['weight'])) { 1123 if (!isset($b['weight'])) { 1124 return strcmp($a['title'], $b['title']); 1125 } 1126 return -$b['weight']; 1127 } 1128 return isset($b['weight']) ? $a['weight'] - $b['weight'] : $a['weight']; 1129 } 1130 1131 /** 1132 * Implementation of hook_node_type(). 1133 * 1134 * Updates theme settings after a node type change. 1135 */ 1136 function system_node_type($op, $info) { 1137 if ($op == 'update' && !empty($info->old_type) && $info->type != $info->old_type) { 1138 $old = 'toggle_node_info_'. $info->old_type; 1139 $new = 'toggle_node_info_'. $info->type; 1140 1141 $theme_settings = variable_get('theme_settings', array()); 1142 if (isset($theme_settings[$old])) { 1143 $theme_settings[$new] = $theme_settings[$old]; 1144 unset($theme_settings[$old]); 1145 variable_set('theme_settings', $theme_settings); 1146 } 1147 } 1148 } 1149 1150 /** 1151 * Generates a form array for a confirmation form. 1152 * 1153 * This function returns a complete form array for confirming an action. The 1154 * form contains a confirm button as well as a cancellation link that allows a 1155 * user to abort the action. 1156 * 1157 * If the submit handler for a form that implements confirm_form() is invoked, 1158 * the user successfully confirmed the action. You should never directly 1159 * inspect $_POST to see if an action was confirmed. 1160 * 1161 * Note - if the parameters $question, $description, $yes, or $no could contain 1162 * any user input (such as node titles or taxonomy terms), it is the 1163 * responsibility of the code calling confirm_form() to sanitize them first with 1164 * a function like check_plain() or filter_xss(). 1165 * 1166 * @param $form 1167 * Additional elements to add to the form; for example, hidden elements. 1168 * @param $question 1169 * The question to ask the user (e.g. "Are you sure you want to delete the 1170 * block <em>foo</em>?"). The page title will be set to this value. 1171 * @param $path 1172 * The page to go to if the user cancels the action. This can be either: 1173 * - A string containing a Drupal path. 1174 * - An associative array with a 'path' key. Additional array values are 1175 * passed as the $options parameter to l(). 1176 * If the 'destination' query parameter is set in the URL when viewing a 1177 * confirmation form, that value will be used instead of $path. 1178 * @param $description 1179 * Additional text to display. Defaults to t('This action cannot be undone.'). 1180 * @param $yes 1181 * A caption for the button that confirms the action (e.g. "Delete", 1182 * "Replace", ...). Defaults to t('Confirm'). 1183 * @param $no 1184 * A caption for the link which cancels the action (e.g. "Cancel"). Defaults 1185 * to t('Cancel'). 1186 * @param $name 1187 * The internal name used to refer to the confirmation item. 1188 * 1189 * @return 1190 * The form array. 1191 */ 1192 function confirm_form($form, $question, $path, $description = NULL, $yes = NULL, $no = NULL, $name = 'confirm') { 1193 $description = isset($description) ? $description : t('This action cannot be undone.'); 1194 1195 // Prepare cancel link 1196 $query = $fragment = NULL; 1197 if (is_array($path)) { 1198 $query = isset($path['query']) ? $path['query'] : NULL; 1199 $fragment = isset($path['fragment']) ? $path['fragment'] : NULL; 1200 $path = isset($path['path']) ? $path['path'] : NULL; 1201 } 1202 $cancel = l($no ? $no : t('Cancel'), $path, array('query' => $query, 'fragment' => $fragment)); 1203 1204 drupal_set_title($question); 1205 1206 // Confirm form fails duplication check, as the form values rarely change -- so skip it. 1207 $form['#skip_duplicate_check'] = TRUE; 1208 1209 $form['#attributes'] = array('class' => 'confirmation'); 1210 $form['description'] = array('#value' => $description); 1211 $form[$name] = array('#type' => 'hidden', '#value' => 1); 1212 1213 $form['actions'] = array('#prefix' => '<div class="container-inline">', '#suffix' => '</div>'); 1214 $form['actions']['submit'] = array('#type' => 'submit', '#value' => $yes ? $yes : t('Confirm')); 1215 $form['actions']['cancel'] = array('#value' => $cancel); 1216 $form['#theme'] = 'confirm_form'; 1217 return $form; 1218 } 1219 1220 /** 1221 * Determine if a user is in compact mode. 1222 */ 1223 function system_admin_compact_mode() { 1224 global $user; 1225 return (isset($user->admin_compact_mode)) ? $user->admin_compact_mode : variable_get('admin_compact_mode', FALSE); 1226 } 1227 1228 /** 1229 * Generate a list of tasks offered by a specified module. 1230 * 1231 * @param $module 1232 * Module name. 1233 * @return 1234 * An array of task links. 1235 */ 1236 function system_get_module_admin_tasks($module) { 1237 static $items; 1238 1239 $admin_access = user_access('administer permissions'); 1240 $admin_tasks = array(); 1241 1242 if (!isset($items)) { 1243 $result = db_query(" 1244 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, ml.* 1245 FROM {menu_links} ml INNER JOIN {menu_router} m ON ml.router_path = m.path WHERE ml.link_path LIKE 'admin/%' AND hidden >= 0 AND module = 'system' AND m.number_parts > 2"); 1246 $items = array(); 1247 while ($item = db_fetch_array($result)) { 1248 _menu_link_translate($item); 1249 if ($item['access']) { 1250 $items[$item['router_path']] = $item; 1251 } 1252 } 1253 } 1254 $admin_tasks = array(); 1255 $admin_task_count = 0; 1256 // Check for permissions. 1257 if (module_hook($module, 'perm') && $admin_access) { 1258 $admin_tasks[-1] = l(t('Configure permissions'), 'admin/user/permissions', array('fragment' => 'module-'. $module)); 1259 } 1260 1261 // Check for menu items that are admin links. 1262 if ($menu = module_invoke($module, 'menu')) { 1263 foreach (array_keys($menu) as $path) { 1264 if (isset($items[$path])) { 1265 $admin_tasks[$items[$path]['title'] . $admin_task_count ++] = l($items[$path]['title'], $path); 1266 } 1267 } 1268 } 1269 1270 return $admin_tasks; 1271 } 1272 1273 /** 1274 * Implementation of hook_cron(). 1275 * 1276 * Remove older rows from flood and batch table. Remove old temporary files. 1277 */ 1278 function system_cron() { 1279 // Cleanup the flood. 1280 db_query('DELETE FROM {flood} WHERE timestamp < %d', time() - 3600); 1281 // Cleanup the batch table. 1282 db_query('DELETE FROM {batch} WHERE timestamp < %d', time() - 864000); 1283 1284 // Remove temporary files that are older than DRUPAL_MAXIMUM_TEMP_FILE_AGE. 1285 $result = db_query('SELECT * FROM {files} WHERE status = %d and timestamp < %d', FILE_STATUS_TEMPORARY, time() - DRUPAL_MAXIMUM_TEMP_FILE_AGE); 1286 while ($file = db_fetch_object($result)) { 1287 if (file_exists($file->filepath)) { 1288 // If files that exist cannot be deleted, continue so the database remains 1289 // consistent. 1290 if (!file_delete($file->filepath)) { 1291 watchdog('file system', 'Could not delete temporary file "%path" during garbage collection', array('%path' => $file->filepath), 'error'); 1292 continue; 1293 } 1294 } 1295 db_query('DELETE FROM {files} WHERE fid = %d', $file->fid); 1296 } 1297 $core = array('cache', 'cache_block', 'cache_filter', 'cache_page', 'cache_form', 'cache_menu'); 1298 $cache_tables = array_merge(module_invoke_all('flush_caches'), $core); 1299 foreach ($cache_tables as $table) { 1300 cache_clear_all(NULL, $table); 1301 } 1302 } 1303 1304 /** 1305 * Implementation of hook_hook_info(). 1306 */ 1307 function system_hook_info() { 1308 return array( 1309 'system' => array( 1310 'cron' => array( 1311 'run' => array( 1312 'runs when' => t('When cron runs'), 1313 ), 1314 ), 1315 ), 1316 ); 1317 } 1318 1319 /** 1320 * Implementation of hook_action_info(). 1321 */ 1322 function system_action_info() { 1323 return array( 1324 'system_message_action' => array( 1325 'type' => 'system', 1326 'description' => t('Display a message to the user'), 1327 'configurable' => TRUE, 1328 'hooks' => array( 1329 'nodeapi' => array('view', 'insert', 'update', 'delete'), 1330 'comment' => array('view', 'insert', 'update', 'delete'), 1331 'user' => array('view', 'insert', 'update', 'delete', 'login'), 1332 'taxonomy' => array('insert', 'update', 'delete'), 1333 ), 1334 ), 1335 'system_send_email_action' => array( 1336 'description' => t('Send e-mail'), 1337 'type' => 'system', 1338 'configurable' => TRUE, 1339 'hooks' => array( 1340 'nodeapi' => array('view', 'insert', 'update', 'delete'), 1341 'comment' => array('view', 'insert', 'update', 'delete'), 1342 'user' => array('view', 'insert', 'update', 'delete', 'login'), 1343 'taxonomy' => array('insert', 'update', 'delete'), 1344 ) 1345 ), 1346 'system_goto_action' => array( 1347 'description' => t('Redirect to URL'), 1348 'type' => 'system', 1349 'configurable' => TRUE, 1350 'hooks' => array( 1351 'nodeapi' => array('view', 'insert', 'update', 'delete'), 1352 'comment' => array('view', 'insert', 'update', 'delete'), 1353 'user' => array('view', 'insert', 'update', 'delete', 'login'), 1354 ) 1355 ) 1356 ); 1357 } 1358 1359 /** 1360 * Menu callback. Display an overview of available and configured actions. 1361 */ 1362 function system_actions_manage() { 1363 $output = ''; 1364 $actions = actions_list(); 1365 actions_synchronize($actions); 1366 $actions_map = actions_actions_map($actions); 1367 $options = array(t('Choose an advanced action')); 1368 $unconfigurable = array(); 1369 1370 foreach ($actions_map as $key => $array) { 1371 if ($array['configurable']) { 1372 $options[$key] = $array['description'] .'...'; 1373 } 1374 else { 1375 $unconfigurable[] = $array; 1376 } 1377 } 1378 1379 $row = array(); 1380 $instances_present = db_fetch_object(db_query("SELECT aid FROM {actions} WHERE parameters <> ''")); 1381 $header = array( 1382 array('data' => t('Action type'), 'field' => 'type'), 1383 array('data' => t('Description'), 'field' => 'description'), 1384 array('data' => $instances_present ? t('Operations') : '', 'colspan' => '2') 1385 ); 1386 $sql = 'SELECT * FROM {actions}'; 1387 $result = pager_query($sql . tablesort_sql($header), 50); 1388 while ($action = db_fetch_object($result)) { 1389 $row[] = array( 1390 array('data' => $action->type), 1391 array('data' => filter_xss_admin($action->description)), 1392 array('data' => $action->parameters ? l(t('configure'), "admin/settings/actions/configure/$action->aid") : ''), 1393 array('data' => $action->parameters ? l(t('delete'), "admin/settings/actions/delete/$action->aid") : '') 1394 ); 1395 } 1396 1397 if ($row) { 1398 $pager = theme('pager', NULL, 50, 0); 1399 if (!empty($pager)) { 1400 $row[] = array(array('data' => $pager, 'colspan' => '3')); 1401 } 1402 $output .= '<h3>'. t('Actions available to Drupal:') .'</h3>'; 1403 $output .= theme('table', $header, $row); 1404 } 1405 1406 if ($actions_map) { 1407 $output .= drupal_get_form('system_actions_manage_form', $options); 1408 } 1409 1410 return $output; 1411 } 1412 1413 /** 1414 * Define the form for the actions overview page. 1415 * 1416 * @see system_actions_manage_form_submit() 1417 * @ingroup forms 1418 * @param $form_state 1419 * An associative array containing the current state of the form; not used. 1420 * @param $options 1421 * An array of configurable actions. 1422 * @return 1423 * Form definition. 1424 */ 1425 function system_actions_manage_form($form_state, $options = array()) { 1426 $form['parent'] = array( 1427 '#type' => 'fieldset', 1428 '#title' => t('Make a new advanced action available'), 1429 '#prefix' => '<div class="container-inline">', 1430 '#suffix' => '</div>', 1431 ); 1432 $form['parent']['action'] = array( 1433 '#type' => 'select', 1434 '#default_value' => '', 1435 '#options' => $options, 1436 '#description' => '', 1437 ); 1438 $form['parent']['buttons']['submit'] = array( 1439 '#type' => 'submit', 1440 '#value' => t('Create'), 1441 ); 1442 return $form; 1443 } 1444 1445 /** 1446 * Process system_actions_manage form submissions. 1447 */ 1448 function system_actions_manage_form_submit($form, &$form_state) { 1449 if ($form_state['values']['action']) { 1450 $form_state['redirect'] = 'admin/settings/actions/configure/'. $form_state['values']['action']; 1451 } 1452 } 1453 1454 /** 1455 * Menu callback. Create the form for configuration of a single action. 1456 * 1457 * We provide the "Description" field. The rest of the form 1458 * is provided by the action. We then provide the Save button. 1459 * Because we are combining unknown form elements with the action 1460 * configuration form, we use actions_ prefix on our elements. 1461 * 1462 * @see system_actions_configure_validate() 1463 * @see system_actions_configure_submit() 1464 * @param $action 1465 * md5 hash of action ID or an integer. If it's an md5 hash, we 1466 * are creating a new instance. If it's an integer, we're editing 1467 * an existing instance. 1468 * @return 1469 * Form definition. 1470 */ 1471 function system_actions_configure($form_state, $action = NULL) { 1472 if ($action === NULL) { 1473 drupal_goto('admin/settings/actions'); 1474 } 1475 1476 $actions_map = actions_actions_map(actions_list()); 1477 $edit = array(); 1478 1479 // Numeric action denotes saved instance of a configurable action; 1480 // else we are creating a new action instance. 1481 if (is_numeric($action)) { 1482 $aid = $action; 1483 // Load stored parameter values from database. 1484 $data = db_fetch_object(db_query("SELECT * FROM {actions} WHERE aid = '%s'", $aid)); 1485 $edit['actions_description'] = $data->description; 1486 $edit['actions_type'] = $data->type; 1487 $function = $data->callback; 1488 $action = md5($data->callback); 1489 $params = unserialize($data->parameters); 1490 if ($params) { 1491 foreach ($params as $name => $val) { 1492 $edit[$name] = $val; 1493 } 1494 } 1495 } 1496 else { 1497 $function = $actions_map[$action]['callback']; 1498 $edit['actions_description'] = $actions_map[$action]['description']; 1499 $edit['actions_type'] = $actions_map[$action]['type']; 1500 } 1501 1502 $form['actions_description'] = array( 1503 '#type' => 'textfield', 1504 '#title' => t('Description'), 1505 '#default_value' => $edit['actions_description'], 1506 '#maxlength' => '255', 1507 '#description' => t('A unique description for this advanced action. This description will be displayed in the interface of modules that integrate with actions, such as Trigger module.'), 1508 '#weight' => -10 1509 ); 1510 $action_form = $function .'_form'; 1511 $form = array_merge($form, $action_form($edit)); 1512 $form['actions_type'] = array( 1513 '#type' => 'value', 1514 '#value' => $edit['actions_type'], 1515 ); 1516 $form['actions_action'] = array( 1517 '#type' => 'hidden', 1518 '#value' => $action, 1519 ); 1520 // $aid is set when configuring an existing action instance. 1521 if (isset($aid)) { 1522 $form['actions_aid'] = array( 1523 '#type' => 'hidden', 1524 '#value' => $aid, 1525 ); 1526 } 1527 $form['actions_configured'] = array( 1528 '#type' => 'hidden', 1529 '#value' => '1', 1530 ); 1531 $form['buttons']['submit'] = array( 1532 '#type' => 'submit', 1533 '#value' => t('Save'), 1534 '#weight' => 13 1535 ); 1536 1537 return $form; 1538 } 1539 1540 /** 1541 * Validate system_actions_configure form submissions. 1542 */ 1543 function system_actions_configure_validate($form, $form_state) { 1544 $function = actions_function_lookup($form_state['values']['actions_action']) .'_validate'; 1545 // Hand off validation to the action. 1546 if (function_exists($function)) { 1547 $function($form, $form_state); 1548 } 1549 } 1550 1551 /** 1552 * Process system_actions_configure form submissions. 1553 */ 1554 function system_actions_configure_submit($form, &$form_state) { 1555 $function = actions_function_lookup($form_state['values']['actions_action']); 1556 $submit_function = $function .'_submit'; 1557 1558 // Action will return keyed array of values to store. 1559 $params = $submit_function($form, $form_state); 1560 $aid = isset($form_state['values']['actions_aid']) ? $form_state['values']['actions_aid'] : NULL; 1561 1562 actions_save($function, $form_state['values']['actions_type'], $params, $form_state['values']['actions_description'], $aid); 1563 drupal_set_message(t('The action has been successfully saved.')); 1564 1565 $form_state['redirect'] = 'admin/settings/actions/manage'; 1566 } 1567 1568 /** 1569 * Create the form for confirmation of deleting an action. 1570 * 1571 * @ingroup forms 1572 * @see system_actions_delete_form_submit() 1573 */ 1574 function system_actions_delete_form($form_state, $action) { 1575 1576 $form['aid'] = array( 1577 '#type' => 'hidden', 1578 '#value' => $action->aid, 1579 ); 1580 return confirm_form($form, 1581 t('Are you sure you want to delete the action %action?', array('%action' => $action->description)), 1582 'admin/settings/actions/manage', 1583 t('This cannot be undone.'), 1584 t('Delete'), t('Cancel') 1585 ); 1586 } 1587 1588 /** 1589 * Process system_actions_delete form submissions. 1590 * 1591 * Post-deletion operations for action deletion. 1592 */ 1593 function system_actions_delete_form_submit($form, &$form_state) { 1594 $aid = $form_state['values']['aid']; 1595 $action = actions_load($aid); 1596 actions_delete($aid); 1597 watchdog('user', 'Deleted action %aid (%action)', array('%aid' => $aid, '%action' => $action->description)); 1598 drupal_set_message(t('Action %action was deleted', array('%action' => $action->description))); 1599 $form_state['redirect'] = 'admin/settings/actions/manage'; 1600 } 1601 1602 /** 1603 * Post-deletion operations for deleting action orphans. 1604 * 1605 * @param $orphaned 1606 * An array of orphaned actions. 1607 */ 1608 function system_action_delete_orphans_post($orphaned) { 1609 foreach ($orphaned as $callback) { 1610 drupal_set_message(t("Deleted orphaned action (%action).", array('%action' => $callback))); 1611 } 1612 } 1613 1614 /** 1615 * Remove actions that are in the database but not supported by any enabled module. 1616 */ 1617 function system_actions_remove_orphans() { 1618 actions_synchronize(actions_list(), TRUE); 1619 drupal_goto('admin/settings/actions/manage'); 1620 } 1621 1622 /** 1623 * Return a form definition so the Send email action can be configured. 1624 * 1625 * @see system_send_email_action_validate() 1626 * @see system_send_email_action_submit() 1627 * @param $context 1628 * Default values (if we are editing an existing action instance). 1629 * @return 1630 * Form definition. 1631 */ 1632 function system_send_email_action_form($context) { 1633 // Set default values for form. 1634 if (!isset($context['recipient'])) { 1635 $context['recipient'] = ''; 1636 } 1637 if (!isset($context['subject'])) { 1638 $context['subject'] = ''; 1639 } 1640 if (!isset($context['message'])) { 1641 $context['message'] = ''; 1642 } 1643 1644 $form['recipient'] = array( 1645 '#type' => 'textfield', 1646 '#title' => t('Recipient'), 1647 '#default_value' => $context['recipient'], 1648 '#maxlength' => '254', 1649 '#description' => t('The email address to which the message should be sent OR enter %author if you would like to send an e-mail to the author of the original post.', array('%author' => '%author')), 1650 ); 1651 $form['subject'] = array( 1652 '#type' => 'textfield', 1653 '#title' => t('Subject'), 1654 '#default_value' => $context['subject'], 1655 '#maxlength' => '254', 1656 '#description' => t('The subject of the message.'), 1657 ); 1658 $form['message'] = array( 1659 '#type' => 'textarea', 1660 '#title' => t('Message'), 1661 '#default_value' => $context['message'], 1662 '#cols' => '80', 1663 '#rows' => '20', 1664 '#description' => t('The message that should be sent. You may include the following variables: %site_name, %username, %node_url, %node_type, %title, %teaser, %body. Not all variables will be available in all contexts.'), 1665 ); 1666 return $form; 1667 } 1668 1669 /** 1670 * Validate system_send_email_action form submissions. 1671 */ 1672 function system_send_email_action_validate($form, $form_state) { 1673 $form_values = $form_state['values']; 1674 // Validate the configuration form. 1675 if (!valid_email_address($form_values['recipient']) && $form_values['recipient'] != '%author') { 1676 // We want the literal %author placeholder to be emphasized in the error message. 1677 form_set_error('recipient', t('Please enter a valid email address or %author.', array('%author' => '%author'))); 1678 } 1679 } 1680 1681 /** 1682 * Process system_send_email_action form submissions. 1683 */ 1684 function system_send_email_action_submit($form, $form_state) { 1685 $form_values = $form_state['values']; 1686 // Process the HTML form to store configuration. The keyed array that 1687 // we return will be serialized to the database. 1688 $params = array( 1689 'recipient' => $form_values['recipient'], 1690 'subject' => $form_values['subject'], 1691 'message' => $form_values['message'], 1692 ); 1693 return $params; 1694 } 1695 1696 /** 1697 * Implementation of a configurable Drupal action. Sends an email. 1698 */ 1699 function system_send_email_action($object, $context) { 1700 global $user; 1701 1702 switch ($context['hook']) { 1703 case 'nodeapi': 1704 // Because this is not an action of type 'node' the node 1705 // will not be passed as $object, but it will still be available 1706 // in $context. 1707 $node = $context['node']; 1708 break; 1709 // The comment hook provides nid, in $context. 1710 case 'comment': 1711 $comment = $context['comment']; 1712 $node = node_load($comment->nid); 1713 break; 1714 case 'user': 1715 // Because this is not an action of type 'user' the user 1716 // object is not passed as $object, but it will still be available 1717 // in $context. 1718 $account = $context['account']; 1719 if (isset($context['node'])) { 1720 $node = $context['node']; 1721 } 1722 elseif ($context['recipient'] == '%author') { 1723 // If we don't have a node, we don't have a node author. 1724 watchdog('error', 'Cannot use %author token in this context.'); 1725 return; 1726 } 1727 break; 1728 default: 1729 // We are being called directly. 1730 $node = $object; 1731 } 1732 1733 $recipient = $context['recipient']; 1734 1735 if (isset($node)) { 1736 if (!isset($account)) { 1737 $account = user_load(array('uid' => $node->uid)); 1738 } 1739 if ($recipient == '%author') { 1740 $recipient = $account->mail; 1741 } 1742 } 1743 1744 if (!isset($account)) { 1745 $account = $user; 1746 1747 } 1748 $language = user_preferred_language($account); 1749 $params = array('account' => $account, 'object' => $object, 'context' => $context); 1750 if (isset($node)) { 1751 $params['node'] = $node; 1752 } 1753 1754 if (drupal_mail('system', 'action_send_email', $recipient, $language, $params)) { 1755 watchdog('action', 'Sent email to %recipient', array('%recipient' => $recipient)); 1756 } 1757 else { 1758 watchdog('error', 'Unable to send email to %recipient', array('%recipient' => $recipient)); 1759 } 1760 } 1761 1762 /** 1763 * Implementation of hook_mail(). 1764 */ 1765 function system_mail($key, &$message, $params) { 1766 $account = $params['account']; 1767 $context = $params['context']; 1768 $variables = array( 1769 '%site_name' => variable_get('site_name', 'Drupal'), 1770 '%username' => $account->name, 1771 ); 1772 if ($context['hook'] == 'taxonomy') { 1773 $object = $params['object']; 1774 $vocabulary = taxonomy_vocabulary_load($object->vid); 1775 $variables += array( 1776 '%term_name' => $object->name, 1777 '%term_description' => $object->description, 1778 '%term_id' => $object->tid, 1779 '%vocabulary_name' => $vocabulary->name, 1780 '%vocabulary_description' => $vocabulary->description, 1781 '%vocabulary_id' => $vocabulary->vid, 1782 ); 1783 } 1784 1785 // Node-based variable translation is only available if we have a node. 1786 if (isset($params['node'])) { 1787 $node = $params['node']; 1788 $variables += array( 1789 '%uid' => $node->uid, 1790 '%node_url' => url('node/'. $node->nid, array('absolute' => TRUE)), 1791 '%node_type' => node_get_types('name', $node), 1792 '%title' => $node->title, 1793 '%teaser' => $node->teaser, 1794 '%body' => $node->body, 1795 ); 1796 } 1797 $subject = strtr($context['subject'], $variables); 1798 $body = strtr(filter_xss_admin($context['message']), $variables); 1799 $message['subject'] .= str_replace(array("\r", "\n"), '', $subject); 1800 $message['body'][] = drupal_html_to_text($body); 1801 } 1802 1803 function system_message_action_form($context) { 1804 $form['message'] = array( 1805 '#type' => 'textarea', 1806 '#title' => t('Message'), 1807 '#default_value' => isset($context['message']) ? $context['message'] : '', 1808 '#required' => TRUE, 1809 '#rows' => '8', 1810 '#description' => t('The message to be displayed to the current user. You may include the following variables: %site_name, %username, %node_url, %node_type, %title, %teaser, %body. Not all variables will be available in all contexts.'), 1811 ); 1812 return $form; 1813 } 1814 1815 function system_message_action_submit($form, $form_state) { 1816 return array('message' => $form_state['values']['message']); 1817 } 1818 1819 /** 1820 * A configurable Drupal action. Sends a message to the current user's screen. 1821 */ 1822 function system_message_action(&$object, $context = array()) { 1823 global $user; 1824 $variables = array( 1825 '%site_name' => variable_get('site_name', 'Drupal'), 1826 '%username' => $user->name ? $user->name : variable_get('anonymous', t('Anonymous')), 1827 ); 1828 1829 // This action can be called in any context, but if placeholders 1830 // are used a node object must be present to be the source 1831 // of substituted text. 1832 switch ($context['hook']) { 1833 case 'nodeapi': 1834 // Because this is not an action of type 'node' the node 1835 // will not be passed as $object, but it will still be available 1836 // in $context. 1837 $node = $context['node']; 1838 break; 1839 // The comment hook also provides the node, in context. 1840 case 'comment': 1841 $comment = $context['comment']; 1842 $node = node_load($comment->nid); 1843 break; 1844 case 'taxonomy': 1845 $vocabulary = taxonomy_vocabulary_load($object->vid); 1846 $variables = array_merge($variables, array( 1847 '%term_name' => check_plain($object->name), 1848 '%term_description' => filter_xss_admin($object->description), 1849 '%term_id' => $object->tid, 1850 '%vocabulary_name' => check_plain($vocabulary->name), 1851 '%vocabulary_description' => filter_xss_admin($vocabulary->description), 1852 '%vocabulary_id' => $vocabulary->vid, 1853 ) 1854 ); 1855 break; 1856 default: 1857 // We are being called directly. 1858 $node = $object; 1859 } 1860 1861 if (isset($node) && is_object($node)) { 1862 $variables = array_merge($variables, array( 1863 '%uid' => $node->uid, 1864 '%node_url' => url('node/'. $node->nid, array('absolute' => TRUE)), 1865 '%node_type' => check_plain(node_get_types('name', $node)), 1866 '%title' => check_plain($node->title), 1867 '%teaser' => check_markup($node->teaser, $node->format, FALSE), 1868 '%body' => check_markup($node->body, $node->format, FALSE), 1869 ) 1870 ); 1871 } 1872 $context['message'] = strtr(filter_xss_admin($context['message']), $variables); 1873 drupal_set_message($context['message']); 1874 } 1875 1876 /** 1877 * Implementation of a configurable Drupal action. Redirect user to a URL. 1878 */ 1879 function system_goto_action_form($context) { 1880 $form['url'] = array( 1881 '#type' => 'textfield', 1882 '#title' => t('URL'), 1883 '#description' => t('The URL to which the user should be redirected. This can be an internal URL like node/1234 or an external URL like http://drupal.org.'), 1884 '#default_value' => isset($context['url']) ? $context['url'] : '', 1885 '#required' => TRUE, 1886 ); 1887 return $form; 1888 } 1889 1890 function system_goto_action_submit($form, $form_state) { 1891 return array( 1892 'url' => $form_state['values']['url'] 1893 ); 1894 } 1895 1896 function system_goto_action($object, $context) { 1897 drupal_goto($context['url']); 1898 } 1899 1900 /** 1901 * Generate an array of time zones and their local time&date. 1902 */ 1903 function _system_zonelist() { 1904 $timestamp = time(); 1905 $zonelist = array(-11, -10, -9.5, -9, -8, -7, -6, -5, -4.5, -4, -3.5, -3, -2.5, -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); 1906 $zones = array(); 1907 foreach ($zonelist as $offset) { 1908 $zone = $offset * 3600; 1909 $zones[$zone] = format_date($timestamp, 'custom', variable_get('date_format_long', 'l, F j, Y - H:i') .' O', $zone); 1910 } 1911 return $zones; 1912 } 1913 1914 /** 1915 * Checks whether the server is capable of issuing HTTP requests. 1916 * 1917 * The function sets the drupal_http_request_fail system variable to TRUE if 1918 * drupal_http_request() does not work and then the system status report page 1919 * will contain an error. 1920 * 1921 * @return 1922 * TRUE if this installation can issue HTTP requests. 1923 */ 1924 function system_check_http_request() { 1925 // Try to get the content of the front page via drupal_http_request(). 1926 $result = drupal_http_request(url('', array('absolute' => TRUE)), array(), 'GET', NULL, 0); 1927 // We only care that we get a http response - this means that Drupal 1928 // can make a http request. 1929 $works = isset($result->code) && ($result->code >= 100) && ($result->code < 600); 1930 variable_set('drupal_http_request_fails', !$works); 1931 return $works; 1932 } 1933 1934 /** 1935 * Format the Powered by Drupal text. 1936 * 1937 * @ingroup themeable 1938 */ 1939 function theme_system_powered_by($image_path) { 1940 $image = theme('image', $image_path, t('Powered by Drupal, an open source content management system'), t('Powered by Drupal, an open source content management system')); 1941 return l($image, 'http://drupal.org', array('html' => TRUE, 'absolute' => TRUE, 'external' => TRUE)); 1942 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Thu Mar 24 11:18:33 2011 | Cross-referenced by PHPXref 0.7 |