Passed
Pull Request — master (#27)
by Anatoly
39:10
created

ServerRequest   A

Complexity

Total Complexity 25

Size/Duplication

Total Lines 351
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 55
c 1
b 0
f 0
dl 0
loc 351
ccs 68
cts 68
cp 1
rs 10
wmc 25

18 Methods

Rating   Name   Duplication   Size   Complexity  
A setUploadedFiles() 0 5 1
A setParsedBody() 0 5 1
A getQueryParams() 0 3 1
A withoutAttribute() 0 6 1
A getParsedBody() 0 3 1
A withQueryParams() 0 6 1
A withParsedBody() 0 6 1
A withAttribute() 0 6 1
A getCookieParams() 0 3 1
A __construct() 0 25 2
A getAttribute() 0 7 2
A validateUploadedFiles() 0 18 3
A getServerParams() 0 3 1
A getUploadedFiles() 0 3 1
A withCookieParams() 0 6 1
A getAttributes() 0 3 1
A withUploadedFiles() 0 6 1
A validateParsedBody() 0 8 4
1
<?php declare(strict_types=1);
2
3
/**
4
 * It's free open-source software released under the MIT License.
5
 *
6
 * @author Anatoly Nekhay <[email protected]>
7
 * @copyright Copyright (c) 2018, Anatoly Nekhay
8
 * @license https://github.com/sunrise-php/http-message/blob/master/LICENSE
9
 * @link https://github.com/sunrise-php/http-message
10
 */
11
12
namespace Sunrise\Http\Message;
13
14
/**
15
 * Import classes
16
 */
17
use Psr\Http\Message\ServerRequestInterface;
18
use Psr\Http\Message\StreamInterface;
19
use Psr\Http\Message\UploadedFileInterface;
20
use Sunrise\Http\Message\Exception\InvalidArgumentException;
21
22
/**
23
 * Import functions
24
 */
25
use function array_key_exists;
26
use function array_walk_recursive;
27
use function is_array;
28
use function is_object;
29
30
/**
31
 * ServerRequest
32
 *
33
 * @link https://www.php-fig.org/psr/psr-7/
34
 */
35
class ServerRequest extends Request implements ServerRequestInterface
36
{
37
38
    /**
39
     * The server parameters
40
     *
41
     * @var array
42
     */
43
    private array $serverParams;
44
45
    /**
46
     * The request's query parameters
47
     *
48
     * @var array
49
     */
50
    private array $queryParams;
51
52
    /**
53
     * The request's cookie parameters
54
     *
55
     * @var array
56
     */
57
    private array $cookieParams;
58
59
    /**
60
     * The request's uploaded files
61
     *
62
     * @var array
63
     */
64
    private array $uploadedFiles;
65
66
    /**
67
     * The request's parsed body
68
     *
69
     * @var array|object|null
70
     */
71
    private $parsedBody;
72
73
    /**
74
     * The request attributes
75
     *
76
     * @var array
77
     */
78
    private array $attributes;
79
80
    /**
81
     * Constructor of the class
82
     *
83
     * @param string|null $protocolVersion
84
     * @param string|null $method
85
     * @param mixed $uri
86
     * @param array<string, string|string[]>|null $headers
87
     * @param StreamInterface|null $body
88
     *
89
     * @param array $serverParams
90
     * @param array $queryParams
91
     * @param array $cookieParams
92
     * @param array $uploadedFiles
93
     * @param array|object|null $parsedBody
94
     * @param array $attributes
95
     *
96
     * @throws InvalidArgumentException
97
     *         If one of the parameters isn't valid.
98
     */
99 266
    public function __construct(
100
        ?string $protocolVersion = null,
101
        ?string $method = null,
102
        $uri = null,
103
        ?array $headers = null,
104
        ?StreamInterface $body = null,
105
        array $serverParams = [],
106
        array $queryParams = [],
107
        array $cookieParams = [],
108
        array $uploadedFiles = [],
109
        $parsedBody = null,
110
        array $attributes = []
111
    ) {
112 266
        if (isset($protocolVersion)) {
113 79
            $this->setProtocolVersion($protocolVersion);
114
        }
115
116 247
        parent::__construct($method, $uri, $headers, $body);
117
118 227
        $this->serverParams = $serverParams;
119 227
        $this->queryParams = $queryParams;
120 227
        $this->cookieParams = $cookieParams;
121 227
        $this->setUploadedFiles($uploadedFiles);
122 226
        $this->setParsedBody($parsedBody);
123 225
        $this->attributes = $attributes;
124
    }
125
126
    /**
127
     * Gets the server parameters
128
     *
129
     * @return array
130
     */
131 31
    public function getServerParams(): array
132
    {
133 31
        return $this->serverParams;
134
    }
135
136
    /**
137
     * Gets the request's query parameters
138
     *
139
     * @return array
140
     */
141 7
    public function getQueryParams(): array
142
    {
143 7
        return $this->queryParams;
144
    }
145
146
    /**
147
     * Creates a new instance of the request with the given query parameters
148
     *
149
     * @param array $query
150
     *
151
     * @return static
152
     */
153 3
    public function withQueryParams(array $query): ServerRequestInterface
154
    {
155 3
        $clone = clone $this;
156 3
        $clone->queryParams = $query;
157
158 3
        return $clone;
159
    }
160
161
    /**
162
     * Gets the request's cookie parameters
163
     *
164
     * @return array
165
     */
166 8
    public function getCookieParams(): array
167
    {
168 8
        return $this->cookieParams;
169
    }
170
171
    /**
172
     * Creates a new instance of the request with the given cookie parameters
173
     *
174
     * @param array $cookies
175
     *
176
     * @return static
177
     */
178 3
    public function withCookieParams(array $cookies): ServerRequestInterface
179
    {
180 3
        $clone = clone $this;
181 3
        $clone->cookieParams = $cookies;
182
183 3
        return $clone;
184
    }
185
186
    /**
187
     * Gets the request's uploaded files
188
     *
189
     * @return array
190
     */
191 7
    public function getUploadedFiles(): array
192
    {
193 7
        return $this->uploadedFiles;
194
    }
195
196
    /**
197
     * Creates a new instance of the request with the given uploaded files
198
     *
199
     * @param array $uploadedFiles
200
     *
201
     * @return static
202
     *
203
     * @throws InvalidArgumentException
204
     *         If one of the files isn't valid.
205
     */
206 4
    public function withUploadedFiles(array $uploadedFiles): ServerRequestInterface
207
    {
208 4
        $clone = clone $this;
209 4
        $clone->setUploadedFiles($uploadedFiles);
210
211 3
        return $clone;
212
    }
213
214
    /**
215
     * Gets the request's parsed body
216
     *
217
     * @return array|object|null
218
     */
219 17
    public function getParsedBody()
220
    {
221 17
        return $this->parsedBody;
222
    }
223
224
    /**
225
     * Creates a new instance of the request with the given parsed body
226
     *
227
     * @param array|object|null $data
228
     *
229
     * @return static
230
     *
231
     * @throws InvalidArgumentException
232
     *         If the data isn't valid.
233
     */
234 12
    public function withParsedBody($data): ServerRequestInterface
235
    {
236 12
        $clone = clone $this;
237 12
        $clone->setParsedBody($data);
238
239 7
        return $clone;
240
    }
241
242
    /**
243
     * Gets the request attributes
244
     *
245
     * @return array
246
     */
247 5
    public function getAttributes(): array
248
    {
249 5
        return $this->attributes;
250
    }
251
252
    /**
253
     * Gets the request's attribute value by the given name
254
     *
255
     * Returns the default value if the attribute wasn't found.
256
     *
257
     * @param array-key $name
0 ignored issues
show
Documentation Bug introduced by
The doc comment array-key at position 0 could not be parsed: Unknown type name 'array-key' at position 0 in array-key.
Loading history...
258
     * @param mixed $default
259
     *
260
     * @return mixed
261
     */
262 6
    public function getAttribute($name, $default = null)
263
    {
264 6
        if (!array_key_exists($name, $this->attributes)) {
265 4
            return $default;
266
        }
267
268 4
        return $this->attributes[$name];
269
    }
270
271
    /**
272
     * Creates a new instance of the request with the given attribute
273
     *
274
     * @param array-key $name
0 ignored issues
show
Documentation Bug introduced by
The doc comment array-key at position 0 could not be parsed: Unknown type name 'array-key' at position 0 in array-key.
Loading history...
275
     * @param mixed $value
276
     *
277
     * @return static
278
     */
279 7
    public function withAttribute($name, $value): ServerRequestInterface
280
    {
281 7
        $clone = clone $this;
282 7
        $clone->attributes[$name] = $value;
283
284 7
        return $clone;
285
    }
286
287
    /**
288
     * Creates a new instance of the request without an attribute with the given name
289
     *
290
     * @param array-key $name
0 ignored issues
show
Documentation Bug introduced by
The doc comment array-key at position 0 could not be parsed: Unknown type name 'array-key' at position 0 in array-key.
Loading history...
291
     *
292
     * @return static
293
     */
294 2
    public function withoutAttribute($name): ServerRequestInterface
295
    {
296 2
        $clone = clone $this;
297 2
        unset($clone->attributes[$name]);
298
299 2
        return $clone;
300
    }
301
302
    /**
303
     * Sets the given uploaded files to the request
304
     *
305
     * @param array $files
306
     *
307
     * @return void
308
     *
309
     * @throws InvalidArgumentException
310
     *         If one of the files isn't valid.
311
     */
312 227
    final protected function setUploadedFiles(array $files): void
313
    {
314 227
        $this->validateUploadedFiles($files);
315
316 226
        $this->uploadedFiles = $files;
317
    }
318
319
    /**
320
     * Sets the given parsed body to the request
321
     *
322
     * @param array|object|null $data
323
     *
324
     * @return void
325
     *
326
     * @throws InvalidArgumentException
327
     *         If the parsed body isn't valid.
328
     */
329 226
    final protected function setParsedBody($data): void
330
    {
331 226
        $this->validateParsedBody($data);
332
333 225
        $this->parsedBody = $data;
334
    }
335
336
    /**
337
     * Validates the given uploaded files
338
     *
339
     * @param array $files
340
     *
341
     * @return void
342
     *
343
     * @throws InvalidArgumentException
344
     *         If one of the files isn't valid.
345
     */
346 227
    private function validateUploadedFiles(array $files): void
347
    {
348 227
        if ([] === $files) {
349 223
            return;
350
        }
351
352
        /**
353
         * @param mixed $file
354
         *
355
         * @return void
356
         *
357
         * @throws InvalidArgumentException
358
         *
359
         * @psalm-suppress MissingClosureParamType
360
         */
361 8
        array_walk_recursive($files, static function ($file): void {
362 8
            if (! ($file instanceof UploadedFileInterface)) {
363 2
                throw new InvalidArgumentException('Invalid uploaded files');
364
            }
365 8
        });
366
    }
367
368
    /**
369
     * Validates the given parsed body
370
     *
371
     * @param mixed $data
372
     *
373
     * @return void
374
     *
375
     * @throws InvalidArgumentException
376
     *         If the parsed body isn't valid.
377
     */
378 226
    private function validateParsedBody($data): void
379
    {
380 226
        if (null === $data) {
381 188
            return;
382
        }
383
384 48
        if (!is_array($data) && !is_object($data)) {
385 6
            throw new InvalidArgumentException('Invalid parsed body');
386
        }
387
    }
388
}
389