/[drupal]/contributions/modules/js/js.php
ViewVC logotype

Contents of /contributions/modules/js/js.php

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.4 - (show annotations) (download) (as text)
Thu Jul 23 10:47:04 2009 UTC (4 months ago) by sun
Branch: MAIN
Changes since 1.3: +2 -2 lines
File MIME type: text/x-php
by sun: Minor code and documentation clean-up.
1 <?php
2 // $Id: js.php,v 1.3 2009/07/03 19:32:17 smk Exp $
3
4 /**
5 * @file
6 * Callback page that serves custom JavaScript requests on a Drupal installation.
7 */
8
9 /**
10 * @name JavaScript callback status codes.
11 * @{
12 * Status codes for JavaScript callbacks.
13 *
14 * @todo Use regular defines from menu.inc?
15 */
16
17 define('JS_FOUND', 1);
18 define('JS_NOT_FOUND', 2);
19 define('JS_ACCESS_DENIED', 3);
20 define('JS_SITE_OFFLINE', 4);
21
22 /**
23 * @} End of "Menu status codes".
24 */
25
26 require_once './includes/bootstrap.inc';
27 drupal_bootstrap(DRUPAL_BOOTSTRAP_PATH);
28 require_once './includes/common.inc';
29 require_once './includes/locale.inc';
30
31 // Prevent caching of JS output.
32 $GLOBALS['conf']['cache'] = FALSE;
33 // Prevent Devel from hi-jacking our output in any case.
34 $GLOBALS['devel_shutdown'] = FALSE;
35
36 /**
37 * Loads the requested module and executes the requested callback.
38 *
39 * @return
40 * The callback function's return value or one of the JS_* constants.
41 */
42 function js_execute_callback() {
43 global $locale;
44
45 $args = explode('/', $_GET['q']);
46
47 // Strip first argument 'js'.
48 array_shift($args);
49
50 // Determine module to load.
51 $module = check_plain(array_shift($args));
52 if (!$module || !drupal_load('module', $module)) {
53 return JS_ACCESS_DENIED;
54 }
55
56 // Get info hook function name.
57 $function = $module .'_js';
58 if (!function_exists($function)) {
59 return JS_NOT_FOUND;
60 }
61
62 // Get valid callbacks.
63 $valid_callbacks = $function();
64
65 $callback = check_plain(array_shift($args));
66 if (!isset($valid_callbacks[$callback]) || !function_exists($valid_callbacks[$callback]['callback'])) {
67 return JS_NOT_FOUND;
68 }
69
70 $info = $valid_callbacks[$callback];
71 $full_boostrap = FALSE;
72
73 // Bootstrap to required level.
74 if (!empty($info['bootstrap'])) {
75 drupal_bootstrap($info['bootstrap']);
76 $full_boostrap = ($info['bootstrap'] == DRUPAL_BOOTSTRAP_FULL);
77 }
78
79 if (!$full_boostrap) {
80 // The following mimics the behavior of _drupal_bootstrap_full().
81 // @see _drupal_bootstrap_full(), common.inc
82
83 // Load required include files.
84 if (isset($info['includes']) && is_array($info['includes'])) {
85 foreach ($info['includes'] as $include) {
86 if (file_exists("./includes/$include.inc")) {
87 require_once "./includes/$include.inc";
88 }
89 }
90 }
91 // Always load locale.inc.
92 require_once "./includes/locale.inc";
93
94 // Set the Drupal custom error handler.
95 set_error_handler('error_handler');
96 // Detect string handling method.
97 if (function_exists('unicode_check')) {
98 unicode_check();
99 }
100 // Undo magic quotes.
101 fix_gpc_magic();
102
103 // Load required modules.
104 $modules = array($module => 0);
105 if (isset($info['dependencies']) && is_array($info['dependencies'])) {
106 // Intersect list with active modules to avoid loading uninstalled ones.
107 $dependencies = array_intersect(module_list(TRUE, FALSE), $info['dependencies']);
108 foreach ($dependencies as $dependency) {
109 drupal_load('module', $dependency);
110 $modules[$dependency] = 0;
111 }
112 }
113 // Reset module list.
114 module_list(FALSE, TRUE, FALSE, $modules);
115
116 // Initialize the localization system.
117 // @todo We actually need to query the database whether the site has any
118 // localization module enabled, and load it automatically.
119 $locale = locale_initialize();
120 // Invoke implementations of hook_init().
121 module_invoke_all('init');
122 }
123
124 // Invoke callback function.
125 return call_user_func_array($info['callback'], $args);
126 }
127
128 /**
129 * l() calls check_url(), which needs to check for XSS attacks.
130 */
131 function filter_xss_bad_protocol($string, $decode = TRUE) {
132 static $allowed_protocols;
133 if (!isset($allowed_protocols)) {
134 $allowed_protocols = array_flip(variable_get('filter_allowed_protocols', array('http', 'https', 'ftp', 'news', 'nntp', 'telnet', 'mailto', 'irc', 'ssh', 'sftp', 'webcal')));
135 }
136
137 // Get the plain text representation of the attribute value (i.e. its meaning).
138 if ($decode) {
139 $string = decode_entities($string);
140 }
141
142 // Iteratively remove any invalid protocol found.
143
144 do {
145 $before = $string;
146 $colonpos = strpos($string, ':');
147 if ($colonpos > 0) {
148 // We found a colon, possibly a protocol. Verify.
149 $protocol = substr($string, 0, $colonpos);
150 // If a colon is preceded by a slash, question mark or hash, it cannot
151 // possibly be part of the URL scheme. This must be a relative URL,
152 // which inherits the (safe) protocol of the base document.
153 if (preg_match('![/?#]!', $protocol)) {
154 break;
155 }
156 // Per RFC2616, section 3.2.3 (URI Comparison) scheme comparison must be case-insensitive.
157 // Check if this is a disallowed protocol.
158 if (!isset($allowed_protocols[strtolower($protocol)])) {
159 $string = substr($string, $colonpos + 1);
160 }
161 }
162 } while ($before != $string);
163 return check_plain($string);
164 }
165
166 $return = js_execute_callback();
167
168 // Menu status constants are integers; page content is a string.
169 if (is_int($return)) {
170 drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
171 switch ($return) {
172 case JS_NOT_FOUND:
173 drupal_not_found();
174 break;
175
176 case JS_ACCESS_DENIED:
177 drupal_access_denied();
178 break;
179
180 case JS_SITE_OFFLINE:
181 drupal_site_offline();
182 break;
183 }
184 }
185 elseif (isset($return)) {
186 // If JavaScript callback did not exit, print any value (including an empty
187 // string) except NULL or undefined:
188 print drupal_to_js($return);
189 }
190

  ViewVC Help
Powered by ViewVC 1.1.2