ServerRequest::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 19
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 7
c 1
b 0
f 0
nc 1
nop 10
dl 0
loc 19
ccs 8
cts 8
cp 1
crap 1
rs 10

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

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