ServerRequest::validateUploadedFiles()   A
last analyzed

Complexity

Conditions 5
Paths 4

Size

Total Lines 13
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 5

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 9
c 1
b 0
f 0
nc 4
nop 1
dl 0
loc 13
ccs 10
cts 10
cp 1
crap 5
rs 9.6111
1
<?php
2
3
declare(strict_types=1);
4
5
namespace HttpSoft\Message;
6
7
use InvalidArgumentException;
8
use Psr\Http\Message\ServerRequestInterface;
9
use Psr\Http\Message\StreamInterface;
10
use Psr\Http\Message\UploadedFileInterface;
11
use Psr\Http\Message\UriInterface;
12
13
use function array_key_exists;
14
use function gettype;
15
use function get_class;
16
use function is_array;
17
use function is_object;
18
use function sprintf;
19
20
final class ServerRequest implements ServerRequestInterface
21
{
22
    use RequestTrait;
23
24
    /**
25
     * @var array
26
     */
27
    private array $attributes = [];
28
29
    /**
30
     * @var array
31
     */
32
    private array $cookieParams;
33
34
    /**
35
     * @var array|object|null
36
     */
37
    private $parsedBody;
38
39
    /**
40
     * @var array
41
     */
42
    private array $queryParams;
43
44
    /**
45
     * @var array
46
     */
47
    private array $serverParams;
48
49
    /**
50
     * @var array
51
     */
52
    private array $uploadedFiles;
53
54
    /**
55
     * @param array $serverParams The server parameters.
56
     * @param array $uploadedFiles The array of uploaded files, each being an instance of `UploadedFileInterface`.
57
     * Nested arrays are allowed.
58
     * @param array $cookieParams The cookie parameters.
59
     * @param array $queryParams The query parameters.
60
     * @param array|object|null $parsedBody The parsed body.
61
     * @param string $method The HTTP method.
62
     * @param UriInterface|string $uri The URI to request.
63
     * @param array $headers The headers to send with the request.
64
     * @param StreamInterface|string|resource|null $body The body of the request. Must be one of the following:
65
     *  - an instance of `StreamInterface`;
66
     *  - a string stream identifier (e.g., 'php://temp') or a file path;
67
     *  - a valid stream resource;
68
     *  - `null`.
69
     * @param string $protocol The HTTP protocol version.
70
     */
71 96
    public function __construct(
72
        array $serverParams = [],
73
        array $uploadedFiles = [],
74
        array $cookieParams = [],
75
        array $queryParams = [],
76
        $parsedBody = null,
77
        string $method = 'GET',
78
        $uri = '',
79
        array $headers = [],
80
        $body = null,
81
        string $protocol = '1.1'
82
    ) {
83 96
        $this->validateUploadedFiles($uploadedFiles);
84 96
        $this->uploadedFiles = $uploadedFiles;
85 96
        $this->serverParams = $serverParams;
86 96
        $this->cookieParams = $cookieParams;
87 96
        $this->queryParams = $queryParams;
88 96
        $this->parsedBody = $parsedBody;
89 96
        $this->init($method, $uri, $headers, $body, $protocol);
90
    }
91
92
    /**
93
     * {@inheritDoc}
94
     */
95 3
    public function getServerParams(): array
96
    {
97 3
        return $this->serverParams;
98
    }
99
100
    /**
101
     * {@inheritDoc}
102
     */
103 5
    public function getCookieParams(): array
104
    {
105 5
        return $this->cookieParams;
106
    }
107
108
    /**
109
     * {@inheritDoc}
110
     */
111 2
    public function withCookieParams(array $cookies): ServerRequestInterface
112
    {
113 2
        $new = clone $this;
114 2
        $new->cookieParams = $cookies;
115 2
        return $new;
116
    }
117
118
    /**
119
     * {@inheritDoc}
120
     */
121 4
    public function getQueryParams(): array
122
    {
123 4
        return $this->queryParams;
124
    }
125
126
    /**
127
     * {@inheritDoc}
128
     */
129 2
    public function withQueryParams(array $query): ServerRequestInterface
130
    {
131 2
        $new = clone $this;
132 2
        $new->queryParams = $query;
133 2
        return $new;
134
    }
135
136
    /**
137
     * {@inheritDoc}
138
     */
139 4
    public function getUploadedFiles(): array
140
    {
141 4
        return $this->uploadedFiles;
142
    }
143
144
    /**
145
     * {@inheritDoc}
146
     */
147 10
    public function withUploadedFiles(array $uploadedFiles): ServerRequestInterface
148
    {
149 10
        $this->validateUploadedFiles($uploadedFiles);
150 2
        $new = clone $this;
151 2
        $new->uploadedFiles = $uploadedFiles;
152 2
        return $new;
153
    }
154
155
    /**
156
     * {@inheritDoc}
157
     */
158 12
    public function getParsedBody()
159
    {
160 12
        return $this->parsedBody;
161
    }
162
163
    /**
164
     * {@inheritDoc}
165
     *
166
     * @psalm-suppress DocblockTypeContradiction
167
     */
168 15
    public function withParsedBody($data): ServerRequestInterface
169
    {
170 15
        if (!is_array($data) && !is_object($data) && $data !== null) {
171 9
            throw new InvalidArgumentException(sprintf(
172 9
                '"%s" is not valid Parsed Body. It must be a null, an array, or an object.',
173 9
                gettype($data)
174 9
            ));
175
        }
176
177 6
        $new = clone $this;
178 6
        $new->parsedBody = $data;
179 6
        return $new;
180
    }
181
182
    /**
183
     * {@inheritDoc}
184
     */
185 4
    public function getAttributes(): array
186
    {
187 4
        return $this->attributes;
188
    }
189
190
    /**
191
     * {@inheritDoc}
192
     */
193 5
    public function getAttribute($name, $default = null)
194
    {
195 5
        if (array_key_exists($name, $this->attributes)) {
196 4
            return $this->attributes[$name];
197
        }
198
199 4
        return $default;
200
    }
201
202
    /**
203
     * {@inheritDoc}
204
     */
205 5
    public function withAttribute($name, $value): ServerRequestInterface
206
    {
207 5
        if (array_key_exists($name, $this->attributes) && $this->attributes[$name] === $value) {
208 1
            return $this;
209
        }
210
211 5
        $new = clone $this;
212 5
        $new->attributes[$name] = $value;
213 5
        return $new;
214
    }
215
216
    /**
217
     * {@inheritDoc}
218
     */
219 2
    public function withoutAttribute($name): ServerRequestInterface
220
    {
221 2
        if (!array_key_exists($name, $this->attributes)) {
222 1
            return $this;
223
        }
224
225 2
        $new = clone $this;
226 2
        unset($new->attributes[$name]);
227 2
        return $new;
228
    }
229
230
    /**
231
     * @param array $uploadedFiles
232
     * @throws InvalidArgumentException
233
     * @psalm-suppress MixedAssignment
234
     */
235 96
    private function validateUploadedFiles(array $uploadedFiles): void
236
    {
237 96
        foreach ($uploadedFiles as $file) {
238 10
            if (is_array($file)) {
239 1
                $this->validateUploadedFiles($file);
240 1
                continue;
241
            }
242
243 10
            if (!$file instanceof UploadedFileInterface) {
244 8
                throw new InvalidArgumentException(sprintf(
245 8
                    'Invalid item in uploaded files structure.'
246 8
                    . '"%s" is not an instance of "\Psr\Http\Message\UploadedFileInterface".',
247 8
                    (is_object($file) ? get_class($file) : gettype($file))
248 8
                ));
249
            }
250
        }
251
    }
252
}
253