ServerRequest::checkUploadedFiles()   A
last analyzed

Complexity

Conditions 5
Paths 5

Size

Total Lines 26
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 9.4494

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 5
eloc 15
c 1
b 0
f 1
nc 5
nop 2
dl 0
loc 26
ccs 7
cts 16
cp 0.4375
crap 9.4494
rs 9.4555
1
<?php
2
3
namespace DMT\Aura\Psr\Message;
4
5
use ArrayObject;
6
use Aura\Web\Request as AuraRequest;
7
use InvalidArgumentException;
8
use Psr\Http\Message\ServerRequestInterface;
9
use Psr\Http\Message\UploadedFileInterface;
10
use Psr\Http\Message\UriInterface;
11
use stdClass;
12
13
/**
14
 * Class ServerRequest
15
 *
16
 * @package DMT\Aura\Psr\Message
17
 */
18
class ServerRequest extends Request implements ServerRequestInterface
19
{
20
    /** @var UploadedFile[] $uploadedFiles */
21
    private $uploadedFiles;
22
23
    /**
24
     * ServerRequest constructor.
25
     *
26
     * @param string $method
27
     * @param string|UriInterface $uri
28
     * @param array $serverParams
29
     */
30 16
    public function __construct(string $method, $uri, array $serverParams = [])
31
    {
32 16
        parent::__construct($method, $uri);
33
34 16
        $request = $this->getInnerObject();
35 16
        $request->server->exchangeArray(['REQUEST_METHOD' => $method] + $serverParams);
36
37 16
        $this->setObjectProperty(
38 16
            $request ,
39 16
            'headers',
40 16
            new AuraRequest\Headers($request->server->get())
41
        );
42 16
    }
43
44
    /**
45
     * Retrieve server parameters.
46
     *
47
     * @return array
48
     */
49 2
    public function getServerParams(): array
50
    {
51 2
        return $this->getInnerObject()->server->get();
52
    }
53
54
    /**
55
     * Retrieve cookies.
56
     *
57
     * @return array
58
     */
59 2
    public function getCookieParams(): array
60
    {
61 2
        return $this->getInnerObject()->cookies->get();
62
    }
63
64
    /**
65
     * Return an instance with the specified cookies.
66
     *
67
     * @param array $cookies
68
     * @return static
69
     */
70 1
    public function withCookieParams(array $cookies): self
71
    {
72 1
        $instance = clone($this);
73
74 1
        $this->setObjectProperty(
75 1
            $instance->getInnerObject(),
76 1
            'cookies',
77 1
            new AuraRequest\Values($cookies)
78
        );
79
80 1
        return $instance;
81
    }
82
83
    /**
84
     * Retrieve query string arguments.
85
     *
86
     * @return array
87
     */
88 1
    public function getQueryParams(): array
89
    {
90 1
        return $this->getInnerObject()->query->get();
91
    }
92
93
    /**
94
     * Return an instance with the specified query string arguments.
95
     *
96
     * @param array $query
97
     * @return static
98
     */
99 1
    public function withQueryParams(array $query): self
100
    {
101 1
        $instance = clone($this);
102
103 1
        $this->setObjectProperty(
104 1
            $instance->getInnerObject(),
105 1
            'query',
106 1
            new AuraRequest\Values($query)
107
        );
108
109 1
        return $instance;
110
    }
111
112
    /**
113
     * Retrieve normalized file upload data.
114
     *
115
     * @return array
116
     */
117 1
    public function getUploadedFiles(): array
118
    {
119 1
        return $this->uploadedFiles ?? [];
120
    }
121
122
    /**
123
     * Create a new instance with the specified uploaded files.
124
     *
125
     * @param array|UploadedFileInterface[] $uploadedFiles
126
     * @return static
127
     * @throws InvalidArgumentException
128
     */
129 1
    public function withUploadedFiles(array $uploadedFiles): self
130
    {
131 1
        $files = [];
132 1
        $uploadedFiles = $this->checkUploadedFiles($uploadedFiles, $files);
133
134 1
        $instance = clone($this);
135 1
        $instance->uploadedFiles = $uploadedFiles;
136 1
        $instance->getInnerObject()->files->exchangeArray($files);
137
138 1
        return $instance;
139
    }
140
141 1
    public function checkUploadedFiles($uploadedFiles, &$entry)
142
    {
143 1
        foreach ($uploadedFiles as $file => &$uploadedFile) {
144 1
            if (is_array($uploadedFile)) {
145
                $uploadedFile = $this->checkUploadedFiles($uploadedFile, $entry[$file]);
146
                continue;
147
            }
148
149 1
            if (!$uploadedFile instanceof UploadedFileInterface) {
150
                throw new InvalidArgumentException('illegal uploaded file entry');
151
            }
152
153 1
            if (!$uploadedFile instanceof UploadedFile) {
154
                $uploadedFile = new UploadedFile(
155
                    new Stream($uploadedFile->getStream()->detach()),
156
                    $uploadedFile->getSize(),
157
                    $uploadedFile->getError(),
158
                    $uploadedFile->getClientFilename(),
159
                    $uploadedFile->getClientMediaType()
160
                );
161
            }
162
163 1
            $entry[$file] = $uploadedFile->getInnerObject()->getArrayCopy();
164
        }
165
166 1
        return $uploadedFiles;
167
    }
168
169
    /**
170
     * Retrieve any parameters provided in the request body.
171
     *
172
     * NOTE: objects are casted to arrays before storage
173
     *
174
     * @return null|array|object
175
     */
176 3
    public function getParsedBody()
177
    {
178 3
        $data = $this->getInnerObject()->post->get();
179
180 3
        if ((ArrayObject::ARRAY_AS_PROPS & $this->getInnerObject()->post->getFlags()) > 0) {
181 1
            return (object)$data;
182
        }
183
184 3
        return $data ?: null;
185
    }
186
187
    /**
188
     * Return an instance with the specified body parameters.
189
     *
190
     * @param null|array|object $data
191
     * @return static
192
     * @throws InvalidArgumentException
193
     */
194 7
    public function withParsedBody($data): self
195
    {
196 7
        if (!is_null($data) && !is_array($data) && !$data instanceof stdClass) {
197 4
            throw new InvalidArgumentException('unsupported body type used');
198
        }
199
200 3
        $instance = clone($this);
201 3
        $instance->getInnerObject()->post->exchangeArray((array)$data);
202
203 3
        if (is_object($data)) {
204 1
            $instance->getInnerObject()->post->setFlags(ArrayObject::ARRAY_AS_PROPS);
205
        }
206
207 3
        return $instance;
208
    }
209
210
    /**
211
     * Retrieve attributes derived from the request.
212
     *
213
     * @return array Attributes derived from the request.
214
     */
215 3
    public function getAttributes(): array
216
    {
217 3
        return $this->getInnerObject()->params->get() ?? [];
218
    }
219
220
    /**
221
     * Retrieve a single derived request attribute.
222
     *
223
     * @param string $name The attribute name.
224
     * @param mixed $default Default value to return if the attribute does not exist.
225
     * @return mixed
226
     */
227 2
    public function getAttribute($name, $default = null)
228
    {
229 2
        return $this->getInnerObject()->params->get($name, $default);
230
    }
231
232
    /**
233
     * Return an instance with the specified derived request attribute.
234
     *
235
     * This method allows setting a single derived request attribute as
236
     * described in getAttributes().
237
     *
238
     * This method MUST be implemented in such a way as to retain the
239
     * immutability of the message, and MUST return an instance that has the
240
     * updated attribute.
241
     *
242
     * @see getAttributes()
243
     * @param string $name The attribute name.
244
     * @param mixed $value The value of the attribute.
245
     * @return static
246
     */
247 3
    public function withAttribute($name, $value)
248
    {
249 3
        $params = $this->getAttributes();
250 3
        $params[$name] = $value;
251
252 3
        $instance = clone($this);
253 3
        $instance->getInnerObject()->params->set($params);
254
255 3
        return $instance;
256
    }
257
258
    /**
259
     * Return an instance that removes the specified derived request attribute.
260
     *
261
     * @param string $name The attribute name.
262
     * @return static
263
     */
264 1
    public function withoutAttribute($name)
265
    {
266 1
        $params = $this->getAttributes();
267 1
        unset($params[$name]);
268
269 1
        $instance = clone($this);
270 1
        $instance->getInnerObject()->params->set($params);
271
272 1
        return $instance;
273
    }
274
}
275