Passed
Push — master ( 4ccf8a...0a732e )
by Anatoly
02:58 queued 15s
created
src/UploadedFile.php 1 patch
Indentation   +136 added lines, -136 removed lines patch added patch discarded remove patch
@@ -40,140 +40,140 @@
 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
-        // @phpstan-ignore function.alreadyNarrowedType
109
-        if (!is_string($targetPath)) {
110
-            throw new TypeError(sprintf(
111
-                'Argument #1 ($targetPath) must be of type string, %s given',
112
-                gettype($targetPath),
113
-            ));
114
-        }
115
-
116
-        $sourceStream = $this->getStream();
117
-
118
-        $sourcePath = $sourceStream->getMetadata('uri');
119
-        if (!is_string($sourcePath) || !is_file($sourcePath) || !is_readable($sourcePath)) {
120
-            throw new RuntimeException('Uploaded file does not exist or is not readable');
121
-        }
122
-
123
-        $sourceDirname = dirname($sourcePath);
124
-        if (!is_writable($sourceDirname)) {
125
-            throw new RuntimeException('To move the uploaded file, the source directory must be writable');
126
-        }
127
-
128
-        $targetDirname = dirname($targetPath);
129
-        if (!is_dir($targetDirname) || !is_writable($targetDirname)) {
130
-            throw new RuntimeException('To move the uploaded file, the target directory must exist and be writable');
131
-        }
132
-
133
-        try {
134
-            $this->isMoved = is_uploaded_file($sourcePath)
135
-                ? move_uploaded_file($sourcePath, $targetPath)
136
-                : rename($sourcePath, $targetPath);
137
-        } catch (Throwable $e) {
138
-        }
139
-
140
-        if (!$this->isMoved) {
141
-            throw new RuntimeException('Failed to move the uploaded file');
142
-        }
143
-
144
-        $sourceStream->close();
145
-        $this->stream = null;
146
-    }
147
-
148
-    /**
149
-     * @inheritDoc
150
-     */
151
-    public function getSize(): ?int
152
-    {
153
-        return $this->size;
154
-    }
155
-
156
-    /**
157
-     * @inheritDoc
158
-     */
159
-    public function getError(): int
160
-    {
161
-        return $this->errorCode;
162
-    }
163
-
164
-    /**
165
-     * @inheritDoc
166
-     */
167
-    public function getClientFilename(): ?string
168
-    {
169
-        return $this->clientFilename;
170
-    }
171
-
172
-    /**
173
-     * @inheritDoc
174
-     */
175
-    public function getClientMediaType(): ?string
176
-    {
177
-        return $this->clientMediaType;
178
-    }
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
+		// @phpstan-ignore function.alreadyNarrowedType
109
+		if (!is_string($targetPath)) {
110
+			throw new TypeError(sprintf(
111
+				'Argument #1 ($targetPath) must be of type string, %s given',
112
+				gettype($targetPath),
113
+			));
114
+		}
115
+
116
+		$sourceStream = $this->getStream();
117
+
118
+		$sourcePath = $sourceStream->getMetadata('uri');
119
+		if (!is_string($sourcePath) || !is_file($sourcePath) || !is_readable($sourcePath)) {
120
+			throw new RuntimeException('Uploaded file does not exist or is not readable');
121
+		}
122
+
123
+		$sourceDirname = dirname($sourcePath);
124
+		if (!is_writable($sourceDirname)) {
125
+			throw new RuntimeException('To move the uploaded file, the source directory must be writable');
126
+		}
127
+
128
+		$targetDirname = dirname($targetPath);
129
+		if (!is_dir($targetDirname) || !is_writable($targetDirname)) {
130
+			throw new RuntimeException('To move the uploaded file, the target directory must exist and be writable');
131
+		}
132
+
133
+		try {
134
+			$this->isMoved = is_uploaded_file($sourcePath)
135
+				? move_uploaded_file($sourcePath, $targetPath)
136
+				: rename($sourcePath, $targetPath);
137
+		} catch (Throwable $e) {
138
+		}
139
+
140
+		if (!$this->isMoved) {
141
+			throw new RuntimeException('Failed to move the uploaded file');
142
+		}
143
+
144
+		$sourceStream->close();
145
+		$this->stream = null;
146
+	}
147
+
148
+	/**
149
+	 * @inheritDoc
150
+	 */
151
+	public function getSize(): ?int
152
+	{
153
+		return $this->size;
154
+	}
155
+
156
+	/**
157
+	 * @inheritDoc
158
+	 */
159
+	public function getError(): int
160
+	{
161
+		return $this->errorCode;
162
+	}
163
+
164
+	/**
165
+	 * @inheritDoc
166
+	 */
167
+	public function getClientFilename(): ?string
168
+	{
169
+		return $this->clientFilename;
170
+	}
171
+
172
+	/**
173
+	 * @inheritDoc
174
+	 */
175
+	public function getClientMediaType(): ?string
176
+	{
177
+		return $this->clientMediaType;
178
+	}
179 179
 }
Please login to merge, or discard this patch.
src/Response/JsonResponse.php 1 patch
Indentation   +39 added lines, -39 removed lines patch added patch discarded remove patch
@@ -24,48 +24,48 @@
 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
-            /** @var non-empty-string $json */
57
-            $json = json_encode($data, $flags | JSON_THROW_ON_ERROR, $depth);
58
-        } catch (JsonException $e) {
59
-            throw new InvalidArgumentException(sprintf(
60
-                'Unable to create the JSON response due to an invalid data: %s',
61
-                $e->getMessage()
62
-            ), 0, $e);
63
-        }
55
+		try {
56
+			/** @var non-empty-string $json */
57
+			$json = json_encode($data, $flags | JSON_THROW_ON_ERROR, $depth);
58
+		} catch (JsonException $e) {
59
+			throw new InvalidArgumentException(sprintf(
60
+				'Unable to create the JSON response due to an invalid data: %s',
61
+				$e->getMessage()
62
+			), 0, $e);
63
+		}
64 64
 
65
-        $stream = new PhpTempStream('r+b');
66
-        $stream->write($json);
67
-        $stream->rewind();
65
+		$stream = new PhpTempStream('r+b');
66
+		$stream->write($json);
67
+		$stream->rewind();
68 68
 
69
-        return $stream;
70
-    }
69
+		return $stream;
70
+	}
71 71
 }
Please login to merge, or discard this patch.
src/Stream.php 1 patch
Indentation   +285 added lines, -285 removed lines patch added patch discarded remove patch
@@ -32,289 +32,289 @@
 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
-        $metadata = stream_get_meta_data($this->resource);
141
-
142
-        return $metadata['seekable'];
143
-    }
144
-
145
-    /**
146
-     * @inheritDoc
147
-     */
148
-    public function rewind(): void
149
-    {
150
-        $this->seek(0);
151
-    }
152
-
153
-    /**
154
-     * @inheritDoc
155
-     */
156
-    public function seek($offset, $whence = SEEK_SET): void
157
-    {
158
-        if (!is_resource($this->resource)) {
159
-            throw new RuntimeException('Stream has no resource');
160
-        }
161
-
162
-        if (!$this->isSeekable()) {
163
-            throw new RuntimeException('Stream is not seekable');
164
-        }
165
-
166
-        $result = fseek($this->resource, $offset, $whence);
167
-        if ($result !== 0) {
168
-            throw new RuntimeException('Unable to move the stream pointer position');
169
-        }
170
-    }
171
-
172
-    /**
173
-     * @inheritDoc
174
-     */
175
-    public function isWritable(): bool
176
-    {
177
-        if (!is_resource($this->resource)) {
178
-            return false;
179
-        }
180
-
181
-        $metadata = stream_get_meta_data($this->resource);
182
-
183
-        return strpbrk($metadata['mode'], '+acwx') !== false;
184
-    }
185
-
186
-    /**
187
-     * @inheritDoc
188
-     */
189
-    public function write($string): int
190
-    {
191
-        if (!is_resource($this->resource)) {
192
-            throw new RuntimeException('Stream has no resource');
193
-        }
194
-
195
-        if (!$this->isWritable()) {
196
-            throw new RuntimeException('Stream is not writable');
197
-        }
198
-
199
-        $result = fwrite($this->resource, $string);
200
-        if ($result === false) {
201
-            throw new RuntimeException('Unable to write to the stream');
202
-        }
203
-
204
-        return $result;
205
-    }
206
-
207
-    /**
208
-     * @inheritDoc
209
-     */
210
-    public function isReadable(): bool
211
-    {
212
-        if (!is_resource($this->resource)) {
213
-            return false;
214
-        }
215
-
216
-        $metadata = stream_get_meta_data($this->resource);
217
-
218
-        return strpbrk($metadata['mode'], '+r') !== false;
219
-    }
220
-
221
-    /**
222
-     * @inheritDoc
223
-     *
224
-     * @psalm-param int $length
225
-     * @phpstan-param int<1, max> $length
226
-     */
227
-    public function read($length): string
228
-    {
229
-        if (!is_resource($this->resource)) {
230
-            throw new RuntimeException('Stream has no resource');
231
-        }
232
-
233
-        if (!$this->isReadable()) {
234
-            throw new RuntimeException('Stream is not readable');
235
-        }
236
-
237
-        $result = fread($this->resource, $length);
238
-        if ($result === false) {
239
-            throw new RuntimeException('Unable to read from the stream');
240
-        }
241
-
242
-        return $result;
243
-    }
244
-
245
-    /**
246
-     * @inheritDoc
247
-     */
248
-    public function getContents(): string
249
-    {
250
-        if (!is_resource($this->resource)) {
251
-            throw new RuntimeException('Stream has no resource');
252
-        }
253
-
254
-        if (!$this->isReadable()) {
255
-            throw new RuntimeException('Stream is not readable');
256
-        }
257
-
258
-        $result = stream_get_contents($this->resource);
259
-        if ($result === false) {
260
-            throw new RuntimeException('Unable to read the remainder of the stream');
261
-        }
262
-
263
-        return $result;
264
-    }
265
-
266
-    /**
267
-     * @inheritDoc
268
-     */
269
-    public function getMetadata($key = null)
270
-    {
271
-        if (!is_resource($this->resource)) {
272
-            return null;
273
-        }
274
-
275
-        $metadata = stream_get_meta_data($this->resource);
276
-        if ($key === null) {
277
-            return $metadata;
278
-        }
279
-
280
-        return $metadata[$key] ?? null;
281
-    }
282
-
283
-    /**
284
-     * @inheritDoc
285
-     */
286
-    public function getSize(): ?int
287
-    {
288
-        if (!is_resource($this->resource)) {
289
-            return null;
290
-        }
291
-
292
-        /** @var array{size: int}|false */
293
-        $stats = fstat($this->resource);
294
-        if ($stats === false) {
295
-            return null;
296
-        }
297
-
298
-        return $stats['size'];
299
-    }
300
-
301
-    /**
302
-     * @inheritDoc
303
-     */
304
-    public function __toString(): string
305
-    {
306
-        if (!$this->isReadable()) {
307
-            return '';
308
-        }
309
-
310
-        try {
311
-            if ($this->isSeekable()) {
312
-                $this->rewind();
313
-            }
314
-
315
-            return $this->getContents();
316
-        } catch (Throwable $e) {
317
-            return '';
318
-        }
319
-    }
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
+		$metadata = stream_get_meta_data($this->resource);
141
+
142
+		return $metadata['seekable'];
143
+	}
144
+
145
+	/**
146
+	 * @inheritDoc
147
+	 */
148
+	public function rewind(): void
149
+	{
150
+		$this->seek(0);
151
+	}
152
+
153
+	/**
154
+	 * @inheritDoc
155
+	 */
156
+	public function seek($offset, $whence = SEEK_SET): void
157
+	{
158
+		if (!is_resource($this->resource)) {
159
+			throw new RuntimeException('Stream has no resource');
160
+		}
161
+
162
+		if (!$this->isSeekable()) {
163
+			throw new RuntimeException('Stream is not seekable');
164
+		}
165
+
166
+		$result = fseek($this->resource, $offset, $whence);
167
+		if ($result !== 0) {
168
+			throw new RuntimeException('Unable to move the stream pointer position');
169
+		}
170
+	}
171
+
172
+	/**
173
+	 * @inheritDoc
174
+	 */
175
+	public function isWritable(): bool
176
+	{
177
+		if (!is_resource($this->resource)) {
178
+			return false;
179
+		}
180
+
181
+		$metadata = stream_get_meta_data($this->resource);
182
+
183
+		return strpbrk($metadata['mode'], '+acwx') !== false;
184
+	}
185
+
186
+	/**
187
+	 * @inheritDoc
188
+	 */
189
+	public function write($string): int
190
+	{
191
+		if (!is_resource($this->resource)) {
192
+			throw new RuntimeException('Stream has no resource');
193
+		}
194
+
195
+		if (!$this->isWritable()) {
196
+			throw new RuntimeException('Stream is not writable');
197
+		}
198
+
199
+		$result = fwrite($this->resource, $string);
200
+		if ($result === false) {
201
+			throw new RuntimeException('Unable to write to the stream');
202
+		}
203
+
204
+		return $result;
205
+	}
206
+
207
+	/**
208
+	 * @inheritDoc
209
+	 */
210
+	public function isReadable(): bool
211
+	{
212
+		if (!is_resource($this->resource)) {
213
+			return false;
214
+		}
215
+
216
+		$metadata = stream_get_meta_data($this->resource);
217
+
218
+		return strpbrk($metadata['mode'], '+r') !== false;
219
+	}
220
+
221
+	/**
222
+	 * @inheritDoc
223
+	 *
224
+	 * @psalm-param int $length
225
+	 * @phpstan-param int<1, max> $length
226
+	 */
227
+	public function read($length): string
228
+	{
229
+		if (!is_resource($this->resource)) {
230
+			throw new RuntimeException('Stream has no resource');
231
+		}
232
+
233
+		if (!$this->isReadable()) {
234
+			throw new RuntimeException('Stream is not readable');
235
+		}
236
+
237
+		$result = fread($this->resource, $length);
238
+		if ($result === false) {
239
+			throw new RuntimeException('Unable to read from the stream');
240
+		}
241
+
242
+		return $result;
243
+	}
244
+
245
+	/**
246
+	 * @inheritDoc
247
+	 */
248
+	public function getContents(): string
249
+	{
250
+		if (!is_resource($this->resource)) {
251
+			throw new RuntimeException('Stream has no resource');
252
+		}
253
+
254
+		if (!$this->isReadable()) {
255
+			throw new RuntimeException('Stream is not readable');
256
+		}
257
+
258
+		$result = stream_get_contents($this->resource);
259
+		if ($result === false) {
260
+			throw new RuntimeException('Unable to read the remainder of the stream');
261
+		}
262
+
263
+		return $result;
264
+	}
265
+
266
+	/**
267
+	 * @inheritDoc
268
+	 */
269
+	public function getMetadata($key = null)
270
+	{
271
+		if (!is_resource($this->resource)) {
272
+			return null;
273
+		}
274
+
275
+		$metadata = stream_get_meta_data($this->resource);
276
+		if ($key === null) {
277
+			return $metadata;
278
+		}
279
+
280
+		return $metadata[$key] ?? null;
281
+	}
282
+
283
+	/**
284
+	 * @inheritDoc
285
+	 */
286
+	public function getSize(): ?int
287
+	{
288
+		if (!is_resource($this->resource)) {
289
+			return null;
290
+		}
291
+
292
+		/** @var array{size: int}|false */
293
+		$stats = fstat($this->resource);
294
+		if ($stats === false) {
295
+			return null;
296
+		}
297
+
298
+		return $stats['size'];
299
+	}
300
+
301
+	/**
302
+	 * @inheritDoc
303
+	 */
304
+	public function __toString(): string
305
+	{
306
+		if (!$this->isReadable()) {
307
+			return '';
308
+		}
309
+
310
+		try {
311
+			if ($this->isSeekable()) {
312
+				$this->rewind();
313
+			}
314
+
315
+			return $this->getContents();
316
+		} catch (Throwable $e) {
317
+			return '';
318
+		}
319
+	}
320 320
 }
Please login to merge, or discard this patch.
src/Request/JsonRequest.php 1 patch
Indentation   +40 added lines, -40 removed lines patch added patch discarded remove patch
@@ -27,49 +27,49 @@
 block discarded – undo
27 27
  */
28 28
 final class JsonRequest extends Request
29 29
 {
30
-    /**
31
-     * @param mixed $uri
32
-     * @param mixed $data
33
-     * @param int<1, max> $depth
34
-     * @psalm-param int<1, 2147483647> $depth
35
-     *
36
-     * @throws InvalidArgumentException
37
-     */
38
-    public function __construct(string $method, $uri, $data, int $flags = 0, int $depth = 512)
39
-    {
40
-        parent::__construct($method, $uri);
30
+	/**
31
+	 * @param mixed $uri
32
+	 * @param mixed $data
33
+	 * @param int<1, max> $depth
34
+	 * @psalm-param int<1, 2147483647> $depth
35
+	 *
36
+	 * @throws InvalidArgumentException
37
+	 */
38
+	public function __construct(string $method, $uri, $data, int $flags = 0, int $depth = 512)
39
+	{
40
+		parent::__construct($method, $uri);
41 41
 
42
-        $this->setBody(self::createBody($data, $flags, $depth));
43
-        $this->setHeader('Content-Type', 'application/json; charset=utf-8');
44
-    }
42
+		$this->setBody(self::createBody($data, $flags, $depth));
43
+		$this->setHeader('Content-Type', 'application/json; charset=utf-8');
44
+	}
45 45
 
46
-    /**
47
-     * @param mixed $data
48
-     * @param int<1, max> $depth
49
-     * @psalm-param int<1, 2147483647> $depth
50
-     *
51
-     * @throws InvalidArgumentException
52
-     */
53
-    private static function createBody($data, int $flags, int $depth): StreamInterface
54
-    {
55
-        if ($data instanceof StreamInterface) {
56
-            return $data;
57
-        }
46
+	/**
47
+	 * @param mixed $data
48
+	 * @param int<1, max> $depth
49
+	 * @psalm-param int<1, 2147483647> $depth
50
+	 *
51
+	 * @throws InvalidArgumentException
52
+	 */
53
+	private static function createBody($data, int $flags, int $depth): StreamInterface
54
+	{
55
+		if ($data instanceof StreamInterface) {
56
+			return $data;
57
+		}
58 58
 
59
-        try {
60
-            /** @var non-empty-string $json */
61
-            $json = json_encode($data, $flags | JSON_THROW_ON_ERROR, $depth);
62
-        } catch (JsonException $e) {
63
-            throw new InvalidArgumentException(sprintf(
64
-                'Unable to create the JSON request due to an invalid data: %s',
65
-                $e->getMessage(),
66
-            ), 0, $e);
67
-        }
59
+		try {
60
+			/** @var non-empty-string $json */
61
+			$json = json_encode($data, $flags | JSON_THROW_ON_ERROR, $depth);
62
+		} catch (JsonException $e) {
63
+			throw new InvalidArgumentException(sprintf(
64
+				'Unable to create the JSON request due to an invalid data: %s',
65
+				$e->getMessage(),
66
+			), 0, $e);
67
+		}
68 68
 
69
-        $stream = new PhpTempStream('r+b');
70
-        $stream->write($json);
71
-        $stream->rewind();
69
+		$stream = new PhpTempStream('r+b');
70
+		$stream->write($json);
71
+		$stream->rewind();
72 72
 
73
-        return $stream;
74
-    }
73
+		return $stream;
74
+	}
75 75
 }
Please login to merge, or discard this patch.