1
2
3
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
51
52 from includes import theme as lib_theme
53 from includes import path as lib_path
54
55
56
57
58
59
60 VERSION = '7.0-dev'
61
62
63
64
65 DRUPAL_CORE_COMPATIBILITY = '7.x'
66
67
68
69
70 DRUPAL_MINIMUM_PHP = None
71
72
73
74
75 DRUPAL_MINIMUM_PYTHON = '2.5'
76
77
78
79
80 DRUPAL_MINIMUM_PHP_MEMORY_LIMIT = None
81
82
83
84
85 DRUPAL_MINIMUM_MYSQL = '5.0'
86
87
88
89
90 DRUPAL_MINIMUM_PGSQL = '8.1'
91
92
93
94
95 DRUPAL_MAXIMUM_TEMP_FILE_AGE = 1440
96
97
98
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
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
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
356 """
357 Implementation of hook_elements().
358
359 @return Dict
360 """
361 type_ = {}
362
363 type_['form'] = {
364 '#method' : 'post',
365 '#action' : request_uri()
366 }
367
368
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
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
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
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
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
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
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
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
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
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
770
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
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
815 items['batch'] = {
816 'page callback' : 'system_batch_page',
817 'access callback' : True,
818 'type' : MENU_CALLBACK
819 }
820 return items
821
822
823
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
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
850 """
851 Implementation of hook_init().
852 """
853 global custom_theme
854
855
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
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
871 version = php.explode('.', VERSION)[0]
872
873 lib_theme.theme('meta_generator_html', version)
874
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
923 'cache' : BLOCK_NO_CACHE
924 }
925 return blocks
926 elif op == 'configure':
927
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
959 block['content'] = lib_theme.theme('system_powered_by', image_path)
960
961
962
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
991
992 if (not php.empty(item['localized_options']['attributes']['title'])):
993 item['description'] = item['localized_options']['attributes']['title']
994
995
996 content[(50000 + item['weight']) + ' ' + item['title'] + \
997 ' ' + item['mlid']] = item
998 p.ksort(content)
999 return content
1000
1001
1003 """
1004 Process admin theme form submissions.
1005 """
1006 php.Reference.check(form_state)
1007
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
1083
1084
1085
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
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
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
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
1168 """
1169 Collect data about all currently available themes.
1170
1171 @return
1172 Array of all available themes and their data.
1173 """
1174
1175 themes = _theme_data()
1176
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
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
1201 themes = lib_common.drupal_system_listing('\.info$', 'themes')
1202
1203 engines = lib_common.drupal_system_listing('\.engine$', 'themes/engines')
1204 defaults = theme_default()
1205 sub_themes = {}
1206
1207 for key,theme in themes.items():
1208 themes[key].info = drupal_parse_info_file(theme.filename) + defaults
1209
1210
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
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
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
1239 if (not empty(themes[key].info['screenshot'])):
1240 themes[key].info['screenshot'] = php.dirname(themes[key].filename) + \
1241 '/' + themes[key].info['screenshot']
1242
1243
1244 for key in sub_themes:
1245 base_key = find_base_theme(themes, key)
1246 if (not base_key):
1247 continue
1248
1249
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
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
1280 if (not php.isset(themes, base_key)):
1281 return None
1282
1283 if (php.isset(themes[base_key].info, 'base theme')):
1284
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
1290 return base_key
1291
1292
1293
1310
1311
1312
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
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
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
1351
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
1386
1387
1388
1418
1419
1420
1421
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
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
1511
1512
1513
1514
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
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
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
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
1592 """
1593 Implementation of hook_cron().
1594
1595 Remove older rows from flood and batch table. Remove old temporary files.
1596 """
1597
1598 lib_database.query('DELETE FROM {flood} WHERE timestamp < %d', \
1599 php.time_() - 3600)
1600
1601 lib_database.query('DELETE FROM {batch} WHERE timestamp < %d', \
1602 php.time_() - 864000)
1603
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
1618
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
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
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
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
1773
1774
1775
1784
1785
1786
1866
1867
1868
1879
1880
1881
1897
1898
1917
1918
1919
1936
1937
1938
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
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
2008
2009
2010
2012 """
2013 Validate system_send_email_action form submissions.
2014 """
2015 form_values = form_state['values']
2016
2017 if (not valid_email_address(form_values['recipient']) and \
2018 form_values['recipient'] != '%author'):
2019
2020
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
2028 """
2029 Process system_send_email_action form submissions.
2030 """
2031 form_values = form_state['values']
2032
2033
2034 params = {
2035 'recipient' : form_values['recipient'],
2036 'subject' : form_values['subject'],
2037 'message' : form_values['message']
2038 }
2039 return params
2040
2041
2042
2044 """
2045 Implementation of a configurable Drupal action. Sends an email.
2046 """
2047 if context['hook'] == 'nodeapi':
2048
2049
2050
2051 node = context['node']
2052
2053 elif context['hook'] == 'comment':
2054 comment = context['comment']
2055 node = plugin_node.load(comment.nid)
2056 elif context['hook'] == 'user':
2057
2058
2059
2060 account = context['account']
2061 if (php.isset(context, 'node')):
2062 node = context['node']
2063 elif (context['recipient'] == '%author'):
2064
2065 lib_bootstrap.watchdog('error', \
2066 'Cannot use %author token in this context.')
2067 return
2068 else:
2069
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
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
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
2149
2150
2152 return {'message' : form_state['values']['message']}
2153
2154
2155
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
2167
2168
2169 if context['hook'] == 'nodeapi':
2170
2171
2172
2173 node = context['node']
2174
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
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
2220
2221
2222
2223
2225 return {
2226 'url' : form_state['values']['url']
2227 }
2228
2229
2230
2233
2234
2235
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
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
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
2278
2279
2280
2281 path_ = 'admin/reports/request-test'
2282 lib_menu.execute_active_handler(path_)
2283 nothing = None
2284
2285
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
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
2311 """
2312 Display the link to show or hide inline help descriptions.
2313
2314 @ingroup themeable
2315 """
2316 output = '<div class="compact-link">'
2317 if (admin_compact_mode()):
2318 output += lib_common.l(lib_common.t('Show descriptions'), \
2319 'admin/compact/off', {'attributes' : \
2320 {'title' : lib_common.t('Expand layout to include descriptions.')}, \
2321 'query' : lib_common.drupal_get_destination()})
2322 else:
2323 output += lib_common.l(lib_common.t('Hide descriptions'), \
2324 'admin/compact/on', {'attributes' : \
2325 {'title' : lib_common.t('Compress layout by hiding descriptions.')}, \
2326 'query' : drupal_get_destination()})
2327 output += '</div>'
2328 return output
2329
2330
2331
2340
2341
2342
2351
2352
2358