1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* Request basic class. |
4
|
|
|
* |
5
|
|
|
* @package App |
6
|
|
|
* |
7
|
|
|
* @copyright YetiForce S.A. |
8
|
|
|
* @license YetiForce Public License 6.5 (licenses/LicenseEN.txt or yetiforce.com) |
9
|
|
|
* @author Mariusz Krzaczkowski <[email protected]> |
10
|
|
|
* @author Radosław Skrzypczak <[email protected]> |
11
|
|
|
*/ |
12
|
|
|
|
13
|
|
|
namespace App; |
14
|
|
|
|
15
|
|
|
/** |
16
|
|
|
* Request basic class. |
17
|
|
|
*/ |
18
|
|
|
class Request |
19
|
|
|
{ |
20
|
|
|
/** |
21
|
|
|
* Raw request data. |
22
|
|
|
* |
23
|
|
|
* @var array |
24
|
|
|
*/ |
25
|
|
|
protected $rawValues = []; |
26
|
|
|
|
27
|
|
|
/** |
28
|
|
|
* Headers request. |
29
|
|
|
* |
30
|
|
|
* @var array |
31
|
|
|
*/ |
32
|
|
|
protected $headers; |
33
|
|
|
|
34
|
|
|
/** |
35
|
|
|
* Self instance. |
36
|
|
|
* |
37
|
|
|
* @var Request |
38
|
|
|
*/ |
39
|
|
|
protected static $request; |
40
|
|
|
|
41
|
|
|
/** |
42
|
|
|
* Purified request values for get. |
43
|
|
|
* |
44
|
|
|
* @var array |
45
|
|
|
*/ |
46
|
|
|
protected $purifiedValuesByGet = []; |
47
|
|
|
|
48
|
|
|
/** |
49
|
|
|
* Purified request values for type. |
50
|
|
|
* |
51
|
|
|
* @var array |
52
|
|
|
*/ |
53
|
|
|
protected $purifiedValuesByType = []; |
54
|
|
|
|
55
|
|
|
/** |
56
|
|
|
* Purified request values for integer. |
57
|
|
|
* |
58
|
|
|
* @var array |
59
|
|
|
*/ |
60
|
|
|
protected $purifiedValuesByInteger = []; |
61
|
|
|
|
62
|
|
|
/** |
63
|
|
|
* Purified request values for array. |
64
|
|
|
* |
65
|
|
|
* @var array |
66
|
|
|
*/ |
67
|
|
|
protected $purifiedValuesByArray = []; |
68
|
|
|
|
69
|
|
|
/** |
70
|
|
|
* Purified request values for exploded. |
71
|
|
|
* |
72
|
|
|
* @var array |
73
|
|
|
*/ |
74
|
|
|
protected $purifiedValuesByExploded = []; |
75
|
|
|
|
76
|
|
|
/** |
77
|
|
|
* Purified request values for multi dimension array. |
78
|
|
|
* |
79
|
|
|
* @var array |
80
|
|
|
*/ |
81
|
|
|
protected $purifiedValuesByMultiDimension = []; |
82
|
|
|
|
83
|
|
|
/** |
84
|
|
|
* Purified request values for date range. |
85
|
|
|
* |
86
|
|
|
* @var array |
87
|
|
|
*/ |
88
|
|
|
protected $purifiedValuesByDateRange = []; |
89
|
|
|
|
90
|
|
|
/** |
91
|
|
|
* Purified request values for date html. |
92
|
|
|
* |
93
|
|
|
* @var array |
94
|
|
|
*/ |
95
|
|
|
protected $purifiedValuesByHtml = []; |
96
|
|
|
/** |
97
|
|
|
* List of headings and sanitization methods. |
98
|
|
|
* |
99
|
|
|
* @var array |
100
|
16 |
|
*/ |
101
|
|
|
public $headersPurifierMap = [ |
102
|
16 |
|
]; |
103
|
16 |
|
|
104
|
|
|
/** |
105
|
|
|
* Constructor. |
106
|
16 |
|
* |
107
|
|
|
* @param array $rawValues |
108
|
|
|
* @param bool $overwrite |
109
|
|
|
*/ |
110
|
|
|
public function __construct($rawValues, $overwrite = true) |
111
|
|
|
{ |
112
|
|
|
$this->rawValues = $rawValues; |
113
|
|
|
if ($overwrite) { |
114
|
|
|
static::$request = $this; |
115
|
|
|
} |
116
|
38 |
|
} |
117
|
|
|
|
118
|
38 |
|
/** |
119
|
|
|
* Function to get the value for a given key. |
120
|
|
|
* |
121
|
38 |
|
* @param string $key |
122
|
|
|
* @param mixed $value Default value |
123
|
|
|
* |
124
|
38 |
|
* @return mixed |
125
|
|
|
*/ |
126
|
|
|
public function get($key, $value = '') |
127
|
|
|
{ |
128
|
|
|
if (isset($this->purifiedValuesByGet[$key])) { |
129
|
|
|
return $this->purifiedValuesByGet[$key]; |
130
|
|
|
} |
131
|
|
|
if (isset($this->rawValues[$key])) { |
132
|
|
|
$value = $this->rawValues[$key]; |
133
|
|
|
} else { |
134
|
|
|
return $value; |
135
|
|
|
} |
136
|
|
|
if (\is_string($value) && (0 === strpos($value, '[') || 0 === strpos($value, '{'))) { |
137
|
|
|
$decodeValue = Json::decode($value); |
138
|
|
|
if (isset($decodeValue)) { |
139
|
|
|
$value = $decodeValue; |
140
|
|
|
} |
141
|
|
|
} |
142
|
|
|
if ($value) { |
143
|
|
|
$value = Purifier::purify($value); |
144
|
|
|
} |
145
|
|
|
|
146
|
|
|
return $this->purifiedValuesByGet[$key] = $value; |
147
|
|
|
} |
148
|
|
|
|
149
|
|
|
/** |
150
|
|
|
* Purify by data type. |
151
|
|
|
* |
152
|
|
|
* Type list: |
153
|
|
|
* Standard - only words |
154
|
15 |
|
* 1 - only words |
155
|
|
|
* Alnum - word and int |
156
|
15 |
|
* 2 - word and int |
157
|
|
|
* |
158
|
|
|
* @param string $key Key name |
159
|
15 |
|
* @param int|string $type Data type that is only acceptable, default only words 'Standard' |
160
|
15 |
|
* @param mixed $convert |
161
|
|
|
* |
162
|
|
|
* @return bool|mixed |
163
|
|
|
*/ |
164
|
|
|
public function getByType($key, $type = 'Standard', $convert = false) |
165
|
|
|
{ |
166
|
|
|
if (isset($this->purifiedValuesByType[$key][$type])) { |
167
|
|
|
return $this->purifiedValuesByType[$key][$type]; |
168
|
|
|
} |
169
|
|
|
if (isset($this->rawValues[$key])) { |
170
|
|
|
return $this->purifiedValuesByType[$key][$type] = Purifier::purifyByType($this->rawValues[$key], $type, $convert); |
171
|
|
|
} |
172
|
|
|
return false; |
173
|
|
|
} |
174
|
|
|
|
175
|
|
|
/** |
176
|
|
|
* Function to get the boolean value for a given key. |
177
|
|
|
* |
178
|
|
|
* @param string $key |
179
|
|
|
* @param bool $defaultValue Default value |
180
|
|
|
* |
181
|
|
|
* @return bool |
182
|
|
|
*/ |
183
|
|
|
public function getBoolean(string $key, bool $defaultValue = null) |
184
|
|
|
{ |
185
|
|
|
$value = $this->get($key, $defaultValue); |
186
|
|
|
if (\is_bool($value)) { |
187
|
|
|
return $value; |
188
|
|
|
} |
189
|
|
|
return 0 === strcasecmp('true', (string) $value) || '1' === (string) $value; |
190
|
|
|
} |
191
|
|
|
|
192
|
|
|
/** |
193
|
|
|
* Function to get the integer value for a given key. |
194
|
|
|
* |
195
|
|
|
* @param string $key |
196
|
|
|
* @param int $value |
197
|
|
|
* |
198
|
|
|
* @return int |
199
|
|
|
*/ |
200
|
|
|
public function getInteger($key, $value = 0) |
201
|
|
|
{ |
202
|
|
|
if (isset($this->purifiedValuesByInteger[$key])) { |
203
|
|
|
return $this->purifiedValuesByInteger[$key]; |
204
|
|
|
} |
205
|
|
|
if (!isset($this->rawValues[$key])) { |
206
|
|
|
return $value; |
207
|
|
|
} |
208
|
|
|
if (false !== ($value = filter_var($this->rawValues[$key], FILTER_VALIDATE_INT))) { |
209
|
|
|
return $this->purifiedValuesByInteger[$key] = $value; |
210
|
|
|
} |
211
|
|
|
|
212
|
|
|
throw new \App\Exceptions\IllegalValue("ERR_NOT_ALLOWED_VALUE||$key||{$this->rawValues[$key]}", 406); |
213
|
|
|
} |
214
|
|
|
|
215
|
|
|
/** |
216
|
|
|
* Function to get the array values for a given key. |
217
|
|
|
* |
218
|
|
|
* @param string $key |
219
|
|
|
* @param mixed $type |
220
|
|
|
* @param array $value |
221
|
|
|
* @param string|null $keyType |
222
|
|
|
* |
223
|
|
|
* @return array |
224
|
|
|
*/ |
225
|
|
|
public function getArray($key, $type = false, $value = [], ?string $keyType = null) |
226
|
|
|
{ |
227
|
|
|
if (isset($this->purifiedValuesByArray[$key])) { |
228
|
|
|
return $this->purifiedValuesByArray[$key]; |
229
|
|
|
} |
230
|
|
|
if (isset($this->rawValues[$key])) { |
231
|
|
|
$value = $this->rawValues[$key]; |
232
|
|
|
if (!$value) { |
233
|
|
|
return []; |
234
|
|
|
} |
235
|
|
|
if (\is_string($value) && (0 === strpos($value, '[') || 0 === strpos($value, '{'))) { |
236
|
|
|
$decodeValue = Json::decode($value); |
237
|
|
|
if (isset($decodeValue)) { |
238
|
|
|
$value = $decodeValue; |
239
|
|
|
} else { |
240
|
|
|
\App\Log::warning('Invalid data format, problem encountered while decoding JSON. Data should be in JSON format. Data: ' . $value); |
241
|
|
|
} |
242
|
|
|
} |
243
|
|
|
if ($value) { |
244
|
|
|
if (\is_array($value)) { |
245
|
|
|
$input = []; |
246
|
|
|
foreach ($value as $k => $v) { |
247
|
|
|
if (!\is_int($k)) { |
248
|
|
|
$k = $keyType ? Purifier::purifyByType($k, $keyType) : Purifier::purify($k); |
249
|
|
|
} |
250
|
|
|
$input[$k] = $type ? Purifier::purifyByType($v, $type) : Purifier::purify($v); |
251
|
|
|
} |
252
|
|
|
$value = $input; |
253
|
|
|
} else { |
254
|
|
|
$value = $type ? Purifier::purifyByType($value, $type) : Purifier::purify($value); |
255
|
|
|
} |
256
|
|
|
} |
257
|
|
|
|
258
|
|
|
return $this->purifiedValuesByArray[$key] = (array) $value; |
259
|
|
|
} |
260
|
|
|
return $value; |
261
|
|
|
} |
262
|
|
|
|
263
|
|
|
/** |
264
|
|
|
* Function to get the exploded values for a given key. |
265
|
|
|
* |
266
|
|
|
* @param string $key |
267
|
|
|
* @param string $delimiter |
268
|
|
|
* @param bool|string $type |
269
|
|
|
* |
270
|
|
|
* @return array |
271
|
|
|
*/ |
272
|
|
|
public function getExploded($key, $delimiter = ',', $type = false) |
273
|
|
|
{ |
274
|
|
|
if (isset($this->purifiedValuesByExploded[$key])) { |
275
|
|
|
return $this->purifiedValuesByExploded[$key]; |
276
|
|
|
} |
277
|
|
|
$value = []; |
278
|
|
|
if (isset($this->rawValues[$key])) { |
279
|
|
|
if ('' === $this->rawValues[$key]) { |
280
|
|
|
return $value; |
281
|
|
|
} |
282
|
1 |
|
$value = explode($delimiter, $this->rawValues[$key]); |
283
|
|
|
if ($value) { |
|
|
|
|
284
|
1 |
|
$value = $type ? Purifier::purifyByType($value, $type) : Purifier::purify($value); |
|
|
|
|
285
|
1 |
|
} |
286
|
1 |
|
|
287
|
1 |
|
return $this->purifiedValuesByExploded[$key] = $value; |
288
|
|
|
} |
289
|
|
|
|
290
|
1 |
|
return $value; |
291
|
1 |
|
} |
292
|
1 |
|
|
293
|
|
|
/** |
294
|
|
|
* Purify multi dimension array. |
295
|
1 |
|
* |
296
|
|
|
* @param mixed $values |
297
|
1 |
|
* @param array|string $template |
298
|
|
|
* |
299
|
|
|
* @throws \App\Exceptions\IllegalValue |
300
|
1 |
|
* |
301
|
|
|
* @return mixed |
302
|
1 |
|
*/ |
303
|
|
|
private function purifyMultiDimensionArray($values, $template) |
304
|
|
|
{ |
305
|
|
|
if (\is_array($template)) { |
306
|
|
|
foreach ($values as $firstKey => $value) { |
307
|
|
|
if (\is_array($value)) { |
308
|
|
|
if (1 === \count($template)) { |
309
|
|
|
$template = current($template); |
310
|
|
|
} |
311
|
|
|
foreach ($value as $secondKey => $val) { |
312
|
|
|
$tempTemplate = $template; |
313
|
|
|
if (isset($template[$firstKey])) { |
314
|
|
|
$tempTemplate = $template[$firstKey]; |
315
|
1 |
|
} |
316
|
|
|
if (1 === \count($tempTemplate)) { |
317
|
|
|
$tempTemplate = current($tempTemplate); |
318
|
1 |
|
} elseif (!isset($tempTemplate[$secondKey])) { |
319
|
|
|
throw new Exceptions\IllegalValue("ERR_NOT_ALLOWED_VALUE||{$secondKey}", 406); |
320
|
|
|
} else { |
321
|
|
|
$tempTemplate = $tempTemplate[$secondKey]; |
322
|
|
|
} |
323
|
|
|
$values[$firstKey][$secondKey] = $this->purifyMultiDimensionArray($val, $tempTemplate); |
324
|
|
|
} |
325
|
|
|
} else { |
326
|
|
|
if (\is_array($template) && 1 === \count($template)) { |
327
|
|
|
$values[$firstKey] = $this->purifyMultiDimensionArray($value, current($template)); |
328
|
|
|
} elseif (isset($template[$firstKey])) { |
329
|
1 |
|
$values[$firstKey] = $this->purifyMultiDimensionArray($value, $template[$firstKey]); |
330
|
|
|
} else { |
331
|
1 |
|
throw new Exceptions\IllegalValue("ERR_NOT_ALLOWED_VALUE||{$firstKey}||" . print_r($template, true), 406); |
|
|
|
|
332
|
1 |
|
} |
333
|
|
|
} |
334
|
1 |
|
} |
335
|
1 |
|
} else { |
336
|
|
|
$values = empty($values) ? $values : ($template ? Purifier::purifyByType($values, $template) : Purifier::purify($values)); |
337
|
|
|
} |
338
|
|
|
return $values; |
339
|
|
|
} |
340
|
|
|
|
341
|
|
|
/** |
342
|
|
|
* Function to get multi dimension array. |
343
|
1 |
|
* |
344
|
1 |
|
* @param string $key |
345
|
|
|
* @param array $template |
346
|
|
|
* |
347
|
1 |
|
* @return array |
348
|
|
|
*/ |
349
|
|
|
public function getMultiDimensionArray(string $key, array $template): array |
350
|
|
|
{ |
351
|
|
|
$return = []; |
352
|
|
|
if (isset($this->purifiedValuesByMultiDimension[$key])) { |
353
|
|
|
$return = $this->purifiedValuesByMultiDimension[$key]; |
354
|
|
|
} elseif (isset($this->rawValues[$key]) && ($value = $this->rawValues[$key])) { |
355
|
|
|
if (\is_string($value) && (0 === strpos($value, '[') || 0 === strpos($value, '{'))) { |
356
|
|
|
$decodeValue = Json::decode($value); |
357
|
|
|
if (null !== $decodeValue) { |
358
|
|
|
$value = $decodeValue; |
359
|
|
|
} else { |
360
|
|
|
Log::warning('Invalid data format, problem encountered while decoding JSON. Data should be in JSON format. Data: ' . $value); |
361
|
|
|
} |
362
|
|
|
} |
363
|
|
|
$value = (array) $this->purifyMultiDimensionArray($value, $template); |
364
|
|
|
$return = $this->purifiedValuesByMultiDimension[$key] = $value; |
365
|
|
|
} |
366
|
|
|
|
367
|
|
|
return $return; |
368
|
|
|
} |
369
|
|
|
|
370
|
|
|
/** |
371
|
|
|
* Function to get the date range values for a given key. |
372
|
|
|
* |
373
|
|
|
* @param string $key request param like 'createdtime' |
374
|
|
|
* |
375
|
|
|
* @return array |
376
|
|
|
*/ |
377
|
|
|
public function getDateRange($key) |
378
|
|
|
{ |
379
|
|
|
return $this->getByType($key, 'DateRangeUserFormat'); |
|
|
|
|
380
|
|
|
} |
381
|
|
|
|
382
|
|
|
/** |
383
|
|
|
* Function to get html the value for a given key. |
384
|
|
|
* |
385
|
|
|
* @param string $key |
386
|
|
|
* @param mixed $value |
387
|
|
|
* |
388
|
|
|
* @return mixed |
389
|
|
|
*/ |
390
|
|
|
public function getForHtml($key, $value = '') |
391
|
|
|
{ |
392
|
|
|
if (isset($this->purifiedValuesByHtml[$key])) { |
393
|
|
|
return $this->purifiedValuesByHtml[$key]; |
394
|
|
|
} |
395
|
|
|
if (isset($this->rawValues[$key])) { |
396
|
|
|
$value = $this->rawValues[$key]; |
397
|
|
|
} |
398
|
|
|
if ($value) { |
399
|
|
|
$value = \App\Purifier::purifyHtml($value); |
400
|
|
|
} |
401
|
|
|
|
402
|
|
|
return $this->purifiedValuesByHtml[$key] = $value; |
403
|
|
|
} |
404
|
|
|
|
405
|
|
|
/** |
406
|
|
|
* Function to get the value if its safe to use for SQL Query (column). |
407
|
|
|
* |
408
|
|
|
* @param string $key |
409
|
|
|
* @param bool $skipEmtpy |
410
|
|
|
* |
411
|
|
|
* @return string |
412
|
|
|
*/ |
413
|
1 |
|
public function getForSql($key, $skipEmtpy = true) |
414
|
|
|
{ |
415
|
1 |
|
return Purifier::purifySql($this->get($key), $skipEmtpy); |
|
|
|
|
416
|
|
|
} |
417
|
|
|
|
418
|
|
|
/** |
419
|
1 |
|
* Function to get the request mode. |
420
|
|
|
* |
421
|
|
|
* @return string |
422
|
|
|
*/ |
423
|
|
|
public function getMode() |
424
|
|
|
{ |
425
|
|
|
return '' !== $this->getRaw('mode') ? $this->getByType('mode', 'Alnum') : ''; |
|
|
|
|
426
|
|
|
} |
427
|
1 |
|
|
428
|
|
|
/** |
429
|
1 |
|
* Get all data. |
430
|
|
|
* |
431
|
|
|
* @return array |
432
|
|
|
*/ |
433
|
|
|
public function getAll() |
434
|
|
|
{ |
435
|
|
|
foreach ($this->rawValues as $key => $value) { |
436
|
|
|
$this->get($key); |
437
|
|
|
} |
438
|
|
|
|
439
|
|
|
return $this->purifiedValuesByGet; |
440
|
|
|
} |
441
|
|
|
|
442
|
|
|
/** |
443
|
|
|
* Get all raw data. |
444
|
|
|
* |
445
|
|
|
* @return array |
446
|
|
|
*/ |
447
|
|
|
public function getAllRaw() |
448
|
|
|
{ |
449
|
|
|
return $this->rawValues; |
450
|
|
|
} |
451
|
|
|
|
452
|
|
|
/** |
453
|
|
|
* Get raw value. |
454
|
1 |
|
* |
455
|
|
|
* @param string $key |
456
|
1 |
|
* @param mixed $defaultValue |
457
|
|
|
* |
458
|
|
|
* @return mixed |
459
|
1 |
|
*/ |
460
|
1 |
|
public function getRaw($key, $defaultValue = '') |
461
|
1 |
|
{ |
462
|
1 |
|
if (isset($this->rawValues[$key])) { |
463
|
|
|
return $this->rawValues[$key]; |
464
|
|
|
} |
465
|
|
|
|
466
|
|
|
return $defaultValue; |
467
|
|
|
} |
468
|
|
|
|
469
|
|
|
/** |
470
|
|
|
* Get all headers. |
471
|
|
|
* |
472
|
|
|
* @return string[] |
473
|
|
|
*/ |
474
|
1 |
|
public function getHeaders() |
475
|
|
|
{ |
476
|
|
|
if (isset($this->headers)) { |
477
|
|
|
return $this->headers; |
478
|
|
|
} |
479
|
|
|
$data = array_change_key_case(getallheaders(), CASE_LOWER); |
480
|
|
|
foreach ($data as $key => &$value) { |
481
|
|
|
if ('' !== $value) { |
482
|
|
|
$value = isset($this->headersPurifierMap[$key]) ? Purifier::purifyByType($value, $this->headersPurifierMap[$key]) : Purifier::purify($value); |
483
|
|
|
} |
484
|
|
|
} |
485
|
|
|
return $this->headers = $data; |
486
|
|
|
} |
487
|
|
|
|
488
|
|
|
/** |
489
|
|
|
* Get header for a given key. |
490
|
|
|
* |
491
|
|
|
* @param string $key |
492
|
|
|
* |
493
|
|
|
* @return string |
494
|
|
|
*/ |
495
|
|
|
public function getHeader($key) |
496
|
|
|
{ |
497
|
|
|
if (!isset($this->headers)) { |
498
|
|
|
$this->getHeaders(); |
499
|
|
|
} |
500
|
|
|
return $this->headers[$key] ?? null; |
501
|
|
|
} |
502
|
|
|
|
503
|
|
|
/** |
504
|
|
|
* Get request method. |
505
|
|
|
* |
506
|
|
|
* @throws \App\Exceptions\AppException |
507
|
|
|
* |
508
|
|
|
* @return string |
509
|
|
|
*/ |
510
|
|
|
public static function getRequestMethod() |
511
|
|
|
{ |
512
|
|
|
$method = $_SERVER['REQUEST_METHOD']; |
513
|
|
|
if ('POST' === $method && isset($_SERVER['HTTP_X_HTTP_METHOD'])) { |
514
|
|
|
if ('DELETE' === $_SERVER['HTTP_X_HTTP_METHOD']) { |
515
|
|
|
$method = 'DELETE'; |
516
|
|
|
} elseif ('PUT' === $_SERVER['HTTP_X_HTTP_METHOD']) { |
517
|
|
|
$method = 'PUT'; |
518
|
|
|
} else { |
519
|
|
|
throw new \App\Exceptions\AppException('Unexpected Header'); |
520
|
|
|
} |
521
|
|
|
} |
522
|
|
|
return strtoupper($method); |
523
|
|
|
} |
524
|
2 |
|
|
525
|
|
|
/** |
526
|
2 |
|
* Get server and execution environment information. |
527
|
2 |
|
* |
528
|
|
|
* @param string $key |
529
|
|
|
* @param mixed $default |
530
|
|
|
* |
531
|
|
|
* @return bool |
532
|
|
|
*/ |
533
|
|
|
public function getServer($key, $default = false) |
534
|
|
|
{ |
535
|
|
|
if (!isset($_SERVER[$key])) { |
536
|
|
|
return $default; |
537
|
|
|
} |
538
|
|
|
return Purifier::purifyByType($_SERVER[$key], 'Text'); |
539
|
|
|
} |
540
|
|
|
|
541
|
|
|
/** |
542
|
|
|
* Get module name. |
543
|
|
|
* |
544
|
|
|
* @param bool $raw |
545
|
|
|
* |
546
|
|
|
* @return string |
547
|
|
|
*/ |
548
|
|
|
public function getModule($raw = true) |
549
|
|
|
{ |
550
|
|
|
$moduleName = $this->getByType('module', \App\Purifier::ALNUM); |
551
|
|
|
if (!$raw && !$this->isEmpty('parent', true) && 'Settings' === ($parentModule = $this->getByType('parent', \App\Purifier::ALNUM))) { |
552
|
|
|
$moduleName = "$parentModule:$moduleName"; |
553
|
|
|
} |
554
|
|
|
return $moduleName; |
|
|
|
|
555
|
|
|
} |
556
|
|
|
|
557
|
1 |
|
/** |
558
|
|
|
* Check for existence of key. |
559
|
1 |
|
* |
560
|
|
|
* @param string $key |
561
|
|
|
* |
562
|
|
|
* @return bool |
563
|
|
|
*/ |
564
|
|
|
public function has($key) |
565
|
|
|
{ |
566
|
|
|
return isset($this->rawValues[$key]); |
567
|
|
|
} |
568
|
|
|
|
569
|
|
|
/** |
570
|
1 |
|
* Function to check if the key is empty. |
571
|
|
|
* |
572
|
1 |
|
* @param string $key |
573
|
|
|
* @param bool $emptyFunction |
574
|
|
|
* |
575
|
|
|
* @return bool |
576
|
1 |
|
*/ |
577
|
|
|
public function isEmpty($key, $emptyFunction = false) |
578
|
|
|
{ |
579
|
|
|
if ($emptyFunction) { |
580
|
|
|
return empty($this->rawValues[$key]); |
581
|
|
|
} |
582
|
|
|
return !isset($this->rawValues[$key]) || '' === $this->rawValues[$key]; |
583
|
|
|
} |
584
|
|
|
|
585
|
|
|
/** |
586
|
|
|
* Function to set the value for a given key. |
587
|
15 |
|
* |
588
|
|
|
* @param string $key |
589
|
15 |
|
* @param mixed $value |
590
|
15 |
|
* @param bool $onlyRaw |
591
|
|
|
* |
592
|
15 |
|
* @return $this |
593
|
|
|
*/ |
594
|
|
|
public function set($key, $value, bool $onlyRaw = false): self |
595
|
|
|
{ |
596
|
|
|
if ($onlyRaw) { |
597
|
|
|
$this->rawValues[$key] = $value; |
598
|
|
|
} else { |
599
|
|
|
$this->rawValues[$key] = $this->purifiedValuesByGet[$key] = $this->purifiedValuesByInteger[$key] = $this->purifiedValuesByHtml[$key] = $value; |
600
|
|
|
$this->purifiedValuesByType[$key] = []; |
601
|
|
|
} |
602
|
|
|
return $this; |
603
|
|
|
} |
604
|
|
|
|
605
|
|
|
/** |
606
|
|
|
* Function to remove the value for a given key. |
607
|
|
|
* |
608
|
|
|
* @param string $key |
609
|
|
|
*/ |
610
|
|
|
public function delete($key) |
611
|
|
|
{ |
612
|
|
|
if (isset($this->purifiedValuesByGet[$key])) { |
613
|
|
|
unset($this->purifiedValuesByGet[$key]); |
614
|
|
|
} |
615
|
|
|
if (isset($this->purifiedValuesByInteger[$key])) { |
616
|
|
|
unset($this->purifiedValuesByInteger[$key]); |
617
|
|
|
} |
618
|
|
|
if (isset($this->purifiedValuesByType[$key])) { |
619
|
|
|
unset($this->purifiedValuesByType[$key]); |
620
|
|
|
} |
621
|
|
|
if (isset($this->purifiedValuesByHtml[$key])) { |
622
|
|
|
unset($this->purifiedValuesByHtml[$key]); |
623
|
|
|
} |
624
|
|
|
if (isset($this->purifiedValuesByArray[$key])) { |
625
|
|
|
unset($this->purifiedValuesByArray[$key]); |
626
|
|
|
} |
627
|
|
|
if (isset($this->purifiedValuesByDateRange[$key])) { |
628
|
|
|
unset($this->purifiedValuesByDateRange[$key]); |
629
|
|
|
} |
630
|
|
|
if (isset($this->purifiedValuesByExploded[$key])) { |
631
|
|
|
unset($this->purifiedValuesByExploded[$key]); |
632
|
|
|
} |
633
|
|
|
if (isset($this->purifiedValuesByMultiDimension[$key])) { |
634
|
|
|
unset($this->purifiedValuesByMultiDimension[$key]); |
635
|
|
|
} |
636
|
|
|
if (isset($this->rawValues[$key])) { |
637
|
|
|
unset($this->rawValues[$key]); |
638
|
|
|
} |
639
|
|
|
} |
640
|
|
|
|
641
|
|
|
/** |
642
|
|
|
* Get all request keys. |
643
|
|
|
* |
644
|
|
|
* @return array |
645
|
|
|
*/ |
646
|
|
|
public function getKeys() |
647
|
|
|
{ |
648
|
|
|
return array_keys($this->rawValues); |
649
|
|
|
} |
650
|
|
|
|
651
|
|
|
/** |
652
|
|
|
* Function to check if the ajax request. |
653
|
|
|
* |
654
|
|
|
* @return bool |
655
|
|
|
*/ |
656
|
|
|
public function isAjax() |
657
|
|
|
{ |
658
|
|
|
if (!empty($_SERVER['HTTP_X_PJAX']) && true === $_SERVER['HTTP_X_PJAX']) { |
659
|
|
|
return true; |
660
|
|
|
} |
661
|
|
|
if (!empty($_SERVER['HTTP_X_REQUESTED_WITH'])) { |
662
|
|
|
return true; |
663
|
|
|
} |
664
|
|
|
return false; |
665
|
|
|
} |
666
|
|
|
|
667
|
|
|
/** |
668
|
|
|
* Is json. |
669
|
|
|
* |
670
|
|
|
* @return bool |
671
|
|
|
*/ |
672
|
|
|
public function isJSON() |
673
|
|
|
{ |
674
|
|
|
return false !== strpos($this->getHeader('accept'), 'application/json'); |
675
|
|
|
} |
676
|
|
|
|
677
|
|
|
/** |
678
|
|
|
* Validating read access request. |
679
|
|
|
* |
680
|
|
|
* @throws \App\Exceptions\Csrf |
681
|
|
|
*/ |
682
|
|
|
public function validateReadAccess() |
683
|
|
|
{ |
684
|
|
|
// Referer check if present - to over come && Check for user post authentication. |
685
|
|
|
if (\Config\Security::$verifyRefererHeader && isset($_SERVER['HTTP_REFERER']) && \App\User::getCurrentUserId() && 'Install' !== $this->get('module')) { |
686
|
|
|
$allowed = array_merge(\Config\Security::$allowedFrameDomains, \Config\Security::$allowedFormDomains); |
687
|
|
|
$allowed[] = \App\Config::main('site_URL'); |
688
|
|
|
$throw = true; |
689
|
|
|
foreach ($allowed as $value) { |
690
|
|
|
if (0 === stripos($_SERVER['HTTP_REFERER'], $value)) { |
691
|
|
|
$throw = false; |
692
|
|
|
} |
693
|
|
|
} |
694
|
|
|
if ($throw) { |
695
|
|
|
throw new \App\Exceptions\Csrf('Illegal request'); |
696
|
|
|
} |
697
|
|
|
} |
698
|
|
|
} |
699
|
|
|
|
700
|
|
|
/** |
701
|
|
|
* Validating write access request. |
702
|
|
|
* |
703
|
|
|
* @param bool $skipRequestTypeCheck |
704
|
|
|
* |
705
|
|
|
* @throws \App\Exceptions\Csrf |
706
|
3 |
|
*/ |
707
|
|
|
public function validateWriteAccess($skipRequestTypeCheck = false) |
708
|
3 |
|
{ |
709
|
|
|
if (!$skipRequestTypeCheck && 'POST' !== $_SERVER['REQUEST_METHOD']) { |
710
|
|
|
throw new \App\Exceptions\Csrf('Invalid request - validate Write Access', 403); |
711
|
|
|
} |
712
|
3 |
|
$this->validateReadAccess(); |
713
|
|
|
if (\App\Config::security('csrfActive')) { |
714
|
|
|
\CsrfMagic\Csrf::check(); |
715
|
|
|
} |
716
|
|
|
} |
717
|
|
|
|
718
|
|
|
/** |
719
|
|
|
* Static instance initialization. |
720
|
|
|
* |
721
|
|
|
* @param array|bool $request |
722
|
|
|
* |
723
|
|
|
* @return Request |
724
|
|
|
*/ |
725
|
41 |
|
public static function init($request = false) |
726
|
|
|
{ |
727
|
41 |
|
if (!static::$request) { |
728
|
|
|
static::$request = new self($request ?: $_REQUEST); |
729
|
|
|
} |
730
|
41 |
|
return static::$request; |
731
|
41 |
|
} |
732
|
|
|
|
733
|
|
|
/** |
734
|
41 |
|
* Support static methods, all functions must start with "_". |
735
|
|
|
* |
736
|
|
|
* @param string $name |
737
|
41 |
|
* @param array|null $arguments |
738
|
41 |
|
* |
739
|
41 |
|
* @throws \App\Exceptions\AppException |
740
|
|
|
* |
741
|
|
|
* @return mixed |
742
|
|
|
*/ |
743
|
|
|
public static function __callStatic($name, $arguments = null) |
744
|
|
|
{ |
745
|
|
|
if (!static::$request) { |
746
|
|
|
static::init(); |
747
|
|
|
} |
748
|
|
|
$function = ltrim($name, '_'); |
749
|
|
|
if (!method_exists(static::$request, $function)) { |
750
|
|
|
throw new \App\Exceptions\AppException('Method not found'); |
751
|
|
|
} |
752
|
|
|
if (empty($arguments)) { |
753
|
|
|
return static::$request->{$function}(); |
754
|
|
|
} |
755
|
|
|
$first = array_shift($arguments); |
756
|
|
|
if (empty($arguments)) { |
757
|
|
|
return static::$request->{$function}($first); |
758
|
|
|
} |
759
|
|
|
return static::$request->{$function}($first, $arguments[0]); |
760
|
|
|
} |
761
|
|
|
} |
762
|
|
|
|
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.