This repository was archived by the owner on Feb 17, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSTUtils.php
More file actions
189 lines (164 loc) · 6.64 KB
/
STUtils.php
File metadata and controls
189 lines (164 loc) · 6.64 KB
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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
<?php
class STUtils {
/** @var array<string> */
static private $acceptedImgHosts = [
"imgur.com", "shamtool.com"
];
/**
* Normalizes a map code into an integer representation.
*/
public static function parseMapCode(string|int|null $code) : ?int {
if ($code === null) return null;
if (is_numeric($code) && is_int((int)$code) && (int)$code >= 0) return (int)$code;
$matches = null;
preg_match("/^@(\d+)$/m", $code, $matches);
$match = $matches[1] ?? null;
if ($match === null) return null;
return (int)$match;
}
/**
* Retrieves query parameter (_GET, _POST, _REQUEST, etc), throwing an error when failed.
*
* @throws Exception On failure
*/
public static function queryToString(array $queryArr, string $param, bool $allowNull = true) : ?string {
$value = $queryArr[$param] ?? null;
if ($value === null) {
if ($allowNull)
return null;
else
throw new Exception("Expected String for '{$param}', got empty instead.");
}
if (is_string($value)) {
return $value;
}
throw new Exception("Expected String for '{$param}', got '{$value}' instead.");
}
/**
* Converts a query parameter (_GET, _POST, _REQUEST, etc) to a boolean, throwing an error when failed.
*
* @throws Exception On failure
*/
public static function queryToBool(array $queryArr, string $param, bool $allowNull = true) : ?bool {
$value = $queryArr[$param] ?? null;
if ($value === null) {
if ($allowNull)
return null;
else
throw new Exception("Expected Boolean for '{$param}', got empty instead.");
}
$result = filter_var($value, FILTER_VALIDATE_BOOLEAN);
if ($result === null)
throw new Exception("Expected Boolean for '{$param}', got '{$value}' instead.");
return $result;
}
/**
* Converts a query parameter (_GET, _POST, _REQUEST, etc) to an integer, throwing an error when failed.
*
* @throws Exception On failure
*/
public static function queryToInt(array $queryArr, string $param, bool $allowNull = true,
int|null $min = null, int|null $max = null) : ?int {
$value = $queryArr[$param] ?? null;
if ($value === null) {
if ($allowNull)
return null;
else
throw new Exception("Expected Integer for '{$param}', got empty instead.");
}
if (is_numeric($value) && is_int((int)$value)) {
$ret = (int)$value;
if ($min !== null && $ret < $min)
throw new Exception("Expected Integer with a minimum of {$min} for '{$param}', got '{$value}' instead.");
if ($max !== null && $ret > $max)
throw new Exception("Expected Integer with a maximum of {$max} for '{$param}', got '{$value}' instead.");
return $ret;
}
throw new Exception("Expected Integer for '{$param}', got '{$value}' instead.");
}
/**
* Converts a query parameter (_GET, _POST, _REQUEST, etc) to an integer, throwing an error when failed.
*
* @throws Exception On failure
*/
public static function queryToFloat(array $queryArr, string $param, bool $allowNull = true) : ?float {
$value = $queryArr[$param] ?? null;
if ($value === null) {
if ($allowNull)
return null;
else
throw new Exception("Expected Float for '{$param}', got empty instead.");
}
if (is_float($value)) {
return (float)$value;
}
throw new Exception("Expected Float for '{$param}', got '{$value}' instead.");
}
/**
* Converts a query parameter (_GET, _POST, _REQUEST, etc) to an integer mapcode, throwing an error when failed.
*
* @throws Exception On failure
*/
public static function queryToMapCode(array $queryArr, string $param, bool $allowNull = true) : ?int {
$value = self::queryToString($queryArr, $param, $allowNull);
if ($value === null)
return null;
$mapcode = self::parseMapCode($value);
if ($mapcode === null)
throw new Exception("Expected valid mapcode (e.g. @123456, 123456) for '{$param}', got '{$value}' instead.");
return $mapcode;
}
/**
* Converts a query parameter (_GET, _POST, _REQUEST, etc) to an accepted image URL string, throwing an error when failed.
* Accepts only:
* - `https` as protocol
* - `shamtool.com`, `imgur.com` as host
* - `.png` or `.jpg` file extensions.
*
* @throws Exception On failure
*/
public static function queryToImgUrl(array $queryArr, string $param, bool $allowNull = true) : ?string {
$value = self::queryToString($queryArr, $param, $allowNull);
if ($value === null)
return null;
/** @var array|false */
$url = parse_url($value);
if (!$url)
throw new Exception("Expected valid image URL for '{$param}', got malformed URL '{$value}' instead.");
// Validate URL requirements
if ($url['scheme'] != "https") {
$scheme = $url['scheme'];
throw new Exception("Expected https protocol for '{$param}', got '{$scheme}' instead.");
}
$matched_host = false;
foreach (self::$acceptedImgHosts as $accepted) {
if (self::endsWith($url['host'], $accepted)) {
$matched_host = true;
break;
}
}
if (!$matched_host) {
$host = $url['host'];
$allowed = implode(",", self::$acceptedImgHosts);
throw new Exception("Expected allowed hosts ({$allowed}) for '{$param}', got '{$host}' instead.");
}
if ($url['path'] === null ||
(!self::endsWith($url['path'], '.png') &&
!self::endsWith($url['path'], '.jpg'))) {
throw new Exception("Expected '.png' or '.jpg' extension for '{$param}'.");
}
// URL has been validated
return $value;
}
/**
* Performs a case-sensitive check indicating if `haystack` ends with `needle`.
* Provided for compatibility with pre-PHP 8.0 environments.
*/
public static function endsWith(string $haystack, string $needle) : bool {
if (version_compare(phpversion(), '8.0', '<')) {
$length = strlen($needle);
return $length > 0 ? substr($haystack, -$length) === $needle : true;
}
return str_ends_with($haystack, $needle);
}
}