1 | <?php |
||
2 | |||
3 | /** |
||
4 | * Bluz Framework Component |
||
5 | * |
||
6 | * @copyright Bluz PHP Team |
||
7 | * @link https://github.com/bluzphp/framework |
||
8 | */ |
||
9 | |||
10 | declare(strict_types=1); |
||
11 | |||
12 | namespace Bluz\Proxy; |
||
13 | |||
14 | use Bluz\Common\Exception\ComponentException; |
||
15 | use Bluz\Http\RequestMethod; |
||
16 | use Psr\Http\Message\UriInterface; |
||
0 ignored issues
–
show
|
|||
17 | use Laminas\Diactoros\ServerRequest as Instance; |
||
0 ignored issues
–
show
The type
Laminas\Diactoros\ServerRequest was not found. Maybe you did not declare it correctly or list all dependencies?
The issue could also be caused by a filter entry in the build configuration.
If the path has been excluded in your configuration, e.g. filter:
dependency_paths: ["lib/*"]
For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths ![]() |
|||
18 | use Laminas\Diactoros\UploadedFile; |
||
0 ignored issues
–
show
The type
Laminas\Diactoros\UploadedFile was not found. Maybe you did not declare it correctly or list all dependencies?
The issue could also be caused by a filter entry in the build configuration.
If the path has been excluded in your configuration, e.g. filter:
dependency_paths: ["lib/*"]
For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths ![]() |
|||
19 | |||
20 | /** |
||
21 | * Proxy to Request |
||
22 | * |
||
23 | * Example of usage |
||
24 | * <code> |
||
25 | * use Bluz\Proxy\Request; |
||
26 | * |
||
27 | * Request::getParam('foo'); |
||
28 | * </code> |
||
29 | * |
||
30 | * @package Bluz\Proxy |
||
31 | * @author Anton Shevchuk |
||
32 | * |
||
33 | * @todo Proxy class should be clean |
||
34 | * |
||
35 | * @method static Instance getInstance() |
||
36 | * |
||
37 | * @method static UriInterface getUri() |
||
38 | * @see \Laminas\Diactoros\RequestTrait::getUri() |
||
39 | */ |
||
40 | final class Request |
||
41 | { |
||
42 | use ProxyTrait; |
||
43 | |||
44 | /** |
||
45 | * @const string HTTP content types |
||
46 | */ |
||
47 | public const TYPE_ANY = '*/*'; |
||
48 | public const TYPE_HTML = 'text/html'; |
||
49 | public const TYPE_JSON = 'application/json'; |
||
50 | |||
51 | /** |
||
52 | * @var array|null Accepted type |
||
53 | */ |
||
54 | private static $accept; |
||
55 | |||
56 | /** |
||
57 | * @var array|null Accepted languages |
||
58 | */ |
||
59 | private static $language; |
||
60 | |||
61 | /** |
||
62 | * Init instance |
||
63 | * |
||
64 | * @throws ComponentException |
||
65 | */ |
||
66 | private static function initInstance() |
||
0 ignored issues
–
show
|
|||
67 | { |
||
68 | throw new ComponentException('Class `Proxy\\Request` required external initialization'); |
||
69 | } |
||
70 | |||
71 | /** |
||
72 | * Retrieve a member of the $_GET super global |
||
73 | * |
||
74 | * If no $key is passed, returns the entire $_GET array. |
||
75 | * |
||
76 | * @param string|null $key |
||
77 | * @param string|null $default Default value to use if key not found |
||
78 | * |
||
79 | * @return string|array|null Returns null if key does not exist |
||
80 | */ |
||
81 | 75 | public static function getQuery(?string $key = null, ?string $default = null) |
|
82 | { |
||
83 | 75 | return self::getInstance()->getQueryParams()[$key] ?? $default; |
|
84 | } |
||
85 | |||
86 | /** |
||
87 | * Retrieve a member of the $_POST super global |
||
88 | * |
||
89 | * If no $key is passed, returns the entire $_POST array. |
||
90 | * |
||
91 | * @param string|null $key |
||
92 | * @param string|null $default Default value to use if key not found |
||
93 | * |
||
94 | * @return string|array|null Returns null if key does not exist |
||
95 | */ |
||
96 | 65 | public static function getPost(?string $key = null, ?string $default = null) |
|
97 | { |
||
98 | 65 | return self::getInstance()->getParsedBody()[$key] ?? $default; |
|
99 | } |
||
100 | |||
101 | /** |
||
102 | * Retrieve a member of the $_SERVER super global |
||
103 | * |
||
104 | * If no $key is passed, returns the entire $_SERVER array. |
||
105 | * |
||
106 | * @param string|null $key |
||
107 | * @param string|null $default Default value to use if key not found |
||
108 | * |
||
109 | * @return string Returns null if key does not exist |
||
110 | */ |
||
111 | 8 | public static function getServer(?string $key = null, ?string $default = null) |
|
112 | { |
||
113 | 8 | return self::getInstance()->getServerParams()[$key] ?? $default; |
|
114 | } |
||
115 | |||
116 | /** |
||
117 | * Retrieve a member of the $_COOKIE super global |
||
118 | * |
||
119 | * If no $key is passed, returns the entire $_COOKIE array. |
||
120 | * |
||
121 | * @param string|null $key |
||
122 | * @param string|null $default Default value to use if key not found |
||
123 | * |
||
124 | * @return string Returns null if key does not exist |
||
125 | */ |
||
126 | 1 | public static function getCookie(?string $key = null, ?string $default = null) |
|
127 | { |
||
128 | 1 | return self::getInstance()->getCookieParams()[$key] ?? $default; |
|
129 | } |
||
130 | |||
131 | /** |
||
132 | * Retrieve a member of the $_ENV super global |
||
133 | * |
||
134 | * If no $key is passed, returns the entire $_ENV array. |
||
135 | * |
||
136 | * @param string|null $key |
||
137 | * @param string|null $default Default value to use if key not found |
||
138 | * |
||
139 | * @return string Returns null if key does not exist |
||
140 | */ |
||
141 | 1 | public static function getEnv(?string $key = null, ?string $default = null) |
|
142 | { |
||
143 | 1 | return $_ENV[$key] ?? $default; |
|
144 | } |
||
145 | |||
146 | /** |
||
147 | * Search for a header value |
||
148 | * |
||
149 | * @param string $header |
||
150 | * @param mixed $default |
||
151 | * |
||
152 | * @return string |
||
153 | */ |
||
154 | 40 | public static function getHeader(string $header, $default = null) |
|
155 | { |
||
156 | 40 | $header = strtolower($header); |
|
157 | 40 | $headers = self::getInstance()->getHeaders(); |
|
158 | 40 | $headers = array_change_key_case($headers, CASE_LOWER); |
|
159 | 40 | if (array_key_exists($header, $headers)) { |
|
160 | 5 | $value = is_array($headers[$header]) ? implode(', ', $headers[$header]) : $headers[$header]; |
|
161 | 5 | return $value; |
|
162 | } |
||
163 | 40 | return $default; |
|
164 | } |
||
165 | |||
166 | /** |
||
167 | * Access values contained in the superglobals as public members |
||
168 | * Order of precedence: 1. GET, 2. POST |
||
169 | * |
||
170 | * @param string $key |
||
171 | * @param null $default |
||
0 ignored issues
–
show
|
|||
172 | * |
||
173 | * @return string|array|null |
||
174 | * @link http://msdn.microsoft.com/en-us/library/system.web.httprequest.item.aspx |
||
175 | */ |
||
176 | 75 | public static function getParam(string $key, $default = null) |
|
177 | { |
||
178 | return |
||
179 | 75 | self::getQuery($key) ?? |
|
180 | 64 | self::getPost($key) ?? |
|
181 | 75 | $default; |
|
182 | } |
||
183 | |||
184 | /** |
||
185 | * Get all params from GET and POST or PUT |
||
186 | * |
||
187 | * @return array |
||
188 | */ |
||
189 | 36 | public static function getParams(): array |
|
190 | { |
||
191 | 36 | $body = (array)self::getInstance()->getParsedBody(); |
|
192 | 36 | $query = (array)self::getInstance()->getQueryParams(); |
|
193 | 36 | return array_merge([], $body, $query); |
|
194 | } |
||
195 | |||
196 | /** |
||
197 | * Get uploaded file |
||
198 | * |
||
199 | * @param string $name |
||
200 | * |
||
201 | * @return UploadedFile |
||
202 | */ |
||
203 | public static function getFile(string $name) |
||
204 | { |
||
205 | return self::getInstance()->getUploadedFiles()[$name] ?? false; |
||
0 ignored issues
–
show
The expression
return self::getInstance...Files()[$name] ?? false could also return false which is incompatible with the documented return type Laminas\Diactoros\UploadedFile . Did you maybe forget to handle an error condition?
If the returned type also contains false, it is an indicator that maybe an error condition leading to the specific return statement remains unhandled. ![]() |
|||
206 | } |
||
207 | |||
208 | /** |
||
209 | * Get the client's IP address |
||
210 | * |
||
211 | * @param bool $checkProxy |
||
212 | * |
||
213 | * @return string |
||
214 | */ |
||
215 | 1 | public static function getClientIp(bool $checkProxy = true) |
|
216 | { |
||
217 | 1 | $result = null; |
|
218 | 1 | if ($checkProxy) { |
|
219 | 1 | $result = self::getServer('HTTP_CLIENT_IP') ?? self::getServer('HTTP_X_FORWARDED_FOR') ?? null; |
|
220 | } |
||
221 | 1 | return $result ?? self::getServer('REMOTE_ADDR'); |
|
222 | } |
||
223 | |||
224 | /** |
||
225 | * Get module |
||
226 | * |
||
227 | * @return string |
||
228 | */ |
||
229 | 44 | public static function getModule(): string |
|
230 | { |
||
231 | 44 | return self::getParam('_module', Router::getDefaultModule()); |
|
0 ignored issues
–
show
|
|||
232 | } |
||
233 | |||
234 | /** |
||
235 | * Get controller |
||
236 | * |
||
237 | * @return string |
||
238 | */ |
||
239 | 44 | public static function getController(): string |
|
240 | { |
||
241 | 44 | return self::getParam('_controller', Router::getDefaultController()); |
|
0 ignored issues
–
show
|
|||
242 | } |
||
243 | |||
244 | /** |
||
245 | * Get method |
||
246 | * |
||
247 | * @return string |
||
248 | */ |
||
249 | 25 | public static function getMethod(): string |
|
250 | { |
||
251 | 25 | return self::getParam('_method', self::getInstance()->getMethod()); |
|
0 ignored issues
–
show
|
|||
252 | } |
||
253 | |||
254 | /** |
||
255 | * Get Accept MIME Type |
||
256 | * |
||
257 | * @return array |
||
258 | */ |
||
259 | 40 | public static function getAccept(): array |
|
260 | { |
||
261 | 40 | if (!self::$accept) { |
|
262 | // get header from request |
||
263 | 40 | self::$accept = self::parseAcceptHeader(self::getHeader('Accept')); |
|
264 | } |
||
265 | 40 | return self::$accept; |
|
266 | } |
||
267 | |||
268 | /** |
||
269 | * Get Accept MIME Type |
||
270 | * |
||
271 | * @return array |
||
272 | */ |
||
273 | public static function getAcceptLanguage(): array |
||
274 | { |
||
275 | if (!self::$language) { |
||
276 | // get header from request |
||
277 | self::$language = self::parseAcceptHeader(self::getHeader('Accept-Language')); |
||
278 | } |
||
279 | return self::$language; |
||
280 | } |
||
281 | |||
282 | /** |
||
283 | * parseAcceptHeader |
||
284 | * |
||
285 | * @param string|null $header |
||
286 | * |
||
287 | * @return array |
||
288 | */ |
||
289 | 40 | private static function parseAcceptHeader(?string $header): array |
|
290 | { |
||
291 | // empty array |
||
292 | 40 | $accept = []; |
|
293 | |||
294 | // check empty |
||
295 | 40 | if (!$header || $header === '') { |
|
296 | 37 | return $accept; |
|
297 | } |
||
298 | |||
299 | // make array from header |
||
300 | 3 | $values = explode(',', $header); |
|
301 | 3 | $values = array_map('trim', $values); |
|
302 | |||
303 | 3 | foreach ($values as $a) { |
|
304 | // the default quality is 1. |
||
305 | 3 | $q = 1; |
|
306 | // check if there is a different quality |
||
307 | 3 | if (strpos($a, ';q=') || strpos($a, '; q=')) { |
|
308 | // divide "mime/type;q=X" into two parts: "mime/type" i "X" |
||
309 | [$a, $q] = preg_split('/;([ ]?)q=/', $a); |
||
310 | } |
||
311 | // remove other extension |
||
312 | 3 | if (strpos($a, ';')) { |
|
313 | $a = substr($a, 0, strpos($a, ';')); |
||
314 | } |
||
315 | |||
316 | // mime-type $a is accepted with the quality $q |
||
317 | // WARNING: $q == 0 means, that isn’t supported! |
||
318 | 3 | $accept[$a] = (float)$q; |
|
319 | } |
||
320 | 3 | arsort($accept); |
|
321 | 3 | return $accept; |
|
322 | } |
||
323 | |||
324 | /** |
||
325 | * Reset accept for tests |
||
326 | * |
||
327 | * @return void |
||
328 | */ |
||
329 | 802 | public static function resetAccept(): void |
|
330 | { |
||
331 | 802 | self::$accept = null; |
|
332 | 802 | } |
|
333 | |||
334 | /** |
||
335 | * Check Accept header |
||
336 | * |
||
337 | * @param array $allowTypes |
||
338 | * |
||
339 | * @return string|false |
||
340 | */ |
||
341 | 40 | public static function checkAccept(array $allowTypes = []) |
|
342 | { |
||
343 | 40 | $accept = self::getAccept(); |
|
344 | |||
345 | // if no parameter was passed, just return first mime type from parsed data |
||
346 | 40 | if (empty($allowTypes)) { |
|
347 | return current(array_keys($accept)); |
||
348 | } |
||
349 | |||
350 | 40 | $allowTypes = array_map('strtolower', $allowTypes); |
|
351 | |||
352 | // let’s check our supported types: |
||
353 | 40 | foreach ($accept as $mime => $quality) { |
|
354 | 3 | if ($quality && in_array($mime, $allowTypes, true)) { |
|
355 | 3 | return $mime; |
|
356 | } |
||
357 | } |
||
358 | // no mime-type found |
||
359 | 38 | return false; |
|
360 | } |
||
361 | |||
362 | /** |
||
363 | * Check CLI |
||
364 | * |
||
365 | * @return bool |
||
366 | */ |
||
367 | 1 | public static function isCli(): bool |
|
368 | { |
||
369 | 1 | return (PHP_SAPI === 'cli'); |
|
370 | } |
||
371 | |||
372 | /** |
||
373 | * Check HTTP |
||
374 | * |
||
375 | * @return bool |
||
376 | */ |
||
377 | 3 | public static function isHttp(): bool |
|
378 | { |
||
379 | 3 | return (PHP_SAPI !== 'cli'); |
|
380 | } |
||
381 | |||
382 | /** |
||
383 | * Is this a GET method request? |
||
384 | * |
||
385 | * @return bool |
||
386 | */ |
||
387 | 2 | public static function isGet(): bool |
|
388 | { |
||
389 | 2 | return (self::getInstance()->getMethod() === RequestMethod::GET); |
|
390 | } |
||
391 | |||
392 | /** |
||
393 | * Is this a POST method request? |
||
394 | * |
||
395 | * @return bool |
||
396 | */ |
||
397 | 2 | public static function isPost(): bool |
|
398 | { |
||
399 | 2 | return (self::getInstance()->getMethod() === RequestMethod::POST); |
|
400 | } |
||
401 | |||
402 | /** |
||
403 | * Is this a PUT method request? |
||
404 | * |
||
405 | * @return bool |
||
406 | */ |
||
407 | 1 | public static function isPut(): bool |
|
408 | { |
||
409 | 1 | return (self::getInstance()->getMethod() === RequestMethod::PUT); |
|
410 | } |
||
411 | |||
412 | /** |
||
413 | * Is this a DELETE method request? |
||
414 | * |
||
415 | * @return bool |
||
416 | */ |
||
417 | 1 | public static function isDelete(): bool |
|
418 | { |
||
419 | 1 | return (self::getInstance()->getMethod() === RequestMethod::DELETE); |
|
420 | } |
||
421 | |||
422 | /** |
||
423 | * Is the request a Javascript XMLHttpRequest? |
||
424 | * |
||
425 | * @return bool |
||
426 | */ |
||
427 | 9 | public static function isXmlHttpRequest(): bool |
|
428 | { |
||
429 | 9 | return (self::getHeader('X-Requested-With') === 'XMLHttpRequest'); |
|
430 | } |
||
431 | } |
||
432 |
The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g.
excluded_paths: ["lib/*"]
, you can move it to the dependency path list as follows:For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths