1: <?php
2: /*
3: You may not change or alter any portion of this comment or credits
4: of supporting developers from this source code or any supporting source code
5: which is considered copyrighted (c) material of the original comment or credit authors.
6:
7: This program is distributed in the hope that it will be useful,
8: but WITHOUT ANY WARRANTY; without even the implied warranty of
9: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10: */
11:
12: namespace Xmf;
13:
14: /**
15: * Request Class
16: *
17: * This class serves to provide a common interface to access
18: * request variables. This includes $_POST, $_GET, and naturally $_REQUEST. Variables
19: * can be passed through an input filter to avoid injection or returned raw.
20: *
21: * @category Xmf\Request
22: * @package Xmf
23: * @author Richard Griffith <richard@geekwright.com>
24: * @author trabis <lusopoemas@gmail.com>
25: * @author Joomla!
26: * @copyright 2011-2016 XOOPS Project (http://xoops.org)
27: * @license GNU GPL 2 or later (http://www.gnu.org/licenses/gpl-2.0.html)
28: * @link http://xoops.org
29: */
30: class Request
31: {
32: /**
33: * Available masks for cleaning variables
34: */
35: const MASK_NO_TRIM = 1;
36: const MASK_ALLOW_RAW = 2;
37: const MASK_ALLOW_HTML = 4;
38:
39: /**
40: * Gets the request method
41: *
42: * @return string
43: */
44: public static function getMethod()
45: {
46: $method = strtoupper($_SERVER['REQUEST_METHOD']);
47:
48: return $method;
49: }
50:
51: /**
52: * Fetches and returns a given variable.
53: *
54: * The default behaviour is fetching variables depending on the
55: * current request method: GET and HEAD will result in returning
56: * an entry from $_GET, POST and PUT will result in returning an
57: * entry from $_POST.
58: *
59: * You can force the source by setting the $hash parameter:
60: *
61: * - post $_POST
62: * - get $_GET
63: * - files $_FILES
64: * - cookie $_COOKIE
65: * - env $_ENV
66: * - server $_SERVER
67: * - method via current $_SERVER['REQUEST_METHOD']
68: * - default $_REQUEST
69: *
70: * @param string $name Variable name
71: * @param mixed $default Default value if the variable does not exist
72: * @param string $hash Source of variable value (POST, GET, FILES, COOKIE, METHOD)
73: * @param string $type Return type for the variable (INT, FLOAT, BOOLEAN, WORD,
74: * ALPHANUM, CMD, BASE64, STRING, ARRAY, PATH, NONE) For more
75: * information see FilterInput::clean().
76: * @param int $mask Filter mask for the variable
77: *
78: * @return mixed Requested variable
79: */
80: public static function getVar($name, $default = null, $hash = 'default', $type = 'none', $mask = 0)
81: {
82: // Ensure hash and type are uppercase
83: $hash = strtoupper($hash);
84: if ($hash === 'METHOD') {
85: $hash = static::getMethod();
86: }
87: $type = strtoupper($type);
88:
89: // Get the input hash
90: switch ($hash) {
91: case 'GET':
92: $input = &$_GET;
93: break;
94: case 'POST':
95: $input = &$_POST;
96: break;
97: case 'FILES':
98: $input = &$_FILES;
99: break;
100: case 'COOKIE':
101: $input = &$_COOKIE;
102: break;
103: case 'ENV':
104: $input = &$_ENV;
105: break;
106: case 'SERVER':
107: $input = &$_SERVER;
108: break;
109: default:
110: $input = &$_REQUEST;
111: break;
112: }
113:
114: if (isset($input[$name]) && $input[$name] !== null) {
115: // Get the variable from the input hash and clean it
116: $var = static::cleanVar($input[$name], $mask, $type);
117:
118: // Handle magic quotes compatibility
119: if (get_magic_quotes_gpc() && ($var != $default) && ($hash !== 'FILES')) {
120: $var = static::stripSlashesRecursive($var);
121: }
122: } else {
123: if ($default !== null) {
124: // Clean the default value
125: $var = static::cleanVar($default, $mask, $type);
126: } else {
127: $var = $default;
128: }
129: }
130:
131: return $var;
132: }
133:
134: /**
135: * Fetches and returns a given filtered variable. The integer
136: * filter will allow only digits to be returned. This is currently
137: * only a proxy function for getVar().
138: *
139: * See getVar() for more in-depth documentation on the parameters.
140: *
141: * @param string $name Variable name
142: * @param int $default Default value if the variable does not exist
143: * @param string $hash Where the var should come from (POST, GET, FILES, COOKIE, METHOD)
144: *
145: * @return int Requested variable
146: */
147: public static function getInt($name, $default = 0, $hash = 'default')
148: {
149: return static::getVar($name, $default, $hash, 'int');
150: }
151:
152: /**
153: * Fetches and returns a given filtered variable. The float
154: * filter only allows digits and periods. This is currently
155: * only a proxy function for getVar().
156: *
157: * See getVar() for more in-depth documentation on the parameters.
158: *
159: * @param string $name Variable name
160: * @param float $default Default value if the variable does not exist
161: * @param string $hash Where the var should come from (POST, GET, FILES, COOKIE, METHOD)
162: *
163: * @return float Requested variable
164: */
165: public static function getFloat($name, $default = 0.0, $hash = 'default')
166: {
167: return static::getVar($name, $default, $hash, 'float');
168: }
169:
170: /**
171: * Fetches and returns a given filtered variable. The bool
172: * filter will only return true/false bool values. This is
173: * currently only a proxy function for getVar().
174: *
175: * See getVar() for more in-depth documentation on the parameters.
176: *
177: * @param string $name Variable name
178: * @param bool $default Default value if the variable does not exist
179: * @param string $hash Where the var should come from (POST, GET, FILES, COOKIE, METHOD)
180: *
181: * @return bool Requested variable
182: */
183: public static function getBool($name, $default = false, $hash = 'default')
184: {
185: return static::getVar($name, $default, $hash, 'bool');
186: }
187:
188: /**
189: * Fetches and returns a given filtered variable. The word
190: * filter only allows the characters [A-Za-z_]. This is currently
191: * only a proxy function for getVar().
192: *
193: * See getVar() for more in-depth documentation on the parameters.
194: *
195: * @param string $name Variable name
196: * @param string $default Default value if the variable does not exist
197: * @param string $hash Where the var should come from (POST, GET, FILES, COOKIE, METHOD)
198: *
199: * @return string Requested variable
200: */
201: public static function getWord($name, $default = '', $hash = 'default')
202: {
203: return static::getVar($name, $default, $hash, 'word');
204: }
205:
206: /**
207: * Fetches and returns a given filtered variable. The cmd filter only allows the characters
208: * [A-Za-z0-9.-_] and returns in lower case. This is currently a proxy function for getVar().
209: *
210: * See getVar() for more in-depth documentation on the parameters.
211: *
212: * @param string $name Variable name
213: * @param string $default Default value if the variable does not exist
214: * @param string $hash Where the var should come from (POST, GET, FILES, COOKIE, METHOD)
215: *
216: * @return string Requested variable
217: */
218: public static function getCmd($name, $default = '', $hash = 'default')
219: {
220: return static::getVar($name, $default, $hash, 'cmd');
221: }
222:
223: /**
224: * Fetches and returns a given filtered variable. The string
225: * filter deletes 'bad' HTML code, if not overridden by the mask.
226: * This is currently only a proxy function for getVar().
227: *
228: * See getVar() for more in-depth documentation on the parameters.
229: *
230: * @param string $name Variable name
231: * @param string $default Default value if the variable does not exist
232: * @param string $hash Where the var should come from (POST, GET, FILES, COOKIE, METHOD)
233: * @param int $mask Filter mask for the variable
234: *
235: * @return string Requested variable
236: */
237: public static function getString($name, $default = '', $hash = 'default', $mask = 0)
238: {
239: // Cast to string, in case static::MASK_ALLOW_RAW was specified for mask
240: return (string) static::getVar($name, $default, $hash, 'string', $mask);
241: }
242:
243: /**
244: * Fetches and returns an array
245: *
246: * @param string $name Variable name
247: * @param mixed $default Default value if the variable does not exist
248: * @param string $hash Where the var should come from (POST, GET, FILES, COOKIE, METHOD)
249: *
250: * @return array
251: */
252: public static function getArray($name, $default = array(), $hash = 'default')
253: {
254: return static::getVar($name, $default, $hash, 'array');
255: }
256:
257: /**
258: * Fetches and returns raw text
259: *
260: * @param string $name Variable name
261: * @param string $default Default value if the variable does not exist
262: * @param string $hash Where the var should come from (POST, GET, FILES, COOKIE, METHOD)
263: *
264: * @return string Requested variable
265: */
266: public static function getText($name, $default = '', $hash = 'default')
267: {
268: return (string) static::getVar($name, $default, $hash, 'string', static::MASK_ALLOW_RAW);
269: }
270:
271: /**
272: * Fetches and returns a web url
273: *
274: * @param string $name Variable name
275: * @param string $default Default value if the variable does not exist
276: * @param string $hash Where the var should come from (POST, GET, FILES, COOKIE, METHOD)
277: *
278: * @return string Requested variable
279: */
280: public static function getUrl($name, $default = '', $hash = 'default')
281: {
282: return (string) static::getVar($name, $default, $hash, 'weburl');
283: }
284:
285: /**
286: * Fetches and returns a file (or web) path
287: *
288: * @param string $name Variable name
289: * @param string $default Default value if the variable does not exist
290: * @param string $hash Where the var should come from (POST, GET, FILES, COOKIE, METHOD)
291: *
292: * @return string Requested variable
293: */
294: public static function getPath($name, $default = '', $hash = 'default')
295: {
296: return (string) static::getVar($name, $default, $hash, 'path');
297: }
298:
299: /**
300: * Fetches and returns an email address
301: *
302: * @param string $name Variable name
303: * @param string $default Default value if the variable does not exist
304: * @param string $hash Where the var should come from (POST, GET, FILES, COOKIE, METHOD)
305: *
306: * @return string email address or default if invalid
307: */
308: public static function getEmail($name, $default = '', $hash = 'default')
309: {
310: $ret = (string) static::getVar($name, $default, $hash, 'email');
311: return empty($ret) ? $default : $ret;
312: }
313:
314: /**
315: * Fetches and returns an IP address
316: *
317: * @param string $name Variable name
318: * @param string $default Default value if the variable does not exist
319: * @param string $hash Where the var should come from (POST, GET, FILES, COOKIE, METHOD)
320: *
321: * @return string IP address or default if invalid
322: */
323: public static function getIP($name, $default = '', $hash = 'default')
324: {
325: $ret = (string) static::getVar($name, $default, $hash, 'ip');
326: return empty($ret) ? $default : $ret;
327: }
328:
329: /**
330: * get request header
331: *
332: * @param string $headerName name of header to retrieve, case insensitive
333: * @param string|null $default default to return if named header is not found
334: *
335: * @return string header value or default if header was not found
336: */
337: public static function getHeader($headerName, $default = '')
338: {
339: static $headers = null;
340:
341: if (null === $headers) {
342: $headers = array();
343: if (function_exists('apache_request_headers')) {
344: $rawHeaders = apache_request_headers();
345: foreach ($rawHeaders as $name => $value) {
346: $headers[strtolower($name)] = $value;
347: }
348: } else {
349: // From joyview - http://php.net/manual/en/function.getallheaders.php
350: foreach ($_SERVER as $name => $value) {
351: if (substr($name, 0, 5) === 'HTTP_') {
352: $translatedName = str_replace(' ', '-', strtolower(str_replace('_', ' ', substr($name, 5))));
353: $headers[$translatedName] = $value;
354: }
355: }
356: }
357: }
358:
359: $name = strtolower($headerName);
360: if (isset($headers[$name])) {
361: return static::cleanVar($headers[$name]);
362: }
363: return $default;
364: }
365:
366: /**
367: * See if a variable exists in one of the request hashes
368: *
369: * @param string $name variable to look for
370: * @param string $hash hash to check
371: *
372: * @return boolean True if hash has an element 'name', otherwise false
373: */
374: public static function hasVar($name, $hash = 'method')
375: {
376: $hash = strtoupper($hash);
377: if ($hash === 'METHOD') {
378: $hash = strtoupper($_SERVER['REQUEST_METHOD']);
379: }
380:
381: // Get the requested hash and determine existing value
382: $original = static::get($hash, static::MASK_ALLOW_RAW);
383: if (isset($original[$name])) {
384: return true;
385: }
386: return false;
387: }
388:
389: /**
390: * Set a variable in one of the request variables
391: *
392: * @param string $name Name
393: * @param string $value Value
394: * @param string $hash Hash
395: * @param boolean $overwrite Boolean
396: *
397: * @return string Previous value
398: */
399: public static function setVar($name, $value = null, $hash = 'method', $overwrite = true)
400: {
401: $hash = strtoupper($hash);
402: if ($hash === 'METHOD') {
403: $hash = strtoupper($_SERVER['REQUEST_METHOD']);
404: }
405:
406: // Get the requested hash and determine existing value
407: $original = static::get($hash, static::MASK_ALLOW_RAW);
408: if (isset($original[$name])) {
409: $previous = $original[$name];
410: // don't overwrite value unless asked
411: if (!$overwrite) {
412: return $previous;
413: }
414: } else {
415: $previous = null;
416: }
417:
418: // set the value
419: switch ($hash) {
420: case 'GET':
421: $_GET[$name] = $value;
422: $_REQUEST[$name] = $value;
423: break;
424: case 'POST':
425: $_POST[$name] = $value;
426: $_REQUEST[$name] = $value;
427: break;
428: case 'REQUEST':
429: $_REQUEST[$name] = $value;
430: break;
431: case 'COOKIE':
432: $_COOKIE[$name] = $value;
433: $_REQUEST[$name] = $value;
434: break;
435: case 'FILES':
436: $_FILES[$name] = $value;
437: break;
438: case 'ENV':
439: $_ENV['name'] = $value;
440: break;
441: case 'SERVER':
442: $_SERVER['name'] = $value;
443: break;
444: }
445:
446: return $previous;
447: }
448:
449: /**
450: * Fetches and returns a request array.
451: *
452: * The default behaviour is fetching variables depending on the
453: * current request method: GET and HEAD will result in returning
454: * $_GET, POST and PUT will result in returning $_POST.
455: *
456: * You can force the source by setting the $hash parameter:
457: *
458: * - post $_POST
459: * - get $_GET
460: * - files $_FILES
461: * - cookie $_COOKIE
462: * - env $_ENV
463: * - server $_SERVER
464: * - method via current $_SERVER['REQUEST_METHOD']
465: * - default $_REQUEST
466: *
467: * @param string $hash to get (POST, GET, FILES, METHOD)
468: * @param int $mask Filter mask for the variable
469: *
470: * @return mixed Request hash
471: */
472: public static function get($hash = 'default', $mask = 0)
473: {
474: $hash = strtoupper($hash);
475:
476: if ($hash === 'METHOD') {
477: $hash = strtoupper($_SERVER['REQUEST_METHOD']);
478: }
479:
480: switch ($hash) {
481: case 'GET':
482: $input = $_GET;
483: break;
484: case 'POST':
485: $input = $_POST;
486: break;
487: case 'FILES':
488: $input = $_FILES;
489: break;
490: case 'COOKIE':
491: $input = $_COOKIE;
492: break;
493: case 'ENV':
494: $input = &$_ENV;
495: break;
496: case 'SERVER':
497: $input = &$_SERVER;
498: break;
499: default:
500: $input = $_REQUEST;
501: break;
502: }
503:
504: // Handle magic quotes compatibility
505: if (get_magic_quotes_gpc() && ($hash !== 'FILES')) {
506: $input = static::stripSlashesRecursive($input);
507: }
508:
509: $result = static::cleanVars($input, $mask);
510:
511: return $result;
512: }
513:
514: /**
515: * Sets a request variable
516: *
517: * @param array $array An associative array of key-value pairs
518: * @param string $hash The request variable to set (POST, GET, FILES, METHOD)
519: * @param boolean $overwrite If true and an existing key is found, the value is overwritten,
520: * otherwise it is ignored
521: *
522: * @return void
523: */
524: public static function set($array, $hash = 'method', $overwrite = true)
525: {
526: foreach ($array as $key => $value) {
527: static::setVar($key, $value, $hash, $overwrite);
528: }
529: }
530:
531: /**
532: * Clean up an input variable.
533: *
534: * @param mixed $var The input variable.
535: * @param int $mask Filter bit mask.
536: * - 1=no trim: If this flag is cleared and the input is a string,
537: * the string will have leading and trailing whitespace trimmed.
538: * - 2=allow_raw: If set, no more filtering is performed, higher bits are ignored.
539: * - 4=allow_html: HTML is allowed, but passed through a safe HTML filter first.
540: * If set, no more filtering is performed.
541: * - If no bits other than the 1 bit is set, a strict filter is applied.
542: * @param string $type The variable type. See {@link FilterInput::clean()}.
543: *
544: * @return string
545: */
546: protected static function cleanVar($var, $mask = 0, $type = null)
547: {
548: // Static input filters for specific settings
549: static $noHtmlFilter = null;
550: static $safeHtmlFilter = null;
551:
552: // convert $var in array if $type is ARRAY
553: if (strtolower($type) === 'array' && !is_array($var)) {
554: $var = array($var);
555: }
556:
557: // If the no trim flag is not set, trim the variable
558: if (!($mask & static::MASK_NO_TRIM) && is_string($var)) {
559: $var = trim($var);
560: }
561:
562: // Now we handle input filtering
563: // If the allow raw flag is set, do not modify the variable
564: if (!($mask & static::MASK_ALLOW_RAW)) {
565: if ($mask & static::MASK_ALLOW_HTML) {
566: // If the allow html flag is set, apply a safe html filter to the variable
567: if (null === $safeHtmlFilter) {
568: $safeHtmlFilter = FilterInput::getInstance(array(), array(), 1, 1);
569: }
570: $var = $safeHtmlFilter->cleanVar($var, $type);
571: } else {
572: // Since no allow flags were set, we will apply the most strict filter to the variable
573: if (null === $noHtmlFilter) {
574: $noHtmlFilter = FilterInput::getInstance();
575: }
576: $var = $noHtmlFilter->clean($var, $type);
577: }
578: }
579:
580: return $var;
581: }
582:
583: /**
584: * Clean up an array of variables.
585: *
586: * @param mixed $var The input variable.
587: * @param int $mask Filter bit mask. See {@link Request::cleanVar()}
588: * @param string $type The variable type. See {@link FilterInput::clean()}.
589: *
590: * @return string
591: */
592: protected static function cleanVars($var, $mask = 0, $type = null)
593: {
594: if (is_array($var)) {
595: foreach ($var as $key => &$value) {
596: $value = static::cleanVars($value, $mask, $type);
597: }
598: } else {
599: $var = static::cleanVar($var, $mask, $type);
600: }
601:
602: return $var;
603: }
604:
605: /**
606: * Strips slashes recursively on an array
607: *
608: * @param string|array $value string of Array of (nested arrays of) strings
609: *
610: * @return array The input array with stripslashes applied to it
611: */
612: protected static function stripSlashesRecursive($value)
613: {
614: $value = is_array($value)
615: ? array_map(array(get_called_class(), 'stripSlashesRecursive'), $value)
616: : stripslashes($value);
617:
618: return $value;
619: }
620: }
621: