Request::getMethod()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
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
Bug introduced by
The type Psr\Http\Message\UriInterface 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. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
17
use Laminas\Diactoros\ServerRequest as Instance;
0 ignored issues
show
Bug introduced by
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. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
18
use Laminas\Diactoros\UploadedFile;
0 ignored issues
show
Bug introduced by
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. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
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
Unused Code introduced by
The method initInstance() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
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
Documentation Bug introduced by
Are you sure the doc-type for parameter $default is correct as it would always require null to be passed?
Loading history...
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
Bug Best Practice introduced by
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.

Loading history...
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
Bug Best Practice introduced by
The expression return self::getParam('_...er::getDefaultModule()) could return the type array which is incompatible with the type-hinted return string. Consider adding an additional type-check to rule them out.
Loading history...
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
Bug Best Practice introduced by
The expression return self::getParam('_...getDefaultController()) could return the type array which is incompatible with the type-hinted return string. Consider adding an additional type-check to rule them out.
Loading history...
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
Bug Best Practice introduced by
The expression return self::getParam('_...nstance()->getMethod()) could return the type array|null which is incompatible with the type-hinted return string. Consider adding an additional type-check to rule them out.
Loading history...
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