Passed
Pull Request — master (#44)
by Anatoly
08:06
created
src/UploadedFile.php 1 patch
Indentation   +136 added lines, -136 removed lines patch added patch discarded remove patch
@@ -43,140 +43,140 @@
 block discarded – undo
43 43
  */
44 44
 class UploadedFile implements UploadedFileInterface
45 45
 {
46
-    /**
47
-     * @link https://www.php.net/manual/en/features.file-upload.errors.php
48
-     *
49
-     * @var array<int, non-empty-string>
50
-     */
51
-    public const UPLOAD_ERRORS = [
52
-        UPLOAD_ERR_OK         => 'No error',
53
-        UPLOAD_ERR_INI_SIZE   => 'Uploaded file exceeds the upload_max_filesize directive in the php.ini',
54
-        UPLOAD_ERR_FORM_SIZE  => 'Uploaded file exceeds the MAX_FILE_SIZE directive in the HTML form',
55
-        UPLOAD_ERR_PARTIAL    => 'Uploaded file was only partially uploaded',
56
-        UPLOAD_ERR_NO_FILE    => 'No file was uploaded',
57
-        UPLOAD_ERR_NO_TMP_DIR => 'Missing temporary directory',
58
-        UPLOAD_ERR_CANT_WRITE => 'Failed to write file to disk',
59
-        UPLOAD_ERR_EXTENSION  => 'File upload was stopped by a PHP extension',
60
-    ];
61
-
62
-    private ?StreamInterface $stream;
63
-    private ?int $size;
64
-    private int $errorCode;
65
-    private string $errorMessage;
66
-    private ?string $clientFilename;
67
-    private ?string $clientMediaType;
68
-    private bool $isMoved = false;
69
-
70
-    public function __construct(
71
-        ?StreamInterface $stream,
72
-        ?int $size = null,
73
-        int $error = UPLOAD_ERR_OK,
74
-        ?string $clientFilename = null,
75
-        ?string $clientMediaType = null
76
-    ) {
77
-        $this->stream = $stream;
78
-        $this->size = $size;
79
-        $this->errorCode = $error;
80
-        $this->errorMessage = self::UPLOAD_ERRORS[$error] ?? 'Unknown file upload error';
81
-        $this->clientFilename = $clientFilename;
82
-        $this->clientMediaType = $clientMediaType;
83
-    }
84
-
85
-    /**
86
-     * @inheritDoc
87
-     */
88
-    public function getStream(): StreamInterface
89
-    {
90
-        if ($this->isMoved) {
91
-            throw new RuntimeException('Uploaded file was moved');
92
-        }
93
-
94
-        if ($this->errorCode !== UPLOAD_ERR_OK) {
95
-            throw new RuntimeException($this->errorMessage, $this->errorCode);
96
-        }
97
-
98
-        if ($this->stream === null) {
99
-            throw new RuntimeException('Uploaded file has no stream');
100
-        }
101
-
102
-        return $this->stream;
103
-    }
104
-
105
-    /**
106
-     * @inheritDoc
107
-     */
108
-    public function moveTo($targetPath): void
109
-    {
110
-        /** @psalm-suppress TypeDoesNotContainType */
111
-        // @phpstan-ignore function.alreadyNarrowedType
112
-        if (!is_string($targetPath)) {
113
-            throw new TypeError(sprintf(
114
-                'Argument #1 ($targetPath) must be of type string, %s given',
115
-                gettype($targetPath),
116
-            ));
117
-        }
118
-
119
-        $sourceStream = $this->getStream();
120
-
121
-        $sourcePath = $sourceStream->getMetadata('uri');
122
-        if (!is_string($sourcePath) || !is_file($sourcePath) || !is_readable($sourcePath)) {
123
-            throw new RuntimeException('Uploaded file does not exist or is not readable');
124
-        }
125
-
126
-        $sourceDirname = dirname($sourcePath);
127
-        if (!is_writable($sourceDirname)) {
128
-            throw new RuntimeException('To move the uploaded file, the source directory must be writable');
129
-        }
130
-
131
-        $targetDirname = dirname($targetPath);
132
-        if (!is_dir($targetDirname) || !is_writable($targetDirname)) {
133
-            throw new RuntimeException('To move the uploaded file, the target directory must exist and be writable');
134
-        }
135
-
136
-        try {
137
-            $this->isMoved = is_uploaded_file($sourcePath)
138
-                ? move_uploaded_file($sourcePath, $targetPath)
139
-                : rename($sourcePath, $targetPath);
140
-        } catch (Throwable $e) {
141
-        }
142
-
143
-        if (!$this->isMoved) {
144
-            throw new RuntimeException('Failed to move the uploaded file');
145
-        }
146
-
147
-        $sourceStream->close();
148
-        $this->stream = null;
149
-    }
150
-
151
-    /**
152
-     * @inheritDoc
153
-     */
154
-    public function getSize(): ?int
155
-    {
156
-        return $this->size;
157
-    }
158
-
159
-    /**
160
-     * @inheritDoc
161
-     */
162
-    public function getError(): int
163
-    {
164
-        return $this->errorCode;
165
-    }
166
-
167
-    /**
168
-     * @inheritDoc
169
-     */
170
-    public function getClientFilename(): ?string
171
-    {
172
-        return $this->clientFilename;
173
-    }
174
-
175
-    /**
176
-     * @inheritDoc
177
-     */
178
-    public function getClientMediaType(): ?string
179
-    {
180
-        return $this->clientMediaType;
181
-    }
46
+	/**
47
+	 * @link https://www.php.net/manual/en/features.file-upload.errors.php
48
+	 *
49
+	 * @var array<int, non-empty-string>
50
+	 */
51
+	public const UPLOAD_ERRORS = [
52
+		UPLOAD_ERR_OK         => 'No error',
53
+		UPLOAD_ERR_INI_SIZE   => 'Uploaded file exceeds the upload_max_filesize directive in the php.ini',
54
+		UPLOAD_ERR_FORM_SIZE  => 'Uploaded file exceeds the MAX_FILE_SIZE directive in the HTML form',
55
+		UPLOAD_ERR_PARTIAL    => 'Uploaded file was only partially uploaded',
56
+		UPLOAD_ERR_NO_FILE    => 'No file was uploaded',
57
+		UPLOAD_ERR_NO_TMP_DIR => 'Missing temporary directory',
58
+		UPLOAD_ERR_CANT_WRITE => 'Failed to write file to disk',
59
+		UPLOAD_ERR_EXTENSION  => 'File upload was stopped by a PHP extension',
60
+	];
61
+
62
+	private ?StreamInterface $stream;
63
+	private ?int $size;
64
+	private int $errorCode;
65
+	private string $errorMessage;
66
+	private ?string $clientFilename;
67
+	private ?string $clientMediaType;
68
+	private bool $isMoved = false;
69
+
70
+	public function __construct(
71
+		?StreamInterface $stream,
72
+		?int $size = null,
73
+		int $error = UPLOAD_ERR_OK,
74
+		?string $clientFilename = null,
75
+		?string $clientMediaType = null
76
+	) {
77
+		$this->stream = $stream;
78
+		$this->size = $size;
79
+		$this->errorCode = $error;
80
+		$this->errorMessage = self::UPLOAD_ERRORS[$error] ?? 'Unknown file upload error';
81
+		$this->clientFilename = $clientFilename;
82
+		$this->clientMediaType = $clientMediaType;
83
+	}
84
+
85
+	/**
86
+	 * @inheritDoc
87
+	 */
88
+	public function getStream(): StreamInterface
89
+	{
90
+		if ($this->isMoved) {
91
+			throw new RuntimeException('Uploaded file was moved');
92
+		}
93
+
94
+		if ($this->errorCode !== UPLOAD_ERR_OK) {
95
+			throw new RuntimeException($this->errorMessage, $this->errorCode);
96
+		}
97
+
98
+		if ($this->stream === null) {
99
+			throw new RuntimeException('Uploaded file has no stream');
100
+		}
101
+
102
+		return $this->stream;
103
+	}
104
+
105
+	/**
106
+	 * @inheritDoc
107
+	 */
108
+	public function moveTo($targetPath): void
109
+	{
110
+		/** @psalm-suppress TypeDoesNotContainType */
111
+		// @phpstan-ignore function.alreadyNarrowedType
112
+		if (!is_string($targetPath)) {
113
+			throw new TypeError(sprintf(
114
+				'Argument #1 ($targetPath) must be of type string, %s given',
115
+				gettype($targetPath),
116
+			));
117
+		}
118
+
119
+		$sourceStream = $this->getStream();
120
+
121
+		$sourcePath = $sourceStream->getMetadata('uri');
122
+		if (!is_string($sourcePath) || !is_file($sourcePath) || !is_readable($sourcePath)) {
123
+			throw new RuntimeException('Uploaded file does not exist or is not readable');
124
+		}
125
+
126
+		$sourceDirname = dirname($sourcePath);
127
+		if (!is_writable($sourceDirname)) {
128
+			throw new RuntimeException('To move the uploaded file, the source directory must be writable');
129
+		}
130
+
131
+		$targetDirname = dirname($targetPath);
132
+		if (!is_dir($targetDirname) || !is_writable($targetDirname)) {
133
+			throw new RuntimeException('To move the uploaded file, the target directory must exist and be writable');
134
+		}
135
+
136
+		try {
137
+			$this->isMoved = is_uploaded_file($sourcePath)
138
+				? move_uploaded_file($sourcePath, $targetPath)
139
+				: rename($sourcePath, $targetPath);
140
+		} catch (Throwable $e) {
141
+		}
142
+
143
+		if (!$this->isMoved) {
144
+			throw new RuntimeException('Failed to move the uploaded file');
145
+		}
146
+
147
+		$sourceStream->close();
148
+		$this->stream = null;
149
+	}
150
+
151
+	/**
152
+	 * @inheritDoc
153
+	 */
154
+	public function getSize(): ?int
155
+	{
156
+		return $this->size;
157
+	}
158
+
159
+	/**
160
+	 * @inheritDoc
161
+	 */
162
+	public function getError(): int
163
+	{
164
+		return $this->errorCode;
165
+	}
166
+
167
+	/**
168
+	 * @inheritDoc
169
+	 */
170
+	public function getClientFilename(): ?string
171
+	{
172
+		return $this->clientFilename;
173
+	}
174
+
175
+	/**
176
+	 * @inheritDoc
177
+	 */
178
+	public function getClientMediaType(): ?string
179
+	{
180
+		return $this->clientMediaType;
181
+	}
182 182
 }
Please login to merge, or discard this patch.
src/UploadedFileFactory.php 1 patch
Indentation   +18 added lines, -18 removed lines patch added patch discarded remove patch
@@ -22,22 +22,22 @@
 block discarded – undo
22 22
  */
23 23
 class UploadedFileFactory implements UploadedFileFactoryInterface
24 24
 {
25
-    /**
26
-     * @inheritDoc
27
-     */
28
-    public function createUploadedFile(
29
-        StreamInterface $stream,
30
-        ?int $size = null,
31
-        int $error = UPLOAD_ERR_OK,
32
-        ?string $clientFilename = null,
33
-        ?string $clientMediaType = null
34
-    ): UploadedFileInterface {
35
-        return new UploadedFile(
36
-            $stream,
37
-            $size,
38
-            $error,
39
-            $clientFilename,
40
-            $clientMediaType
41
-        );
42
-    }
25
+	/**
26
+	 * @inheritDoc
27
+	 */
28
+	public function createUploadedFile(
29
+		StreamInterface $stream,
30
+		?int $size = null,
31
+		int $error = UPLOAD_ERR_OK,
32
+		?string $clientFilename = null,
33
+		?string $clientMediaType = null
34
+	): UploadedFileInterface {
35
+		return new UploadedFile(
36
+			$stream,
37
+			$size,
38
+			$error,
39
+			$clientFilename,
40
+			$clientMediaType
41
+		);
42
+	}
43 43
 }
Please login to merge, or discard this patch.
src/Uri.php 1 patch
Indentation   +370 added lines, -370 removed lines patch added patch discarded remove patch
@@ -31,374 +31,374 @@
 block discarded – undo
31 31
  */
32 32
 class Uri implements UriInterface
33 33
 {
34
-    private string $scheme = '';
35
-    private string $userInfo = '';
36
-    private string $host = '';
37
-    private ?int $port = null;
38
-    private string $path = '';
39
-    private string $query = '';
40
-    private string $fragment = '';
41
-
42
-    /**
43
-     * @throws InvalidArgumentException
44
-     */
45
-    public function __construct(string $uri = '')
46
-    {
47
-        if ($uri === '') {
48
-            return;
49
-        }
50
-
51
-        $this->parseUri($uri);
52
-    }
53
-
54
-    /**
55
-     * @param mixed $uri
56
-     *
57
-     * @throws InvalidArgumentException
58
-     */
59
-    public static function create($uri): UriInterface
60
-    {
61
-        if ($uri instanceof UriInterface) {
62
-            return $uri;
63
-        }
64
-
65
-        if (!is_string($uri)) {
66
-            throw new InvalidArgumentException('URI should be a string');
67
-        }
68
-
69
-        return new self($uri);
70
-    }
71
-
72
-    /**
73
-     * @inheritDoc
74
-     */
75
-    public function withScheme($scheme): UriInterface
76
-    {
77
-        $clone = clone $this;
78
-        $clone->setScheme($scheme);
79
-
80
-        return $clone;
81
-    }
82
-
83
-    /**
84
-     * @inheritDoc
85
-     *
86
-     * @throws InvalidArgumentException
87
-     */
88
-    public function withUserInfo($user, $password = null): UriInterface
89
-    {
90
-        $clone = clone $this;
91
-        $clone->setUserInfo($user, $password);
92
-
93
-        return $clone;
94
-    }
95
-
96
-    /**
97
-     * @inheritDoc
98
-     */
99
-    public function withHost($host): UriInterface
100
-    {
101
-        $clone = clone $this;
102
-        $clone->setHost($host);
103
-
104
-        return $clone;
105
-    }
106
-
107
-    /**
108
-     * @inheritDoc
109
-     */
110
-    public function withPort($port): UriInterface
111
-    {
112
-        $clone = clone $this;
113
-        $clone->setPort($port);
114
-
115
-        return $clone;
116
-    }
117
-
118
-    /**
119
-     * @inheritDoc
120
-     */
121
-    public function withPath($path): UriInterface
122
-    {
123
-        $clone = clone $this;
124
-        $clone->setPath($path);
125
-
126
-        return $clone;
127
-    }
128
-
129
-    /**
130
-     * @inheritDoc
131
-     */
132
-    public function withQuery($query): UriInterface
133
-    {
134
-        $clone = clone $this;
135
-        $clone->setQuery($query);
136
-
137
-        return $clone;
138
-    }
139
-
140
-    /**
141
-     * @inheritDoc
142
-     *
143
-     * @throws InvalidArgumentException
144
-     */
145
-    public function withFragment($fragment): UriInterface
146
-    {
147
-        $clone = clone $this;
148
-        $clone->setFragment($fragment);
149
-
150
-        return $clone;
151
-    }
152
-
153
-    /**
154
-     * @inheritDoc
155
-     */
156
-    public function getScheme(): string
157
-    {
158
-        return $this->scheme;
159
-    }
160
-
161
-    /**
162
-     * @inheritDoc
163
-     */
164
-    public function getUserInfo(): string
165
-    {
166
-        return $this->userInfo;
167
-    }
168
-
169
-    /**
170
-     * @inheritDoc
171
-     */
172
-    public function getHost(): string
173
-    {
174
-        return $this->host;
175
-    }
176
-
177
-    /**
178
-     * @inheritDoc
179
-     */
180
-    public function getPort(): ?int
181
-    {
182
-        // The 80 is the default port number for the HTTP protocol.
183
-        if ($this->port === 80 && $this->scheme === 'http') {
184
-            return null;
185
-        }
186
-
187
-        // The 443 is the default port number for the HTTPS protocol.
188
-        if ($this->port === 443 && $this->scheme === 'https') {
189
-            return null;
190
-        }
191
-
192
-        return $this->port;
193
-    }
194
-
195
-    /**
196
-     * @inheritDoc
197
-     */
198
-    public function getPath(): string
199
-    {
200
-        // CVE-2015-3257
201
-        if (strncmp($this->path, '//', 2) === 0) {
202
-            return '/' . ltrim($this->path, '/');
203
-        }
204
-
205
-        return $this->path;
206
-    }
207
-
208
-    /**
209
-     * @inheritDoc
210
-     */
211
-    public function getQuery(): string
212
-    {
213
-        return $this->query;
214
-    }
215
-
216
-    /**
217
-     * @inheritDoc
218
-     */
219
-    public function getFragment(): string
220
-    {
221
-        return $this->fragment;
222
-    }
223
-
224
-    /**
225
-     * @inheritDoc
226
-     */
227
-    public function getAuthority(): string
228
-    {
229
-        // The host is the basic subcomponent.
230
-        if ($this->host === '') {
231
-            return '';
232
-        }
233
-
234
-        $authority = $this->host;
235
-        if ($this->userInfo !== '') {
236
-            $authority = $this->userInfo . '@' . $authority;
237
-        }
238
-
239
-        $port = $this->getPort();
240
-        if ($port !== null) {
241
-            $authority = $authority . ':' . (string) $port;
242
-        }
243
-
244
-        return $authority;
245
-    }
246
-
247
-    /**
248
-     * @inheritDoc
249
-     */
250
-    public function __toString(): string
251
-    {
252
-        $uri = '';
253
-
254
-        $scheme = $this->scheme;
255
-        if ($scheme !== '') {
256
-            $uri .= $scheme . ':';
257
-        }
258
-
259
-        $authority = $this->getAuthority();
260
-        if ($authority !== '') {
261
-            $uri .= '//' . $authority;
262
-        }
263
-
264
-        $path = $this->path;
265
-        if ($path !== '') {
266
-            // https://github.com/sunrise-php/uri/issues/31
267
-            // https://datatracker.ietf.org/doc/html/rfc3986#section-3.3
268
-            //
269
-            // If a URI contains an authority component,
270
-            // then the path component must either be empty
271
-            // or begin with a slash ("/") character.
272
-            if ($authority !== '' && strncmp($path, '/', 1) !== 0) {
273
-                $path = '/' . $path;
274
-            }
275
-
276
-            // https://github.com/sunrise-php/uri/issues/31
277
-            // https://datatracker.ietf.org/doc/html/rfc3986#section-3.3
278
-            //
279
-            // If a URI does not contain an authority component,
280
-            // then the path cannot begin with two slash characters ("//").
281
-            if ($authority === '' && strncmp($path, '//', 2) === 0) {
282
-                $path = '/' . ltrim($path, '/');
283
-            }
284
-
285
-            $uri .= $path;
286
-        }
287
-
288
-        $query = $this->query;
289
-        if ($query !== '') {
290
-            $uri .= '?' . $query;
291
-        }
292
-
293
-        $fragment = $this->fragment;
294
-        if ($fragment !== '') {
295
-            $uri .= '#' . $fragment;
296
-        }
297
-
298
-        return $uri;
299
-    }
300
-
301
-    /**
302
-     * @param mixed $scheme
303
-     *
304
-     * @throws InvalidArgumentException
305
-     */
306
-    final protected function setScheme($scheme): void
307
-    {
308
-        $this->scheme = (new Scheme($scheme))->getValue();
309
-    }
310
-
311
-    /**
312
-     * @param mixed $user
313
-     * @param mixed $password
314
-     *
315
-     * @throws InvalidArgumentException
316
-     */
317
-    final protected function setUserInfo($user, $password): void
318
-    {
319
-        $this->userInfo = (new UserInfo($user, $password))->getValue();
320
-    }
321
-
322
-    /**
323
-     * @param mixed $host
324
-     *
325
-     * @throws InvalidArgumentException
326
-     */
327
-    final protected function setHost($host): void
328
-    {
329
-        $this->host = (new Host($host))->getValue();
330
-    }
331
-
332
-    /**
333
-     * @param mixed $port
334
-     *
335
-     * @throws InvalidArgumentException
336
-     */
337
-    final protected function setPort($port): void
338
-    {
339
-        $this->port = (new Port($port))->getValue();
340
-    }
341
-
342
-    /**
343
-     * @param mixed $path
344
-     *
345
-     * @throws InvalidArgumentException
346
-     */
347
-    final protected function setPath($path): void
348
-    {
349
-        $this->path = (new Path($path))->getValue();
350
-    }
351
-
352
-    /**
353
-     * @param mixed $query
354
-     *
355
-     * @throws InvalidArgumentException
356
-     */
357
-    final protected function setQuery($query): void
358
-    {
359
-        $this->query = (new Query($query))->getValue();
360
-    }
361
-
362
-    /**
363
-     * @param mixed $fragment
364
-     *
365
-     * @throws InvalidArgumentException
366
-     */
367
-    final protected function setFragment($fragment): void
368
-    {
369
-        $this->fragment = (new Fragment($fragment))->getValue();
370
-    }
371
-
372
-    /**
373
-     * @throws InvalidArgumentException
374
-     */
375
-    private function parseUri(string $uri): void
376
-    {
377
-        $components = parse_url($uri);
378
-        if ($components === false) {
379
-            throw new InvalidArgumentException('Invalid URI');
380
-        }
381
-
382
-        if (isset($components['scheme'])) {
383
-            $this->setScheme($components['scheme']);
384
-        }
385
-        if (isset($components['user'])) {
386
-            $this->setUserInfo($components['user'], $components['pass'] ?? null);
387
-        }
388
-        if (isset($components['host'])) {
389
-            $this->setHost($components['host']);
390
-        }
391
-        if (isset($components['port'])) {
392
-            $this->setPort($components['port']);
393
-        }
394
-        if (isset($components['path'])) {
395
-            $this->setPath($components['path']);
396
-        }
397
-        if (isset($components['query'])) {
398
-            $this->setQuery($components['query']);
399
-        }
400
-        if (isset($components['fragment'])) {
401
-            $this->setFragment($components['fragment']);
402
-        }
403
-    }
34
+	private string $scheme = '';
35
+	private string $userInfo = '';
36
+	private string $host = '';
37
+	private ?int $port = null;
38
+	private string $path = '';
39
+	private string $query = '';
40
+	private string $fragment = '';
41
+
42
+	/**
43
+	 * @throws InvalidArgumentException
44
+	 */
45
+	public function __construct(string $uri = '')
46
+	{
47
+		if ($uri === '') {
48
+			return;
49
+		}
50
+
51
+		$this->parseUri($uri);
52
+	}
53
+
54
+	/**
55
+	 * @param mixed $uri
56
+	 *
57
+	 * @throws InvalidArgumentException
58
+	 */
59
+	public static function create($uri): UriInterface
60
+	{
61
+		if ($uri instanceof UriInterface) {
62
+			return $uri;
63
+		}
64
+
65
+		if (!is_string($uri)) {
66
+			throw new InvalidArgumentException('URI should be a string');
67
+		}
68
+
69
+		return new self($uri);
70
+	}
71
+
72
+	/**
73
+	 * @inheritDoc
74
+	 */
75
+	public function withScheme($scheme): UriInterface
76
+	{
77
+		$clone = clone $this;
78
+		$clone->setScheme($scheme);
79
+
80
+		return $clone;
81
+	}
82
+
83
+	/**
84
+	 * @inheritDoc
85
+	 *
86
+	 * @throws InvalidArgumentException
87
+	 */
88
+	public function withUserInfo($user, $password = null): UriInterface
89
+	{
90
+		$clone = clone $this;
91
+		$clone->setUserInfo($user, $password);
92
+
93
+		return $clone;
94
+	}
95
+
96
+	/**
97
+	 * @inheritDoc
98
+	 */
99
+	public function withHost($host): UriInterface
100
+	{
101
+		$clone = clone $this;
102
+		$clone->setHost($host);
103
+
104
+		return $clone;
105
+	}
106
+
107
+	/**
108
+	 * @inheritDoc
109
+	 */
110
+	public function withPort($port): UriInterface
111
+	{
112
+		$clone = clone $this;
113
+		$clone->setPort($port);
114
+
115
+		return $clone;
116
+	}
117
+
118
+	/**
119
+	 * @inheritDoc
120
+	 */
121
+	public function withPath($path): UriInterface
122
+	{
123
+		$clone = clone $this;
124
+		$clone->setPath($path);
125
+
126
+		return $clone;
127
+	}
128
+
129
+	/**
130
+	 * @inheritDoc
131
+	 */
132
+	public function withQuery($query): UriInterface
133
+	{
134
+		$clone = clone $this;
135
+		$clone->setQuery($query);
136
+
137
+		return $clone;
138
+	}
139
+
140
+	/**
141
+	 * @inheritDoc
142
+	 *
143
+	 * @throws InvalidArgumentException
144
+	 */
145
+	public function withFragment($fragment): UriInterface
146
+	{
147
+		$clone = clone $this;
148
+		$clone->setFragment($fragment);
149
+
150
+		return $clone;
151
+	}
152
+
153
+	/**
154
+	 * @inheritDoc
155
+	 */
156
+	public function getScheme(): string
157
+	{
158
+		return $this->scheme;
159
+	}
160
+
161
+	/**
162
+	 * @inheritDoc
163
+	 */
164
+	public function getUserInfo(): string
165
+	{
166
+		return $this->userInfo;
167
+	}
168
+
169
+	/**
170
+	 * @inheritDoc
171
+	 */
172
+	public function getHost(): string
173
+	{
174
+		return $this->host;
175
+	}
176
+
177
+	/**
178
+	 * @inheritDoc
179
+	 */
180
+	public function getPort(): ?int
181
+	{
182
+		// The 80 is the default port number for the HTTP protocol.
183
+		if ($this->port === 80 && $this->scheme === 'http') {
184
+			return null;
185
+		}
186
+
187
+		// The 443 is the default port number for the HTTPS protocol.
188
+		if ($this->port === 443 && $this->scheme === 'https') {
189
+			return null;
190
+		}
191
+
192
+		return $this->port;
193
+	}
194
+
195
+	/**
196
+	 * @inheritDoc
197
+	 */
198
+	public function getPath(): string
199
+	{
200
+		// CVE-2015-3257
201
+		if (strncmp($this->path, '//', 2) === 0) {
202
+			return '/' . ltrim($this->path, '/');
203
+		}
204
+
205
+		return $this->path;
206
+	}
207
+
208
+	/**
209
+	 * @inheritDoc
210
+	 */
211
+	public function getQuery(): string
212
+	{
213
+		return $this->query;
214
+	}
215
+
216
+	/**
217
+	 * @inheritDoc
218
+	 */
219
+	public function getFragment(): string
220
+	{
221
+		return $this->fragment;
222
+	}
223
+
224
+	/**
225
+	 * @inheritDoc
226
+	 */
227
+	public function getAuthority(): string
228
+	{
229
+		// The host is the basic subcomponent.
230
+		if ($this->host === '') {
231
+			return '';
232
+		}
233
+
234
+		$authority = $this->host;
235
+		if ($this->userInfo !== '') {
236
+			$authority = $this->userInfo . '@' . $authority;
237
+		}
238
+
239
+		$port = $this->getPort();
240
+		if ($port !== null) {
241
+			$authority = $authority . ':' . (string) $port;
242
+		}
243
+
244
+		return $authority;
245
+	}
246
+
247
+	/**
248
+	 * @inheritDoc
249
+	 */
250
+	public function __toString(): string
251
+	{
252
+		$uri = '';
253
+
254
+		$scheme = $this->scheme;
255
+		if ($scheme !== '') {
256
+			$uri .= $scheme . ':';
257
+		}
258
+
259
+		$authority = $this->getAuthority();
260
+		if ($authority !== '') {
261
+			$uri .= '//' . $authority;
262
+		}
263
+
264
+		$path = $this->path;
265
+		if ($path !== '') {
266
+			// https://github.com/sunrise-php/uri/issues/31
267
+			// https://datatracker.ietf.org/doc/html/rfc3986#section-3.3
268
+			//
269
+			// If a URI contains an authority component,
270
+			// then the path component must either be empty
271
+			// or begin with a slash ("/") character.
272
+			if ($authority !== '' && strncmp($path, '/', 1) !== 0) {
273
+				$path = '/' . $path;
274
+			}
275
+
276
+			// https://github.com/sunrise-php/uri/issues/31
277
+			// https://datatracker.ietf.org/doc/html/rfc3986#section-3.3
278
+			//
279
+			// If a URI does not contain an authority component,
280
+			// then the path cannot begin with two slash characters ("//").
281
+			if ($authority === '' && strncmp($path, '//', 2) === 0) {
282
+				$path = '/' . ltrim($path, '/');
283
+			}
284
+
285
+			$uri .= $path;
286
+		}
287
+
288
+		$query = $this->query;
289
+		if ($query !== '') {
290
+			$uri .= '?' . $query;
291
+		}
292
+
293
+		$fragment = $this->fragment;
294
+		if ($fragment !== '') {
295
+			$uri .= '#' . $fragment;
296
+		}
297
+
298
+		return $uri;
299
+	}
300
+
301
+	/**
302
+	 * @param mixed $scheme
303
+	 *
304
+	 * @throws InvalidArgumentException
305
+	 */
306
+	final protected function setScheme($scheme): void
307
+	{
308
+		$this->scheme = (new Scheme($scheme))->getValue();
309
+	}
310
+
311
+	/**
312
+	 * @param mixed $user
313
+	 * @param mixed $password
314
+	 *
315
+	 * @throws InvalidArgumentException
316
+	 */
317
+	final protected function setUserInfo($user, $password): void
318
+	{
319
+		$this->userInfo = (new UserInfo($user, $password))->getValue();
320
+	}
321
+
322
+	/**
323
+	 * @param mixed $host
324
+	 *
325
+	 * @throws InvalidArgumentException
326
+	 */
327
+	final protected function setHost($host): void
328
+	{
329
+		$this->host = (new Host($host))->getValue();
330
+	}
331
+
332
+	/**
333
+	 * @param mixed $port
334
+	 *
335
+	 * @throws InvalidArgumentException
336
+	 */
337
+	final protected function setPort($port): void
338
+	{
339
+		$this->port = (new Port($port))->getValue();
340
+	}
341
+
342
+	/**
343
+	 * @param mixed $path
344
+	 *
345
+	 * @throws InvalidArgumentException
346
+	 */
347
+	final protected function setPath($path): void
348
+	{
349
+		$this->path = (new Path($path))->getValue();
350
+	}
351
+
352
+	/**
353
+	 * @param mixed $query
354
+	 *
355
+	 * @throws InvalidArgumentException
356
+	 */
357
+	final protected function setQuery($query): void
358
+	{
359
+		$this->query = (new Query($query))->getValue();
360
+	}
361
+
362
+	/**
363
+	 * @param mixed $fragment
364
+	 *
365
+	 * @throws InvalidArgumentException
366
+	 */
367
+	final protected function setFragment($fragment): void
368
+	{
369
+		$this->fragment = (new Fragment($fragment))->getValue();
370
+	}
371
+
372
+	/**
373
+	 * @throws InvalidArgumentException
374
+	 */
375
+	private function parseUri(string $uri): void
376
+	{
377
+		$components = parse_url($uri);
378
+		if ($components === false) {
379
+			throw new InvalidArgumentException('Invalid URI');
380
+		}
381
+
382
+		if (isset($components['scheme'])) {
383
+			$this->setScheme($components['scheme']);
384
+		}
385
+		if (isset($components['user'])) {
386
+			$this->setUserInfo($components['user'], $components['pass'] ?? null);
387
+		}
388
+		if (isset($components['host'])) {
389
+			$this->setHost($components['host']);
390
+		}
391
+		if (isset($components['port'])) {
392
+			$this->setPort($components['port']);
393
+		}
394
+		if (isset($components['path'])) {
395
+			$this->setPath($components['path']);
396
+		}
397
+		if (isset($components['query'])) {
398
+			$this->setQuery($components['query']);
399
+		}
400
+		if (isset($components['fragment'])) {
401
+			$this->setFragment($components['fragment']);
402
+		}
403
+	}
404 404
 }
Please login to merge, or discard this patch.
src/ServerRequestFactory.php 1 patch
Indentation   +52 added lines, -52 removed lines patch added patch discarded remove patch
@@ -20,58 +20,58 @@
 block discarded – undo
20 20
  */
21 21
 class ServerRequestFactory implements ServerRequestFactoryInterface
22 22
 {
23
-    /**
24
-     * @param array<array-key, mixed>|null $serverParams
25
-     * @param array<array-key, mixed>|null $queryParams
26
-     * @param array<array-key, mixed>|null $cookieParams
27
-     * @param array<array-key, mixed>|null $uploadedFiles
28
-     * @param array<array-key, mixed>|null $parsedBody
29
-     *
30
-     * @link http://php.net/manual/en/language.variables.superglobals.php
31
-     * @link https://www.php-fig.org/psr/psr-15/meta/
32
-     */
33
-    public static function fromGlobals(
34
-        ?array $serverParams = null,
35
-        ?array $queryParams = null,
36
-        ?array $cookieParams = null,
37
-        ?array $uploadedFiles = null,
38
-        ?array $parsedBody = null
39
-    ): ServerRequestInterface {
40
-        $serverParams ??= $_SERVER;
41
-        $queryParams ??= $_GET;
42
-        $cookieParams ??= $_COOKIE;
43
-        $uploadedFiles ??= $_FILES;
44
-        $parsedBody ??= $_POST;
23
+	/**
24
+	 * @param array<array-key, mixed>|null $serverParams
25
+	 * @param array<array-key, mixed>|null $queryParams
26
+	 * @param array<array-key, mixed>|null $cookieParams
27
+	 * @param array<array-key, mixed>|null $uploadedFiles
28
+	 * @param array<array-key, mixed>|null $parsedBody
29
+	 *
30
+	 * @link http://php.net/manual/en/language.variables.superglobals.php
31
+	 * @link https://www.php-fig.org/psr/psr-15/meta/
32
+	 */
33
+	public static function fromGlobals(
34
+		?array $serverParams = null,
35
+		?array $queryParams = null,
36
+		?array $cookieParams = null,
37
+		?array $uploadedFiles = null,
38
+		?array $parsedBody = null
39
+	): ServerRequestInterface {
40
+		$serverParams ??= $_SERVER;
41
+		$queryParams ??= $_GET;
42
+		$cookieParams ??= $_COOKIE;
43
+		$uploadedFiles ??= $_FILES;
44
+		$parsedBody ??= $_POST;
45 45
 
46
-        return new ServerRequest(
47
-            server_request_protocol_version($serverParams),
48
-            server_request_method($serverParams),
49
-            server_request_uri($serverParams),
50
-            server_request_headers($serverParams),
51
-            new PhpInputStream(),
52
-            $serverParams,
53
-            $queryParams,
54
-            $cookieParams,
55
-            server_request_files($uploadedFiles),
56
-            $parsedBody
57
-        );
58
-    }
46
+		return new ServerRequest(
47
+			server_request_protocol_version($serverParams),
48
+			server_request_method($serverParams),
49
+			server_request_uri($serverParams),
50
+			server_request_headers($serverParams),
51
+			new PhpInputStream(),
52
+			$serverParams,
53
+			$queryParams,
54
+			$cookieParams,
55
+			server_request_files($uploadedFiles),
56
+			$parsedBody
57
+		);
58
+	}
59 59
 
60
-    /**
61
-     * {@inheritDoc}
62
-     *
63
-     * @param mixed $uri
64
-     * @param array<array-key, mixed> $serverParams
65
-     */
66
-    public function createServerRequest(string $method, $uri, array $serverParams = []): ServerRequestInterface
67
-    {
68
-        return new ServerRequest(
69
-            server_request_protocol_version($serverParams),
70
-            $method,
71
-            $uri,
72
-            server_request_headers($serverParams),
73
-            null, // body
74
-            $serverParams
75
-        );
76
-    }
60
+	/**
61
+	 * {@inheritDoc}
62
+	 *
63
+	 * @param mixed $uri
64
+	 * @param array<array-key, mixed> $serverParams
65
+	 */
66
+	public function createServerRequest(string $method, $uri, array $serverParams = []): ServerRequestInterface
67
+	{
68
+		return new ServerRequest(
69
+			server_request_protocol_version($serverParams),
70
+			$method,
71
+			$uri,
72
+			server_request_headers($serverParams),
73
+			null, // body
74
+			$serverParams
75
+		);
76
+	}
77 77
 }
Please login to merge, or discard this patch.
src/RequestFactory.php 1 patch
Indentation   +7 added lines, -7 removed lines patch added patch discarded remove patch
@@ -19,11 +19,11 @@
 block discarded – undo
19 19
  */
20 20
 class RequestFactory implements RequestFactoryInterface
21 21
 {
22
-    /**
23
-     * @inheritDoc
24
-     */
25
-    public function createRequest(string $method, $uri): RequestInterface
26
-    {
27
-        return new Request($method, $uri);
28
-    }
22
+	/**
23
+	 * @inheritDoc
24
+	 */
25
+	public function createRequest(string $method, $uri): RequestInterface
26
+	{
27
+		return new Request($method, $uri);
28
+	}
29 29
 }
Please login to merge, or discard this patch.
src/ServerRequest.php 1 patch
Indentation   +313 added lines, -313 removed lines patch added patch discarded remove patch
@@ -26,317 +26,317 @@
 block discarded – undo
26 26
  */
27 27
 class ServerRequest extends Request implements ServerRequestInterface
28 28
 {
29
-    /**
30
-     * @var array<array-key, mixed>
31
-     */
32
-    private array $serverParams;
33
-
34
-    /**
35
-     * @var array<array-key, mixed>
36
-     */
37
-    private array $queryParams;
38
-
39
-    /**
40
-     * @var array<array-key, mixed>
41
-     */
42
-    private array $cookieParams;
43
-
44
-    /**
45
-     * @var array<array-key, mixed>
46
-     */
47
-    private array $uploadedFiles = [];
48
-
49
-    /**
50
-     * @var array<array-key, mixed>|object|null
51
-     */
52
-    private $parsedBody = null;
53
-
54
-    /**
55
-     * @var array<array-key, mixed>
56
-     */
57
-    private array $attributes;
58
-
59
-    /**
60
-     * Constructor of the class
61
-     *
62
-     * @param mixed $uri
63
-     * @param array<string, string|string[]>|null $headers
64
-     *
65
-     * @param array<array-key, mixed> $serverParams
66
-     * @param array<array-key, mixed> $queryParams
67
-     * @param array<array-key, mixed> $cookieParams
68
-     * @param array<array-key, mixed> $uploadedFiles
69
-     * @param array<array-key, mixed>|object|null $parsedBody
70
-     * @param array<array-key, mixed> $attributes
71
-     *
72
-     * @throws InvalidArgumentException
73
-     */
74
-    public function __construct(
75
-        ?string $protocolVersion = null,
76
-        ?string $method = null,
77
-        $uri = null,
78
-        ?array $headers = null,
79
-        ?StreamInterface $body = null,
80
-        array $serverParams = [],
81
-        array $queryParams = [],
82
-        array $cookieParams = [],
83
-        array $uploadedFiles = [],
84
-        $parsedBody = null,
85
-        array $attributes = []
86
-    ) {
87
-        parent::__construct($method, $uri, $headers, $body);
88
-
89
-        if ($protocolVersion !== null) {
90
-            $this->setProtocolVersion($protocolVersion);
91
-        }
92
-
93
-        if ($uploadedFiles !== []) {
94
-            $this->setUploadedFiles($uploadedFiles);
95
-        }
96
-
97
-        if ($parsedBody !== null) {
98
-            $this->setParsedBody($parsedBody);
99
-        }
100
-
101
-        $this->serverParams = $serverParams;
102
-        $this->queryParams = $queryParams;
103
-        $this->cookieParams = $cookieParams;
104
-        $this->attributes = $attributes;
105
-    }
106
-
107
-    /**
108
-     * {@inheritDoc}
109
-     *
110
-     * @return array<array-key, mixed>
111
-     */
112
-    public function getServerParams(): array
113
-    {
114
-        return $this->serverParams;
115
-    }
116
-
117
-    /**
118
-     * {@inheritDoc}
119
-     *
120
-     * @return array<array-key, mixed>
121
-     */
122
-    public function getQueryParams(): array
123
-    {
124
-        return $this->queryParams;
125
-    }
126
-
127
-    /**
128
-     * {@inheritDoc}
129
-     *
130
-     * @param array<array-key, mixed> $query
131
-     *
132
-     * @return static
133
-     */
134
-    public function withQueryParams(array $query): ServerRequestInterface
135
-    {
136
-        $clone = clone $this;
137
-        $clone->queryParams = $query;
138
-
139
-        return $clone;
140
-    }
141
-
142
-    /**
143
-     * {@inheritDoc}
144
-     *
145
-     * @return array<array-key, mixed>
146
-     */
147
-    public function getCookieParams(): array
148
-    {
149
-        return $this->cookieParams;
150
-    }
151
-
152
-    /**
153
-     * {@inheritDoc}
154
-     *
155
-     * @param array<array-key, mixed> $cookies
156
-     *
157
-     * @return static
158
-     */
159
-    public function withCookieParams(array $cookies): ServerRequestInterface
160
-    {
161
-        $clone = clone $this;
162
-        $clone->cookieParams = $cookies;
163
-
164
-        return $clone;
165
-    }
166
-
167
-    /**
168
-     * {@inheritDoc}
169
-     *
170
-     * @return array<array-key, mixed>
171
-     */
172
-    public function getUploadedFiles(): array
173
-    {
174
-        return $this->uploadedFiles;
175
-    }
176
-
177
-    /**
178
-     * {@inheritDoc}
179
-     *
180
-     * @param array<array-key, mixed> $uploadedFiles
181
-     *
182
-     * @return static
183
-     *
184
-     * @throws InvalidArgumentException
185
-     */
186
-    public function withUploadedFiles(array $uploadedFiles): ServerRequestInterface
187
-    {
188
-        $clone = clone $this;
189
-        $clone->setUploadedFiles($uploadedFiles);
190
-
191
-        return $clone;
192
-    }
193
-
194
-    /**
195
-     * {@inheritDoc}
196
-     *
197
-     * @return array<array-key, mixed>|object|null
198
-     */
199
-    public function getParsedBody()
200
-    {
201
-        return $this->parsedBody;
202
-    }
203
-
204
-    /**
205
-     * {@inheritDoc}
206
-     *
207
-     * @param array<array-key, mixed>|object|null $data
208
-     *
209
-     * @return static
210
-     *
211
-     * @throws InvalidArgumentException
212
-     */
213
-    public function withParsedBody($data): ServerRequestInterface
214
-    {
215
-        $clone = clone $this;
216
-        $clone->setParsedBody($data);
217
-
218
-        return $clone;
219
-    }
220
-
221
-    /**
222
-     * {@inheritDoc}
223
-     *
224
-     * @return array<array-key, mixed>
225
-     */
226
-    public function getAttributes(): array
227
-    {
228
-        return $this->attributes;
229
-    }
230
-
231
-    /**
232
-     * {@inheritDoc}
233
-     *
234
-     * @param array-key $name
235
-     * @param mixed $default
236
-     *
237
-     * @return mixed
238
-     */
239
-    public function getAttribute($name, $default = null)
240
-    {
241
-        if (!array_key_exists($name, $this->attributes)) {
242
-            return $default;
243
-        }
244
-
245
-        return $this->attributes[$name];
246
-    }
247
-
248
-    /**
249
-     * {@inheritDoc}
250
-     *
251
-     * @param array-key $name
252
-     * @param mixed $value
253
-     *
254
-     * @return static
255
-     */
256
-    public function withAttribute($name, $value): ServerRequestInterface
257
-    {
258
-        $clone = clone $this;
259
-        $clone->attributes[$name] = $value;
260
-
261
-        return $clone;
262
-    }
263
-
264
-    /**
265
-     * {@inheritDoc}
266
-     *
267
-     * @param array-key $name
268
-     *
269
-     * @return static
270
-     */
271
-    public function withoutAttribute($name): ServerRequestInterface
272
-    {
273
-        $clone = clone $this;
274
-        unset($clone->attributes[$name]);
275
-
276
-        return $clone;
277
-    }
278
-
279
-    /**
280
-     * Sets the given uploaded files to the request
281
-     *
282
-     * @param array<array-key, mixed> $files
283
-     *
284
-     * @throws InvalidArgumentException
285
-     */
286
-    final protected function setUploadedFiles(array $files): void
287
-    {
288
-        $this->validateUploadedFiles($files);
289
-
290
-        $this->uploadedFiles = $files;
291
-    }
292
-
293
-    /**
294
-     * Sets the given parsed body to the request
295
-     *
296
-     * @param array<array-key, mixed>|object|null $data
297
-     *
298
-     * @throws InvalidArgumentException
299
-     */
300
-    final protected function setParsedBody($data): void
301
-    {
302
-        $this->validateParsedBody($data);
303
-
304
-        $this->parsedBody = $data;
305
-    }
306
-
307
-    /**
308
-     * Validates the given uploaded files
309
-     *
310
-     * @param array<array-key, mixed> $files
311
-     *
312
-     * @throws InvalidArgumentException
313
-     */
314
-    private function validateUploadedFiles(array $files): void
315
-    {
316
-        if ($files === []) {
317
-            return;
318
-        }
319
-
320
-        array_walk_recursive($files, /** @param mixed $file */ static function ($file): void {
321
-            if (!($file instanceof UploadedFileInterface)) {
322
-                throw new InvalidArgumentException('Invalid uploaded file');
323
-            }
324
-        });
325
-    }
326
-
327
-    /**
328
-     * Validates the given parsed body
329
-     *
330
-     * @param mixed $data
331
-     *
332
-     * @throws InvalidArgumentException
333
-     */
334
-    private function validateParsedBody($data): void
335
-    {
336
-        if ($data === null || is_array($data) || is_object($data)) {
337
-            return;
338
-        }
339
-
340
-        throw new InvalidArgumentException('Invalid parsed body');
341
-    }
29
+	/**
30
+	 * @var array<array-key, mixed>
31
+	 */
32
+	private array $serverParams;
33
+
34
+	/**
35
+	 * @var array<array-key, mixed>
36
+	 */
37
+	private array $queryParams;
38
+
39
+	/**
40
+	 * @var array<array-key, mixed>
41
+	 */
42
+	private array $cookieParams;
43
+
44
+	/**
45
+	 * @var array<array-key, mixed>
46
+	 */
47
+	private array $uploadedFiles = [];
48
+
49
+	/**
50
+	 * @var array<array-key, mixed>|object|null
51
+	 */
52
+	private $parsedBody = null;
53
+
54
+	/**
55
+	 * @var array<array-key, mixed>
56
+	 */
57
+	private array $attributes;
58
+
59
+	/**
60
+	 * Constructor of the class
61
+	 *
62
+	 * @param mixed $uri
63
+	 * @param array<string, string|string[]>|null $headers
64
+	 *
65
+	 * @param array<array-key, mixed> $serverParams
66
+	 * @param array<array-key, mixed> $queryParams
67
+	 * @param array<array-key, mixed> $cookieParams
68
+	 * @param array<array-key, mixed> $uploadedFiles
69
+	 * @param array<array-key, mixed>|object|null $parsedBody
70
+	 * @param array<array-key, mixed> $attributes
71
+	 *
72
+	 * @throws InvalidArgumentException
73
+	 */
74
+	public function __construct(
75
+		?string $protocolVersion = null,
76
+		?string $method = null,
77
+		$uri = null,
78
+		?array $headers = null,
79
+		?StreamInterface $body = null,
80
+		array $serverParams = [],
81
+		array $queryParams = [],
82
+		array $cookieParams = [],
83
+		array $uploadedFiles = [],
84
+		$parsedBody = null,
85
+		array $attributes = []
86
+	) {
87
+		parent::__construct($method, $uri, $headers, $body);
88
+
89
+		if ($protocolVersion !== null) {
90
+			$this->setProtocolVersion($protocolVersion);
91
+		}
92
+
93
+		if ($uploadedFiles !== []) {
94
+			$this->setUploadedFiles($uploadedFiles);
95
+		}
96
+
97
+		if ($parsedBody !== null) {
98
+			$this->setParsedBody($parsedBody);
99
+		}
100
+
101
+		$this->serverParams = $serverParams;
102
+		$this->queryParams = $queryParams;
103
+		$this->cookieParams = $cookieParams;
104
+		$this->attributes = $attributes;
105
+	}
106
+
107
+	/**
108
+	 * {@inheritDoc}
109
+	 *
110
+	 * @return array<array-key, mixed>
111
+	 */
112
+	public function getServerParams(): array
113
+	{
114
+		return $this->serverParams;
115
+	}
116
+
117
+	/**
118
+	 * {@inheritDoc}
119
+	 *
120
+	 * @return array<array-key, mixed>
121
+	 */
122
+	public function getQueryParams(): array
123
+	{
124
+		return $this->queryParams;
125
+	}
126
+
127
+	/**
128
+	 * {@inheritDoc}
129
+	 *
130
+	 * @param array<array-key, mixed> $query
131
+	 *
132
+	 * @return static
133
+	 */
134
+	public function withQueryParams(array $query): ServerRequestInterface
135
+	{
136
+		$clone = clone $this;
137
+		$clone->queryParams = $query;
138
+
139
+		return $clone;
140
+	}
141
+
142
+	/**
143
+	 * {@inheritDoc}
144
+	 *
145
+	 * @return array<array-key, mixed>
146
+	 */
147
+	public function getCookieParams(): array
148
+	{
149
+		return $this->cookieParams;
150
+	}
151
+
152
+	/**
153
+	 * {@inheritDoc}
154
+	 *
155
+	 * @param array<array-key, mixed> $cookies
156
+	 *
157
+	 * @return static
158
+	 */
159
+	public function withCookieParams(array $cookies): ServerRequestInterface
160
+	{
161
+		$clone = clone $this;
162
+		$clone->cookieParams = $cookies;
163
+
164
+		return $clone;
165
+	}
166
+
167
+	/**
168
+	 * {@inheritDoc}
169
+	 *
170
+	 * @return array<array-key, mixed>
171
+	 */
172
+	public function getUploadedFiles(): array
173
+	{
174
+		return $this->uploadedFiles;
175
+	}
176
+
177
+	/**
178
+	 * {@inheritDoc}
179
+	 *
180
+	 * @param array<array-key, mixed> $uploadedFiles
181
+	 *
182
+	 * @return static
183
+	 *
184
+	 * @throws InvalidArgumentException
185
+	 */
186
+	public function withUploadedFiles(array $uploadedFiles): ServerRequestInterface
187
+	{
188
+		$clone = clone $this;
189
+		$clone->setUploadedFiles($uploadedFiles);
190
+
191
+		return $clone;
192
+	}
193
+
194
+	/**
195
+	 * {@inheritDoc}
196
+	 *
197
+	 * @return array<array-key, mixed>|object|null
198
+	 */
199
+	public function getParsedBody()
200
+	{
201
+		return $this->parsedBody;
202
+	}
203
+
204
+	/**
205
+	 * {@inheritDoc}
206
+	 *
207
+	 * @param array<array-key, mixed>|object|null $data
208
+	 *
209
+	 * @return static
210
+	 *
211
+	 * @throws InvalidArgumentException
212
+	 */
213
+	public function withParsedBody($data): ServerRequestInterface
214
+	{
215
+		$clone = clone $this;
216
+		$clone->setParsedBody($data);
217
+
218
+		return $clone;
219
+	}
220
+
221
+	/**
222
+	 * {@inheritDoc}
223
+	 *
224
+	 * @return array<array-key, mixed>
225
+	 */
226
+	public function getAttributes(): array
227
+	{
228
+		return $this->attributes;
229
+	}
230
+
231
+	/**
232
+	 * {@inheritDoc}
233
+	 *
234
+	 * @param array-key $name
235
+	 * @param mixed $default
236
+	 *
237
+	 * @return mixed
238
+	 */
239
+	public function getAttribute($name, $default = null)
240
+	{
241
+		if (!array_key_exists($name, $this->attributes)) {
242
+			return $default;
243
+		}
244
+
245
+		return $this->attributes[$name];
246
+	}
247
+
248
+	/**
249
+	 * {@inheritDoc}
250
+	 *
251
+	 * @param array-key $name
252
+	 * @param mixed $value
253
+	 *
254
+	 * @return static
255
+	 */
256
+	public function withAttribute($name, $value): ServerRequestInterface
257
+	{
258
+		$clone = clone $this;
259
+		$clone->attributes[$name] = $value;
260
+
261
+		return $clone;
262
+	}
263
+
264
+	/**
265
+	 * {@inheritDoc}
266
+	 *
267
+	 * @param array-key $name
268
+	 *
269
+	 * @return static
270
+	 */
271
+	public function withoutAttribute($name): ServerRequestInterface
272
+	{
273
+		$clone = clone $this;
274
+		unset($clone->attributes[$name]);
275
+
276
+		return $clone;
277
+	}
278
+
279
+	/**
280
+	 * Sets the given uploaded files to the request
281
+	 *
282
+	 * @param array<array-key, mixed> $files
283
+	 *
284
+	 * @throws InvalidArgumentException
285
+	 */
286
+	final protected function setUploadedFiles(array $files): void
287
+	{
288
+		$this->validateUploadedFiles($files);
289
+
290
+		$this->uploadedFiles = $files;
291
+	}
292
+
293
+	/**
294
+	 * Sets the given parsed body to the request
295
+	 *
296
+	 * @param array<array-key, mixed>|object|null $data
297
+	 *
298
+	 * @throws InvalidArgumentException
299
+	 */
300
+	final protected function setParsedBody($data): void
301
+	{
302
+		$this->validateParsedBody($data);
303
+
304
+		$this->parsedBody = $data;
305
+	}
306
+
307
+	/**
308
+	 * Validates the given uploaded files
309
+	 *
310
+	 * @param array<array-key, mixed> $files
311
+	 *
312
+	 * @throws InvalidArgumentException
313
+	 */
314
+	private function validateUploadedFiles(array $files): void
315
+	{
316
+		if ($files === []) {
317
+			return;
318
+		}
319
+
320
+		array_walk_recursive($files, /** @param mixed $file */ static function ($file): void {
321
+			if (!($file instanceof UploadedFileInterface)) {
322
+				throw new InvalidArgumentException('Invalid uploaded file');
323
+			}
324
+		});
325
+	}
326
+
327
+	/**
328
+	 * Validates the given parsed body
329
+	 *
330
+	 * @param mixed $data
331
+	 *
332
+	 * @throws InvalidArgumentException
333
+	 */
334
+	private function validateParsedBody($data): void
335
+	{
336
+		if ($data === null || is_array($data) || is_object($data)) {
337
+			return;
338
+		}
339
+
340
+		throw new InvalidArgumentException('Invalid parsed body');
341
+	}
342 342
 }
Please login to merge, or discard this patch.
src/StreamFactory.php 1 patch
Indentation   +31 added lines, -31 removed lines patch added patch discarded remove patch
@@ -21,35 +21,35 @@
 block discarded – undo
21 21
  */
22 22
 class StreamFactory implements StreamFactoryInterface
23 23
 {
24
-    /**
25
-     * @inheritDoc
26
-     */
27
-    public function createStream(string $content = ''): StreamInterface
28
-    {
29
-        $stream = new PhpTempStream();
30
-        if ($content === '') {
31
-            return $stream;
32
-        }
33
-
34
-        $stream->write($content);
35
-        $stream->rewind();
36
-
37
-        return $stream;
38
-    }
39
-
40
-    /**
41
-     * @inheritDoc
42
-     */
43
-    public function createStreamFromFile(string $filename, string $mode = 'r'): StreamInterface
44
-    {
45
-        return new FileStream($filename, $mode);
46
-    }
47
-
48
-    /**
49
-     * @inheritDoc
50
-     */
51
-    public function createStreamFromResource($resource): StreamInterface
52
-    {
53
-        return new Stream($resource);
54
-    }
24
+	/**
25
+	 * @inheritDoc
26
+	 */
27
+	public function createStream(string $content = ''): StreamInterface
28
+	{
29
+		$stream = new PhpTempStream();
30
+		if ($content === '') {
31
+			return $stream;
32
+		}
33
+
34
+		$stream->write($content);
35
+		$stream->rewind();
36
+
37
+		return $stream;
38
+	}
39
+
40
+	/**
41
+	 * @inheritDoc
42
+	 */
43
+	public function createStreamFromFile(string $filename, string $mode = 'r'): StreamInterface
44
+	{
45
+		return new FileStream($filename, $mode);
46
+	}
47
+
48
+	/**
49
+	 * @inheritDoc
50
+	 */
51
+	public function createStreamFromResource($resource): StreamInterface
52
+	{
53
+		return new Stream($resource);
54
+	}
55 55
 }
Please login to merge, or discard this patch.
src/Request/UrlEncodedRequest.php 1 patch
Indentation   +30 added lines, -30 removed lines patch added patch discarded remove patch
@@ -26,40 +26,40 @@
 block discarded – undo
26 26
  */
27 27
 final class UrlEncodedRequest extends Request
28 28
 {
29
-    public const ENCODING_TYPE_RFC1738 = PHP_QUERY_RFC1738;
30
-    public const ENCODING_TYPE_RFC3986 = PHP_QUERY_RFC3986;
29
+	public const ENCODING_TYPE_RFC1738 = PHP_QUERY_RFC1738;
30
+	public const ENCODING_TYPE_RFC3986 = PHP_QUERY_RFC3986;
31 31
 
32
-    /**
33
-     * @param mixed $uri
34
-     * @param mixed $data
35
-     * @param self::ENCODING_TYPE_* $encodingType
36
-     *
37
-     * @throws InvalidArgumentException
38
-     */
39
-    public function __construct(string $method, $uri, $data, int $encodingType = self::ENCODING_TYPE_RFC1738)
40
-    {
41
-        parent::__construct($method, $uri);
32
+	/**
33
+	 * @param mixed $uri
34
+	 * @param mixed $data
35
+	 * @param self::ENCODING_TYPE_* $encodingType
36
+	 *
37
+	 * @throws InvalidArgumentException
38
+	 */
39
+	public function __construct(string $method, $uri, $data, int $encodingType = self::ENCODING_TYPE_RFC1738)
40
+	{
41
+		parent::__construct($method, $uri);
42 42
 
43
-        $this->setBody(self::createBody($data, $encodingType));
44
-        $this->setHeader('Content-Type', 'application/x-www-form-urlencoded; charset=utf-8');
45
-    }
43
+		$this->setBody(self::createBody($data, $encodingType));
44
+		$this->setHeader('Content-Type', 'application/x-www-form-urlencoded; charset=utf-8');
45
+	}
46 46
 
47
-    /**
48
-     * @param mixed $data
49
-     * @param self::ENCODING_TYPE_* $encodingType
50
-     */
51
-    private static function createBody($data, int $encodingType): StreamInterface
52
-    {
53
-        if ($data instanceof StreamInterface) {
54
-            return $data;
55
-        }
47
+	/**
48
+	 * @param mixed $data
49
+	 * @param self::ENCODING_TYPE_* $encodingType
50
+	 */
51
+	private static function createBody($data, int $encodingType): StreamInterface
52
+	{
53
+		if ($data instanceof StreamInterface) {
54
+			return $data;
55
+		}
56 56
 
57
-        $query = http_build_query((array) $data, '', '&', $encodingType);
57
+		$query = http_build_query((array) $data, '', '&', $encodingType);
58 58
 
59
-        $stream = new PhpTempStream('r+b');
60
-        $stream->write($query);
61
-        $stream->rewind();
59
+		$stream = new PhpTempStream('r+b');
60
+		$stream->write($query);
61
+		$stream->rewind();
62 62
 
63
-        return $stream;
64
-    }
63
+		return $stream;
64
+	}
65 65
 }
Please login to merge, or discard this patch.
src/UriFactory.php 1 patch
Indentation   +7 added lines, -7 removed lines patch added patch discarded remove patch
@@ -19,11 +19,11 @@
 block discarded – undo
19 19
  */
20 20
 class UriFactory implements UriFactoryInterface
21 21
 {
22
-    /**
23
-     * @inheritDoc
24
-     */
25
-    public function createUri(string $uri = ''): UriInterface
26
-    {
27
-        return new Uri($uri);
28
-    }
22
+	/**
23
+	 * @inheritDoc
24
+	 */
25
+	public function createUri(string $uri = ''): UriInterface
26
+	{
27
+		return new Uri($uri);
28
+	}
29 29
 }
Please login to merge, or discard this patch.