1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* Http Request class for providing global vars to class for improved |
5
|
|
|
* encapsulation |
6
|
|
|
* |
7
|
|
|
* @package ElkArte Forum |
8
|
|
|
* @copyright ElkArte Forum contributors |
9
|
|
|
* @license BSD http://opensource.org/licenses/BSD-3-Clause (see accompanying LICENSE.txt file) |
10
|
|
|
* |
11
|
|
|
* @version 2.0 dev |
12
|
|
|
* |
13
|
|
|
*/ |
14
|
|
|
|
15
|
|
|
namespace ElkArte\Helper; |
16
|
|
|
|
17
|
|
|
/** |
18
|
|
|
* Class used to interact with super globals, POST, GET, SERVER, COOKIES, SESSION |
19
|
|
|
* |
20
|
|
|
* - Currently only a 'getter' of values |
21
|
|
|
* - Can be passed DataValidation sanitation values to return sanitized values |
22
|
|
|
* - Fetch raw values as $instance->post->keyname |
23
|
|
|
* - $this->-req->post->filename |
24
|
|
|
* - $this->_req->query->sa |
25
|
|
|
* - Fetch cleaned values with $instance->getPost('keyname', 'sanitation needs', 'default value') |
26
|
|
|
* - $this->-req->getPost('filename', 'trim|strval', ''); |
27
|
|
|
* - $this->-req->getQuery('filename', 'intval', 0); |
28
|
|
|
* - Can use rules as 'htmlspecialchars[ENT_COMPAT]', '\\ElkArte\\Helper\\Util::htmlspecialchars[ENT_QUOTES]' |
29
|
|
|
*/ |
30
|
|
|
class HttpReq |
31
|
|
|
{ |
32
|
|
|
/** @var object The returned POST values */ |
33
|
|
|
public $post; |
34
|
|
|
|
35
|
|
|
/** @var array The compiled post values (json and cleaned from request) */ |
36
|
|
|
private $_derived_post; |
37
|
|
|
|
38
|
|
|
/** @var object The returned GET values */ |
39
|
|
|
public $query; |
40
|
|
|
|
41
|
|
|
/** @var object The returned COOKIE values */ |
42
|
|
|
public $cookie; |
43
|
|
|
|
44
|
|
|
/** @var object The returned SESSION values */ |
45
|
|
|
public $session; |
46
|
|
|
|
47
|
|
|
/** @var object The returned SERVER values */ |
48
|
|
|
public $server; |
49
|
|
|
|
50
|
|
|
/** @var HttpReq Sole private \ElkArte\Helper\HttpReq instance */ |
51
|
|
|
private static $instance; |
52
|
|
|
|
53
|
|
|
/** @var array Used to hold processed (sanitised) values */ |
54
|
|
|
private $_param; |
55
|
|
|
|
56
|
|
|
/** @var DataValidator holds instance of the validator */ |
57
|
|
|
protected $_dataValidator; |
58
|
|
|
|
59
|
|
|
/** |
60
|
|
|
* Class constructor, sets PHP globals to class members |
61
|
|
|
* |
62
|
|
|
* @param $dataValidator DataValidator|null Instance of the data validator |
63
|
|
|
*/ |
64
|
|
|
private function __construct($dataValidator = null) |
65
|
|
|
{ |
66
|
|
|
// Make sure the validator is initiated |
67
|
|
|
$this->_dataValidator = $dataValidator ?? new DataValidator(); |
68
|
|
|
|
69
|
|
|
// Make the superglobals available as R/W properties |
70
|
|
|
$this->cookie = new \ArrayObject($_COOKIE, \ArrayObject::ARRAY_AS_PROPS); |
71
|
|
|
if (session_status() === PHP_SESSION_ACTIVE) |
72
|
|
|
{ |
73
|
|
|
$this->session = new \ArrayObject($_SESSION, \ArrayObject::ARRAY_AS_PROPS); |
74
|
|
|
} |
75
|
|
|
else |
76
|
|
|
{ |
77
|
|
|
$this->session = new \ArrayObject(array(), \ArrayObject::ARRAY_AS_PROPS); |
78
|
|
|
} |
79
|
|
|
|
80
|
|
|
$this->server = detectServer(); |
81
|
|
|
|
82
|
|
|
// Get will be in ->query, Post in ->post |
83
|
|
|
$this->_loadParsed(); |
84
|
|
|
} |
85
|
|
|
|
86
|
|
|
/** |
87
|
|
|
* Certain variables are born in Request, others are sanitized, and stored in |
88
|
|
|
* $_REQUEST, its a awful mess really. |
89
|
|
|
* |
90
|
|
|
* Once that mess is cleaned up this should not be needed. But the basis is due to |
91
|
|
|
* what function cleanRequest() does. |
92
|
|
|
* |
93
|
|
|
* What it does: |
94
|
|
|
* |
95
|
|
|
* - Finds items added by cleanRequest to $_REQUEST |
96
|
|
|
* - Adds the above to both $_POST and $_GET |
97
|
|
|
* - Looks for duplicate items in $_REQUEST and $_POST and uses the $_REQUEST |
98
|
|
|
* values, being they are "sanitized" |
99
|
|
|
* - $_GET ones are already re-stuffed by cleanRequest |
100
|
|
|
*/ |
101
|
|
|
private function _loadParsed() |
102
|
|
|
{ |
103
|
|
|
// Any that were born in cleanRequest, like start from topic=xyz.START |
104
|
|
|
// are added to the other supers |
105
|
|
|
$derived = array_diff_key($_REQUEST, $_POST, $_GET); |
106
|
|
|
$derived_get = array_merge($_GET, $derived); |
107
|
|
|
$this->_derived_post = array_merge($_POST, $derived); |
108
|
|
|
|
109
|
|
|
// Others may have been "sanitized" from either get or post and saved in request |
110
|
|
|
// these values replace the existing ones in $_POST |
111
|
|
|
$cleaned = array_intersect_key($_REQUEST, $this->_derived_post); |
112
|
|
|
$this->_derived_post = array_merge($this->_derived_post, $cleaned); |
113
|
|
|
|
114
|
|
|
// Make the $_GET $_POST super globals available as R/W properties |
115
|
|
|
$this->post = new \ArrayObject($this->_derived_post, \ArrayObject::ARRAY_AS_PROPS); |
116
|
|
|
$this->query = new \ArrayObject($derived_get, \ArrayObject::ARRAY_AS_PROPS); |
117
|
|
|
} |
118
|
|
|
|
119
|
|
|
/** |
120
|
|
|
* Generic fetch access for values contained in the super globals |
121
|
|
|
* |
122
|
|
|
* - gets in order of param, get and post |
123
|
|
|
* - $instance->keyanme will check cleaned params, get then post for values |
124
|
|
|
* - $_POST['foo'] = 'bar', $_GET['bar'] = 'foo' |
125
|
|
|
* - $this->req->post->foo is explicit and returns bar |
126
|
|
|
* - $this->req->foo is loose and will trigger this method, return foo as its a found key in GET |
127
|
|
|
* |
128
|
|
|
* @param string $key |
129
|
|
|
* |
130
|
|
|
* @return mixed|null |
131
|
|
|
*/ |
132
|
|
|
public function __get($key) |
133
|
|
|
{ |
134
|
|
|
if (isset($this->_param[$key])) |
135
|
|
|
{ |
136
|
|
|
return $this->_param[$key]; |
137
|
|
|
} |
138
|
|
|
|
139
|
|
|
if (isset($this->query->{$key})) |
140
|
|
|
{ |
141
|
|
|
return $this->query->{$key}; |
142
|
|
|
} |
143
|
|
|
|
144
|
|
|
return $this->post->{$key} ?? null; |
145
|
|
|
} |
146
|
|
|
|
147
|
|
|
/** |
148
|
|
|
* Alias to __get |
149
|
|
|
* |
150
|
|
|
* Allows lazy way to find and return a value from get or post key name |
151
|
|
|
* |
152
|
|
|
* @param string $name The key name of the value to return |
153
|
|
|
* @param string|null $sanitize a comma separated list of sanitation rules to apply |
154
|
|
|
* @param mixed|null $default default value to return if key value is not found |
155
|
|
|
* |
156
|
|
|
* @return mixed |
157
|
|
|
*/ |
158
|
|
|
public function get($name, $sanitize = null, $default = null) |
159
|
|
|
{ |
160
|
|
|
// See if it exists in one of the supers |
161
|
|
|
$temp = $this->__get($name); |
162
|
|
|
|
163
|
|
|
$this->_param[$name] = $default; |
164
|
|
|
|
165
|
|
|
if (isset($temp)) |
166
|
|
|
{ |
167
|
|
|
$this->_param[$name] = $temp; |
168
|
|
|
$this->_param[$name] = $this->cleanValue($name, $sanitize); |
169
|
|
|
} |
170
|
|
|
|
171
|
|
|
return $this->_param[$name]; |
172
|
|
|
} |
173
|
|
|
|
174
|
|
|
/** |
175
|
|
|
* Generic check to see if a property is set in one of the super globals |
176
|
|
|
* |
177
|
|
|
* - checks in order of param, get, post |
178
|
|
|
* |
179
|
|
|
* @param string $key |
180
|
|
|
* |
181
|
|
|
* @return bool |
182
|
|
|
*/ |
183
|
|
|
public function __isset($key) |
184
|
|
|
{ |
185
|
|
|
return match (true) |
186
|
|
|
{ |
187
|
|
|
isset($this->post->{$key}), isset($this->query->{$key}), isset($this->_param[$key]) => true, |
188
|
|
|
default => false, |
189
|
|
|
}; |
190
|
|
|
} |
191
|
|
|
|
192
|
|
|
/** |
193
|
|
|
* Alias to __isset() |
194
|
|
|
* |
195
|
|
|
* @param string $key |
196
|
|
|
* |
197
|
|
|
* @return bool |
198
|
|
|
*/ |
199
|
|
|
public function isSet($key) |
200
|
|
|
{ |
201
|
|
|
return $this->__isset($key); |
202
|
|
|
} |
203
|
|
|
|
204
|
|
|
/** |
205
|
|
|
* Method to return a $_GET value |
206
|
|
|
* |
207
|
|
|
* - Uses any sanitize rule(s) that can be passed to the \ElkArte\Helper\DataValidator class |
208
|
|
|
* - Returned value will be the sanitized value or null of the key is not in $_GET |
209
|
|
|
* - If you just want a value back access it directly as $req->query->{$name} |
210
|
|
|
* |
211
|
|
|
* @param string $name The key name of the value to return |
212
|
|
|
* @param string|null $sanitize a comma separated list of sanitation rules to apply |
213
|
|
|
* @param mixed|null $default default value to return if key value is not found |
214
|
|
|
* |
215
|
|
|
* @return mixed |
216
|
|
|
*/ |
217
|
|
|
public function getQuery($name = '', $sanitize = null, $default = null) |
218
|
|
|
{ |
219
|
|
|
$this->_param[$name] = $default; |
220
|
|
|
|
221
|
|
|
if (isset($this->query->{$name})) |
222
|
|
|
{ |
223
|
|
|
$this->_param[$name] = $this->query->{$name}; |
224
|
|
|
$this->_param[$name] = $this->cleanValue($name, $sanitize); |
225
|
|
|
} |
226
|
|
|
|
227
|
|
|
return $this->_param[$name]; |
228
|
|
|
} |
229
|
|
|
|
230
|
|
|
/** |
231
|
|
|
* Method to return a $_POST value |
232
|
|
|
* |
233
|
|
|
* - Uses any sanitize rule(s) that can be passed to the \ElkArte\Helper\DataValidator class |
234
|
|
|
* - Returned value will be the sanitized value or null of the key is not in $_POST |
235
|
|
|
* - If you just want a value back access it directly as $req->post->{$name} |
236
|
|
|
* |
237
|
|
|
* @param string $name The key name of the value to return |
238
|
|
|
* @param string|null $sanitize a comma separated list of sanitation rules to apply |
239
|
|
|
* @param mixed|null $default default value to return if key value is not found |
240
|
|
|
* |
241
|
|
|
* @return mixed |
242
|
|
|
*/ |
243
|
|
|
public function getPost($name = '', $sanitize = null, $default = null) |
244
|
|
|
{ |
245
|
|
|
$this->_param[$name] = $default; |
246
|
|
|
|
247
|
|
|
if (isset($this->post->{$name})) |
248
|
|
|
{ |
249
|
|
|
$this->_param[$name] = $this->post->{$name}; |
250
|
|
|
$this->_param[$name] = $this->cleanValue($name, $sanitize); |
251
|
|
|
} |
252
|
|
|
|
253
|
|
|
return $this->_param[$name]; |
254
|
|
|
} |
255
|
|
|
|
256
|
|
|
/** |
257
|
|
|
* Method to return a $_REQUEST value |
258
|
|
|
* |
259
|
|
|
* - Uses any sanitize rule(s) that can be passed to the \ElkArte\Helper\DataValidator class |
260
|
|
|
* - Returned value will be the sanitized value or null if the key is not found in either $_GET |
261
|
|
|
* or $_POST (in that order). Ideally you should know if something is in GET or POST and use |
262
|
|
|
* those get function directly. |
263
|
|
|
* |
264
|
|
|
* @param string $name The key name of the value to return |
265
|
|
|
* @param string|null $sanitize a comma separated list of sanitation rules to apply |
266
|
|
|
* @param mixed|null $default default value to return if key value is not found |
267
|
|
|
* |
268
|
|
|
* @return mixed |
269
|
|
|
*/ |
270
|
|
|
public function getRequest($name = '', $sanitize = null, $default = null) |
271
|
|
|
{ |
272
|
|
|
$this->_param[$name] = $default; |
273
|
|
|
|
274
|
|
|
if (isset($this->query->{$name})) |
275
|
|
|
{ |
276
|
|
|
$this->_param[$name] = $this->query->{$name}; |
277
|
|
|
$this->_param[$name] = $this->cleanValue($name, $sanitize); |
278
|
|
|
} |
279
|
|
|
elseif (isset($this->post->{$name})) |
280
|
|
|
{ |
281
|
|
|
$this->_param[$name] = $this->post->{$name}; |
282
|
|
|
$this->_param[$name] = $this->cleanValue($name, $sanitize); |
283
|
|
|
} |
284
|
|
|
|
285
|
|
|
return $this->_param[$name]; |
286
|
|
|
} |
287
|
|
|
|
288
|
|
|
/** |
289
|
|
|
* Helper function to do a value comparison to a GET value. Returns false |
290
|
|
|
* if the value does not exist or if it does not equal the comparison value. |
291
|
|
|
* |
292
|
|
|
* @param string $name get value to fetch |
293
|
|
|
* @param mixed $compare value to compare the get value to |
294
|
|
|
* @param null|string $sanitize optional | delimited data for validator |
295
|
|
|
* @param null|mixed $default if no value exists, what to set it to (will also be used in the compare) |
296
|
|
|
* |
297
|
|
|
* @return bool |
298
|
|
|
*/ |
299
|
|
|
public function compareQuery($name, $compare, $sanitize = null, $default = null) |
300
|
|
|
{ |
301
|
|
|
$this->getQuery($name, $sanitize, $default); |
302
|
|
|
|
303
|
|
|
return $this->isSet($name) && $this->_param[$name] === $compare; |
304
|
|
|
} |
305
|
|
|
|
306
|
|
|
/** |
307
|
|
|
* Helper function to do a value comparison to a Post value. Returns false |
308
|
|
|
* if the value does not exist or if it does not equal the comparison value. |
309
|
|
|
* |
310
|
|
|
* @param string $name get value to fetch |
311
|
|
|
* @param mixed $compare value to compare the post value to |
312
|
|
|
* @param null|string $sanitize optional | delimited data for validator |
313
|
|
|
* @param null|mixed $default if no value exists, what to set it to (will also be used in the compare) |
314
|
|
|
* |
315
|
|
|
* @return bool |
316
|
|
|
*/ |
317
|
|
|
public function comparePost($name, $compare, $sanitize = null, $default = null) |
318
|
|
|
{ |
319
|
|
|
$this->getPost($name, $sanitize, $default); |
320
|
|
|
|
321
|
|
|
return $this->isSet($name) && $this->_param[$name] === $compare; |
322
|
|
|
} |
323
|
|
|
|
324
|
|
|
/** |
325
|
|
|
* Method to return a $_COOKIE value |
326
|
|
|
* |
327
|
|
|
* - Does not provide sanitation capability |
328
|
|
|
* |
329
|
|
|
* @param string $name the name of the value to return |
330
|
|
|
* @param mixed|null $default default value to return if key value is not found |
331
|
|
|
* |
332
|
|
|
* @return mixed|null |
333
|
|
|
*/ |
334
|
|
|
public function getCookie($name = '', $default = null) |
335
|
|
|
{ |
336
|
|
|
if (isset($this->cookie->{$name})) |
337
|
|
|
{ |
338
|
|
|
return $this->cookie->{$name}; |
339
|
|
|
} |
340
|
|
|
|
341
|
|
|
return $default ?? null; |
342
|
|
|
} |
343
|
|
|
|
344
|
|
|
/** |
345
|
|
|
* Method to get a $_SESSION value |
346
|
|
|
* |
347
|
|
|
* - Does not provide sanitation capability |
348
|
|
|
* |
349
|
|
|
* @param string $name the name of the value to return |
350
|
|
|
* @param mixed|null $default default value to return if key value is not found |
351
|
|
|
* |
352
|
|
|
* @return mixed|null |
353
|
|
|
*/ |
354
|
|
|
public function getSession($name = '', $default = null) |
355
|
|
|
{ |
356
|
|
|
if (isset($this->session->{$name})) |
357
|
|
|
{ |
358
|
|
|
return $this->session->{$name}; |
359
|
|
|
} |
360
|
|
|
|
361
|
|
|
return $default ?? null; |
362
|
|
|
} |
363
|
|
|
|
364
|
|
|
/** |
365
|
|
|
* Runs sanitation rules against a single value |
366
|
|
|
* |
367
|
|
|
* @param string $name the key name in the _param array |
368
|
|
|
* @param string|null $sanitize comma separated list of rules |
369
|
|
|
* |
370
|
|
|
* @return mixed|array|null |
371
|
|
|
*/ |
372
|
|
|
public function cleanValue($name, $sanitize = null) |
373
|
|
|
{ |
374
|
|
|
// No rules, then return the current value |
375
|
|
|
if ($sanitize === null) |
376
|
|
|
{ |
377
|
|
|
return $this->_param[$name]; |
378
|
|
|
} |
379
|
|
|
|
380
|
|
|
// To the validator |
381
|
|
|
$this->_dataValidator->validation_rules(); |
382
|
|
|
$this->_dataValidator->sanitation_rules([$name => $sanitize]); |
383
|
|
|
|
384
|
|
|
if (is_array($this->_param[$name])) |
385
|
|
|
{ |
386
|
|
|
$this->_dataValidator->input_processing([$name => 'array']); |
387
|
|
|
} |
388
|
|
|
|
389
|
|
|
$this->_dataValidator->validate($this->_param); |
390
|
|
|
|
391
|
|
|
// Return the clean value |
392
|
|
|
return $this->_dataValidator->validation_data($name); |
393
|
|
|
} |
394
|
|
|
|
395
|
|
|
/** |
396
|
|
|
* Removes a value from the post or query arrays |
397
|
|
|
* |
398
|
|
|
* @param string $name the key name in the _param array |
399
|
|
|
* @param string|null $type where you want the value removed from post, query, both |
400
|
|
|
*/ |
401
|
|
|
public function clearValue($name, $type) |
402
|
|
|
{ |
403
|
|
|
unset($this->_param[$name]); |
404
|
|
|
|
405
|
|
|
if ($type === 'post' || $type === 'both') |
406
|
|
|
{ |
407
|
|
|
unset($this->post->{$name}); |
408
|
|
|
} |
409
|
|
|
|
410
|
|
|
if ($type === 'query' || $type === 'both') |
411
|
|
|
{ |
412
|
|
|
unset($this->post->{$name}); |
413
|
|
|
} |
414
|
|
|
} |
415
|
|
|
|
416
|
|
|
/** |
417
|
|
|
* Retrieve the sole instance of this class. |
418
|
|
|
* |
419
|
|
|
* @return HttpReq |
420
|
|
|
*/ |
421
|
|
|
public static function instance() |
422
|
|
|
{ |
423
|
|
|
if (self::$instance === null) |
424
|
|
|
{ |
425
|
|
|
self::$instance = new HttpReq(); |
426
|
|
|
} |
427
|
|
|
|
428
|
|
|
return self::$instance; |
429
|
|
|
} |
430
|
|
|
} |
431
|
|
|
|