Test Failed
Pull Request — master (#34)
by Anatoly
04:34
created
src/UploadedFile.php 1 patch
Indentation   +135 added lines, -135 removed lines patch added patch discarded remove patch
@@ -40,139 +40,139 @@
 block discarded – undo
40 40
 
41 41
 class UploadedFile implements UploadedFileInterface
42 42
 {
43
-    /**
44
-     * @link https://www.php.net/manual/en/features.file-upload.errors.php
45
-     *
46
-     * @var array<int, non-empty-string>
47
-     */
48
-    public const UPLOAD_ERRORS = [
49
-        UPLOAD_ERR_OK         => 'No error',
50
-        UPLOAD_ERR_INI_SIZE   => 'Uploaded file exceeds the upload_max_filesize directive in the php.ini',
51
-        UPLOAD_ERR_FORM_SIZE  => 'Uploaded file exceeds the MAX_FILE_SIZE directive in the HTML form',
52
-        UPLOAD_ERR_PARTIAL    => 'Uploaded file was only partially uploaded',
53
-        UPLOAD_ERR_NO_FILE    => 'No file was uploaded',
54
-        UPLOAD_ERR_NO_TMP_DIR => 'Missing temporary directory',
55
-        UPLOAD_ERR_CANT_WRITE => 'Failed to write file to disk',
56
-        UPLOAD_ERR_EXTENSION  => 'File upload was stopped by a PHP extension',
57
-    ];
58
-
59
-    private ?StreamInterface $stream;
60
-    private ?int $size;
61
-    private int $errorCode;
62
-    private string $errorMessage;
63
-    private ?string $clientFilename;
64
-    private ?string $clientMediaType;
65
-    private bool $isMoved = false;
66
-
67
-    public function __construct(
68
-        ?StreamInterface $stream,
69
-        ?int $size = null,
70
-        int $error = UPLOAD_ERR_OK,
71
-        ?string $clientFilename = null,
72
-        ?string $clientMediaType = null
73
-    ) {
74
-        $this->stream = $stream;
75
-        $this->size = $size;
76
-        $this->errorCode = $error;
77
-        $this->errorMessage = self::UPLOAD_ERRORS[$error] ?? 'Unknown file upload error';
78
-        $this->clientFilename = $clientFilename;
79
-        $this->clientMediaType = $clientMediaType;
80
-    }
81
-
82
-    /**
83
-     * @inheritDoc
84
-     */
85
-    public function getStream(): StreamInterface
86
-    {
87
-        if ($this->isMoved) {
88
-            throw new RuntimeException('Uploaded file was moved');
89
-        }
90
-
91
-        if ($this->errorCode !== UPLOAD_ERR_OK) {
92
-            throw new RuntimeException($this->errorMessage, $this->errorCode);
93
-        }
94
-
95
-        if ($this->stream === null) {
96
-            throw new RuntimeException('Uploaded file has no stream');
97
-        }
98
-
99
-        return $this->stream;
100
-    }
101
-
102
-    /**
103
-     * @inheritDoc
104
-     */
105
-    public function moveTo($targetPath): void
106
-    {
107
-        /** @psalm-suppress TypeDoesNotContainType */
108
-        if (!is_string($targetPath)) {
109
-            throw new TypeError(sprintf(
110
-                'Argument #1 ($targetPath) must be of type string, %s given',
111
-                gettype($targetPath),
112
-            ));
113
-        }
114
-
115
-        $sourceStream = $this->getStream();
116
-
117
-        $sourcePath = $sourceStream->getMetadata('uri');
118
-        if (!is_string($sourcePath) || !is_file($sourcePath) || !is_readable($sourcePath)) {
119
-            throw new RuntimeException('Uploaded file does not exist or is not readable');
120
-        }
121
-
122
-        $sourceDirname = dirname($sourcePath);
123
-        if (!is_writable($sourceDirname)) {
124
-            throw new RuntimeException('To move the uploaded file, the source directory must be writable');
125
-        }
126
-
127
-        $targetDirname = dirname($targetPath);
128
-        if (!is_dir($targetDirname) || !is_writable($targetDirname)) {
129
-            throw new RuntimeException('To move the uploaded file, the target directory must exist and be writable');
130
-        }
131
-
132
-        try {
133
-            $this->isMoved = is_uploaded_file($sourcePath)
134
-                ? move_uploaded_file($sourcePath, $targetPath)
135
-                : rename($sourcePath, $targetPath);
136
-        } catch (Throwable $e) {
137
-        }
138
-
139
-        if (!$this->isMoved) {
140
-            throw new RuntimeException('Failed to move the uploaded file');
141
-        }
142
-
143
-        $sourceStream->close();
144
-        $this->stream = null;
145
-    }
146
-
147
-    /**
148
-     * @inheritDoc
149
-     */
150
-    public function getSize(): ?int
151
-    {
152
-        return $this->size;
153
-    }
154
-
155
-    /**
156
-     * @inheritDoc
157
-     */
158
-    public function getError(): int
159
-    {
160
-        return $this->errorCode;
161
-    }
162
-
163
-    /**
164
-     * @inheritDoc
165
-     */
166
-    public function getClientFilename(): ?string
167
-    {
168
-        return $this->clientFilename;
169
-    }
170
-
171
-    /**
172
-     * @inheritDoc
173
-     */
174
-    public function getClientMediaType(): ?string
175
-    {
176
-        return $this->clientMediaType;
177
-    }
43
+	/**
44
+	 * @link https://www.php.net/manual/en/features.file-upload.errors.php
45
+	 *
46
+	 * @var array<int, non-empty-string>
47
+	 */
48
+	public const UPLOAD_ERRORS = [
49
+		UPLOAD_ERR_OK         => 'No error',
50
+		UPLOAD_ERR_INI_SIZE   => 'Uploaded file exceeds the upload_max_filesize directive in the php.ini',
51
+		UPLOAD_ERR_FORM_SIZE  => 'Uploaded file exceeds the MAX_FILE_SIZE directive in the HTML form',
52
+		UPLOAD_ERR_PARTIAL    => 'Uploaded file was only partially uploaded',
53
+		UPLOAD_ERR_NO_FILE    => 'No file was uploaded',
54
+		UPLOAD_ERR_NO_TMP_DIR => 'Missing temporary directory',
55
+		UPLOAD_ERR_CANT_WRITE => 'Failed to write file to disk',
56
+		UPLOAD_ERR_EXTENSION  => 'File upload was stopped by a PHP extension',
57
+	];
58
+
59
+	private ?StreamInterface $stream;
60
+	private ?int $size;
61
+	private int $errorCode;
62
+	private string $errorMessage;
63
+	private ?string $clientFilename;
64
+	private ?string $clientMediaType;
65
+	private bool $isMoved = false;
66
+
67
+	public function __construct(
68
+		?StreamInterface $stream,
69
+		?int $size = null,
70
+		int $error = UPLOAD_ERR_OK,
71
+		?string $clientFilename = null,
72
+		?string $clientMediaType = null
73
+	) {
74
+		$this->stream = $stream;
75
+		$this->size = $size;
76
+		$this->errorCode = $error;
77
+		$this->errorMessage = self::UPLOAD_ERRORS[$error] ?? 'Unknown file upload error';
78
+		$this->clientFilename = $clientFilename;
79
+		$this->clientMediaType = $clientMediaType;
80
+	}
81
+
82
+	/**
83
+	 * @inheritDoc
84
+	 */
85
+	public function getStream(): StreamInterface
86
+	{
87
+		if ($this->isMoved) {
88
+			throw new RuntimeException('Uploaded file was moved');
89
+		}
90
+
91
+		if ($this->errorCode !== UPLOAD_ERR_OK) {
92
+			throw new RuntimeException($this->errorMessage, $this->errorCode);
93
+		}
94
+
95
+		if ($this->stream === null) {
96
+			throw new RuntimeException('Uploaded file has no stream');
97
+		}
98
+
99
+		return $this->stream;
100
+	}
101
+
102
+	/**
103
+	 * @inheritDoc
104
+	 */
105
+	public function moveTo($targetPath): void
106
+	{
107
+		/** @psalm-suppress TypeDoesNotContainType */
108
+		if (!is_string($targetPath)) {
109
+			throw new TypeError(sprintf(
110
+				'Argument #1 ($targetPath) must be of type string, %s given',
111
+				gettype($targetPath),
112
+			));
113
+		}
114
+
115
+		$sourceStream = $this->getStream();
116
+
117
+		$sourcePath = $sourceStream->getMetadata('uri');
118
+		if (!is_string($sourcePath) || !is_file($sourcePath) || !is_readable($sourcePath)) {
119
+			throw new RuntimeException('Uploaded file does not exist or is not readable');
120
+		}
121
+
122
+		$sourceDirname = dirname($sourcePath);
123
+		if (!is_writable($sourceDirname)) {
124
+			throw new RuntimeException('To move the uploaded file, the source directory must be writable');
125
+		}
126
+
127
+		$targetDirname = dirname($targetPath);
128
+		if (!is_dir($targetDirname) || !is_writable($targetDirname)) {
129
+			throw new RuntimeException('To move the uploaded file, the target directory must exist and be writable');
130
+		}
131
+
132
+		try {
133
+			$this->isMoved = is_uploaded_file($sourcePath)
134
+				? move_uploaded_file($sourcePath, $targetPath)
135
+				: rename($sourcePath, $targetPath);
136
+		} catch (Throwable $e) {
137
+		}
138
+
139
+		if (!$this->isMoved) {
140
+			throw new RuntimeException('Failed to move the uploaded file');
141
+		}
142
+
143
+		$sourceStream->close();
144
+		$this->stream = null;
145
+	}
146
+
147
+	/**
148
+	 * @inheritDoc
149
+	 */
150
+	public function getSize(): ?int
151
+	{
152
+		return $this->size;
153
+	}
154
+
155
+	/**
156
+	 * @inheritDoc
157
+	 */
158
+	public function getError(): int
159
+	{
160
+		return $this->errorCode;
161
+	}
162
+
163
+	/**
164
+	 * @inheritDoc
165
+	 */
166
+	public function getClientFilename(): ?string
167
+	{
168
+		return $this->clientFilename;
169
+	}
170
+
171
+	/**
172
+	 * @inheritDoc
173
+	 */
174
+	public function getClientMediaType(): ?string
175
+	{
176
+		return $this->clientMediaType;
177
+	}
178 178
 }
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
@@ -19,22 +19,22 @@
 block discarded – undo
19 19
 
20 20
 class UploadedFileFactory implements UploadedFileFactoryInterface
21 21
 {
22
-    /**
23
-     * @inheritDoc
24
-     */
25
-    public function createUploadedFile(
26
-        StreamInterface $stream,
27
-        ?int $size = null,
28
-        int $error = UPLOAD_ERR_OK,
29
-        ?string $clientFilename = null,
30
-        ?string $clientMediaType = null
31
-    ): UploadedFileInterface {
32
-        return new UploadedFile(
33
-            $stream,
34
-            $size,
35
-            $error,
36
-            $clientFilename,
37
-            $clientMediaType
38
-        );
39
-    }
22
+	/**
23
+	 * @inheritDoc
24
+	 */
25
+	public function createUploadedFile(
26
+		StreamInterface $stream,
27
+		?int $size = null,
28
+		int $error = UPLOAD_ERR_OK,
29
+		?string $clientFilename = null,
30
+		?string $clientMediaType = null
31
+	): UploadedFileInterface {
32
+		return new UploadedFile(
33
+			$stream,
34
+			$size,
35
+			$error,
36
+			$clientFilename,
37
+			$clientMediaType
38
+		);
39
+	}
40 40
 }
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
@@ -16,11 +16,11 @@
 block discarded – undo
16 16
 
17 17
 class RequestFactory implements RequestFactoryInterface
18 18
 {
19
-    /**
20
-     * @inheritDoc
21
-     */
22
-    public function createRequest(string $method, $uri): RequestInterface
23
-    {
24
-        return new Request($method, $uri);
25
-    }
19
+	/**
20
+	 * @inheritDoc
21
+	 */
22
+	public function createRequest(string $method, $uri): RequestInterface
23
+	{
24
+		return new Request($method, $uri);
25
+	}
26 26
 }
Please login to merge, or discard this patch.
src/ResponseFactory.php 1 patch
Indentation   +7 added lines, -7 removed lines patch added patch discarded remove patch
@@ -16,11 +16,11 @@
 block discarded – undo
16 16
 
17 17
 class ResponseFactory implements ResponseFactoryInterface
18 18
 {
19
-    /**
20
-     * @inheritDoc
21
-     */
22
-    public function createResponse(int $code = 200, string $reasonPhrase = ''): ResponseInterface
23
-    {
24
-        return new Response($code, $reasonPhrase);
25
-    }
19
+	/**
20
+	 * @inheritDoc
21
+	 */
22
+	public function createResponse(int $code = 200, string $reasonPhrase = ''): ResponseInterface
23
+	{
24
+		return new Response($code, $reasonPhrase);
25
+	}
26 26
 }
Please login to merge, or discard this patch.
src/Stream.php 1 patch
Indentation   +288 added lines, -288 removed lines patch added patch discarded remove patch
@@ -32,292 +32,292 @@
 block discarded – undo
32 32
 
33 33
 class Stream implements StreamInterface
34 34
 {
35
-    /**
36
-     * @var resource|null
37
-     */
38
-    private $resource;
39
-
40
-    private bool $autoClose;
41
-
42
-    /**
43
-     * @param mixed $resource
44
-     *
45
-     * @throws InvalidArgumentException
46
-     */
47
-    public function __construct($resource, bool $autoClose = true)
48
-    {
49
-        if (!is_resource($resource)) {
50
-            throw new InvalidArgumentException('Unexpected stream resource');
51
-        }
52
-
53
-        $this->resource = $resource;
54
-        $this->autoClose = $autoClose;
55
-    }
56
-
57
-    /**
58
-     * @param mixed $resource
59
-     *
60
-     * @throws InvalidArgumentException
61
-     */
62
-    public static function create($resource): StreamInterface
63
-    {
64
-        if ($resource instanceof StreamInterface) {
65
-            return $resource;
66
-        }
67
-
68
-        return new self($resource);
69
-    }
70
-
71
-    public function __destruct()
72
-    {
73
-        if ($this->autoClose) {
74
-            $this->close();
75
-        }
76
-    }
77
-
78
-    /**
79
-     * @inheritDoc
80
-     */
81
-    public function detach()
82
-    {
83
-        $resource = $this->resource;
84
-        $this->resource = null;
85
-
86
-        return $resource;
87
-    }
88
-
89
-    /**
90
-     * @inheritDoc
91
-     */
92
-    public function close(): void
93
-    {
94
-        $resource = $this->detach();
95
-        if (!is_resource($resource)) {
96
-            return;
97
-        }
98
-
99
-        fclose($resource);
100
-    }
101
-
102
-    /**
103
-     * @inheritDoc
104
-     */
105
-    public function eof(): bool
106
-    {
107
-        if (!is_resource($this->resource)) {
108
-            return true;
109
-        }
110
-
111
-        return feof($this->resource);
112
-    }
113
-
114
-    /**
115
-     * @inheritDoc
116
-     */
117
-    public function tell(): int
118
-    {
119
-        if (!is_resource($this->resource)) {
120
-            throw new RuntimeException('Stream has no resource');
121
-        }
122
-
123
-        $result = ftell($this->resource);
124
-        if ($result === false) {
125
-            throw new RuntimeException('Unable to get the stream pointer position');
126
-        }
127
-
128
-        return $result;
129
-    }
130
-
131
-    /**
132
-     * @inheritDoc
133
-     */
134
-    public function isSeekable(): bool
135
-    {
136
-        if (!is_resource($this->resource)) {
137
-            return false;
138
-        }
139
-
140
-        /** @var array{seekable: bool} */
141
-        $metadata = stream_get_meta_data($this->resource);
142
-
143
-        return $metadata['seekable'];
144
-    }
145
-
146
-    /**
147
-     * @inheritDoc
148
-     */
149
-    public function rewind(): void
150
-    {
151
-        $this->seek(0);
152
-    }
153
-
154
-    /**
155
-     * @inheritDoc
156
-     */
157
-    public function seek($offset, $whence = SEEK_SET): void
158
-    {
159
-        if (!is_resource($this->resource)) {
160
-            throw new RuntimeException('Stream has no resource');
161
-        }
162
-
163
-        if (!$this->isSeekable()) {
164
-            throw new RuntimeException('Stream is not seekable');
165
-        }
166
-
167
-        $result = fseek($this->resource, $offset, $whence);
168
-        if ($result !== 0) {
169
-            throw new RuntimeException('Unable to move the stream pointer position');
170
-        }
171
-    }
172
-
173
-    /**
174
-     * @inheritDoc
175
-     */
176
-    public function isWritable(): bool
177
-    {
178
-        if (!is_resource($this->resource)) {
179
-            return false;
180
-        }
181
-
182
-        /** @var array{mode: string} */
183
-        $metadata = stream_get_meta_data($this->resource);
184
-
185
-        return strpbrk($metadata['mode'], '+acwx') !== false;
186
-    }
187
-
188
-    /**
189
-     * @inheritDoc
190
-     */
191
-    public function write($string): int
192
-    {
193
-        if (!is_resource($this->resource)) {
194
-            throw new RuntimeException('Stream has no resource');
195
-        }
196
-
197
-        if (!$this->isWritable()) {
198
-            throw new RuntimeException('Stream is not writable');
199
-        }
200
-
201
-        $result = fwrite($this->resource, $string);
202
-        if ($result === false) {
203
-            throw new RuntimeException('Unable to write to the stream');
204
-        }
205
-
206
-        return $result;
207
-    }
208
-
209
-    /**
210
-     * @inheritDoc
211
-     */
212
-    public function isReadable(): bool
213
-    {
214
-        if (!is_resource($this->resource)) {
215
-            return false;
216
-        }
217
-
218
-        /** @var array{mode: string} */
219
-        $metadata = stream_get_meta_data($this->resource);
220
-
221
-        return strpbrk($metadata['mode'], '+r') !== false;
222
-    }
223
-
224
-    /**
225
-     * @inheritDoc
226
-     *
227
-     * @psalm-param int $length
228
-     * @phpstan-param int<1, max> $length
229
-     */
230
-    public function read($length): string
231
-    {
232
-        if (!is_resource($this->resource)) {
233
-            throw new RuntimeException('Stream has no resource');
234
-        }
235
-
236
-        if (!$this->isReadable()) {
237
-            throw new RuntimeException('Stream is not readable');
238
-        }
239
-
240
-        $result = fread($this->resource, $length);
241
-        if ($result === false) {
242
-            throw new RuntimeException('Unable to read from the stream');
243
-        }
244
-
245
-        return $result;
246
-    }
247
-
248
-    /**
249
-     * @inheritDoc
250
-     */
251
-    public function getContents(): string
252
-    {
253
-        if (!is_resource($this->resource)) {
254
-            throw new RuntimeException('Stream has no resource');
255
-        }
256
-
257
-        if (!$this->isReadable()) {
258
-            throw new RuntimeException('Stream is not readable');
259
-        }
260
-
261
-        $result = stream_get_contents($this->resource);
262
-        if ($result === false) {
263
-            throw new RuntimeException('Unable to read the remainder of the stream');
264
-        }
265
-
266
-        return $result;
267
-    }
268
-
269
-    /**
270
-     * @inheritDoc
271
-     */
272
-    public function getMetadata($key = null)
273
-    {
274
-        if (!is_resource($this->resource)) {
275
-            return null;
276
-        }
277
-
278
-        $metadata = stream_get_meta_data($this->resource);
279
-        if ($key === null) {
280
-            return $metadata;
281
-        }
282
-
283
-        return $metadata[$key] ?? null;
284
-    }
285
-
286
-    /**
287
-     * @inheritDoc
288
-     */
289
-    public function getSize(): ?int
290
-    {
291
-        if (!is_resource($this->resource)) {
292
-            return null;
293
-        }
294
-
295
-        /** @var array{size: int}|false */
296
-        $stats = fstat($this->resource);
297
-        if ($stats === false) {
298
-            return null;
299
-        }
300
-
301
-        return $stats['size'];
302
-    }
303
-
304
-    /**
305
-     * @inheritDoc
306
-     */
307
-    public function __toString(): string
308
-    {
309
-        if (!$this->isReadable()) {
310
-            return '';
311
-        }
312
-
313
-        try {
314
-            if ($this->isSeekable()) {
315
-                $this->rewind();
316
-            }
317
-
318
-            return $this->getContents();
319
-        } catch (Throwable $e) {
320
-            return '';
321
-        }
322
-    }
35
+	/**
36
+	 * @var resource|null
37
+	 */
38
+	private $resource;
39
+
40
+	private bool $autoClose;
41
+
42
+	/**
43
+	 * @param mixed $resource
44
+	 *
45
+	 * @throws InvalidArgumentException
46
+	 */
47
+	public function __construct($resource, bool $autoClose = true)
48
+	{
49
+		if (!is_resource($resource)) {
50
+			throw new InvalidArgumentException('Unexpected stream resource');
51
+		}
52
+
53
+		$this->resource = $resource;
54
+		$this->autoClose = $autoClose;
55
+	}
56
+
57
+	/**
58
+	 * @param mixed $resource
59
+	 *
60
+	 * @throws InvalidArgumentException
61
+	 */
62
+	public static function create($resource): StreamInterface
63
+	{
64
+		if ($resource instanceof StreamInterface) {
65
+			return $resource;
66
+		}
67
+
68
+		return new self($resource);
69
+	}
70
+
71
+	public function __destruct()
72
+	{
73
+		if ($this->autoClose) {
74
+			$this->close();
75
+		}
76
+	}
77
+
78
+	/**
79
+	 * @inheritDoc
80
+	 */
81
+	public function detach()
82
+	{
83
+		$resource = $this->resource;
84
+		$this->resource = null;
85
+
86
+		return $resource;
87
+	}
88
+
89
+	/**
90
+	 * @inheritDoc
91
+	 */
92
+	public function close(): void
93
+	{
94
+		$resource = $this->detach();
95
+		if (!is_resource($resource)) {
96
+			return;
97
+		}
98
+
99
+		fclose($resource);
100
+	}
101
+
102
+	/**
103
+	 * @inheritDoc
104
+	 */
105
+	public function eof(): bool
106
+	{
107
+		if (!is_resource($this->resource)) {
108
+			return true;
109
+		}
110
+
111
+		return feof($this->resource);
112
+	}
113
+
114
+	/**
115
+	 * @inheritDoc
116
+	 */
117
+	public function tell(): int
118
+	{
119
+		if (!is_resource($this->resource)) {
120
+			throw new RuntimeException('Stream has no resource');
121
+		}
122
+
123
+		$result = ftell($this->resource);
124
+		if ($result === false) {
125
+			throw new RuntimeException('Unable to get the stream pointer position');
126
+		}
127
+
128
+		return $result;
129
+	}
130
+
131
+	/**
132
+	 * @inheritDoc
133
+	 */
134
+	public function isSeekable(): bool
135
+	{
136
+		if (!is_resource($this->resource)) {
137
+			return false;
138
+		}
139
+
140
+		/** @var array{seekable: bool} */
141
+		$metadata = stream_get_meta_data($this->resource);
142
+
143
+		return $metadata['seekable'];
144
+	}
145
+
146
+	/**
147
+	 * @inheritDoc
148
+	 */
149
+	public function rewind(): void
150
+	{
151
+		$this->seek(0);
152
+	}
153
+
154
+	/**
155
+	 * @inheritDoc
156
+	 */
157
+	public function seek($offset, $whence = SEEK_SET): void
158
+	{
159
+		if (!is_resource($this->resource)) {
160
+			throw new RuntimeException('Stream has no resource');
161
+		}
162
+
163
+		if (!$this->isSeekable()) {
164
+			throw new RuntimeException('Stream is not seekable');
165
+		}
166
+
167
+		$result = fseek($this->resource, $offset, $whence);
168
+		if ($result !== 0) {
169
+			throw new RuntimeException('Unable to move the stream pointer position');
170
+		}
171
+	}
172
+
173
+	/**
174
+	 * @inheritDoc
175
+	 */
176
+	public function isWritable(): bool
177
+	{
178
+		if (!is_resource($this->resource)) {
179
+			return false;
180
+		}
181
+
182
+		/** @var array{mode: string} */
183
+		$metadata = stream_get_meta_data($this->resource);
184
+
185
+		return strpbrk($metadata['mode'], '+acwx') !== false;
186
+	}
187
+
188
+	/**
189
+	 * @inheritDoc
190
+	 */
191
+	public function write($string): int
192
+	{
193
+		if (!is_resource($this->resource)) {
194
+			throw new RuntimeException('Stream has no resource');
195
+		}
196
+
197
+		if (!$this->isWritable()) {
198
+			throw new RuntimeException('Stream is not writable');
199
+		}
200
+
201
+		$result = fwrite($this->resource, $string);
202
+		if ($result === false) {
203
+			throw new RuntimeException('Unable to write to the stream');
204
+		}
205
+
206
+		return $result;
207
+	}
208
+
209
+	/**
210
+	 * @inheritDoc
211
+	 */
212
+	public function isReadable(): bool
213
+	{
214
+		if (!is_resource($this->resource)) {
215
+			return false;
216
+		}
217
+
218
+		/** @var array{mode: string} */
219
+		$metadata = stream_get_meta_data($this->resource);
220
+
221
+		return strpbrk($metadata['mode'], '+r') !== false;
222
+	}
223
+
224
+	/**
225
+	 * @inheritDoc
226
+	 *
227
+	 * @psalm-param int $length
228
+	 * @phpstan-param int<1, max> $length
229
+	 */
230
+	public function read($length): string
231
+	{
232
+		if (!is_resource($this->resource)) {
233
+			throw new RuntimeException('Stream has no resource');
234
+		}
235
+
236
+		if (!$this->isReadable()) {
237
+			throw new RuntimeException('Stream is not readable');
238
+		}
239
+
240
+		$result = fread($this->resource, $length);
241
+		if ($result === false) {
242
+			throw new RuntimeException('Unable to read from the stream');
243
+		}
244
+
245
+		return $result;
246
+	}
247
+
248
+	/**
249
+	 * @inheritDoc
250
+	 */
251
+	public function getContents(): string
252
+	{
253
+		if (!is_resource($this->resource)) {
254
+			throw new RuntimeException('Stream has no resource');
255
+		}
256
+
257
+		if (!$this->isReadable()) {
258
+			throw new RuntimeException('Stream is not readable');
259
+		}
260
+
261
+		$result = stream_get_contents($this->resource);
262
+		if ($result === false) {
263
+			throw new RuntimeException('Unable to read the remainder of the stream');
264
+		}
265
+
266
+		return $result;
267
+	}
268
+
269
+	/**
270
+	 * @inheritDoc
271
+	 */
272
+	public function getMetadata($key = null)
273
+	{
274
+		if (!is_resource($this->resource)) {
275
+			return null;
276
+		}
277
+
278
+		$metadata = stream_get_meta_data($this->resource);
279
+		if ($key === null) {
280
+			return $metadata;
281
+		}
282
+
283
+		return $metadata[$key] ?? null;
284
+	}
285
+
286
+	/**
287
+	 * @inheritDoc
288
+	 */
289
+	public function getSize(): ?int
290
+	{
291
+		if (!is_resource($this->resource)) {
292
+			return null;
293
+		}
294
+
295
+		/** @var array{size: int}|false */
296
+		$stats = fstat($this->resource);
297
+		if ($stats === false) {
298
+			return null;
299
+		}
300
+
301
+		return $stats['size'];
302
+	}
303
+
304
+	/**
305
+	 * @inheritDoc
306
+	 */
307
+	public function __toString(): string
308
+	{
309
+		if (!$this->isReadable()) {
310
+			return '';
311
+		}
312
+
313
+		try {
314
+			if ($this->isSeekable()) {
315
+				$this->rewind();
316
+			}
317
+
318
+			return $this->getContents();
319
+		} catch (Throwable $e) {
320
+			return '';
321
+		}
322
+	}
323 323
 }
Please login to merge, or discard this patch.
src/Response/HtmlResponse.php 1 patch
Indentation   +38 added lines, -38 removed lines patch added patch discarded remove patch
@@ -22,42 +22,42 @@
 block discarded – undo
22 22
 
23 23
 final class HtmlResponse extends Response
24 24
 {
25
-    /**
26
-     * @param mixed $html
27
-     *
28
-     * @throws InvalidArgumentException
29
-     */
30
-    public function __construct(int $statusCode, $html)
31
-    {
32
-        parent::__construct($statusCode);
33
-
34
-        $this->setBody(self::createBody($html));
35
-        $this->setHeader('Content-Type', 'text/html; charset=utf-8');
36
-    }
37
-
38
-    /**
39
-     * @param mixed $html
40
-     *
41
-     * @throws InvalidArgumentException
42
-     */
43
-    private static function createBody($html): StreamInterface
44
-    {
45
-        if ($html instanceof StreamInterface) {
46
-            return $html;
47
-        }
48
-
49
-        if (is_object($html) && method_exists($html, '__toString')) {
50
-            $html = (string) $html;
51
-        }
52
-
53
-        if (!is_string($html)) {
54
-            throw new InvalidArgumentException('Unable to create the HTML response due to a unexpected HTML type');
55
-        }
56
-
57
-        $stream = new PhpTempStream('r+b');
58
-        $stream->write($html);
59
-        $stream->rewind();
60
-
61
-        return $stream;
62
-    }
25
+	/**
26
+	 * @param mixed $html
27
+	 *
28
+	 * @throws InvalidArgumentException
29
+	 */
30
+	public function __construct(int $statusCode, $html)
31
+	{
32
+		parent::__construct($statusCode);
33
+
34
+		$this->setBody(self::createBody($html));
35
+		$this->setHeader('Content-Type', 'text/html; charset=utf-8');
36
+	}
37
+
38
+	/**
39
+	 * @param mixed $html
40
+	 *
41
+	 * @throws InvalidArgumentException
42
+	 */
43
+	private static function createBody($html): StreamInterface
44
+	{
45
+		if ($html instanceof StreamInterface) {
46
+			return $html;
47
+		}
48
+
49
+		if (is_object($html) && method_exists($html, '__toString')) {
50
+			$html = (string) $html;
51
+		}
52
+
53
+		if (!is_string($html)) {
54
+			throw new InvalidArgumentException('Unable to create the HTML response due to a unexpected HTML type');
55
+		}
56
+
57
+		$stream = new PhpTempStream('r+b');
58
+		$stream->write($html);
59
+		$stream->rewind();
60
+
61
+		return $stream;
62
+	}
63 63
 }
Please login to merge, or discard this patch.
src/Response/JsonResponse.php 1 patch
Indentation   +38 added lines, -38 removed lines patch added patch discarded remove patch
@@ -24,47 +24,47 @@
 block discarded – undo
24 24
 
25 25
 final class JsonResponse extends Response
26 26
 {
27
-    /**
28
-     * @param mixed $data
29
-     * @param int<1, max> $depth
30
-     * @psalm-param int<1, 2147483647> $depth
31
-     *
32
-     * @throws InvalidArgumentException
33
-     */
34
-    public function __construct(int $statusCode, $data, int $flags = 0, int $depth = 512)
35
-    {
36
-        parent::__construct($statusCode);
27
+	/**
28
+	 * @param mixed $data
29
+	 * @param int<1, max> $depth
30
+	 * @psalm-param int<1, 2147483647> $depth
31
+	 *
32
+	 * @throws InvalidArgumentException
33
+	 */
34
+	public function __construct(int $statusCode, $data, int $flags = 0, int $depth = 512)
35
+	{
36
+		parent::__construct($statusCode);
37 37
 
38
-        $this->setBody(self::createBody($data, $flags, $depth));
39
-        $this->setHeader('Content-Type', 'application/json; charset=utf-8');
40
-    }
38
+		$this->setBody(self::createBody($data, $flags, $depth));
39
+		$this->setHeader('Content-Type', 'application/json; charset=utf-8');
40
+	}
41 41
 
42
-    /**
43
-     * @param mixed $data
44
-     * @param int<1, max> $depth
45
-     * @psalm-param int<1, 2147483647> $depth
46
-     *
47
-     * @throws InvalidArgumentException
48
-     */
49
-    private static function createBody($data, int $flags, int $depth): StreamInterface
50
-    {
51
-        if ($data instanceof StreamInterface) {
52
-            return $data;
53
-        }
42
+	/**
43
+	 * @param mixed $data
44
+	 * @param int<1, max> $depth
45
+	 * @psalm-param int<1, 2147483647> $depth
46
+	 *
47
+	 * @throws InvalidArgumentException
48
+	 */
49
+	private static function createBody($data, int $flags, int $depth): StreamInterface
50
+	{
51
+		if ($data instanceof StreamInterface) {
52
+			return $data;
53
+		}
54 54
 
55
-        try {
56
-            $json = json_encode($data, $flags | JSON_THROW_ON_ERROR, $depth);
57
-        } catch (JsonException $e) {
58
-            throw new InvalidArgumentException(sprintf(
59
-                'Unable to create the JSON response due to an invalid data: %s',
60
-                $e->getMessage()
61
-            ), 0, $e);
62
-        }
55
+		try {
56
+			$json = json_encode($data, $flags | JSON_THROW_ON_ERROR, $depth);
57
+		} catch (JsonException $e) {
58
+			throw new InvalidArgumentException(sprintf(
59
+				'Unable to create the JSON response due to an invalid data: %s',
60
+				$e->getMessage()
61
+			), 0, $e);
62
+		}
63 63
 
64
-        $stream = new PhpTempStream('r+b');
65
-        $stream->write($json);
66
-        $stream->rewind();
64
+		$stream = new PhpTempStream('r+b');
65
+		$stream->write($json);
66
+		$stream->rewind();
67 67
 
68
-        return $stream;
69
-    }
68
+		return $stream;
69
+	}
70 70
 }
Please login to merge, or discard this patch.
src/Request/UrlEncodedRequest.php 1 patch
Indentation   +40 added lines, -40 removed lines patch added patch discarded remove patch
@@ -31,51 +31,51 @@
 block discarded – undo
31 31
  */
32 32
 final class UrlEncodedRequest extends Request
33 33
 {
34
-    public const ENCODING_TYPE_RFC1738 = PHP_QUERY_RFC1738;
35
-    public const ENCODING_TYPE_RFC3986 = PHP_QUERY_RFC3986;
34
+	public const ENCODING_TYPE_RFC1738 = PHP_QUERY_RFC1738;
35
+	public const ENCODING_TYPE_RFC3986 = PHP_QUERY_RFC3986;
36 36
 
37
-    /**
38
-     * @param mixed $uri
39
-     * @param array<array-key, mixed>|object $data
40
-     * @param self::ENCODING_TYPE_* $encodingType
41
-     *
42
-     * @throws InvalidArgumentException
43
-     */
44
-    public function __construct(string $method, $uri, $data, int $encodingType = self::ENCODING_TYPE_RFC1738)
45
-    {
46
-        /**
47
-         * @psalm-suppress DocblockTypeContradiction
48
-         * @phpstan-ignore-next-line
49
-         */
50
-        if (!is_array($data) && !is_object($data)) {
51
-            throw new TypeError(sprintf(
52
-                'Argument #3 ($data) must be of type string, %s given',
53
-                gettype($data),
54
-            ));
55
-        }
37
+	/**
38
+	 * @param mixed $uri
39
+	 * @param array<array-key, mixed>|object $data
40
+	 * @param self::ENCODING_TYPE_* $encodingType
41
+	 *
42
+	 * @throws InvalidArgumentException
43
+	 */
44
+	public function __construct(string $method, $uri, $data, int $encodingType = self::ENCODING_TYPE_RFC1738)
45
+	{
46
+		/**
47
+		 * @psalm-suppress DocblockTypeContradiction
48
+		 * @phpstan-ignore-next-line
49
+		 */
50
+		if (!is_array($data) && !is_object($data)) {
51
+			throw new TypeError(sprintf(
52
+				'Argument #3 ($data) must be of type string, %s given',
53
+				gettype($data),
54
+			));
55
+		}
56 56
 
57
-        parent::__construct($method, $uri);
57
+		parent::__construct($method, $uri);
58 58
 
59
-        $this->setBody(self::createBody($data, $encodingType));
60
-        $this->setHeader('Content-Type', 'application/x-www-form-urlencoded; charset=utf-8');
61
-    }
59
+		$this->setBody(self::createBody($data, $encodingType));
60
+		$this->setHeader('Content-Type', 'application/x-www-form-urlencoded; charset=utf-8');
61
+	}
62 62
 
63
-    /**
64
-     * @param array<array-key, mixed>|object $data
65
-     * @param self::ENCODING_TYPE_* $encodingType
66
-     */
67
-    private static function createBody($data, int $encodingType): StreamInterface
68
-    {
69
-        if ($data instanceof StreamInterface) {
70
-            return $data;
71
-        }
63
+	/**
64
+	 * @param array<array-key, mixed>|object $data
65
+	 * @param self::ENCODING_TYPE_* $encodingType
66
+	 */
67
+	private static function createBody($data, int $encodingType): StreamInterface
68
+	{
69
+		if ($data instanceof StreamInterface) {
70
+			return $data;
71
+		}
72 72
 
73
-        $encodedData = http_build_query($data, '', null, $encodingType);
73
+		$encodedData = http_build_query($data, '', null, $encodingType);
74 74
 
75
-        $stream = new PhpTempStream('r+b');
76
-        $stream->write($encodedData);
77
-        $stream->rewind();
75
+		$stream = new PhpTempStream('r+b');
76
+		$stream->write($encodedData);
77
+		$stream->rewind();
78 78
 
79
-        return $stream;
80
-    }
79
+		return $stream;
80
+	}
81 81
 }
Please login to merge, or discard this patch.