Add some documentation comments
[lhc/web/wiklou.git] / includes / WebRequest.php
1 <?php
2 /**
3 * Deal with importing all those nasssty globals and things
4 * @package MediaWiki
5 */
6
7 # Copyright (C) 2003 Brion Vibber <brion@pobox.com>
8 # http://www.mediawiki.org/
9 #
10 # This program is free software; you can redistribute it and/or modify
11 # it under the terms of the GNU General Public License as published by
12 # the Free Software Foundation; either version 2 of the License, or
13 # (at your option) any later version.
14 #
15 # This program is distributed in the hope that it will be useful,
16 # but WITHOUT ANY WARRANTY; without even the implied warranty of
17 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 # GNU General Public License for more details.
19 #
20 # You should have received a copy of the GNU General Public License along
21 # with this program; if not, write to the Free Software Foundation, Inc.,
22 # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 # http://www.gnu.org/copyleft/gpl.html
24
25 /**
26 * The WebRequest class encapsulates getting at data passed in the
27 * URL or via a POSTed form, handling remove of "magic quotes" slashes,
28 * stripping illegal input characters and normalizing Unicode sequences.
29 *
30 * Usually this is used via a global singleton, $wgRequest. You should
31 * not create a second WebRequest object; make a FauxRequest object if
32 * you want to pass arbitrary data to some function in place of the web
33 * input.
34 *
35 * @package MediaWiki
36 */
37 class WebRequest {
38 function WebRequest() {
39 $this->checkMagicQuotes();
40 global $wgUsePathInfo;
41 if( isset( $_SERVER['PATH_INFO'] ) && $wgUsePathInfo ) {
42 # Stuff it!
43 $_REQUEST['title'] = substr( $_SERVER['PATH_INFO'], 1 );
44 }
45 global $wgUseLatin1;
46 if( !$wgUseLatin1 ) {
47 require_once( 'normal/UtfNormal.php' );
48 wfProfileIn( 'WebRequest:normalizeUnicode-fix' );
49 $this->normalizeUnicode( $_REQUEST );
50 wfProfileOut( 'WebRequest:normalizeUnicode-fix' );
51 }
52 }
53
54 /**
55 * Recursively strips slashes from the given array;
56 * used for undoing the evil that is magic_quotes_gpc.
57 * @private
58 */
59 function &fix_magic_quotes( &$arr ) {
60 foreach( $arr as $key => $val ) {
61 if( is_array( $val ) ) {
62 $this->fix_magic_quotes( $arr[$key] );
63 } else {
64 $arr[$key] = stripslashes( $val );
65 }
66 }
67 return $arr;
68 }
69
70 /**
71 * If magic_quotes_gpc option is on, run the global arrays
72 * through fix_magic_quotes to strip out the stupid dlashes.
73 * WARNING: This should only be done once! Running a second
74 * time could damage the values.
75 * @private
76 */
77 function checkMagicQuotes() {
78 if ( get_magic_quotes_gpc() ) {
79 $this->fix_magic_quotes( $_COOKIE );
80 $this->fix_magic_quotes( $_ENV );
81 $this->fix_magic_quotes( $_GET );
82 $this->fix_magic_quotes( $_POST );
83 $this->fix_magic_quotes( $_REQUEST );
84 $this->fix_magic_quotes( $_SERVER );
85 }
86 }
87
88 /**
89 * Recursively normalizes UTF-8 strings in the given array.
90 * @private
91 */
92 function normalizeUnicode( &$arr ) {
93 foreach( $arr as $key => $val ) {
94 if( is_array( $val ) ) {
95 $this->normalizeUnicode( $arr[$key ] );
96 } else {
97 $arr[$key] = UtfNormal::cleanUp( $val );
98 }
99 }
100 }
101
102 /**
103 * Fetch a value from the given array or return $default if it's not set.
104 * @private
105 */
106 function getGPCVal( &$arr, $name, $default ) {
107 if( isset( $arr[$name] ) ) {
108 return $arr[$name];
109 } else {
110 return $default;
111 }
112 }
113
114 /**
115 * Fetch a value from the given array or return $default if it's not set.
116 * \r is stripped from the text, and with some language modules there is
117 * an input transliteration applied.
118 * @private
119 */
120 function getGPCText( &$arr, $name, $default ) {
121 # Text fields may be in an alternate encoding which we should check.
122 # Also, strip CRLF line endings down to LF to achieve consistency.
123 global $wgLang;
124 if( isset( $arr[$name] ) ) {
125 return str_replace( "\r\n", "\n", $wgLang->recodeInput( $arr[$name] ) );
126 } else {
127 return $default;
128 }
129 }
130
131 /**
132 * Fetch a value from the input or return $default if it's not set.
133 * Value may be of any type -- even an array -- and is not altered.
134 */
135 function getVal( $name, $default = NULL ) {
136 return $this->getGPCVal( $_REQUEST, $name, $default );
137 }
138
139 /**
140 * Fetch an integer value from the input or return $default if not set.
141 * Guaranteed to return an integer; non-integer input will typically
142 * return 0.
143 */
144 function getInt( $name, $default = 0 ) {
145 return IntVal( $this->getVal( $name, $default ) );
146 }
147
148 /**
149 * Fetch a boolean value from the input or return $default if not set.
150 * Guaranteed to return true or false, with normal PHP semantics for
151 * boolean interpretation of strings.
152 */
153 function getBool( $name, $default = false ) {
154 return $this->getVal( $name, $default ) ? true : false;
155 }
156
157 /**
158 * Return true if the named value is set in the input, whatever that
159 * value is (even "0"). Return false if the named value is not set.
160 * Example use is checking for the presence of check boxes in forms.
161 */
162 function getCheck( $name ) {
163 # Checkboxes and buttons are only present when clicked
164 # Presence connotes truth, abscense false
165 $val = $this->getVal( $name, NULL );
166 return isset( $val );
167 }
168
169 /**
170 * Fetch a text string from the given array or return $default if it's not
171 * set. \r is stripped from the text, and with some language modules there
172 * is an input transliteration applied. This should generally be used for
173 * form <textarea> and <input> fields.
174 */
175 function getText( $name, $default = '' ) {
176 return $this->getGPCText( $_REQUEST, $name, $default );
177 }
178
179 /**
180 * Extracts the given named values into an array.
181 * If no arguments are given, returns all input values.
182 * No transformation is performed on the values.
183 */
184 function getValues() {
185 $names = func_get_args();
186 if ( count( $names ) == 0 ) {
187 $names = array_keys( $_REQUEST );
188 }
189
190 $retVal = array();
191 foreach ( $names as $name ) {
192 $value = $this->getVal( $name );
193 if ( !is_null( $value ) ) {
194 $retVal[$name] = $value;
195 }
196 }
197 return $retVal;
198 }
199
200 /**
201 * Returns true if the present request was reached by a POST operation,
202 * false otherwise (GET, HEAD, or command-line).
203 *
204 * Note that values retrieved by the object may come from the
205 * GET URL etc even on a POST request.
206 */
207 function wasPosted() {
208 return $_SERVER['REQUEST_METHOD'] == 'POST';
209 }
210
211 /**
212 * Returns true if there is a session cookie set.
213 * This does not necessarily mean that the user is logged in!
214 */
215 function checkSessionCookie() {
216 return isset( $_COOKIE[ini_get('session.name')] );
217 }
218
219 /**
220 * Return the path portion of the request URI.
221 */
222 function getRequestURL() {
223 return $_SERVER['REQUEST_URI'];
224 }
225
226 /**
227 * Return the request URI with the canonical service and hostname.
228 */
229 function getFullRequestURL() {
230 global $wgServer;
231 return $wgServer . $this->getRequestURL();
232 }
233
234 /**
235 * Take an arbitrary query and rewrite the present URL to include it
236 */
237 function appendQuery( $query ) {
238 global $wgTitle;
239 $basequery = '';
240 foreach( $_GET as $var => $val ) {
241 if( $var == 'title' ) continue;
242 $basequery .= '&' . urlencode( $var ) . '=' . urlencode( $val );
243 }
244 $basequery .= '&' . $query;
245
246 # Trim the extra &
247 $basequery = substr( $basequery, 1 );
248 return $wgTitle->getLocalURL( $basequery );
249 }
250
251 /**
252 * HTML-safe version of appendQuery().
253 */
254 function escapeAppendQuery( $query ) {
255 return htmlspecialchars( $this->appendQuery( $query ) );
256 }
257
258 function getLimitOffset( $deflimit = 50, $optionname = 'rclimit' ) {
259 global $wgUser;
260
261 $limit = $this->getInt( 'limit', 0 );
262 if( $limit < 0 ) $limit = 0;
263 if( ( $limit == 0 ) && ( $optionname != '' ) ) {
264 $limit = (int)$wgUser->getOption( $optionname );
265 }
266 if( $limit <= 0 ) $limit = $deflimit;
267 if( $limit > 5000 ) $limit = 5000; # We have *some* limits...
268
269 $offset = $this->getInt( 'offset', 0 );
270 if( $offset < 0 ) $offset = 0;
271
272 return array( $limit, $offset );
273 }
274
275 /**
276 * Return the path to the temporary file where PHP has stored the upload.
277 * Returns NULL if no such thing.
278 */
279 function getFileTempname( $key ) {
280 if( !isset( $_FILES[$key] ) ) {
281 return NULL;
282 }
283 return $_FILES[$key]['tmp_name'];
284 }
285
286 /**
287 * Return the size of the upload, or 0.
288 */
289 function getFileSize( $key ) {
290 if( !isset( $_FILES[$key] ) ) {
291 return 0;
292 }
293 return $_FILES[$key]['size'];
294 }
295
296 /**
297 * Return the original filename of the uploaded file, as reported by
298 * the submitting user agent. HTML-style character entities are
299 * interpreted and normalized to Unicode normalization form C, in part
300 * to deal with weird input from Safari with non-ASCII filenames.
301 *
302 * Other than this the name is not verified for being a safe filename.
303 */
304 function getFileName( $key ) {
305 if( !isset( $_FILES[$key] ) ) {
306 return NULL;
307 }
308 $name = $_FILES[$key]['name'];
309
310 # Safari sends filenames in HTML-encoded Unicode form D...
311 # Horrid and evil! Let's try to make some kind of sense of it.
312 global $wgUseLatin1;
313 if( $wgUseLatin1 ) {
314 $name = utf8_encode( $name );
315 }
316 $name = wfMungeToUtf8( $name );
317 $name = UtfNormal::cleanUp( $name );
318 if( $wgUseLatin1 ) {
319 $name = utf8_decode( $name );
320 }
321 wfDebug( "WebRequest::getFileName() '" . $_FILES[$key]['name'] . "' normalized to '$name'\n" );
322 return $name;
323 }
324 }
325
326 /**
327 * WebRequest clone which takes values from a provided array.
328 *
329 * @package MediaWiki
330 */
331 class FauxRequest extends WebRequest {
332 var $data = null;
333 var $wasPosted = false;
334
335 function WebRequest( $data, $wasPosted = false ) {
336 if( is_array( $data ) ) {
337 $this->data = $data;
338 } else {
339 wfDebugDieBacktrace( "FauxReqeust() got bogus data" );
340 }
341 $this->wasPosted = $wasPosted;
342 }
343
344 function getVal( $name, $default = NULL ) {
345 return $this->getGPCVal( $this->data, $name, $default );
346 }
347
348 function getText( $name, $default = '' ) {
349 # Override; don't recode since we're using internal data
350 return $this->getVal( $name, $default );
351 }
352
353 function getValues() {
354 return $this->data;
355 }
356
357 function wasPosted() {
358 return $this->wasPosted;
359 }
360
361 function checkSessionCookie() {
362 return false;
363 }
364
365 function getRequestURL() {
366 wfDebugDieBacktrace( 'FauxRequest::getRequestURL() not implemented' );
367 }
368
369 function appendQuery( $query ) {
370 wfDebugDieBacktrace( 'FauxRequest::appendQuery() not implemented' );
371 }
372
373 }
374
375 ?>