1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
|
<?php
declare(strict_types=1);
/**
* Wrapper for getting fields from the request (GET, POST, ...)
*/
class Request
{
/**
* Required and not empty
*/
const REQUIRED = "\0\1\2REQ\0\1\2";
/**
* Required, but might be empty
*/
const REQUIRED_EMPTY = "\0\3\4REQ\0\3\4";
/**
*
* @param string $key Key of field to get from $_GET
* @param string $default Value to return if $_GET does not contain $key
* @param string $type if the parameter exists, cast it to given type
* @return mixed Field from $_GET, or $default if not set
*/
public static function get(string $key, $default = false, $type = false)
{
return self::handle($_GET, $key, $default, $type);
}
/**
*
* @param string $key Key of field to get from $_POST
* @param string $default Value to return if $_POST does not contain $key
* @return mixed Field from $_POST, or $default if not set
*/
public static function post(string $key, $default = false, $type = false)
{
return self::handle($_POST, $key, $default, $type);
}
/**
*
* @param string $key Key of field to get from $_REQUEST
* @param string $default Value to return if $_REQUEST does not contain $key
* @return mixed Field from $_REQUEST, or $default if not set
*/
public static function any(string $key, $default = false, $type = false)
{
return self::handle($_REQUEST, $key, $default, $type);
}
/**
* @return true iff the request is a POST request
*/
public static function isPost(): bool
{
return $_SERVER['REQUEST_METHOD'] === 'POST';
}
/**
* @return true iff the request is a GET request
*/
public static function isGet(): bool
{
return $_SERVER['REQUEST_METHOD'] === 'GET';
}
private static function handle(&$array, $key, $default, $type)
{
$err = false;
if ($default === self::REQUIRED_EMPTY || $default === self::REQUIRED) {
if (!array_key_exists($key, $array)) {
$err = 'missing';
} elseif ($default === self::REQUIRED && ($array[$key] === '' || $array[$key] === [])) {
$err = 'empty';
}
}
if ($err !== false) {
http_response_code(400);
if (API)
die("Parameter $key $err");
if ($err === 'missing') { // Explicit so translate module finds the addError calls
Message::addError('main.parameter-missing', $key);
} else {
Message::addError('main.parameter-empty', $key);
}
Render::addFooter('<button class="btn btn-danger" style="margin:20px" onclick="history.back()">Back</button>');
Render::output();
exit;
}
if (!isset($array[$key]))
return $default;
if ($type !== false) {
settype($array[$key], $type);
}
return $array[$key];
}
/**
* Processes post parameters based on specified limits and assigns the processed values to the output array.
* $params is expected to have one or more keys specifying a type (int, string, ...), and each of them
* an array with field name as key, and then an array as value that can have optional
* keys 'default', 'min' and 'max', as well as 'enum' (array of allowed values).
*
* @param array $out Reference to an array where the processed parameter values will be stored.
* @param array $params An array containing the parameters to be processed, their types, and limits.
*/
public static function processPostParameters(array &$out, array $params, ?string $source = 'POST'): void
{
if ($source === 'GET') {
$input =& $_GET;
} elseif ($source === 'POST') {
$input =& $_POST;
} elseif ($source === 'REQUEST') {
$input =& $_REQUEST;
} elseif ($source === null) {
$input = [];
} else {
ErrorHandler::traceError("Invalid parameter source: '$source'");
}
foreach ($params as $type => $list) {
foreach ($list as $field => $limits) {
if ($type === 'bool') {
// An unchecked checkbox will not have its key in the post data, so self::handle would fall back
// to the default value. If the default is true, this would mean the parameter would be set to
// true, which is incorrect.
$default = false;
} else {
$default = $limits['default'] ?? false;
}
$value = self::handle($input, $field, $default, $type);
if (isset($limits['min']) && $value < $limits['min']) {
$value = $limits['min'];
}
if (isset($limits['max']) && $value > $limits['max']) {
$value = $limits['max'];
}
if (isset($limits['enum']) && !in_array($value, $limits['enum'])) {
$value = $limits['default'] ?? array_shift($limits['enum']);
}
$out[$field] = $value;
}
}
}
}
|