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 Xoops\Core;
13:
14: use Xoops\Core\Locale\Time;
15:
16: /**
17: * Request Class
18: *
19: * This class serves to provide a common interface to access
20: * request variables. This includes $_POST, $_GET, and naturally $_REQUEST. Variables
21: * can be passed through an input filter to avoid injection or returned raw.
22: *
23: * @category Xoops\Core\Request
24: * @package Xoops\Core
25: * @author Richard Griffith <richard@geekwright.com>
26: * @author trabis <lusopoemas@gmail.com>
27: * @author Joomla!
28: * @copyright 2011-2015 XOOPS Project (http://xoops.org)
29: * @license GNU GPL 2 or later (http://www.gnu.org/licenses/gpl-2.0.html)
30: * @version Release: 1.0
31: * @link http://xoops.org
32: * @since 1.0
33: */
34: class Request
35: {
36:
37: /**
38: * Available masks for cleaning variables
39: */
40: const NOTRIM = 1;
41: const ALLOWRAW = 2;
42: const ALLOWHTML = 4;
43:
44: /**
45: * Gets the request method
46: *
47: * @return string
48: */
49: public static function getMethod()
50: {
51: $method = strtoupper($_SERVER['REQUEST_METHOD']);
52:
53: return $method;
54: }
55:
56: /**
57: * Fetches and returns a given variable.
58: *
59: * The default behaviour is fetching variables depending on the
60: * current request method: GET and HEAD will result in returning
61: * an entry from $_GET, POST and PUT will result in returning an
62: * entry from $_POST.
63: *
64: * You can force the source by setting the $hash parameter:
65: *
66: * - post $_POST
67: * - get $_GET
68: * - files $_FILES
69: * - cookie $_COOKIE
70: * - env $_ENV
71: * - server $_SERVER
72: * - method via current $_SERVER['REQUEST_METHOD']
73: * - default $_REQUEST
74: *
75: * @param string $name Variable name
76: * @param mixed $default Default value if the variable does not exist
77: * @param string $hash Source of variable value (POST, GET, FILES, COOKIE, METHOD)
78: * @param string $type Return type for the variable (INT, FLOAT, BOOLEAN, WORD,
79: * ALNUM, CMD, BASE64, STRING, ARRAY, PATH, NONE) For more
80: * information see Xoops\Core\FilterInput::clean().
81: * @param int $mask Filter mask for the variable
82: *
83: * @return mixed Requested variable
84: */
85: public static function getVar($name, $default = null, $hash = 'default', $type = 'none', $mask = 0)
86: {
87: // Ensure hash and type are uppercase
88: $hash = strtoupper($hash);
89: if ($hash === 'METHOD') {
90: $hash = self::getMethod();
91: }
92: $type = strtoupper($type);
93:
94: // Get the input hash
95: switch ($hash) {
96: case 'GET':
97: $input = &$_GET;
98: break;
99: case 'POST':
100: $input = &$_POST;
101: break;
102: case 'FILES':
103: $input = &$_FILES;
104: break;
105: case 'COOKIE':
106: $input = &$_COOKIE;
107: break;
108: case 'ENV':
109: $input = &$_ENV;
110: break;
111: case 'SERVER':
112: $input = &$_SERVER;
113: break;
114: default:
115: $input = &$_REQUEST;
116: break;
117: }
118:
119: if (isset($input[$name]) && $input[$name] !== null) {
120: // Get the variable from the input hash and clean it
121: $var = self::cleanVar($input[$name], $mask, $type);
122: } else {
123: if ($default !== null) {
124: // Clean the default value
125: $var = self::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 self::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 self::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 self::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 self::getVar($name, $default, $hash, 'word');
204: }
205:
206: /**
207: * Fetches and returns a given filtered variable. The cmd
208: * filter only allows the characters [A-Za-z0-9.-_]. This is
209: * currently only a proxy function for getVar().
210: *
211: * See getVar() for more in-depth documentation on the parameters.
212: *
213: * @param string $name Variable name
214: * @param string $default Default value if the variable does not exist
215: * @param string $hash Where the var should come from (POST, GET, FILES, COOKIE, METHOD)
216: *
217: * @return string Requested variable
218: */
219: public static function getCmd($name, $default = '', $hash = 'default')
220: {
221: return self::getVar($name, $default, $hash, 'cmd');
222: }
223:
224: /**
225: * Fetches and returns a given filtered variable. The string
226: * filter deletes 'bad' HTML code, if not overridden by the mask.
227: * This is currently only a proxy function for getVar().
228: *
229: * See getVar() for more in-depth documentation on the parameters.
230: *
231: * @param string $name Variable name
232: * @param string $default Default value if the variable does not exist
233: * @param string $hash Where the var should come from (POST, GET, FILES, COOKIE, METHOD)
234: * @param int $mask Filter mask for the variable
235: *
236: * @return string Requested variable
237: */
238: public static function getString($name, $default = '', $hash = 'default', $mask = 0)
239: {
240: // Cast to string, in case self::ALLOWRAW was specified for mask
241: return (string) self::getVar($name, $default, $hash, 'string', $mask);
242: }
243:
244: /**
245: * Fetches and returns an array
246: *
247: * @param string $name Variable name
248: * @param mixed $default Default value if the variable does not exist
249: * @param string $hash Where the var should come from (POST, GET, FILES, COOKIE, METHOD)
250: *
251: * @return array
252: */
253: public static function getArray($name, $default = array(), $hash = 'default')
254: {
255: return self::getVar($name, $default, $hash, 'array');
256: }
257:
258: /**
259: * Fetches and returns raw text
260: *
261: * @param string $name Variable name
262: * @param string $default Default value if the variable does not exist
263: * @param string $hash Where the var should come from (POST, GET, FILES, COOKIE, METHOD)
264: *
265: * @return string Requested variable
266: */
267: public static function getText($name, $default = '', $hash = 'default')
268: {
269: return (string) self::getVar($name, $default, $hash, 'string', self::ALLOWRAW);
270: }
271:
272: /**
273: * Fetches and returns a web url
274: *
275: * @param string $name Variable name
276: * @param string $default Default value if the variable does not exist
277: * @param string $hash Where the var should come from (POST, GET, FILES, COOKIE, METHOD)
278: *
279: * @return string Requested variable
280: */
281: public static function getUrl($name, $default = '', $hash = 'default')
282: {
283: return (string) self::getVar($name, $default, $hash, 'weburl');
284: }
285:
286: /**
287: * Fetches and returns a file (or web) path
288: *
289: * @param string $name Variable name
290: * @param string $default Default value if the variable does not exist
291: * @param string $hash Where the var should come from (POST, GET, FILES, COOKIE, METHOD)
292: *
293: * @return string Requested variable
294: */
295: public static function getPath($name, $default = '', $hash = 'default')
296: {
297: return (string) self::getVar($name, $default, $hash, 'path');
298: }
299:
300: /**
301: * Fetches and returns an email address
302: *
303: * @param string $name Variable name
304: * @param string $default Default value if the variable does not exist
305: * @param string $hash Where the var should come from (POST, GET, FILES, COOKIE, METHOD)
306: *
307: * @return string email address or default if invalid
308: */
309: public static function getEmail($name, $default = '', $hash = 'default')
310: {
311: $ret = (string) self::getVar($name, $default, $hash, 'email');
312: return empty($ret) ? $default : $ret;
313: }
314:
315: /**
316: * Fetches and returns an IP address
317: *
318: * @param string $name Variable name
319: * @param string $default Default value if the variable does not exist
320: * @param string $hash Where the var should come from (POST, GET, FILES, COOKIE, METHOD)
321: *
322: * @return string IP address or default if invalid
323: */
324: public static function getIP($name, $default = '', $hash = 'default')
325: {
326: $ret = (string) self::getVar($name, $default, $hash, 'ip');
327: return empty($ret) ? $default : $ret;
328: }
329:
330: /**
331: * Return a DateTime object from a Xoops\Form\DateSelect of Xoops\Form\DateTime field
332: *
333: * @param string $name Variable name
334: * @param mixed $default Default value if the variable does not exist
335: * @param string $hash Where the var should come from (POST, GET, FILES, COOKIE, METHOD)
336: *
337: * @return \DateTime object
338: */
339: public static function getDateTime($name, $default = null, $hash = 'default')
340: {
341: $values = self::getVar($name, [], $hash, 'array');
342: $count = count($values);
343: if ($count === 1) {
344: $date = reset($values);
345: $ret = Time::inputToDateTime($date);
346: } elseif (isset($values['date']) && isset($values['time'])) {
347: $ret = Time::inputToDateTime($values);
348: } else {
349: $ret = Time::cleanTime($default);
350: }
351: return $ret;
352: }
353:
354: /**
355: * Set a variable in one of the request variables
356: *
357: * @param string $name Name
358: * @param string $value Value
359: * @param string $hash Hash
360: * @param boolean $overwrite Boolean
361: *
362: * @return string Previous value
363: */
364: public static function setVar($name, $value = null, $hash = 'method', $overwrite = true)
365: {
366: $hash = strtoupper($hash);
367: if ($hash === 'METHOD') {
368: $hash = strtoupper($_SERVER['REQUEST_METHOD']);
369: }
370:
371: // Get the requested hash and determine existing value
372: $original = self::get($hash, self::ALLOWRAW);
373: if (isset($original[$name])) {
374: $previous = $original[$name];
375: // don't overwrite value unless asked
376: if (!$overwrite) {
377: return $previous;
378: }
379: } else {
380: $previous = null;
381: }
382:
383: // set the value
384: switch ($hash) {
385: case 'GET':
386: $_GET[$name] = $value;
387: $_REQUEST[$name] = $value;
388: break;
389: case 'POST':
390: $_POST[$name] = $value;
391: $_REQUEST[$name] = $value;
392: break;
393: case 'REQUEST':
394: $_REQUEST[$name] = $value;
395: break;
396: case 'COOKIE':
397: $_COOKIE[$name] = $value;
398: $_REQUEST[$name] = $value;
399: break;
400: case 'FILES':
401: $_FILES[$name] = $value;
402: break;
403: case 'ENV':
404: $_ENV['name'] = $value;
405: break;
406: case 'SERVER':
407: $_SERVER['name'] = $value;
408: break;
409: }
410:
411: return $previous;
412: }
413:
414: /**
415: * Fetches and returns a request array.
416: *
417: * The default behaviour is fetching variables depending on the
418: * current request method: GET and HEAD will result in returning
419: * $_GET, POST and PUT will result in returning $_POST.
420: *
421: * You can force the source by setting the $hash parameter:
422: *
423: * - post $_POST
424: * - get $_GET
425: * - files $_FILES
426: * - cookie $_COOKIE
427: * - env $_ENV
428: * - server $_SERVER
429: * - method via current $_SERVER['REQUEST_METHOD']
430: * - default $_REQUEST
431: *
432: * @param string $hash to get (POST, GET, FILES, METHOD)
433: * @param int $mask Filter mask for the variable
434: *
435: * @return mixed Request hash
436: */
437: public static function get($hash = 'default', $mask = 0)
438: {
439: $hash = strtoupper($hash);
440:
441: if ($hash === 'METHOD') {
442: $hash = strtoupper($_SERVER['REQUEST_METHOD']);
443: }
444:
445: switch ($hash) {
446: case 'GET':
447: $input = $_GET;
448: break;
449: case 'POST':
450: $input = $_POST;
451: break;
452: case 'FILES':
453: $input = $_FILES;
454: break;
455: case 'COOKIE':
456: $input = $_COOKIE;
457: break;
458: case 'ENV':
459: $input = &$_ENV;
460: break;
461: case 'SERVER':
462: $input = &$_SERVER;
463: break;
464: default:
465: $input = $_REQUEST;
466: break;
467: }
468:
469: $result = self::cleanVars($input, $mask);
470:
471: return $result;
472: }
473:
474: /**
475: * Sets a request variable
476: *
477: * @param array $array An associative array of key-value pairs
478: * @param string $hash The request variable to set (POST, GET, FILES, METHOD)
479: * @param boolean $overwrite If true and an existing key is found, the value is overwritten, otherwise it is ingored
480: *
481: * @return void
482: */
483: public static function set($array, $hash = 'default', $overwrite = true)
484: {
485: foreach ($array as $key => $value) {
486: self::setVar($key, $value, $hash, $overwrite);
487: }
488: }
489:
490: /**
491: * Clean up an input variable.
492: *
493: * @param mixed $var The input variable.
494: * @param int $mask Filter bit mask.
495: * - 1=no trim: If this flag is cleared and the input is a string,
496: * the string will have leading and trailing whitespace trimmed.
497: * - 2=allow_raw: If set, no more filtering is performed, higher bits are ignored.
498: * - 4=allow_html: HTML is allowed, but passed through a safe HTML filter first.
499: * If set, no more filtering is performed.
500: * - If no bits other than the 1 bit is set, a strict filter is applied.
501: * @param string $type The variable type. See {@link FilterInput::clean()}.
502: *
503: * @return string
504: */
505: private static function cleanVar($var, $mask = 0, $type = null)
506: {
507: // Static input filters for specific settings
508: static $noHtmlFilter = null;
509: static $safeHtmlFilter = null;
510:
511: // convert $var in array if $type is ARRAY
512: if (strtolower($type) === 'array' && !is_array($var)) {
513: $var = array($var);
514: }
515:
516: // If the no trim flag is not set, trim the variable
517: if (!($mask & 1) && is_string($var)) {
518: $var = trim($var);
519: }
520:
521: // Now we handle input filtering
522: if ($mask & 2) {
523: // If the allow raw flag is set, do not modify the variable
524: } else {
525: if ($mask & 4) {
526: // If the allow html flag is set, apply a safe html filter to the variable
527: if (is_null($safeHtmlFilter)) {
528: $safeHtmlFilter = FilterInput::getInstance(null, null, 1, 1);
529: }
530: $var = $safeHtmlFilter->clean($var, $type);
531: } else {
532: // Since no allow flags were set, we will apply the most strict filter to the variable
533: if (is_null($noHtmlFilter)) {
534: $noHtmlFilter = FilterInput::getInstance();
535: }
536: $var = $noHtmlFilter->clean($var, $type);
537: }
538: }
539:
540: return $var;
541: }
542:
543: /**
544: * Clean up an array of variables.
545: *
546: * @param mixed $var The input variable.
547: * @param int $mask Filter bit mask. See {@link Request::cleanVar()}
548: * @param string $type The variable type. See {@link FilterInput::clean()}.
549: *
550: * @return string
551: */
552: private static function cleanVars($var, $mask = 0, $type = null)
553: {
554: if (is_string($var)) {
555: $var = self::cleanVar($var, $mask, $type);
556: } else {
557: foreach ($var as $key => &$value) {
558: $value = self::cleanVars($value, $mask, $type);
559: }
560: }
561:
562: return $var;
563: }
564: }
565: