Package base :: Package plugins :: Package system
[hide private]

Source Code for Package base.plugins.system

   1  #!/usr/bin/env python 
   2   
   3  # $Id: system.module,v 1.612 2008/08/02 19:01:02 dries Exp $ 
   4   
   5  """ 
   6    Configuration system that lets administrators 
   7    modify the workings of the site. 
   8   
   9    @package system 
  10    @see <a href='http://drupy.net'>Drupy Homepage</a> 
  11    @see <a href='http://drupal.org'>Drupal Homepage</a> 
  12    @note Drupy is a port of the Drupal project. 
  13    @note This file was ported from Drupal's modules/system/system.module 
  14    @depends plugins.user 
  15    @depends plugins.node 
  16    @depends plugins.taxonomy 
  17    @author Brendon Crawford 
  18    @copyright 2008 Brendon Crawford 
  19    @contact message144 at users dot sourceforge dot net 
  20    @created 2008-01-10 
  21    @version 0.1 
  22    @note License: 
  23   
  24      This program is free software; you can redistribute it and/or 
  25      modify it under the terms of the GNU General Public License 
  26      as published by the Free Software Foundation; either version 2 
  27      of the License, or (at your option) any later version. 
  28   
  29      This program is distributed in the hope that it will be useful, 
  30      but WITHOUT ANY WARRANTY; without even the implied warranty of 
  31      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
  32      GNU General Public License for more details. 
  33   
  34      You should have received a copy of the GNU General Public License 
  35      along with this program; if not, write to: 
  36       
  37      The Free Software Foundation, Inc., 
  38      51 Franklin Street, Fifth Floor, 
  39      Boston, MA  02110-1301, 
  40      USA 
  41  """ 
  42   
  43  __version__ = "$Revision: 1 $" 
  44   
  45  from lib.drupy import DrupyPHP as php 
  46  from includes import database as lib_database 
  47  from includes import bootstrap as lib_bootstrap 
  48  from includes import common as lib_common 
  49  from includes import menu as lib_menu 
  50  #from includes import tablesort as lib_tablesort 
  51  #from includes import form as lib_form 
  52  from includes import theme as lib_theme 
  53  from includes import path as lib_path 
  54  #from includes import mail as lib_mail 
  55   
  56  # 
  57  # 
  58  # The current system version. 
  59  # 
  60  VERSION = '7.0-dev' 
  61   
  62  # 
  63  # Core API compatibility. 
  64  # 
  65  DRUPAL_CORE_COMPATIBILITY = '7.x' 
  66   
  67  # 
  68  # Minimum supported version of PHP. 
  69  # 
  70  DRUPAL_MINIMUM_PHP = None 
  71   
  72  # 
  73  # Minimum supported version of PHP. 
  74  # 
  75  DRUPAL_MINIMUM_PYTHON = '2.5' 
  76   
  77  # 
  78  # Minimum recommended value of PHP memory_limit. 
  79  # 
  80  DRUPAL_MINIMUM_PHP_MEMORY_LIMIT = None 
  81   
  82  # 
  83  # Minimum supported version of MySQL, if it is used. 
  84  # 
  85  DRUPAL_MINIMUM_MYSQL = '5.0' 
  86   
  87  # 
  88  # Minimum supported version of PostgreSQL, if it is used. 
  89  # 
  90  DRUPAL_MINIMUM_PGSQL = '8.1' 
  91   
  92  # 
  93  # Maximum age of temporary files in seconds. 
  94  # 
  95  DRUPAL_MAXIMUM_TEMP_FILE_AGE = 1440 
  96   
  97   
  98   
99 -def hook_help(path_, arg):
100 """ 101 Implementation of hook_help(). 102 103 @param path_ Str 104 @param arg Dict 105 @return Str 106 """ 107 if path_ == 'admin/help#system': 108 output = '<p>' + t('The system module is at the foundation of your ' + \ 109 'Drupal website, and provides basic but extensible functionality for ' + \ 110 'use by other modules and themes + Some integral elements of ' + \ 111 'Drupal are contained in and managed by the system module, including ' + \ 112 'caching, enabling or disabling of modules and themes, preparing ' + \ 113 'and displaying the administrative page, and configuring ' + \ 114 'fundamental site settings. A number of key system maintenance ' + \ 115 'operations are also part of the system module.') + '</p>' 116 output += '<p>' + t('The system module provides:') + '</p>' 117 output += '<ul><li>' + t('support for enabling and disabling ' + \ 118 '<a href="@modules">modules</a> + Drupal comes packaged with a ' + \ 119 'number of core modules; each module provides a discrete set ' + \ 120 'of features and may be enabled depending on the needs of your ' + \ 121 'site. A wide array of additional modules contributed by members ' + \ 122 'of the Drupal community are available for download at the ' + \ 123 '<a href="@drupal-modules">Drupal.org module page</a>.', {'@modules' : \ 124 url('admin/build/modules'), '@drupal-modules' : \ 125 'http://drupal.org/project/modules'}) + '</li>' 126 output += '<li>' + t('support for enabling and disabling ' + \ 127 '<a href="@themes">themes</a>, which determine the design and ' + \ 128 'presentation of your site + Drupal comes packaged with several ' + \ 129 'core themes and additional contributed themes are available at ' + \ 130 'the <a href="@drupal-themes">Drupal.org theme page</a>.', \ 131 {'@themes' : url('admin/build/themes'), '@drupal-themes' : \ 132 'http://drupal.org/project/themes'}) + '</li>' 133 output += '<li>' + t('a robust ' + \ 134 '<a href="@cache-settings">caching system</a> that allows the ' + \ 135 'efficient re-use of previously-constructed web pages and web page ' + \ 136 'components + Drupal stores the pages requested by anonymous ' + \ 137 'users in a compressed format; depending on your site configuration ' + \ 138 'and the amount of your web traffic tied to anonymous visitors, ' + \ 139 'Drupal\'s caching system may significantly increase the speed ' + \ 140 'of your site.', {'@cache-settings' : \ 141 url('admin/settings/performance')}) + '</li>' 142 output += '<li>' + t('a set of routine administrative operations that ' + \ 143 'rely on a correctly-configured <a href="@cron">cron maintenance ' + \ 144 'task</a> to run automatically + A number of other modules, ' + \ 145 'including the feed aggregator, and search also rely on ' + \ 146 '<a href="@cron">cron maintenance tasks</a>. For more information, ' + \ 147 'see the online handbook entry for ' + \ 148 '<a href="@handbook">configuring cron jobs</a>.', \ 149 {'@cron' : url('admin/reports/status'), '@handbook' : \ 150 'http://drupal.org/cron'}) + '</li>' 151 output += '<li>' + t('basic configuration options for your site, ' + \ 152 'including <a href="@date-settings">date and time settings</a>, ' + \ 153 '<a href="@file-system">file system settings</a>, ' + \ 154 '<a href="@clean-url">clean URL support</a>, ' + \ 155 '<a href="@site-info">site name and other information</a>, and a ' + \ 156 '<a href="@site-maintenance">site maintenance</a> function for ' + \ 157 'taking your site temporarily off-line.', {'@date-settings' : \ 158 url('admin/settings/date-time'), '@file-system' : \ 159 url('admin/settings/file-system'), '@clean-url' : \ 160 url('admin/settings/clean-urls'), '@site-info' : \ 161 url('admin/settings/site-information'), '@site-maintenance' : \ 162 url('admin/settings/site-maintenance')}) + '</li></ul>' 163 output += '<p>' + t('For more information, see the online handbook ' + \ 164 'entry for <a href="@system">System module</a>.', \ 165 {'@system' : 'http://drupal.org/handbook/modules/system/'}) + '</p>' 166 return output 167 elif path_ == 'admin': 168 return '<p>' + t('Welcome to the administration section + Here ' + \ 169 'you may control how your site functions.') + '</p>' 170 elif path_ == 'admin/by-module': 171 return '<p>' + t('This page shows you all available administration ' + \ 172 'tasks for each module.') + '</p>' 173 elif path_ == 'admin/build/themes': 174 output = '<p>' + t('Select which themes are available to your users ' + \ 175 'and specify the default theme + To configure site-wide display ' + \ 176 'settings, click the "configure" task above. Alternatively, ' + \ 177 'to override these settings in a specific theme, click the ' + \ 178 '"configure" link for that theme. Note that different themes ' + \ 179 'may have different regions available for displaying content; ' + \ 180 'for consistency in presentation, you may wish to enable ' + \ 181 'only one theme.') + '</p>' 182 output += '<p>' + t('To change the appearance of your site, a ' + \ 183 'number of <a href="@themes">contributed themes</a> are available.', \ 184 {'@themes' : 'http://drupal.org/project/themes'}) + '</p>' 185 return output 186 elif path_ == 'admin/build/themes/settings/' + arg[4]: 187 reference = php.explode('.', arg[4], 2) 188 theme = php.array_pop(reference) 189 return '<p>' + t('These options control the display settings for ' + \ 190 'the <code>%template</code> theme + When your site is displayed ' + \ 191 'using this theme, these settings will be used. By clicking ' + \ 192 '"Reset to defaults," you can choose to use the ' + \ 193 '<a href="@global">global settings</a> for this theme.', \ 194 {'%template' : theme, '@global' : \ 195 url('admin/build/themes/settings')}) + '</p>' 196 elif path_ == 'admin/build/themes/settings': 197 return '<p>' + t('These options control the default display settings ' + \ 198 'for your entire site, across all themes + Unless they have been ' + \ 199 'overridden by a specific theme, these settings will be used.') + '</p>' 200 elif path_ == 'admin/build/modules': 201 output = '<p>' + t('Modules are plugins that extend Drupal\'s core ' + \ 202 'functionality + Enable modules by selecting the ' + \ 203 '<em>Enabled</em> checkboxes below and clicking the ' + \ 204 '<em>Save configuration</em> button. Once a module is enabled, ' + \ 205 'new <a href="@permissions">permissions</a> may be available.)', \ 206 {'@permissions' : url('admin/user/permissions')}) + '</p>' 207 output += '<p>' + t('It is important that ' + \ 208 '<a href="@update-php">update.php</a> is run every time a module ' + \ 209 'is updated to a newer version.', {'@update-php' : base_url + \ 210 '/update.php'}) + '</p>' 211 output += '<p>' + t('You can find all administration tasks belonging ' + \ 212 'to a particular module on the <a href="@by-module">administration ' + \ 213 'by module page</a>.', {'@by-module' : url('admin/by-module')}) + '</p>' 214 output += '<p>' + t('To extend the functionality of your site, ' + \ 215 'a number of <a href="@modules">contributed modules</a> are ' + \ 216 'available.', {'@modules' : \ 217 'http://drupal.org/project/modules'}) + '</p>' 218 return output 219 elif path_ == 'admin/build/modules/uninstall': 220 return '<p>' + t('The uninstall process removes all data related to ' + \ 221 'a module + To uninstall a module, you must first disable it. ' + \ 222 'Not all modules support this feature.') + '</p>' 223 elif path_ == 'admin/build/block/configure': 224 if (arg[4] == 'system' and arg[5] == 0): 225 return '<p>' + t('The <em>Powered by Drupal</em> block is an ' + \ 226 'optional link to the home page of the Drupal project + ' + \ 227 'While there is absolutely no requirement that sites feature ' + \ 228 'this link, it may be used to show support for Drupal.') + '</p>' 229 elif path_ == 'admin/settings/actions' or \ 230 path_ == 'admin/settings/actions/manage': 231 output = '<p>' + t('Actions are individual tasks that the system can ' + \ 232 'do, such as unpublishing a piece of content or banning a user + ' + \ 233 'Modules, such as the trigger module, can fire these actions ' + \ 234 'when certain system events happen; for example, when a new ' + \ 235 'post is added or when a user logs in. Modules may also ' + \ 236 'provide additional actions.') + '</p>' 237 output += '<p>' + t('There are two types of actions: simple and ' + \ 238 'advanced + Simple actions do not require any additional ' + \ 239 'configuration, and are listed here automatically. Advanced actions ' + \ 240 'can do more than simple actions; for example, send an e-mail to ' + \ 241 'a specified address, or check for certain words within a piece ' + \ 242 'of content. These actions need to be created and configured first ' + \ 243 'before they may be used. To create an advanced action, select ' + \ 244 'the action from the drop-down below and click the ' + \ 245 '<em>Create</em> button.') + '</p>' 246 if (lib_plugin.exists('trigger')): 247 output += '<p>' + t('You may proceed to the ' + \ 248 '<a href="@url">Triggers</a> page to assign these actions ' + \ 249 'to system events.', {'@url' : url('admin/build/trigger')}) + '</p>' 250 return output 251 elif path_ == 'admin/settings/actions/configure': 252 return t('An advanced action offers additional configuration options ' + \ 253 'which may be filled out below + Changing the ' + \ 254 '<em>Description</em> field is recommended, in order to better ' + \ 255 'identify the precise action taking place. This description ' + \ 256 'will be displayed in modules such as the trigger module when ' + \ 257 'assigning actions to system events, so it is best if it is as ' + \ 258 'descriptive as possible (for example, "Send e-mail to ' + \ 259 'Moderation Team" rather than simply "Send e-mail").') 260 elif path_ == 'admin/settings/ip-blocking': 261 return '<p>' + t('IP addresses listed here are blocked from your ' + \ 262 'site before any modules are loaded + You may add IP addresses to ' + \ 263 'the list, or delete existing entries.') + '</p>' 264 elif path_ == 'admin/reports/status': 265 return '<p>' + t("Here you can find a short overview of your " + \ 266 "site's parameters as well as any problems detected with your " + \ 267 "installation + It may be useful to copy and paste this " + \ 268 "information into support requests filed on drupal.org's " + \ 269 "support forums and project issue queues.") + '</p>'
270 271
272 -def hook_theme():
273 """ 274 Implementation of hook_theme(). 275 276 @return Dict 277 """ 278 return array_merge(drupal_common_theme(), { 279 'system_theme_select_form' : { 280 'arguments' : {'form' : None}, 281 'file' : 'system.admin.inc' 282 }, 283 'system_themes_form' : { 284 'arguments' : {'form' : None}, 285 'file' : 'system.admin.inc' 286 }, 287 'system_plugins_fieldset' : { 288 'arguments' : {'form' : None}, 289 'file' : 'system.admin.inc' 290 }, 291 'system_plugins_incompatible' : { 292 'arguments' : {'message' : None}, 293 'file' : 'system.admin.inc' 294 }, 295 'system_plugins_uninstall' : { 296 'arguments' : {'form' : None}, 297 'file' : 'system.admin.inc' 298 }, 299 'status_report' : { 300 'arguments' : {'requirements' : None}, 301 'file' : 'system.admin.inc' 302 }, 303 'admin_page' : { 304 'arguments' : {'blocks' : None}, 305 'file' : 'system.admin.inc' 306 }, 307 'admin_block' : { 308 'arguments' : {'block' : None}, 309 'file' : 'system.admin.inc' 310 }, 311 'admin_block_content' : { 312 'arguments' : {'content' : None}, 313 'file' : 'system.admin.inc' 314 }, 315 'system_admin_by_plugin' : { 316 'arguments' : {'menu_items' : None}, 317 'file' : 'system.admin.inc' 318 }, 319 'system_powered_by' : { 320 'arguments' : {'image_path' : None} 321 }, 322 'meta_generator_html' : { 323 'arguments' : {'version' : None} 324 }, 325 'meta_generator_header' : { 326 'arguments' : {'version' : None} 327 }, 328 'system_compact_link' : {} 329 })
330 331 332
333 -def hook_perm():
334 """ 335 Implementation of hook_perm(). 336 337 @return Dict 338 """ 339 return { 340 'administer site configuration' : t(\ 341 'Configure site-wide settings such as module or theme ' + \ 342 'administration settings.'), 343 'access administration pages' : t('View the administration panel ' + \ 344 'and browse the help system.'), 345 'administer actions' : t('Manage the actions defined for your site.'), 346 'access site reports' : t('View reports from system logs and other ' + \ 347 'status information.'), 348 'select different theme' : t('Select a theme other than the default ' + \ 349 'theme set by the site administrator.'), 350 'administer files' : t('Manage user-uploaded files.'), 351 'block IP addresses' : t('Block IP addresses from accessing your site.') 352 }
353 354
355 -def hook_elements():
356 """ 357 Implementation of hook_elements(). 358 359 @return Dict 360 """ 361 type_ = {} 362 # Top level form 363 type_['form'] = { 364 '#method' : 'post', 365 '#action' : request_uri() 366 } 367 # 368 # Input elements. 369 # 370 type_['submit'] = { 371 '#input' : True, 372 '#name' : 'op', 373 '#button_type' : 'submit', 374 '#executes_submit_callback' : True, 375 '#process' : ('form_process_ahah',) 376 } 377 type_['button'] = { 378 '#input' : True, 379 '#name' : 'op', 380 '#button_type' : 'submit', 381 '#executes_submit_callback' : False, 382 '#process' : ('form_process_ahah',) 383 } 384 type_['image_button'] = { 385 '#input' : True, 386 '#button_type' : 'submit', 387 '#executes_submit_callback' : True, 388 '#process' : ('form_process_ahah',), 389 '#return_value' : True, 390 '#has_garbage_value' : True, 391 '#src' : None 392 } 393 type_['textfield'] = { 394 '#input' : True, 395 '#size' : 60, 396 '#maxlength' : 128, 397 '#autocomplete_path' : False, 398 '#process' : ('form_process_ahah',) 399 } 400 type_['password'] = { 401 '#input' : True, 402 '#size' : 60, 403 '#maxlength' : 128, 404 '#process' : ('form_process_ahah',) 405 } 406 type_['password_confirm'] = { 407 '#input' : True, 408 '#process' : ('form_process_password_confirm',) 409 } 410 type_['textarea'] = { 411 '#input' : True, 412 '#cols' : 60, 413 '#rows' : 5, 414 '#resizable' : True, 415 '#process' : ('form_process_ahah',), 416 } 417 type_['radios'] = { 418 '#input' : True, 419 '#process' : ('form_process_radios',) 420 } 421 type_['radio'] = { 422 '#input' : True, 423 '#default_value' : None, 424 '#process' : ('form_process_ahah',) 425 } 426 type_['checkboxes'] = { 427 '#input' : True, 428 '#tree' : True, 429 '#process' : ('form_process_checkboxes',) 430 } 431 type_['checkbox'] = { 432 '#input' : True, 433 '#return_value' : 1, 434 '#process' : ('form_process_ahah',) 435 } 436 type_['select'] = { 437 '#input' : True, 438 '#size' : 0, 439 '#multiple' : False, 440 '#process' : ('form_process_ahah',) 441 } 442 type_['weight'] = { 443 '#input' : True, 444 '#delta' : 10, 445 '#default_value' : 0, 446 '#process' : ('form_process_weight', 'form_process_ahah') 447 } 448 type_['date'] = { 449 '#input' : True, 450 '#element_validate' : ('date_validate',), 451 '#process' : ('form_process_date',) 452 } 453 type_['file'] = { 454 '#input' : True, 455 '#size' : 60 456 } 457 # 458 # Form structure. 459 # 460 type_['item'] = { 461 '#markup' : '' 462 } 463 type_['hidden'] = { 464 '#input' : True, 465 '#process' : ('form_process_ahah',) 466 } 467 type_['value'] = { 468 '#input' : True 469 } 470 type_['markup'] = { 471 '#prefix' : '', 472 '#suffix' : '' 473 } 474 type_['fieldset'] = { 475 '#collapsible' : False, 476 '#collapsed' : False, 477 '#value' : None, 478 '#process' : ('form_process_ahah',) 479 } 480 type_['token'] = { 481 '#input' : True 482 } 483 return type_
484 485
486 -def hook_menu():
487 """ 488 Implementation of hook_menu(). 489 490 @return Dict 491 """ 492 items = {} 493 items['system/files'] = { 494 'title' : 'File download', 495 'page callback' : 'file_download', 496 'access callback' : True, 497 'type' : MENU_CALLBACK 498 } 499 items['admin'] = { 500 'title' : 'Administer', 501 'access arguments' : ('access administration pages',), 502 'page callback' : 'system_main_admin_page', 503 'weight' : 9 504 } 505 items['admin/compact'] = { 506 'title' : 'Compact mode', 507 'page callback' : 'system_admin_compact_page', 508 'access arguments' : ('access administration pages',), 509 'type' : MENU_CALLBACK 510 } 511 items['admin/by-task'] = { 512 'title' : 'By task', 513 'page callback' : 'system_main_admin_page', 514 'access arguments' : ('access administration pages',), 515 'type' : MENU_DEFAULT_LOCAL_TASK 516 } 517 items['admin/by-module'] = { 518 'title' : 'By module', 519 'page callback' : 'system_admin_by_module', 520 'access arguments' : ('access administration pages',), 521 'type' : MENU_LOCAL_TASK, 522 'weight' : 2 523 } 524 items['admin/content'] = { 525 'title' : 'Content management', 526 'description' : "Manage your site's content.", 527 'position' : 'left', 528 'weight' : -10, 529 'page callback' : 'system_admin_menu_block_page', 530 'access arguments' : ('access administration pages',) 531 } 532 # menu items that are basically just menu blocks 533 items['admin/settings'] = { 534 'title' : 'Site configuration', 535 'description' : 'Adjust basic site configuration options.', 536 'position' : 'right', 537 'weight' : -5, 538 'page callback' : 'system_settings_overview', 539 'access arguments' : ('access administration pages',) 540 } 541 items['admin/build'] = { 542 'title' : 'Site building', 543 'description' : 'Control how your site looks and feels.', 544 'position' : 'right', 545 'weight' : -10, 546 'page callback' : 'system_admin_menu_block_page', 547 'access arguments' : ('access administration pages',) 548 } 549 items['admin/settings/admin'] = { 550 'title' : 'Administration theme', 551 'description' : 'Settings for how your administrative pages should look.', 552 'position' : 'left', 553 'page callback' : 'drupal_get_form', 554 'page arguments' : ('system_admin_theme_settings',), 555 'access arguments' : ('administer site configuration',), 556 'block callback' : 'system_admin_theme_settings' 557 } 558 # Themes: 559 items['admin/build/themes'] = { 560 'title' : 'Themes', 561 'description' : 'Change which theme your site uses or allows users to set.', 562 'page callback' : 'drupal_get_form', 563 'page arguments' : ('system_themes_form', None), 564 'access arguments' : ('administer site configuration',) 565 } 566 items['admin/build/themes/select'] = { 567 'title' : 'List', 568 'description' : 'Select the default theme.', 569 'type' : MENU_DEFAULT_LOCAL_TASK, 570 'weight' : -1 571 } 572 items['admin/build/themes/settings'] = { 573 'title' : 'Configure', 574 'page arguments' : ('system_theme_settings',), 575 'access arguments' : ('administer site configuration',), 576 'type' : MENU_LOCAL_TASK 577 } 578 # Theme configuration subtabs 579 items['admin/build/themes/settings/global'] = { 580 'title' : 'Global settings', 581 'type' : MENU_DEFAULT_LOCAL_TASK, 582 'weight' : -1 583 } 584 for theme in list_themes(): 585 items['admin/build/themes/settings/' + theme.name] = { 586 'title' : theme.info['name'], 587 'page arguments' : array('system_theme_settings', theme.name), 588 'type' : MENU_LOCAL_TASK, 589 'access callback' : '_system_themes_access', 590 'access arguments' : (theme,) 591 } 592 # Modules: 593 items['admin/build/modules'] = { 594 'title' : 'Modules', 595 'description' : 'Enable or disable add-on modules for your site.', 596 'page callback' : 'drupal_get_form', 597 'page arguments' : ('system_modules',), 598 'access arguments' : ('administer site configuration',) 599 } 600 items['admin/build/modules/list'] = { 601 'title' : 'List', 602 'type' : MENU_DEFAULT_LOCAL_TASK 603 } 604 items['admin/build/modules/list/confirm'] = { 605 'title' : 'List', 606 'access arguments' : ('administer site configuration',), 607 'type' : MENU_CALLBACK 608 } 609 items['admin/build/modules/uninstall'] = { 610 'title' : 'Uninstall', 611 'page arguments' : ('system_modules_uninstall',), 612 'access arguments' : ('administer site configuration',), 613 'type' : MENU_LOCAL_TASK 614 } 615 items['admin/build/modules/uninstall/confirm'] = { 616 'title' : 'Uninstall', 617 'access arguments' : ('administer site configuration',), 618 'type' : MENU_CALLBACK 619 } 620 # Actions: 621 items['admin/settings/actions'] = { 622 'title' : 'Actions', 623 'description' : 'Manage the actions defined for your site.', 624 'access arguments' : ('administer actions',), 625 'page callback' : 'system_actions_manage' 626 } 627 items['admin/settings/actions/manage'] = { 628 'title' : 'Manage actions', 629 'description' : 'Manage the actions defined for your site.', 630 'page callback' : 'system_actions_manage', 631 'type' : MENU_DEFAULT_LOCAL_TASK, 632 'weight' : -2 633 } 634 items['admin/settings/actions/configure'] = { 635 'title' : 'Configure an advanced action', 636 'page callback' : 'drupal_get_form', 637 'page arguments' : ('system_actions_configure',), 638 'access arguments' : ('administer actions',), 639 'type' : MENU_CALLBACK 640 } 641 items['admin/settings/actions/delete/%actions'] = { 642 'title' : 'Delete action', 643 'description' : 'Delete an action.', 644 'page callback' : 'drupal_get_form', 645 'page arguments' : ('system_actions_delete_form', 4), 646 'access arguments' : ('administer actions',), 647 'type' : MENU_CALLBACK 648 } 649 items['admin/settings/actions/orphan'] = { 650 'title' : 'Remove orphans', 651 'page callback' : 'system_actions_remove_orphans', 652 'access arguments' : ('administer actions',), 653 'type' : MENU_CALLBACK 654 } 655 # IP address blocking. 656 items['admin/settings/ip-blocking'] = { 657 'title' : 'IP address blocking', 658 'description' : 'Manage blocked IP addresses.', 659 'page callback' : 'system_ip_blocking', 660 'access arguments' : ('block IP addresses',), 661 } 662 items['admin/settings/ip-blocking/%'] = { 663 'title' : 'IP address blocking', 664 'description' : 'Manage blocked IP addresses.', 665 'page callback' : 'system_ip_blocking', 666 'access arguments' : ('block IP addresses',), 667 'type' : MENU_CALLBACK 668 } 669 items['admin/settings/ip-blocking/delete/%blocked_ip'] = { 670 'title' : 'Delete IP address', 671 'page callback' : 'drupal_get_form', 672 'page arguments' : ('system_ip_blocking_delete', 4), 673 'access arguments' : ('block IP addresses',), 674 'type' : MENU_CALLBACK 675 } 676 # Settings: 677 items['admin/settings/site-information'] = { 678 'title' : 'Site information', 679 'description' : 'Change basic site information, such as the site ' + \ 680 'name, slogan, e-mail address, mission, front page and more.', 681 'page callback' : 'drupal_get_form', 682 'page arguments' : ('system_site_information_settings',), 683 'access arguments' : ('administer site configuration',) 684 } 685 items['admin/settings/error-reporting'] = { 686 'title' : 'Error reporting', 687 'description' : 'Control how Drupal deals with errors including ' + \ 688 '403/404 errors as well as PHP error reporting.', 689 'page callback' : 'drupal_get_form', 690 'page arguments' : ('system_error_reporting_settings'), 691 'access arguments' : ('administer site configuration',) 692 } 693 items['admin/settings/logging'] = { 694 'title' : 'Logging and alerts', 695 'description' : "Settings for logging and alerts modules + Various " + \ 696 "modules can route Drupal's system events to different destination, " + \ 697 "such as syslog, database, email, + ..etc.", 698 'page callback' : 'system_logging_overview', 699 'access arguments' : ('administer site configuration',) 700 } 701 items['admin/settings/performance'] = { 702 'title' : 'Performance', 703 'description' : 'Enable or disable page caching for anonymous ' + \ 704 'users and set CSS and JS bandwidth optimization options.', 705 'page callback' : 'drupal_get_form', 706 'page arguments' : ('system_performance_settings',), 707 'access arguments' : ('administer site configuration',) 708 } 709 items['admin/settings/file-system'] = { 710 'title' : 'File system', 711 'description' : 'Tell Drupal where to store uploaded files and ' + \ 712 'how they are accessed.', 713 'page callback' : 'drupal_get_form', 714 'page arguments' : ('system_file_system_settings',), 715 'access arguments' : ('administer site configuration',) 716 } 717 items['admin/settings/image-toolkit'] = { 718 'title' : 'Image toolkit', 719 'description' : 'Choose which image toolkit to use if you ' + \ 720 'have installed optional toolkits.', 721 'page callback' : 'drupal_get_form', 722 'page arguments' : ('system_image_toolkit_settings'), 723 'access arguments' : ('administer site configuration',) 724 } 725 items['admin/content/rss-publishing'] = { 726 'title' : 'RSS publishing', 727 'description' : 'Configure the number of items per feed and whether ' + \ 728 'feeds should be titles/teasers/full-text.', 729 'page callback' : 'drupal_get_form', 730 'page arguments' : ('system_rss_feeds_settings',), 731 'access arguments' : ('administer site configuration',) 732 } 733 items['admin/settings/date-time'] = { 734 'title' : 'Date and time', 735 'description' : "Settings for how Drupal displays date and time, " + \ 736 "as well as the system's default timezone.", 737 'page callback' : 'drupal_get_form', 738 'page arguments' : ('system_date_time_settings',), 739 'access arguments' : ('administer site configuration',) 740 } 741 items['admin/settings/date-time/lookup'] = { 742 'title' : 'Date and time lookup', 743 'type' : MENU_CALLBACK, 744 'page callback' : 'system_date_time_lookup', 745 'access arguments' : ('administer site configuration',) 746 } 747 items['admin/settings/site-maintenance'] = { 748 'title' : 'Site maintenance', 749 'description' : 'Take the site off-line for maintenance ' + \ 750 'or bring it back online.', 751 'page callback' : 'drupal_get_form', 752 'page arguments' : ('system_site_maintenance_settings',), 753 'access arguments' : array('administer site configuration',) 754 } 755 items['admin/settings/clean-urls'] = { 756 'title' : 'Clean URLs', 757 'description' : 'Enable or disable clean URLs for your site.', 758 'page callback' : 'drupal_get_form', 759 'page arguments' : ('system_clean_url_settings',), 760 'access arguments' : ('administer site configuration',) 761 } 762 items['admin/settings/clean-urls/check'] = { 763 'title' : 'Clean URL check', 764 'page callback' : 'drupal_json', 765 'page arguments' : ({'status' : True},), 766 'access callback' : True, 767 'type' : MENU_CALLBACK 768 } 769 # Menu handler to test that drupal_http_request() works locally. 770 # @see system_check_http_request() 771 items['admin/reports/request-test'] = { 772 'title' : 'Request test', 773 'page callback' : 'printf', 774 'page arguments' : ('request test',), 775 'access callback' : True, 776 'type' : MENU_CALLBACK 777 } 778 # Reports: 779 items['admin/reports'] = { 780 'title' : 'Reports', 781 'description' : 'View reports from system logs ' + \ 782 'and other status information.', 783 'page callback' : 'system_admin_menu_block_page', 784 'access arguments' : ('access site reports',), 785 'weight' : 5, 786 'position' : 'left' 787 } 788 items['admin/reports/status'] = { 789 'title' : 'Status report', 790 'description' : "Get a status report about your site's " + \ 791 "operation and any detected problems.", 792 'page callback' : 'system_status', 793 'weight' : 10, 794 'access arguments' : ('administer site configuration',) 795 } 796 items['admin/reports/status/run-cron'] = { 797 'title' : 'Run cron', 798 'page callback' : 'system_run_cron', 799 'access arguments' : ('administer site configuration',), 800 'type' : MENU_CALLBACK 801 } 802 items['admin/reports/status/php'] = { 803 'title' : 'PHP', 804 'page callback' : 'system_php', 805 'access arguments' : ('administer site configuration',), 806 'type' : MENU_CALLBACK 807 } 808 items['admin/reports/status/sql'] = { 809 'title' : 'SQL', 810 'page callback' : 'system_sql', 811 'access arguments' : ('administer site configuration',), 812 'type' : MENU_CALLBACK 813 } 814 # Default page for batch operations 815 items['batch'] = { 816 'page callback' : 'system_batch_page', 817 'access callback' : True, 818 'type' : MENU_CALLBACK 819 } 820 return items
821 822 823
824 -def blocked_ip_load(iid):
825 """ 826 Retrieve a blocked IP address from the database. 827 828 @param iid integer 829 The ID of the blocked IP address to retrieve. 830 831 @return 832 The blocked IP address from the database as an array. 833 """ 834 blocked_ip = lib_database.fetch_array(lib_database.query(\ 835 "SELECT * FROM {blocked_ips} WHERE iid = %d", iid)) 836 return blocked_ip
837 838 839
840 -def _themes_access(theme_):
841 """ 842 Menu item access callback - only admin or enabled themes can be accessed. 843 """ 844 return lib_plugin.plugins['user'].access('administer site configuration') and \ 845 (theme_.status or theme_.name == \ 846 lib_bootstrap.variable_get('admin_theme', '0'))
847 848
849 -def hook_init():
850 """ 851 Implementation of hook_init(). 852 """ 853 global custom_theme 854 # Use the administrative theme if the user 855 # is looking at a page in the admin/* path. 856 if (lib_path.arg(0) == 'admin' or \ 857 (lib_bootstrap.variable_get('node_admin_theme', '0') and \ 858 lib_path.arg(0) == 'node' and (lib_path.arg(1) == 'add' or \ 859 lib_path.arg(2) == 'edit'))): 860 custom_theme = lib_bootstrap.variable_get('admin_theme', '0') 861 lib_common.drupal_add_css(lib_common.drupal_get_path('plugin', 'system') + \ 862 '/admin.css', 'plugin') 863 # Add the CSS for this module. 864 lib_common.drupal_add_css(lib_common.drupal_get_path('plugin', 'system') + \ 865 '/defaults.css', 'plugin') 866 lib_common.drupal_add_css(lib_common.drupal_get_path('plugin', 'system') + \ 867 '/system.css', 'plugin') 868 lib_common.drupal_add_css(lib_common.drupal_get_path('plugin', 'system') + \ 869 '/system-menus.css', 'plugin') 870 # Get the major version 871 version = php.explode('.', VERSION)[0] 872 # Emit the META tag in the HTML HEAD section 873 lib_theme.theme('meta_generator_html', version) 874 # Emit the HTTP Header too 875 lib_theme.theme('meta_generator_header', version)
876 877
878 -def hook_user(type_, edit, user, category = None):
879 """ 880 Implementation of hook_user(). 881 882 Allows users to individually set their theme and time zone. 883 """ 884 php.Reference.check(user) 885 if (type_ == 'form' and category == 'account'): 886 form['theme_select'] = theme_select_form(lib_common.t( 887 'Selecting a different theme will ' + \ 888 'change the look and feel of the site.'), \ 889 (edit['theme'] if php.isset(edit, 'theme') else None), 2) 890 if (lib_bootstrap.variable_get('configurable_timezones', 1)): 891 zones = _zonelist() 892 form['timezone'] = { 893 '#type' : 'fieldset', 894 '#title' : lib_common.t('Locale settings'), 895 '#weight' : 6, 896 '#collapsible' : True, 897 } 898 form['timezone']['timezone'] = { 899 '#type' : 'select', 900 '#title' : lib_common.t('Time zone'), 901 '#default_value' : (edit['timezone'] if \ 902 php.strlen(edit['timezone']) else \ 903 lib_common.variable_get('date_default_timezone', 0)), 904 '#options' : zones, 905 '#description' : lib_common.t('Select your current local time. ' + \ 906 'Dates and times throughout this site will be displayed using ' + \ 907 'this time zone.'), 908 } 909 return form
910 911
912 -def hook_block(op = 'list', delta = '', edit = None):
913 """ 914 Implementation of hook_block(). 915 916 Generate a block with a promotional link to Drupal.org. 917 """ 918 if op == 'list': 919 blocks['powered-by'] = { 920 'info' : lib_common.t('Powered by Drupal'), 921 'weight' : '10', 922 # Not worth caching. 923 'cache' : BLOCK_NO_CACHE 924 } 925 return blocks 926 elif op == 'configure': 927 # Compile a list of fields to show 928 form['wrapper']['color'] = { 929 '#type' : 'select', 930 '#title' : lib_common.t('Badge color'), 931 '#default_value' : lib_bootstrap.variable_get(\ 932 'drupal_badge_color', 'powered-blue'), 933 '#options' : { 934 'powered-black' : lib_common.t('Black'), 935 'powered-blue' : lib_common.t('Blue'), 936 'powered-gray' : lib_common.t('Gray') 937 } 938 } 939 form['wrapper']['size'] = { 940 '#type' : 'select', 941 '#title' : t('Badge size'), 942 '#default_value' : lib_bootstrap.variable_get(\ 943 'drupal_badge_size', '80x15'), 944 '#options' : { 945 '80x15' : lib_common.t('Small'), 946 '88x31' : lib_common.t('Medium'), 947 '135x42' : lib_common.t('Large') 948 } 949 } 950 return form 951 elif op == 'save': 952 lib_bootstrap.variable_set('drupal_badge_color', edit['color']) 953 lib_bootstrap.variable_set('drupal_badge_size', edit['size']) 954 elif op == 'view': 955 image_path = 'misc/' + lib_bootstrap.variable_get('drupal_badge_color', \ 956 'powered-blue') + '-' + lib_bootstrap.variable_get(\ 957 'drupal_badge_size', '80x15') + '.png' 958 block['subject'] = None # Don't display a title 959 block['content'] = lib_theme.theme('system_powered_by', image_path)
960 961 962
963 -def admin_menu_block(item):
964 """ 965 Provide a single block on the administration overview page. 966 967 @param item 968 The menu item to be displayed. 969 """ 970 content = [] 971 if (not php.isset(item['mlid'])): 972 item += lib_database.fetch_array(lib_database.query(\ 973 "SELECT mlid, menu_name FROM {menu_links} ml " + \ 974 "WHERE ml.router_path = '%s' AND module = 'system'", item['path'])) 975 result = lib_database.query( 976 "SELECT m.load_functions, m.to_arg_functions, m.access_callback, " + \ 977 "m.access_arguments, m.page_callback, m.page_arguments, m.title, " + \ 978 "m.title_callback, m.title_arguments, m.type, m.description, ml.* " + \ 979 "FROM {menu_links} ml " + 980 "LEFT JOIN {menu_router} m ON ml.router_path = m.path " + \ 981 "WHERE ml.plid = %d AND ml.menu_name = '%s' AND hidden = 0", \ 982 item['mlid'], item['menu_name']) 983 while True: 984 item = lib_database.fetch_array(result) 985 if not item: 986 break 987 lib_menu._link_translate(item) 988 if (not item['access']): 989 continue 990 # The link 'description' either derived from the hook_menu 'description' or 991 # entered by the user via menu module is saved as the title attribute. 992 if (not php.empty(item['localized_options']['attributes']['title'])): 993 item['description'] = item['localized_options']['attributes']['title'] 994 # Prepare for sorting as in function _menu_tree_check_access(). 995 # The weight is offset so it is always positive, with a uniform 5-digits. 996 content[(50000 + item['weight']) + ' ' + item['title'] + \ 997 ' ' + item['mlid']] = item 998 p.ksort(content) 999 return content
1000 1001
1002 -def admin_theme_submit(form, form_state):
1003 """ 1004 Process admin theme form submissions. 1005 """ 1006 php.Reference.check(form_state) 1007 # If we're changing themes, make sure the theme has its blocks initialized. 1008 if (form_state['values']['admin_theme'] and \ 1009 form_state['values']['admin_theme'] != \ 1010 lib_bootstrap.variable_get('admin_theme', '0')): 1011 result = lib_database.result(lib_database.query(\ 1012 "SELECT COUNT(*) FROM {blocks} WHERE theme = '%s'", \ 1013 form_state['values']['admin_theme'])) 1014 if (not result): 1015 initialize_theme_blocks(form_state['values']['admin_theme'])
1016 1017
1018 -def theme_select_form(description = '', default_value = '', weight = 0):
1019 """ 1020 Returns a fieldset containing the theme select form. 1021 1022 @param description 1023 description of the fieldset 1024 @param default_value 1025 default value of theme radios 1026 @param weight 1027 weight of the fieldset 1028 @return 1029 a form array 1030 """ 1031 if (plugin_user.access('select different theme')): 1032 enabled = [] 1033 themes = list_themes() 1034 for theme_ in themes: 1035 if (theme_.status): 1036 enabled.append( theme_ ) 1037 if (php.count(enabled) > 1): 1038 p.ksort(enabled) 1039 form['themes'] = { 1040 '#type' : 'fieldset', 1041 '#title' : lib_common.t('Theme configuration'), 1042 '#description' : description, 1043 '#collapsible' : True, 1044 '#theme' : 'system_theme_select_form' 1045 } 1046 for info in enabled: 1047 # For the default theme, revert to an empty string 1048 # so the user's theme updates when the site theme is changed. 1049 info.key = (info.name == ('' if \ 1050 lib_bootstrap.variable_get('theme_default', 'garland') else \ 1051 info.name)) 1052 screenshot = None 1053 theme_key = info.name 1054 while theme_key: 1055 if (php.file_exists(themes[theme_key].info['screenshot'])): 1056 screenshot = themes[theme_key].info['screenshot'] 1057 break 1058 theme_key = (themes[theme_key].info['base theme'] if \ 1059 php.isset(themes[theme_key].info['base theme']) else None) 1060 screenshot = (screenshot if lib_theme.theme('image', screenshot, \ 1061 lib_common.t('Screenshot for %theme theme', \ 1062 {'%theme' : info.name}), '', {'class' : 'screenshot'}, False) else \ 1063 lib_common.t('no screenshot')) 1064 form['themes'][info.key]['screenshot'] = {'#markup' : screenshot} 1065 form['themes'][info.key]['description'] = \ 1066 { 1067 '#type' : 'item', 1068 '#title' : info.name, 1069 '#markup' : 1070 php.dirname(info.filename) + ( 1071 '<br /> <em>' + lib_common.t(\ 1072 '(site default theme)') + '</em>' if \ 1073 info.name == \ 1074 lib_bootstrap.variable_get('theme_default', 'garland') else \ 1075 '' 1076 ) 1077 } 1078 options[info.key] = '' 1079 form['themes']['theme'] = {'#type' : 'radios', '#options' : options, \ 1080 '#default_value' : (default_value if default_value else '')} 1081 form['#weight'] = weight 1082 return form
1083 1084 1085
1086 -def check_directory(form_element):
1087 """ 1088 Checks the existence of the directory specified in form_element. This 1089 function is called from the system_settings form to check both the 1090 file_directory_path and file_directory_temp directories. If validation 1091 fails, the form element is flagged with an error from within the 1092 file_check_directory function. 1093 1094 @param form_element 1095 The form element containing the name of the directory to check. 1096 """ 1097 file_check_directory(form_element['#value'], FILE_CREATE_DIRECTORY, \ 1098 form_element['#parents'][0]) 1099 return form_element
1100 1101 1102
1103 -def get_files_database(files, type):
1104 """ 1105 Retrieves the current status of an array of files in the system table. 1106 1107 @param files 1108 An array of files to check. 1109 @param type 1110 The type of the files. 1111 """ 1112 php.Reference.check(files) 1113 # Extract current files from database. 1114 result = lib_database.query( 1115 "SELECT filename, name, type, status, schema_version " + \ 1116 "FROM {system} WHERE type = '%s'", type_) 1117 while True: 1118 file = lib_database.fetch_object(result) 1119 if not file: 1120 break 1121 if (php.isset(files[file.name]) and php.is_object(files[file.name])): 1122 file.old_filename = file.filename 1123 for key,value in file.items(): 1124 if (not php.isset(files[file.name]) or not php.isset(files[file.name], key)): 1125 setattr(files[file.name], key, value)
1126 1127 1128
1129 -def theme_default():
1130 """ 1131 Prepare defaults for themes. 1132 1133 @return 1134 An array of default themes settings. 1135 """ 1136 return { 1137 'regions' : { 1138 'left' : 'Left sidebar', 1139 'right' : 'Right sidebar', 1140 'content' : 'Content', 1141 'header' : 'Header', 1142 'footer' : 'Footer' 1143 }, 1144 'description' : '', 1145 'features' : ( 1146 'comment_user_picture', 1147 'favicon', 1148 'mission', 1149 'logo', 1150 'name', 1151 'node_user_picture', 1152 'search', 1153 'slogan', 1154 'main_menu', 1155 'secondary_menu' 1156 ), 1157 'stylesheets' : { 1158 'all' : ('style.css',) 1159 }, 1160 'scripts' : ('script.js',), 1161 'screenshot' : 'screenshot.png', 1162 'python' : DRUPAL_MINIMUM_PYTHON 1163 }
1164 1165 1166
1167 -def theme_data():
1168 """ 1169 Collect data about all currently available themes. 1170 1171 @return 1172 Array of all available themes and their data. 1173 """ 1174 # Scan the installation theme .info files and their engines. 1175 themes = _theme_data() 1176 # Extract current files from database. 1177 get_files_database(themes, 'theme') 1178 lib_database.query("DELETE FROM {system} WHERE type = 'theme'") 1179 for theme_ in themes: 1180 if (not isset(theme_, 'owner')): 1181 theme_.owner = '' 1182 lib_database.query(\ 1183 "INSERT INTO {system} (name, owner, info, type, filename, " + \ 1184 "status, bootstrap) VALUES ('%s', '%s', '%s', '%s', '%s', %d, %d)", \ 1185 theme.name, theme.owner, serialize(theme.info), 'theme', \ 1186 theme.filename, (theme.status if isset(theme, 'status') else 0), 0) 1187 return themes
1188 1189 1190
1191 -def _theme_data():
1192 """ 1193 Helper function to scan and collect theme .info data and their engines. 1194 1195 @return 1196 An associative array of themes information. 1197 """ 1198 php.static(_theme_data, 'themes_info', {}) 1199 if (php.empty(_theme_data.themes_info)): 1200 # Find themes 1201 themes = lib_common.drupal_system_listing('\.info$', 'themes') 1202 # Find theme engines 1203 engines = lib_common.drupal_system_listing('\.engine$', 'themes/engines') 1204 defaults = theme_default() 1205 sub_themes = {} 1206 # Read info files for each theme 1207 for key,theme in themes.items(): 1208 themes[key].info = drupal_parse_info_file(theme.filename) + defaults 1209 # Invoke hook_system_info_alter() to give installed modules a chance to 1210 # modify the data in the .info files if necessary. 1211 lib_common.drupal_alter('system_info', themes[key].info, themes[key]) 1212 if (not empty(themes[key].info['base theme'])): 1213 sub_themes.append( key ) 1214 if (php.empty(themes[key].info['engine'])): 1215 filename = php.dirname(themes[key].filename) + \ 1216 '/' + themes[key].name + '.theme' 1217 if (php.file_exists(filename)): 1218 themes[key].owner = filename 1219 themes[key].prefix = key 1220 else: 1221 engine = themes[key].info['engine'] 1222 if (php.isset(engines, engine)): 1223 themes[key].owner = engines[engine].filename 1224 themes[key].prefix = engines[engine].name 1225 themes[key].template = True 1226 # Give the stylesheets proper path information. 1227 pathed_stylesheets = {} 1228 for media, stylesheets in themes[key].info['stylesheets'].items(): 1229 for stylesheet in stylesheets: 1230 pathed_stylesheets[media][stylesheet] = \ 1231 php.dirname(themes[key].filename) + '/' + stylesheet 1232 themes[key].info['stylesheets'] = pathed_stylesheets 1233 # Give the scripts proper path information. 1234 scripts = {} 1235 for script in themes[key].info['scripts']: 1236 scripts[script] = php.dirname(themes[key].filename) + '/' + script 1237 themes[key].info['scripts'] = scripts 1238 # Give the screenshot proper path information. 1239 if (not empty(themes[key].info['screenshot'])): 1240 themes[key].info['screenshot'] = php.dirname(themes[key].filename) + \ 1241 '/' + themes[key].info['screenshot'] 1242 # Now that we've established all our master themes, go back and fill in 1243 # data for subthemes. 1244 for key in sub_themes: 1245 base_key = find_base_theme(themes, key) 1246 if (not base_key): 1247 continue 1248 # Copy the 'owner' and 'engine' over if the top level theme uses a 1249 # theme engine. 1250 if (isset(themes[base_key], 'owner')): 1251 if (isset(themes[base_key].info, 'engine')): 1252 themes[key].info['engine'] = themes[base_key].info['engine'] 1253 themes[key].owner = themes[base_key].owner 1254 themes[key].prefix = themes[base_key].prefix 1255 else: 1256 themes[key].prefix = key 1257 themes_info = themes 1258 return themes_info
1259 1260 1261 1262
1263 -def find_base_theme(themes, key, used_keys = []):
1264 """ 1265 Recursive function to find the top level base theme. Themes can inherit 1266 templates and function implementations from earlier themes. 1267 1268 @param themes 1269 An array of available themes. 1270 @param key 1271 The name of the theme whose base we are looking for. 1272 @param used_keys 1273 A recursion parameter preventing endless loops. 1274 @return 1275 Returns the top level parent that has no ancestor 1276 or returns None if there isn't a valid parent. 1277 """ 1278 base_key = themes[key].info['base theme'] 1279 # Does the base theme exist? 1280 if (not php.isset(themes, base_key)): 1281 return None 1282 # Is the base theme itself a child of another theme? 1283 if (php.isset(themes[base_key].info, 'base theme')): 1284 # Prevent loops. 1285 if (not php.empty(used_keys[base_key])): 1286 return None 1287 used_keys[base_key] = True 1288 return find_base_theme(themes, base_key, used_keys) 1289 # If we get here, then this is our parent theme. 1290 return base_key
1291 1292 1293
1294 -def region_list(theme_key):
1295 """ 1296 Get a list of available regions from a specified theme. 1297 1298 @param theme_key 1299 The name of a theme. 1300 @return 1301 An array of regions in the form region['name'] = 'description'. 1302 """ 1303 php.static(region_list, 'list_', {}) 1304 if (not array_key_exists(theme_key, region_list.list_)): 1305 info = php.unserialize(lib_database.result(lib_database.query(\ 1306 "SELECT info FROM {system} WHERE type = 'theme' AND name = '%s'",\ 1307 theme_key))) 1308 region_list.list_[theme_key] = p.array_map('t', info['regions']) 1309 return region_list.list_[theme_key]
1310 1311 1312
1313 -def default_region(theme_):
1314 """ 1315 Get the name of the default region for a given theme. 1316 1317 @param theme 1318 The name of a theme. 1319 @return 1320 A string that is the region name. 1321 """ 1322 regions = php.array_keys(region_list(theme_)) 1323 return (regions[0] if php.isset(regions[0]) else '')
1324 1325 1326
1327 -def initialize_theme_blocks(theme_):
1328 """ 1329 Assign an initial, default set of blocks for a theme. 1330 1331 This function is called the first time a new theme is enabled. The new theme 1332 gets a copy of the default theme's blocks, with the difference that if a 1333 particular region isn't available in the new theme, the block is assigned 1334 to the new theme's default region. 1335 1336 @param theme 1337 The name of a theme. 1338 """ 1339 # Initialize theme's blocks if none already registered. 1340 if (not (db_result(db_query(\ 1341 "SELECT COUNT(*) FROM {blocks} WHERE theme = '%s'", theme)))): 1342 default_theme = variable_get('theme_default', 'garland') 1343 regions = system_region_list(theme) 1344 result = db_query("SELECT * FROM {blocks} WHERE theme = '%s'", \ 1345 default_theme) 1346 while True: 1347 block = lib_database.fetch_array(result) 1348 if not block: 1349 break 1350 # If the region isn't supported by the theme, 1351 # assign the block to the theme's default region. 1352 if (not php.array_key_exists(block['region'], regions)): 1353 block['region'] = default_region(theme_) 1354 lib_database.query(\ 1355 "INSERT INTO {blocks} (module, delta, theme, status, weight, " + \ 1356 "region, visibility, pages, custom, cache) VALUES ('%s', '%s', " + \ 1357 "'%s', %d, %d, '%s', %d, '%s', %d, %d)", \ 1358 block['module'], block['delta'], theme, block['status'], \ 1359 block['weight'], block['region'], block['visibility'], \ 1360 block['pages'], block['custom'], block['cache'])
1361 1362 1363 1364
1365 -def settings_form(form):
1366 """ 1367 Add default buttons to a form and set its prefix. 1368 1369 @ingroup forms 1370 @see system_settings_form_submit() 1371 @param form 1372 An associative array containing the structure of the form. 1373 @return 1374 The form structure. 1375 """ 1376 form['buttons']['submit'] = {'#type' : 'submit', '#value' : \ 1377 lib_common.t('Save configuration') } 1378 form['buttons']['reset'] = {'#type' : 'submit', '#value' : \ 1379 lib_common.t('Reset to defaults') } 1380 if (not empty(php.POST) and inc_form.form_get_errors()): 1381 lib_common.drupal_set_message(lib_common.t(\ 1382 'The settings have not been saved because of the errors.'), 'error') 1383 form['#submit'].append( 'system_settings_form_submit' ) 1384 form['#theme'] = 'system_settings_form' 1385 return form
1386 1387 1388
1389 -def settings_form_submit(form, form_state):
1390 """ 1391 Execute the system_settings_form. 1392 1393 If you want node type configure style handling of your checkboxes, 1394 add an array_filter value to your form. 1395 """ 1396 php.Reference.check(form_state) 1397 op = (form_state['values']['op'] if \ 1398 php.isset(form_state['values']['op']) else '') 1399 # Exclude unnecessary elements. 1400 del(form_state['values']['submit'], form_state['values']['reset'], \ 1401 form_state['values']['form_id'], form_state['values']['op'], \ 1402 form_state['values']['form_token'], form_state['values']['form_build_id']) 1403 for key,value in form_state['values'].items(): 1404 if (op == lib_common.t('Reset to defaults')): 1405 lib_bootstrap.variable_del(key) 1406 else: 1407 if (php.is_array(value) and php.isset(form_state['values']['array_filter'])): 1408 value = php.array_keys(php.array_filter(value)) 1409 lib_bootstrap.variable_set(key, value) 1410 if (op == t('Reset to defaults')): 1411 lib_common.drupal_set_message(lib_common.t(\ 1412 'The configuration options have been reset to their default values.')) 1413 else: 1414 lib_common.drupal_set_message(lib_common.t(\ 1415 'The configuration options have been saved.')) 1416 lib_cache.clear_all() 1417 lib_theme.drupal_theme_rebuild()
1418 1419 1420 1421
1422 -def _sort_requirements(a, b):
1423 """ 1424 Helper function to sort requirements. 1425 """ 1426 if (not php.isset(a, 'weight')): 1427 if (not php.isset(b, 'weight')): 1428 return p.strcmp(a['title'], b['title']) 1429 return -b['weight'] 1430 return ((a['weight'] - b['weight']) if php.isset(b['weight']) else a['weight'])
1431 1432 1433
1434 -def hook_node_type(op, info):
1435 """ 1436 Implementation of hook_node_type(). 1437 1438 Updates theme settings after a node type change. 1439 """ 1440 if (op == 'update' and not php.empty(info.old_type) and \ 1441 info.type != info.old_type): 1442 old = 'toggle_node_info_' + info.old_type 1443 new = 'toggle_node_info_' + info.type 1444 theme_settings = lib_bootstrap.variable_get('theme_settings', {}) 1445 if (php.isset(theme_settings, old)): 1446 theme_settings[new] = theme_settings[old] 1447 del(theme_settings[old]) 1448 lib_bootstrap.variable_set('theme_settings', theme_settings)
1449 1450 1451
1452 -def confirm_form(form, question, path_, description = None, yes = None, \ 1453 no = None, name = 'confirm'):
1454 """ 1455 Output a confirmation form 1456 1457 This function returns a complete form for confirming an action. A link is 1458 offered to go back to the item that is being changed in case the user changes 1459 his/her mind. 1460 1461 If the submit handler for this form is invoked, the user successfully 1462 confirmed the action. You should never directly inspect _POST to see if an 1463 action was confirmed. 1464 1465 @ingroup forms 1466 @param form 1467 Additional elements to inject into the form, for example hidden elements. 1468 @param question 1469 The question to ask the user (e.g. "Are you sure you want to delete the 1470 block <em>foo</em>?"). 1471 @param path 1472 The page to go to if the user denies the action. 1473 Can be either a drupal path, 1474 or an array with the keys 'path', 'query', 'fragment'. 1475 @param description 1476 Additional text to display (defaults to "This action cannot be undone."). 1477 @param yes 1478 A caption for the button which confirms the action (e.g. "Delete", 1479 "Replace", ...). 1480 @param no 1481 A caption for the link which denies the action (e.g. "Cancel"). 1482 @param name 1483 The internal name used to refer to the confirmation item. 1484 @return 1485 The form. 1486 """ 1487 description = (description if description is not None \ 1488 else lib_common.t('This action cannot be undone.')) 1489 # Prepare cancel link 1490 query = fragment = None 1491 if (php.is_array(path_)): 1492 query = (path_['query'] if php.isset(path_, 'query') else None) 1493 fragment = (path_['fragment'] if php.isset(path_['fragment']) else None) 1494 path = (path_['path'] if php.isset(path_, 'path') else None) 1495 cancel = lib_common.l((no if no else lib_common.t('Cancel')), path_, \ 1496 {'query' : query, 'fragment' : fragment}) 1497 lib_path.drupal_set_title(question) 1498 # Confirm form fails duplication check, 1499 # as the form values rarely change -- so skip it. 1500 form['#skip_duplicate_check'] = True 1501 form['#attributes'] = {'class' : 'confirmation'} 1502 form['description'] = {'#markup' : description} 1503 form[name] = {'#type' : 'hidden', '#value' : 1} 1504 form['actions'] = {'#prefix' : \ 1505 '<div class="container-inline">', '#suffix' : '</div>'} 1506 form['actions']['submit'] = {'#type' : 'submit', '#value' : \ 1507 (yes if yes else lib_common.t('Confirm'))} 1508 form['actions']['cancel'] = {'#markup' : cancel} 1509 form['#theme'] = 'confirm_form' 1510 return form
1511 1512 1513 1514
1515 -def admin_compact_mode():
1516 """ 1517 Determine if a user is in compact mode. 1518 """ 1519 return (lib_bootstrap.user.admin_compact_mode if \ 1520 php.isset(lib_bootstrap.user, 'admin_compact_mode') else \ 1521 variable_get('admin_compact_mode', False))
1522 1523 1524
1525 -def admin_compact_page(mode = 'off'):
1526 """ 1527 Menu callback; Sets whether the admin menu is in compact mode or not. 1528 1529 @param mode 1530 Valid values are 'on' and 'off'. 1531 """ 1532 plugin_user.save(lib_bootstrap.user, {'admin_compact_mode' : (mode == 'on')}) 1533 lib_common.drupal_goto(lib_common.drupal_get_destination())
1534 1535 1536
1537 -def get_module_admin_tasks(plugin):
1538 """ 1539 Generate a list of tasks offered by a specified module. 1540 1541 @param module 1542 Module name. 1543 @return 1544 An array of task links. 1545 """ 1546 php.static(get_module_admin_tasks, 'items', None) 1547 admin_access = plugin_user.access('administer permissions') 1548 admin_tasks = {} 1549 if (get_module_admin_tasks.items is None): 1550 result = lib_database.query( 1551 "SELECT " + \ 1552 " m.load_functions, m.to_arg_functions, " + \ 1553 " m.access_callback, m.access_arguments, " + \ 1554 " m.page_callback, m.page_arguments, " + \ 1555 " m.title, m.title_callback, " + \ 1556 " m.title_arguments, m.type, ml.* " + \ 1557 "FROM {menu_links} ml " + \ 1558 "INNER JOIN {menu_router} m ON ml.router_path = m.path " + \ 1559 "WHERE " + \ 1560 " ml.link_path LIKE 'admin/%' AND " + \ 1561 " hidden >= 0 AND " + \ 1562 " module = 'system' AND " + \ 1563 " m.number_parts > 2") 1564 get_module_admin_tasks.items = {} 1565 while True: 1566 item = lib_database.fetch_array(result) 1567 if not item: 1568 break 1569 lib_menu._link_translate(item) 1570 if (item['access']): 1571 get_module_admin_tasks.items[item['router_path']] = item 1572 admin_tasks = {} 1573 admin_task_count = 0 1574 # Check for permissions. 1575 if (lib_plugin.hook(plugin, 'perm') and admin_access): 1576 admin_tasks[-1] = lib_common.l(lib_common.t('Configure permissions'), \ 1577 'admin/user/permissions', {'fragment' : 'plugin-' + plugin}) 1578 # Check for menu items that are admin links. 1579 menu_ = lib_plugin.invoke(plugin, 'menu') 1580 if menu_: 1581 for path_ in php.array_keys(menu_): 1582 if (php.isset(get_module_admin_tasks.items[path_])): 1583 admin_tasks[ \ 1584 get_module_admin_tasks.items[path_]['title'] + admin_task_count] = \ 1585 l(get_module_admin_tasks.items[path_]['title'], path_) 1586 admin_task_count += 1 1587 return admin_tasks
1588 1589 1590
1591 -def hook_cron():
1592 """ 1593 Implementation of hook_cron(). 1594 1595 Remove older rows from flood and batch table. Remove old temporary files. 1596 """ 1597 # Cleanup the flood. 1598 lib_database.query('DELETE FROM {flood} WHERE timestamp < %d', \ 1599 php.time_() - 3600) 1600 # Cleanup the batch table. 1601 lib_database.query('DELETE FROM {batch} WHERE timestamp < %d', \ 1602 php.time_() - 864000) 1603 # Remove temporary files that are older than DRUPAL_MAXIMUM_TEMP_FILE_AGE. 1604 result = lib_database.query( 1605 'SELECT * ' + \ 1606 'FROM {files} ' + \ 1607 'WHERE ' + \ 1608 ' status = %d and ' + \ 1609 ' timestamp < %d', \ 1610 FILE_STATUS_TEMPORARY, \ 1611 php.time_() - DRUPAL_MAXIMUM_TEMP_FILE_AGE) 1612 while True: 1613 file = lib_database.fetch_object(result) 1614 if not file: 1615 break 1616 if (php.file_exists(file.filepath)): 1617 # If files that exist cannot be deleted, continue so the database remains 1618 # consistent. 1619 if (not lib_path.file_delete(file.filepath)): 1620 lib_bootstrap.watchdog('file system', \ 1621 'Could not delete temporary file "%path" during garbage collection', \ 1622 {'%path' : file.filepath}, 'error') 1623 continue 1624 lib_database.query('DELETE FROM {files} WHERE fid = %d', file.fid)
1625 1626 1627
1628 -def hook_hook_info():
1629 """ 1630 Implementation of hook_hook_info(). 1631 """ 1632 return { 1633 'system' : { 1634 'cron' : { 1635 'run' : { 1636 'runs when' : lib_common.t('When cron runs') 1637 } 1638 } 1639 } 1640 }
1641 1642 1643
1644 -def hook_action_info():
1645 """ 1646 Implementation of hook_action_info(). 1647 """ 1648 return { 1649 'system_message_action' : { 1650 'type' : 'system', 1651 'description' : lib_common.t('Display a message to the user'), 1652 'configurable' : True, 1653 'hooks' : { 1654 'nodeapi' : ('view', 'insert', 'update', 'delete'), 1655 'comment' : ('view', 'insert', 'update', 'delete'), 1656 'user' : ('view', 'insert', 'update', 'delete', 'login'), 1657 'taxonomy' : ('insert', 'update', 'delete') 1658 } 1659 }, 1660 'system_send_email_action' : { 1661 'description' : lib_common.t('Send e-mail'), 1662 'type' : 'system', 1663 'configurable' : True, 1664 'hooks' : { 1665 'nodeapi' : ('view', 'insert', 'update', 'delete'), 1666 'comment' : ('view', 'insert', 'update', 'delete'), 1667 'user' : ('view', 'insert', 'update', 'delete', 'login'), 1668 'taxonomy' : ('insert', 'update', 'delete') 1669 } 1670 }, 1671 'system_block_ip_action' : { 1672 'description' : lib_common.t('Ban IP address of current user'), 1673 'type' : 'user', 1674 'configurable' : False, 1675 'hooks' : (), 1676 }, 1677 'system_goto_action' : { 1678 'description' : lib_common.t('Redirect to URL'), 1679 'type' : 'system', 1680 'configurable' : True, 1681 'hooks' : { 1682 'nodeapi' : ('view', 'insert', 'update', 'delete'), 1683 'comment' : ('view', 'insert', 'update', 'delete'), 1684 'user' : ('view', 'insert', 'update', 'delete', 'login') 1685 } 1686 } 1687 }
1688 1689 1690
1691 -def actions_manage():
1692 """ 1693 Menu callback. Display an overview of available and configured actions. 1694 """ 1695 output = '' 1696 actions = actions_list() 1697 actions_synchronize(actions) 1698 actions_map = actions_actions_map(actions) 1699 options = [lib_common.t('Choose an advanced action')] 1700 unconfigurable = [] 1701 for key,array_ in actions_map.items(): 1702 if (array_['configurable']): 1703 options[key] = array_['description'] + '...' 1704 else: 1705 unconfigurable.append( array_ ) 1706 row = [] 1707 instances_present = lib_database.fetch_object(lib_database.query(\ 1708 "SELECT aid FROM {actions} WHERE parameters != ''")) 1709 header_ = ( 1710 {'data' : lib_common.t('Action type'), 'field' : 'type'}, 1711 {'data' : lib_common.t('Description'), 'field' : 'description'}, 1712 {'data' : (lib_common.t('Operations') if \ 1713 instances_present else ''), 'colspan' : '2'} 1714 ) 1715 sql = 'SELECT * FROM {actions}' 1716 result = pager_query(sql + inc_tablesort.tablesort_sql(header_), 50) 1717 while True: 1718 action = lib_database.fetch_object(result) 1719 if not action: 1720 break 1721 row.append(( 1722 {'data' : action.type_}, 1723 {'data' : action.description}, 1724 {'data' : (lib_common.l(lib_common.t('configure'), \ 1725 "admin/settings/actions/configure/%s" % action.aid) if 1726 action.parameters else '')}, 1727 {'data' : (lib_common.l(lib_common.t('delete'), \ 1728 "admin/settings/actions/delete/%s" % action.aid) if \ 1729 action.parameters else '')} 1730 )) 1731 if (row): 1732 pager = lib_theme.theme('pager', None, 50, 0) 1733 if (not empty(pager)): 1734 row.append([{'data' : pager, 'colspan' : '3'}]) 1735 output += '<h3>' + lib_common.t('Actions available to Drupal:') + '</h3>' 1736 output += lib_theme.theme('table', header, row) 1737 if (actions_map): 1738 output += inc_form.drupal_get_form('system_actions_manage_form', options) 1739 return output
1740 1741 1742
1743 -def actions_manage_form(form_state, options = []):
1744 """ 1745 Define the form for the actions overview page. 1746 1747 @see system_actions_manage_form_submit() 1748 @ingroup forms 1749 @param form_state 1750 An associative array containing the current state of the form; not used. 1751 @param options 1752 An array of configurable actions. 1753 @return 1754 Form definition. 1755 """ 1756 form['parent'] = { 1757 '#type' : 'fieldset', 1758 '#title' : lib_common.t('Make a new advanced action available'), 1759 '#prefix' : '<div class="container-inline">', 1760 '#suffix' : '</div>' 1761 } 1762 form['parent']['action'] = { 1763 '#type' : 'select', 1764 '#default_value' : '', 1765 '#options' : options, 1766 '#description' : '' 1767 } 1768 form['parent']['buttons']['submit'] = { 1769 '#type' : 'submit', 1770 '#value' : lib_common.t('Create') 1771 } 1772 return form
1773 1774 1775
1776 -def actions_manage_form_submit(form, form_state):
1777 """ 1778 Process system_actions_manage form submissions. 1779 """ 1780 php.Reference.check(form_state) 1781 if (form_state['values']['action']): 1782 form_state['redirect'] = 'admin/settings/actions/configure/%s' % \ 1783 form_state['values']['action']
1784 1785 1786
1787 -def actions_configure(form_state, action = None):
1788 """ 1789 Menu callback. Create the form for configuration of a single action. 1790 1791 We provide the "Description" field. The rest of the form 1792 is provided by the action. We then provide the Save button. 1793 Because we are combining unknown form elements with the action 1794 configuration form, we use actions_ prefix on our elements. 1795 1796 @see system_actions_configure_validate() 1797 @see system_actions_configure_submit() 1798 @param action 1799 md5 hash of action ID or an integer. If it's an md5 hash, we 1800 are creating a new instance. If it's an integer, we're editing 1801 an existing instance. 1802 @return 1803 Form definition. 1804 """ 1805 if (action is None): 1806 lib_common.drupal_goto('admin/settings/actions') 1807 actions_map = actions_actions_map(actions_list()) 1808 edit = [] 1809 # Numeric action denotes saved instance of a configurable action 1810 # else we are creating a new action instance. 1811 if (php.is_numeric(action)): 1812 aid = action 1813 # Load stored parameter values from database. 1814 data = lib_database.fetch_object(lib_database.query(\ 1815 "SELECT * FROM {actions} WHERE aid = %d", p.intval(aid))) 1816 edit['actions_description'] = data.description 1817 edit['actions_type'] = data.type 1818 function = data.callback 1819 action = php.md5(data.callback) 1820 params = php.unserialize(data.parameters) 1821 if (params): 1822 for name,val in params.items(): 1823 edit[name] = val 1824 else: 1825 aid = None 1826 function = actions_map[action]['callback'] 1827 edit['actions_description'] = actions_map[action]['description'] 1828 edit['actions_type'] = actions_map[action]['type'] 1829 form['actions_description'] = { 1830 '#type' : 'textfield', 1831 '#title' : lib_common.t('Description'), 1832 '#default_value' : edit['actions_description'], 1833 '#maxlength' : '255', 1834 '#description' : lib_common.t(\ 1835 'A unique description for this advanced action. This description ' + \ 1836 'will be displayed in the interface of modules that integrate ' + \ 1837 'with actions, such as Trigger module.'), 1838 '#weight' : -10 1839 } 1840 action_form = function + '_form' 1841 form = php.array_merge(form, action_form(edit)) 1842 form['actions_type'] = { 1843 '#type' : 'value', 1844 '#value' : edit['actions_type'], 1845 } 1846 form['actions_action'] = { 1847 '#type' : 'hidden', 1848 '#value' : action, 1849 } 1850 # aid is set when configuring an existing action instance. 1851 if (aid is not None): 1852 form['actions_aid'] = { 1853 '#type' : 'hidden', 1854 '#value' : aid, 1855 } 1856 form['actions_configured'] = { 1857 '#type' : 'hidden', 1858 '#value' : '1', 1859 } 1860 form['buttons']['submit'] = { 1861 '#type' : 'submit', 1862 '#value' : lib_common.t('Save'), 1863 '#weight' : 13 1864 } 1865 return form
1866 1867 1868
1869 -def actions_configure_validate(form, form_state):
1870 """ 1871 Validate system_actions_configure form submissions. 1872 """ 1873 function = actions_function_lookup(\ 1874 form_state['values']['actions_action']) + \ 1875 '_validate' 1876 # Hand off validation to the action. 1877 if (php.function_exists(function)): 1878 function(form, form_state)
1879 1880 1881
1882 -def actions_configure_submit(form, form_state):
1883 """ 1884 Process system_actions_configure form submissions. 1885 """ 1886 php.Reference.check(form_state) 1887 function = actions_function_lookup(form_state['values']['actions_action']) 1888 submit_function = function + '_submit' 1889 # Action will return keyed array of values to store. 1890 params = submit_function(form, form_state) 1891 aid = (form_state['values']['actions_aid'] if \ 1892 php.isset(form_state['values']['actions_aid']) else None) 1893 actions_save(function, form_state['values']['actions_type'], params, \ 1894 form_state['values']['actions_description'], aid) 1895 lib_bootstrap.drupal_set_message(t('The action has been successfully saved.')) 1896 form_state['redirect'] = 'admin/settings/actions/manage'
1897 1898
1899 -def actions_delete_form(form_state, action):
1900 """ 1901 Create the form for confirmation of deleting an action. 1902 1903 @ingroup forms 1904 @see system_actions_delete_form_submit() 1905 """ 1906 form['aid'] = { 1907 '#type' : 'hidden', 1908 '#value' : action.aid, 1909 } 1910 return confirm_form(form, 1911 lib_common.t('Are you sure you want to delete the action %action?', \ 1912 {'%action' : action.description}), 1913 'admin/settings/actions/manage', 1914 lib_common.t('This cannot be undone.'), 1915 lib_common.t('Delete'), lib_common.t('Cancel') 1916 )
1917 1918 1919
1920 -def actions_delete_form_submit(form, form_state):
1921 """ 1922 Process system_actions_delete form submissions. 1923 1924 Post-deletion operations for action deletion. 1925 """ 1926 php.Reference.check(form_state) 1927 aid = form_state['values']['aid'] 1928 action = actions_load(aid) 1929 actions_delete(aid) 1930 description = lib_bootstrap.check_plain(action.description) 1931 lib_bootstrap.watchdog('user', 'Deleted action %aid (%action)', \ 1932 {'%aid' : aid, '%action' : description}) 1933 lib_common.drupal_set_message(lib_common.t('Action %action was deleted', \ 1934 {'%action' : description})) 1935 form_state['redirect'] = 'admin/settings/actions/manage'
1936 1937 1938
1939 -def action_delete_orphans_post(orphaned):
1940 """ 1941 Post-deletion operations for deleting action orphans. 1942 1943 @param orphaned 1944 An array of orphaned actions. 1945 """ 1946 for callback in orphaned: 1947 lib_common.drupal_set_message(lib_common.t(\ 1948 "Deleted orphaned action (%action).", {'%action' : callback}))
1949 1950 1951
1952 -def actions_remove_orphans():
1953 """ 1954 Remove actions that are in the database but not supported by any enabled module. 1955 """ 1956 actions_synchronize(actions_list(), True) 1957 lib_common.drupal_goto('admin/settings/actions/manage')
1958 1959 1960
1961 -def send_email_action_form(context):
1962 """ 1963 Return a form definition so the Send email action can be configured. 1964 1965 @see system_send_email_action_validate() 1966 @see system_send_email_action_submit() 1967 @param context 1968 Default values (if we are editing an existing action instance). 1969 @return 1970 Form definition. 1971 """ 1972 # Set default values for form. 1973 if (not php.isset(context, 'recipient')): 1974 context['recipient'] = '' 1975 if (not php.isset(context, 'subject')): 1976 context['subject'] = '' 1977 if (not php.isset(context, 'message')): 1978 context['message'] = '' 1979 form['recipient'] = { 1980 '#type' : 'textfield', 1981 '#title' : lib_common.t('Recipient'), 1982 '#default_value' : context['recipient'], 1983 '#maxlength' : '254', 1984 '#description' : lib_common.t(\ 1985 'The email address to which the message should be sent OR ' + \ 1986 'enter %author if you would like to send an e-mail to the author ' + \ 1987 'of the original post.', {'%author' : '%author'}) 1988 } 1989 form['subject'] = { 1990 '#type' : 'textfield', 1991 '#title' : lib_common.t('Subject'), 1992 '#default_value' : context['subject'], 1993 '#maxlength' : '254', 1994 '#description' : lib_common.t('The subject of the message.') 1995 } 1996 form['message'] = { 1997 '#type' : 'textarea', 1998 '#title' : lib_common.t('Message'), 1999 '#default_value' : context['message'], 2000 '#cols' : '80', 2001 '#rows' : '20', 2002 '#description' : lib_common.t( 2003 'The message that should be sent. You may include the following ' + \ 2004 'variables: %site_name, %username, %node_url, %node_type, %title, ' + \ 2005 '%teaser, %body. Not all variables will be available in all contexts.') 2006 } 2007 return form
2008 2009 2010
2011 -def send_email_action_validate(form, form_state):
2012 """ 2013 Validate system_send_email_action form submissions. 2014 """ 2015 form_values = form_state['values'] 2016 # Validate the configuration form. 2017 if (not valid_email_address(form_values['recipient']) and \ 2018 form_values['recipient'] != '%author'): 2019 # We want the literal %author placeholder 2020 # to be emphasized in the error message. 2021 inc_form.form_set_error('recipient', lib_common.t( 2022 'Please enter a valid email address or %author.', \ 2023 {'%author' : '%author'}))
2024 2025 2026
2027 -def send_email_action_submit(form, form_state):
2028 """ 2029 Process system_send_email_action form submissions. 2030 """ 2031 form_values = form_state['values'] 2032 # Process the HTML form to store configuration. The keyed array that 2033 # we return will be serialized to the database. 2034 params = { 2035 'recipient' : form_values['recipient'], 2036 'subject' : form_values['subject'], 2037 'message' : form_values['message'] 2038 } 2039 return params
2040 2041 2042
2043 -def send_email_action(object_, context):
2044 """ 2045 Implementation of a configurable Drupal action. Sends an email. 2046 """ 2047 if context['hook'] == 'nodeapi': 2048 # Because this is not an action of type 'node' the node 2049 # will not be passed as object, but it will still be available 2050 # in context. 2051 node = context['node'] 2052 # The comment hook provides nid, in context. 2053 elif context['hook'] == 'comment': 2054 comment = context['comment'] 2055 node = plugin_node.load(comment.nid) 2056 elif context['hook'] == 'user': 2057 # Because this is not an action of type 'user' the user 2058 # object is not passed as object, but it will still be available 2059 # in context. 2060 account = context['account'] 2061 if (php.isset(context, 'node')): 2062 node = context['node'] 2063 elif (context['recipient'] == '%author'): 2064 # If we don't have a node, we don't have a node author. 2065 lib_bootstrap.watchdog('error', \ 2066 'Cannot use %author token in this context.') 2067 return 2068 else: 2069 # We are being called directly. 2070 node = object_ 2071 recipient = context['recipient'] 2072 if node is not None: 2073 if (account is None): 2074 account = plugin_user.load({'uid' : node.uid}) 2075 if (recipient == '%author'): 2076 recipient = account.mail 2077 if (not isset(account)): 2078 account = lib_bootstrap.user 2079 language = plugin_user.preferred_language(account) 2080 params = {'account' : account, 'object' : object_, 'context' : context} 2081 if (node is not None): 2082 params['node'] = node 2083 if (inc_mail.drupal_mail('system', 'action_send_email', recipient, \ 2084 language, params)): 2085 lib_bootstrap.watchdog('action', 'Sent email to %recipient', \ 2086 {'%recipient' : recipient}) 2087 else: 2088 lib_bootstrap.watchdog('error', 'Unable to send email to %recipient', \ 2089 {'%recipient' : recipient})
2090 2091 2092
2093 -def hook_mail(key, message, params):
2094 """ 2095 Implementation of hook_mail(). 2096 """ 2097 php.Reference.check(message) 2098 account = params['account'] 2099 context = params['context'] 2100 variables_ = { 2101 '%site_name' : lib_bootstrap.variable_get('site_name', 'Drupal'), 2102 '%username' : account.name, 2103 } 2104 if (context['hook'] == 'taxonomy'): 2105 object_ = params['object'] 2106 vocabulary = plugin_taxonomy.vocabulary_load(object_.vid) 2107 variables_ += { 2108 '%term_name' : object_.name, 2109 '%term_description' : object_.description, 2110 '%term_id' : object_.tid, 2111 '%vocabulary_name' : vocabulary.name, 2112 '%vocabulary_description' : vocabulary.description, 2113 '%vocabulary_id' : vocabulary.vid 2114 } 2115 # Node-based variable translation is only available if we have a node. 2116 if (php.isset(params['node'])): 2117 node = params['node'] 2118 variables_ += { 2119 '%uid' : node.uid, 2120 '%node_url' : lib_common.url('node/' + node.nid, {'absolute' : True}), 2121 '%node_type' : plugin_node.get_types('name', node), 2122 '%title' : node.title, 2123 '%teaser' : node.teaser, 2124 '%body' : node.body 2125 } 2126 subject = php.strtr(context['subject'], variables_) 2127 body = php.strtr(context['message'], variables_) 2128 message['subject'] += php.str_replace(("\r", "\n"), '', subject) 2129 message['body'].append( inc_mail.drupal_html_to_text(body) )
2130 2131 2132 2133
2134 -def message_action_form(context):
2135 form['message'] = { 2136 '#type' : 'textarea', 2137 '#title' : lib_common.t('Message'), 2138 '#default_value' : (context['message'] if \ 2139 php.isset(context['message']) else ''), 2140 '#required' : True, 2141 '#rows' : '8', 2142 '#description' : lib_common.t(\ 2143 'The message to be displayed to the current user. You may include ' + \ 2144 'the following variables: %site_name, %username, %node_url, ' + \ 2145 '%node_type, %title, %teaser, %body. Not all variables will be ' + \ 2146 'available in all contexts.') 2147 } 2148 return form
2149 2150
2151 -def message_action_submit(form, form_state):
2152 return {'message' : form_state['values']['message']}
2153 2154 2155
2156 -def message_action(object_, context = []):
2157 """ 2158 A configurable Drupal action. Sends a message to the current user's screen. 2159 """ 2160 php.Reference.check(object_) 2161 variables_ = { 2162 '%site_name' : lib_common.variable_get('site_name', 'Drupal'), 2163 '%username' : (lib_bootstrap.user.name if lib_bootstrap.user.name else \ 2164 lib_bootstrap.variable_get('anonymous', lib_common.t('Anonymous'))) 2165 } 2166 # This action can be called in any context, but if placeholders 2167 # are used a node object must be present to be the source 2168 # of substituted text. 2169 if context['hook'] == 'nodeapi': 2170 # Because this is not an action of type 'node' the node 2171 # will not be passed as object, but it will still be available 2172 # in context. 2173 node = context['node'] 2174 # The comment hook also provides the node, in context. 2175 elif context['hook'] == 'comment': 2176 comment = context['comment'] 2177 node = plugin_node.load(comment.nid) 2178 elif context['hook'] == 'taxonomy': 2179 vocabulary = plugin_taxonomy.vocabulary_load(object_.vid) 2180 variables_ = php.array_merge(variables_, { 2181 '%term_name' : object_.name, 2182 '%term_description' : object_.description, 2183 '%term_id' : object_.tid, 2184 '%vocabulary_name' : vocabulary.name, 2185 '%vocabulary_description' : vocabulary.description, 2186 '%vocabulary_id' : vocabulary.vid 2187 }) 2188 else: 2189 # We are being called directly. 2190 node = object_ 2191 if (php.isset(node) and php.is_object(node)): 2192 variables_ = php.array_merge(variables_, { 2193 '%uid' : node.uid, 2194 '%node_url' : lib_common.url('node/' + node.nid, {'absolute' : True}), 2195 '%node_type' : lib_bootstrap.check_plain(\ 2196 plugin_node.get_types('name', node)), 2197 '%title' : plugin_filter.xss(node.title), 2198 '%teaser' : plugin_filter.xss(node.teaser), 2199 '%body' : plugin_filter.xss(node.body) 2200 }) 2201 context['message'] = php.strtr(context['message'], variables_) 2202 lib_bootstrap.drupal_set_message(context['message'])
2203 2204 2205
2206 -def goto_action_form(context):
2207 """ 2208 Implementation of a configurable Drupal action. Redirect user to a URL. 2209 """ 2210 form['url'] = { 2211 '#type' : 'textfield', 2212 '#title' : lib_common.t('URL'), 2213 '#description' : t(\ 2214 'The URL to which the user should be redirected. This can be an ' + \ 2215 'internal URL like node/1234 or an external URL like http://drupal.org.'), 2216 '#default_value' : (context['url'] if php.isset(context['url']) else ''), 2217 '#required' : True, 2218 } 2219 return form
2220 2221 2222 2223
2224 -def goto_action_submit(form, form_state):
2225 return { 2226 'url' : form_state['values']['url'] 2227 }
2228 2229 2230
2231 -def goto_action(object_, context):
2232 lib_common.drupal_goto(context['url'])
2233 2234 2235
2236 -def block_ip_action():
2237 """ 2238 Implementation of a Drupal action. 2239 Blocks the user's IP address. 2240 """ 2241 ip = lib_bootstrap.ip_address() 2242 db_query("INSERT INTO {blocked_ips} (ip) VALUES ('%s')", ip); 2243 lib_bootstrap.watchdog('action', 'Banned IP address %ip', {'%ip' : ip})
2244 2245 2246
2247 -def _zonelist():
2248 """ 2249 Generate an array of time zones and their local time&date. 2250 """ 2251 timestamp = time() 2252 zonelist = array(-11, -10, -9.5, -9, -8, -7, -6, -5, -4, -3.5, -3, \ 2253 -2, -1, 0, 1, 2, 3, 3.5, 4, 5, 5.5, 5.75, 6, 6.5, 7, 8, 9, 9.5, 10, \ 2254 10.5, 11, 11.5, 12, 12.75, 13, 14) 2255 zones = [] 2256 for offset in zonelist: 2257 zone = offset * 3600 2258 zones[zone] = p.format_date(timestamp, 'custom', \ 2259 lib_bootstrap.variable_get('date_format_long', \ 2260 'l, F j, Y - H:i') + ' O', zone) 2261 return zones
2262 2263 2264
2265 -def check_http_request():
2266 """ 2267 Checks whether the server is capable of issuing HTTP requests. 2268 2269 The function sets the drupal_http_request_fail system variable to True if 2270 drupal_http_request() does not work and then the system status report page 2271 will contain an error. 2272 2273 @return 2274 Whether the admin/reports/request-test page can be requested via HTTP 2275 and contains the same output as if called via the menu system. 2276 """ 2277 # Check whether we can do any request at all. First get the results for 2278 # a very simple page which has access True set via the menu system. Then, 2279 # try to drupal_http_request() the same page and compare. 2280 # ob_start() 2281 path_ = 'admin/reports/request-test' 2282 lib_menu.execute_active_handler(path_) 2283 nothing = None 2284 # nothing = ob_get_contents() 2285 # ob_end_clean() 2286 result = lib_common.drupal_http_request(lib_common.url(path_, \ 2287 {'absolute' : True})) 2288 works = (php.isset(result.data) and (result.data == nothing)) 2289 lib_bootstrap.variable_set('drupal_http_request_fails', not works) 2290 return works
2291 2292 2293
2294 -def theme_powered_by(image_path):
2295 """ 2296 Format the Powered by Drupal text. 2297 2298 @ingroup themeable 2299 """ 2300 image = theme('image', image_path, \ 2301 lib_common.t(\ 2302 'Powered by Drupal, an open source content management system'), \ 2303 lib_common.t(\ 2304 'Powered by Drupal, an open source content management system')) 2305 return lib_common.l(image, 'http://drupal.org', \ 2306 {'html' : True, 'absolute' : True, 'external' : True})
2307 2308 2309 2329 2330 2331
2332 -def theme_meta_generator_html(version = VERSION):
2333 """ 2334 Send Drupal and the major version number in the META GENERATOR HTML. 2335 2336 @ingroup themeable 2337 """ 2338 lib_common.drupal_set_html_head('<meta name="Generator" content="Drupal ' + \ 2339 version + ' (http://drupal.org)" />')
2340 2341 2342
2343 -def theme_meta_generator_header(version = VERSION):
2344 """ 2345 Send Drupal and the major version number in the HTTP headers. 2346 2347 @ingroup themeable 2348 """ 2349 lib_common.drupal_set_header(\ 2350 'X-Generator: Drupal ' + version + ' (http://drupal.org)')
2351 2352
2353 -def hook_image_toolkits():
2354 """ 2355 Implementation of hook_image_toolkits(). 2356 """ 2357 return ('gd',)
2358