Test Failed
Branch master (cc711f)
by Alexpts
06:27
created
src/LowercaseTrait.php 1 patch
Indentation   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -7,8 +7,8 @@
 block discarded – undo
7 7
 
8 8
 trait LowercaseTrait
9 9
 {
10
-	protected static function lowercase(string $value): string
11
-	{
12
-		return strtr($value, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz');
13
-	}
10
+    protected static function lowercase(string $value): string
11
+    {
12
+        return strtr($value, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz');
13
+    }
14 14
 }
15 15
\ No newline at end of file
Please login to merge, or discard this patch.
src/Response.php 1 patch
Indentation   +109 added lines, -109 removed lines patch added patch discarded remove patch
@@ -11,124 +11,124 @@
 block discarded – undo
11 11
 class Response extends Message implements ServerMessageInterface, ResponseInterface
12 12
 {
13 13
 
14
-	use ServerMessage;
14
+    use ServerMessage;
15 15
 
16
-	/** @var array Map of standard HTTP status code/reason phrases */
17
-	protected const PHRASES = [
18
-		100 => 'Continue',
19
-		101 => 'Switching Protocols',
20
-		102 => 'Processing',
21
-		200 => 'OK',
22
-		201 => 'Created',
23
-		202 => 'Accepted',
24
-		203 => 'Non-Authoritative Information',
25
-		204 => 'No Content',
26
-		205 => 'Reset Content',
27
-		206 => 'Partial Content',
28
-		207 => 'Multi-status',
29
-		208 => 'Already Reported',
30
-		300 => 'Multiple Choices',
31
-		301 => 'Moved Permanently',
32
-		302 => 'Found',
33
-		303 => 'See Other',
34
-		304 => 'Not Modified',
35
-		305 => 'Use Proxy',
36
-		306 => 'Switch Proxy',
37
-		307 => 'Temporary Redirect',
38
-		400 => 'Bad Request',
39
-		401 => 'Unauthorized',
40
-		402 => 'Payment Required',
41
-		403 => 'Forbidden',
42
-		404 => 'Not Found',
43
-		405 => 'Method Not Allowed',
44
-		406 => 'Not Acceptable',
45
-		407 => 'Proxy Authentication Required',
46
-		408 => 'Request Time-out',
47
-		409 => 'Conflict',
48
-		410 => 'Gone',
49
-		411 => 'Length Required',
50
-		412 => 'Precondition Failed',
51
-		413 => 'Request Entity Too Large',
52
-		414 => 'Request-URI Too Large',
53
-		415 => 'Unsupported Media Type',
54
-		416 => 'Requested range not satisfiable',
55
-		417 => 'Expectation Failed',
56
-		418 => 'I\'m a teapot',
57
-		422 => 'Unprocessable Entity',
58
-		423 => 'Locked',
59
-		424 => 'Failed Dependency',
60
-		425 => 'Unordered Collection',
61
-		426 => 'Upgrade Required',
62
-		428 => 'Precondition Required',
63
-		429 => 'Too Many Requests',
64
-		431 => 'Request Header Fields Too Large',
65
-		451 => 'Unavailable For Legal Reasons',
66
-		500 => 'Internal Server Error',
67
-		501 => 'Not Implemented',
68
-		502 => 'Bad Gateway',
69
-		503 => 'Service Unavailable',
70
-		504 => 'Gateway Time-out',
71
-		505 => 'HTTP Version not supported',
72
-		506 => 'Variant Also Negotiates',
73
-		507 => 'Insufficient Storage',
74
-		508 => 'Loop Detected',
75
-		511 => 'Network Authentication Required',
76
-	];
16
+    /** @var array Map of standard HTTP status code/reason phrases */
17
+    protected const PHRASES = [
18
+        100 => 'Continue',
19
+        101 => 'Switching Protocols',
20
+        102 => 'Processing',
21
+        200 => 'OK',
22
+        201 => 'Created',
23
+        202 => 'Accepted',
24
+        203 => 'Non-Authoritative Information',
25
+        204 => 'No Content',
26
+        205 => 'Reset Content',
27
+        206 => 'Partial Content',
28
+        207 => 'Multi-status',
29
+        208 => 'Already Reported',
30
+        300 => 'Multiple Choices',
31
+        301 => 'Moved Permanently',
32
+        302 => 'Found',
33
+        303 => 'See Other',
34
+        304 => 'Not Modified',
35
+        305 => 'Use Proxy',
36
+        306 => 'Switch Proxy',
37
+        307 => 'Temporary Redirect',
38
+        400 => 'Bad Request',
39
+        401 => 'Unauthorized',
40
+        402 => 'Payment Required',
41
+        403 => 'Forbidden',
42
+        404 => 'Not Found',
43
+        405 => 'Method Not Allowed',
44
+        406 => 'Not Acceptable',
45
+        407 => 'Proxy Authentication Required',
46
+        408 => 'Request Time-out',
47
+        409 => 'Conflict',
48
+        410 => 'Gone',
49
+        411 => 'Length Required',
50
+        412 => 'Precondition Failed',
51
+        413 => 'Request Entity Too Large',
52
+        414 => 'Request-URI Too Large',
53
+        415 => 'Unsupported Media Type',
54
+        416 => 'Requested range not satisfiable',
55
+        417 => 'Expectation Failed',
56
+        418 => 'I\'m a teapot',
57
+        422 => 'Unprocessable Entity',
58
+        423 => 'Locked',
59
+        424 => 'Failed Dependency',
60
+        425 => 'Unordered Collection',
61
+        426 => 'Upgrade Required',
62
+        428 => 'Precondition Required',
63
+        429 => 'Too Many Requests',
64
+        431 => 'Request Header Fields Too Large',
65
+        451 => 'Unavailable For Legal Reasons',
66
+        500 => 'Internal Server Error',
67
+        501 => 'Not Implemented',
68
+        502 => 'Bad Gateway',
69
+        503 => 'Service Unavailable',
70
+        504 => 'Gateway Time-out',
71
+        505 => 'HTTP Version not supported',
72
+        506 => 'Variant Also Negotiates',
73
+        507 => 'Insufficient Storage',
74
+        508 => 'Loop Detected',
75
+        511 => 'Network Authentication Required',
76
+    ];
77 77
 
78
-	protected string $reasonPhrase = '';
79
-	protected int $statusCode = 200;
78
+    protected string $reasonPhrase = '';
79
+    protected int $statusCode = 200;
80 80
 
81
-	/**
82
-	 * @param int $status Status code
83
-	 * @param array $headers Response headers
84
-	 * @param string|resource|StreamInterface|null $body Response body
85
-	 * @param string $version Protocol version
86
-	 * @param string|null $reason Reason phrase (when empty a default will be used based on the status code)
87
-	 */
88
-	public function __construct(
89
-		int $status = 200,
90
-		array $headers = [],
91
-		$body = null,
92
-		string $version = '1.1',
93
-		string $reason = null
94
-	) {
95
-		// If we got no body, defer initialization of the stream until Response::getBody()
96
-		if ('' !== $body && null !== $body) {
97
-			$this->stream = Stream::create($body);
98
-		}
81
+    /**
82
+     * @param int $status Status code
83
+     * @param array $headers Response headers
84
+     * @param string|resource|StreamInterface|null $body Response body
85
+     * @param string $version Protocol version
86
+     * @param string|null $reason Reason phrase (when empty a default will be used based on the status code)
87
+     */
88
+    public function __construct(
89
+        int $status = 200,
90
+        array $headers = [],
91
+        $body = null,
92
+        string $version = '1.1',
93
+        string $reason = null
94
+    ) {
95
+        // If we got no body, defer initialization of the stream until Response::getBody()
96
+        if ('' !== $body && null !== $body) {
97
+            $this->stream = Stream::create($body);
98
+        }
99 99
 
100
-		$this->statusCode = $status;
101
-		$this->setHeaders($headers);
100
+        $this->statusCode = $status;
101
+        $this->setHeaders($headers);
102 102
 
103
-		$this->reasonPhrase = $reason === null && isset(self::PHRASES[$this->statusCode])
104
-			? self::PHRASES[$status]
105
-			: $reason ?? '';
103
+        $this->reasonPhrase = $reason === null && isset(self::PHRASES[$this->statusCode])
104
+            ? self::PHRASES[$status]
105
+            : $reason ?? '';
106 106
 
107
-		$this->protocol = $version;
108
-	}
107
+        $this->protocol = $version;
108
+    }
109 109
 
110
-	public function getStatusCode(): int
111
-	{
112
-		return $this->statusCode;
113
-	}
110
+    public function getStatusCode(): int
111
+    {
112
+        return $this->statusCode;
113
+    }
114 114
 
115
-	public function getReasonPhrase(): string
116
-	{
117
-		return $this->reasonPhrase;
118
-	}
115
+    public function getReasonPhrase(): string
116
+    {
117
+        return $this->reasonPhrase;
118
+    }
119 119
 
120
-	public function withStatus($code, $reasonPhrase = ''): self
121
-	{
122
-		if ($code < 100 || $code > 599) {
123
-			throw new InvalidArgumentException('Status code has to be an integer between 100 and 599');
124
-		}
120
+    public function withStatus($code, $reasonPhrase = ''): self
121
+    {
122
+        if ($code < 100 || $code > 599) {
123
+            throw new InvalidArgumentException('Status code has to be an integer between 100 and 599');
124
+        }
125 125
 
126
-		$this->statusCode = $code;
127
-		if ('' === $reasonPhrase && isset(self::PHRASES[$this->statusCode])) {
128
-			$reasonPhrase = self::PHRASES[$this->statusCode];
129
-		}
126
+        $this->statusCode = $code;
127
+        if ('' === $reasonPhrase && isset(self::PHRASES[$this->statusCode])) {
128
+            $reasonPhrase = self::PHRASES[$this->statusCode];
129
+        }
130 130
 
131
-		$this->reasonPhrase = $reasonPhrase;
132
-		return $this;
133
-	}
131
+        $this->reasonPhrase = $reasonPhrase;
132
+        return $this;
133
+    }
134 134
 }
135 135
\ No newline at end of file
Please login to merge, or discard this patch.
src/Request.php 1 patch
Indentation   +103 added lines, -103 removed lines patch added patch discarded remove patch
@@ -11,107 +11,107 @@
 block discarded – undo
11 11
 
12 12
 class Request extends Message implements RequestInterface
13 13
 {
14
-	protected string $method;
15
-
16
-	protected ?string $requestTarget = null;
17
-	protected ?UriInterface $uri;
18
-
19
-	/**
20
-	 * @param string $method HTTP method
21
-	 * @param UriInterface $uri URI
22
-	 * @param array $headers Request headers
23
-	 * @param string|resource|StreamInterface|null $body Request body
24
-	 * @param string $version Protocol version
25
-	 */
26
-	public function __construct(
27
-		string $method,
28
-		UriInterface $uri,
29
-		array $headers = [],
30
-		$body = null,
31
-		string $version = '1.1'
32
-	) {
33
-		$this->method = $method;
34
-		$this->uri = $uri;
35
-		$this->setHeaders($headers);
36
-		$this->protocol = $version;
37
-
38
-		if (!$this->hasHeader('host')) {
39
-			$this->updateHostFromUri();
40
-		}
41
-
42
-		if ('' !== $body && null !== $body) {
43
-			$this->stream = Stream::create($body);
44
-		}
45
-	}
46
-
47
-	public function getRequestTarget(): string
48
-	{
49
-		if (null !== $this->requestTarget) {
50
-			return $this->requestTarget;
51
-		}
52
-
53
-		$target = $this->uri->getPath();
54
-		$target = $target ?: '/';
55
-
56
-		if ('' !== $this->uri->getQuery()) {
57
-			$target .= '?' . $this->uri->getQuery();
58
-		}
59
-
60
-		$this->requestTarget = $target;
61
-		return $target;
62
-	}
63
-
64
-	public function withRequestTarget($requestTarget): self
65
-	{
66
-		if (preg_match('#\s#', $requestTarget)) {
67
-			throw new InvalidArgumentException('Invalid request target provided; cannot contain whitespace');
68
-		}
69
-
70
-		$this->requestTarget = $requestTarget;
71
-		return $this;
72
-	}
73
-
74
-	public function getMethod(): string
75
-	{
76
-		return $this->method;
77
-	}
78
-
79
-	public function withMethod($method): self
80
-	{
81
-		$this->method = $method;
82
-		return $this;
83
-	}
84
-
85
-	public function getUri(): UriInterface
86
-	{
87
-		return $this->uri;
88
-	}
89
-
90
-	public function withUri(UriInterface $uri, $preserveHost = false): self
91
-	{
92
-		if ($uri === $this->uri) {
93
-			return $this;
94
-		}
95
-
96
-		$this->uri = $uri;
97
-
98
-		if (!$preserveHost || !$this->hasHeader('Host')) {
99
-			$this->updateHostFromUri();
100
-		}
101
-
102
-		return $this;
103
-	}
104
-
105
-	protected function updateHostFromUri(): void
106
-	{
107
-		if ('' === $host = $this->uri->getHost()) {
108
-			return;
109
-		}
110
-
111
-		if (null !== ($port = $this->uri->getPort())) {
112
-			$host .= ':' . $port;
113
-		}
114
-
115
-		$this->headers['host'] = [$host];
116
-	}
14
+    protected string $method;
15
+
16
+    protected ?string $requestTarget = null;
17
+    protected ?UriInterface $uri;
18
+
19
+    /**
20
+     * @param string $method HTTP method
21
+     * @param UriInterface $uri URI
22
+     * @param array $headers Request headers
23
+     * @param string|resource|StreamInterface|null $body Request body
24
+     * @param string $version Protocol version
25
+     */
26
+    public function __construct(
27
+        string $method,
28
+        UriInterface $uri,
29
+        array $headers = [],
30
+        $body = null,
31
+        string $version = '1.1'
32
+    ) {
33
+        $this->method = $method;
34
+        $this->uri = $uri;
35
+        $this->setHeaders($headers);
36
+        $this->protocol = $version;
37
+
38
+        if (!$this->hasHeader('host')) {
39
+            $this->updateHostFromUri();
40
+        }
41
+
42
+        if ('' !== $body && null !== $body) {
43
+            $this->stream = Stream::create($body);
44
+        }
45
+    }
46
+
47
+    public function getRequestTarget(): string
48
+    {
49
+        if (null !== $this->requestTarget) {
50
+            return $this->requestTarget;
51
+        }
52
+
53
+        $target = $this->uri->getPath();
54
+        $target = $target ?: '/';
55
+
56
+        if ('' !== $this->uri->getQuery()) {
57
+            $target .= '?' . $this->uri->getQuery();
58
+        }
59
+
60
+        $this->requestTarget = $target;
61
+        return $target;
62
+    }
63
+
64
+    public function withRequestTarget($requestTarget): self
65
+    {
66
+        if (preg_match('#\s#', $requestTarget)) {
67
+            throw new InvalidArgumentException('Invalid request target provided; cannot contain whitespace');
68
+        }
69
+
70
+        $this->requestTarget = $requestTarget;
71
+        return $this;
72
+    }
73
+
74
+    public function getMethod(): string
75
+    {
76
+        return $this->method;
77
+    }
78
+
79
+    public function withMethod($method): self
80
+    {
81
+        $this->method = $method;
82
+        return $this;
83
+    }
84
+
85
+    public function getUri(): UriInterface
86
+    {
87
+        return $this->uri;
88
+    }
89
+
90
+    public function withUri(UriInterface $uri, $preserveHost = false): self
91
+    {
92
+        if ($uri === $this->uri) {
93
+            return $this;
94
+        }
95
+
96
+        $this->uri = $uri;
97
+
98
+        if (!$preserveHost || !$this->hasHeader('Host')) {
99
+            $this->updateHostFromUri();
100
+        }
101
+
102
+        return $this;
103
+    }
104
+
105
+    protected function updateHostFromUri(): void
106
+    {
107
+        if ('' === $host = $this->uri->getHost()) {
108
+            return;
109
+        }
110
+
111
+        if (null !== ($port = $this->uri->getPort())) {
112
+            $host .= ':' . $port;
113
+        }
114
+
115
+        $this->headers['host'] = [$host];
116
+    }
117 117
 }
Please login to merge, or discard this patch.
src/Stream.php 1 patch
Indentation   +223 added lines, -223 removed lines patch added patch discarded remove patch
@@ -23,227 +23,227 @@
 block discarded – undo
23 23
 
24 24
 class Stream implements StreamInterface
25 25
 {
26
-	/** @var resource|null A resource reference */
27
-	protected $stream = null;
28
-	protected bool $seekable = false;
29
-	protected bool $readable = false;
30
-	protected bool $writable = false;
31
-	/** @var array|mixed|void|null */
32
-	protected $uri;
33
-	/** @var int|null */
34
-	protected ?int $size = null;
35
-
36
-	protected const READ_WRITE_HASH = [
37
-		'read' => [
38
-			'r' => true, 'w+' => true, 'r+' => true, 'x+' => true, 'c+' => true,
39
-			'rb' => true, 'w+b' => true, 'r+b' => true, 'x+b' => true,
40
-			'c+b' => true, 'rt' => true, 'w+t' => true, 'r+t' => true,
41
-			'x+t' => true, 'c+t' => true, 'a+' => true,
42
-		],
43
-		'write' => [
44
-			'w' => true, 'w+' => true, 'rw' => true, 'r+' => true, 'x+' => true,
45
-			'c+' => true, 'wb' => true, 'w+b' => true, 'r+b' => true,
46
-			'x+b' => true, 'c+b' => true, 'w+t' => true, 'r+t' => true,
47
-			'x+t' => true, 'c+t' => true, 'a' => true, 'a+' => true,
48
-		],
49
-	];
50
-
51
-	/**
52
-	 * Creates a new PSR-7 stream.
53
-	 *
54
-	 * @param string|resource|StreamInterface $body
55
-	 *
56
-	 * @return StreamInterface
57
-	 *
58
-	 * @throws InvalidArgumentException
59
-	 */
60
-	public static function create($body = ''): StreamInterface
61
-	{
62
-		if ($body instanceof StreamInterface) {
63
-			return $body;
64
-		}
65
-
66
-		if (is_string($body)) {
67
-			$resource = fopen('php://temp', 'rw+');
68
-			fwrite($resource, $body);
69
-			$body = $resource;
70
-		}
71
-
72
-		if (is_resource($body)) {
73
-			$new = new self();
74
-			$new->stream = $body;
75
-			$meta = stream_get_meta_data($new->stream);
76
-			$new->seekable = $meta['seekable'] && 0 === \fseek($new->stream, 0, \SEEK_CUR);
77
-			$new->readable = isset(self::READ_WRITE_HASH['read'][$meta['mode']]);
78
-			$new->writable = isset(self::READ_WRITE_HASH['write'][$meta['mode']]);
79
-			$new->uri = $new->getMetadata('uri');
80
-
81
-			return $new;
82
-		}
83
-
84
-		throw new InvalidArgumentException('First argument to Stream::create() must be a string, resource or StreamInterface.');
85
-	}
86
-
87
-	/**
88
-	 * Closes the stream when the destructed.
89
-	 */
90
-	public function __destruct()
91
-	{
92
-		$this->close();
93
-	}
94
-
95
-	public function __toString(): string
96
-	{
97
-		if ($this->isSeekable()) {
98
-			$this->seek(0);
99
-		}
100
-
101
-		return $this->getContents();
102
-	}
103
-
104
-	public function close(): void
105
-	{
106
-		if (isset($this->stream) && is_resource($this->stream)) {
107
-			fclose($this->stream);
108
-			$this->detach();
109
-		}
110
-	}
111
-
112
-	public function detach()
113
-	{
114
-		if (!isset($this->stream)) {
115
-			return null;
116
-		}
117
-
118
-		$result = $this->stream;
119
-		unset($this->stream);
120
-
121
-		$this->size = $this->uri = null;
122
-		$this->readable = $this->writable = $this->seekable = false;
123
-
124
-		return $result;
125
-	}
126
-
127
-	public function getSize(): ?int
128
-	{
129
-		if (null !== $this->size) {
130
-			return $this->size;
131
-		}
132
-
133
-		if (!isset($this->stream)) {
134
-			return null;
135
-		}
136
-
137
-		// Clear the stat cache if the stream has a URI
138
-		if ($this->uri) {
139
-			clearstatcache(true, $this->uri);
140
-		}
141
-
142
-		$stats = fstat($this->stream);
143
-		if (isset($stats['size'])) {
144
-			$this->size = $stats['size'];
145
-			return $this->size;
146
-		}
147
-
148
-		return null;
149
-	}
150
-
151
-	public function tell(): int
152
-	{
153
-		$position = ftell($this->stream);
154
-		if (false === $position) {
155
-			throw new RuntimeException('Unable to determine stream position');
156
-		}
157
-
158
-		return $position;
159
-	}
160
-
161
-	public function eof(): bool
162
-	{
163
-		return !$this->stream || feof($this->stream);
164
-	}
165
-
166
-	public function isSeekable(): bool
167
-	{
168
-		return $this->seekable;
169
-	}
170
-
171
-	public function seek($offset, $whence = SEEK_SET): void
172
-	{
173
-		if (!$this->seekable) {
174
-			throw new RuntimeException('Stream is not seekable');
175
-		}
176
-
177
-		if (-1 === fseek($this->stream, $offset, $whence)) {
178
-			throw new RuntimeException('Unable to seek to stream position ' . $offset . ' with whence ' . \var_export($whence, true));
179
-		}
180
-	}
181
-
182
-	public function rewind(): void
183
-	{
184
-		$this->seek(0);
185
-	}
186
-
187
-	public function isWritable(): bool
188
-	{
189
-		return $this->writable;
190
-	}
191
-
192
-	public function write($string): int
193
-	{
194
-		if (!$this->writable) {
195
-			throw new RuntimeException('Cannot write to a non-writable stream');
196
-		}
197
-
198
-		// We can't know the size after writing anything
199
-		$this->size = null;
200
-
201
-		if (false === $result = fwrite($this->stream, $string)) {
202
-			throw new RuntimeException('Unable to write to stream');
203
-		}
204
-
205
-		return $result;
206
-	}
207
-
208
-	public function isReadable(): bool
209
-	{
210
-		return $this->readable;
211
-	}
212
-
213
-	public function read($length): string
214
-	{
215
-		if (!$this->readable) {
216
-			throw new RuntimeException('Cannot read from non-readable stream');
217
-		}
218
-
219
-		return fread($this->stream, $length);
220
-	}
221
-
222
-	public function getContents(): string
223
-	{
224
-		if (!isset($this->stream)) {
225
-			throw new RuntimeException('Unable to read stream contents');
226
-		}
227
-
228
-		if (false === $contents = stream_get_contents($this->stream)) {
229
-			throw new RuntimeException('Unable to read stream contents');
230
-		}
231
-
232
-		return $contents;
233
-	}
234
-
235
-	public function getMetadata($key = null)
236
-	{
237
-		if (!isset($this->stream)) {
238
-			return $key ? null : [];
239
-		}
240
-
241
-		$meta = stream_get_meta_data($this->stream);
242
-
243
-		if (null === $key) {
244
-			return $meta;
245
-		}
246
-
247
-		return $meta[$key] ?? null;
248
-	}
26
+    /** @var resource|null A resource reference */
27
+    protected $stream = null;
28
+    protected bool $seekable = false;
29
+    protected bool $readable = false;
30
+    protected bool $writable = false;
31
+    /** @var array|mixed|void|null */
32
+    protected $uri;
33
+    /** @var int|null */
34
+    protected ?int $size = null;
35
+
36
+    protected const READ_WRITE_HASH = [
37
+        'read' => [
38
+            'r' => true, 'w+' => true, 'r+' => true, 'x+' => true, 'c+' => true,
39
+            'rb' => true, 'w+b' => true, 'r+b' => true, 'x+b' => true,
40
+            'c+b' => true, 'rt' => true, 'w+t' => true, 'r+t' => true,
41
+            'x+t' => true, 'c+t' => true, 'a+' => true,
42
+        ],
43
+        'write' => [
44
+            'w' => true, 'w+' => true, 'rw' => true, 'r+' => true, 'x+' => true,
45
+            'c+' => true, 'wb' => true, 'w+b' => true, 'r+b' => true,
46
+            'x+b' => true, 'c+b' => true, 'w+t' => true, 'r+t' => true,
47
+            'x+t' => true, 'c+t' => true, 'a' => true, 'a+' => true,
48
+        ],
49
+    ];
50
+
51
+    /**
52
+     * Creates a new PSR-7 stream.
53
+     *
54
+     * @param string|resource|StreamInterface $body
55
+     *
56
+     * @return StreamInterface
57
+     *
58
+     * @throws InvalidArgumentException
59
+     */
60
+    public static function create($body = ''): StreamInterface
61
+    {
62
+        if ($body instanceof StreamInterface) {
63
+            return $body;
64
+        }
65
+
66
+        if (is_string($body)) {
67
+            $resource = fopen('php://temp', 'rw+');
68
+            fwrite($resource, $body);
69
+            $body = $resource;
70
+        }
71
+
72
+        if (is_resource($body)) {
73
+            $new = new self();
74
+            $new->stream = $body;
75
+            $meta = stream_get_meta_data($new->stream);
76
+            $new->seekable = $meta['seekable'] && 0 === \fseek($new->stream, 0, \SEEK_CUR);
77
+            $new->readable = isset(self::READ_WRITE_HASH['read'][$meta['mode']]);
78
+            $new->writable = isset(self::READ_WRITE_HASH['write'][$meta['mode']]);
79
+            $new->uri = $new->getMetadata('uri');
80
+
81
+            return $new;
82
+        }
83
+
84
+        throw new InvalidArgumentException('First argument to Stream::create() must be a string, resource or StreamInterface.');
85
+    }
86
+
87
+    /**
88
+     * Closes the stream when the destructed.
89
+     */
90
+    public function __destruct()
91
+    {
92
+        $this->close();
93
+    }
94
+
95
+    public function __toString(): string
96
+    {
97
+        if ($this->isSeekable()) {
98
+            $this->seek(0);
99
+        }
100
+
101
+        return $this->getContents();
102
+    }
103
+
104
+    public function close(): void
105
+    {
106
+        if (isset($this->stream) && is_resource($this->stream)) {
107
+            fclose($this->stream);
108
+            $this->detach();
109
+        }
110
+    }
111
+
112
+    public function detach()
113
+    {
114
+        if (!isset($this->stream)) {
115
+            return null;
116
+        }
117
+
118
+        $result = $this->stream;
119
+        unset($this->stream);
120
+
121
+        $this->size = $this->uri = null;
122
+        $this->readable = $this->writable = $this->seekable = false;
123
+
124
+        return $result;
125
+    }
126
+
127
+    public function getSize(): ?int
128
+    {
129
+        if (null !== $this->size) {
130
+            return $this->size;
131
+        }
132
+
133
+        if (!isset($this->stream)) {
134
+            return null;
135
+        }
136
+
137
+        // Clear the stat cache if the stream has a URI
138
+        if ($this->uri) {
139
+            clearstatcache(true, $this->uri);
140
+        }
141
+
142
+        $stats = fstat($this->stream);
143
+        if (isset($stats['size'])) {
144
+            $this->size = $stats['size'];
145
+            return $this->size;
146
+        }
147
+
148
+        return null;
149
+    }
150
+
151
+    public function tell(): int
152
+    {
153
+        $position = ftell($this->stream);
154
+        if (false === $position) {
155
+            throw new RuntimeException('Unable to determine stream position');
156
+        }
157
+
158
+        return $position;
159
+    }
160
+
161
+    public function eof(): bool
162
+    {
163
+        return !$this->stream || feof($this->stream);
164
+    }
165
+
166
+    public function isSeekable(): bool
167
+    {
168
+        return $this->seekable;
169
+    }
170
+
171
+    public function seek($offset, $whence = SEEK_SET): void
172
+    {
173
+        if (!$this->seekable) {
174
+            throw new RuntimeException('Stream is not seekable');
175
+        }
176
+
177
+        if (-1 === fseek($this->stream, $offset, $whence)) {
178
+            throw new RuntimeException('Unable to seek to stream position ' . $offset . ' with whence ' . \var_export($whence, true));
179
+        }
180
+    }
181
+
182
+    public function rewind(): void
183
+    {
184
+        $this->seek(0);
185
+    }
186
+
187
+    public function isWritable(): bool
188
+    {
189
+        return $this->writable;
190
+    }
191
+
192
+    public function write($string): int
193
+    {
194
+        if (!$this->writable) {
195
+            throw new RuntimeException('Cannot write to a non-writable stream');
196
+        }
197
+
198
+        // We can't know the size after writing anything
199
+        $this->size = null;
200
+
201
+        if (false === $result = fwrite($this->stream, $string)) {
202
+            throw new RuntimeException('Unable to write to stream');
203
+        }
204
+
205
+        return $result;
206
+    }
207
+
208
+    public function isReadable(): bool
209
+    {
210
+        return $this->readable;
211
+    }
212
+
213
+    public function read($length): string
214
+    {
215
+        if (!$this->readable) {
216
+            throw new RuntimeException('Cannot read from non-readable stream');
217
+        }
218
+
219
+        return fread($this->stream, $length);
220
+    }
221
+
222
+    public function getContents(): string
223
+    {
224
+        if (!isset($this->stream)) {
225
+            throw new RuntimeException('Unable to read stream contents');
226
+        }
227
+
228
+        if (false === $contents = stream_get_contents($this->stream)) {
229
+            throw new RuntimeException('Unable to read stream contents');
230
+        }
231
+
232
+        return $contents;
233
+    }
234
+
235
+    public function getMetadata($key = null)
236
+    {
237
+        if (!isset($this->stream)) {
238
+            return $key ? null : [];
239
+        }
240
+
241
+        $meta = stream_get_meta_data($this->stream);
242
+
243
+        if (null === $key) {
244
+            return $meta;
245
+        }
246
+
247
+        return $meta[$key] ?? null;
248
+    }
249 249
 }
250 250
\ No newline at end of file
Please login to merge, or discard this patch.
src/ServerRequest.php 1 patch
Indentation   +83 added lines, -83 removed lines patch added patch discarded remove patch
@@ -13,87 +13,87 @@
 block discarded – undo
13 13
 
14 14
 class ServerRequest extends Request implements ServerRequestInterface, ServerMessageInterface
15 15
 {
16
-	use ServerMessage;
17
-
18
-	protected array $cookieParams = [];
19
-
20
-	/** @var array|object|null */
21
-	protected $parsedBody;
22
-	protected array $queryParams = [];
23
-	protected array $serverParams;
24
-
25
-	/** @var UploadedFileInterface[] */
26
-	protected array $uploadedFiles = [];
27
-
28
-
29
-	public function __construct(
30
-		string $method,
31
-		UriInterface $uri,
32
-		array $headers = [],
33
-		$body = null,
34
-		string $version = '1.1',
35
-		array $serverParams = []
36
-	) {
37
-		parent::__construct($method, $uri, $headers, $body, $version);
38
-		$this->serverParams = $serverParams;
39
-	}
40
-
41
-	public function getServerParams(): array
42
-	{
43
-		return $this->serverParams;
44
-	}
45
-
46
-	public function getUploadedFiles(): array
47
-	{
48
-		return $this->uploadedFiles;
49
-	}
50
-
51
-	public function withUploadedFiles(array $uploadedFiles)
52
-	{
53
-		$new = clone $this;
54
-		$new->uploadedFiles = $uploadedFiles;
55
-
56
-		return $new;
57
-	}
58
-
59
-	public function getCookieParams(): array
60
-	{
61
-		return $this->cookieParams;
62
-	}
63
-
64
-	public function withCookieParams(array $cookies)
65
-	{
66
-		$new = clone $this;
67
-		$new->cookieParams = $cookies;
68
-
69
-		return $new;
70
-	}
71
-
72
-	public function getQueryParams(): array
73
-	{
74
-		return $this->queryParams;
75
-	}
76
-
77
-	public function withQueryParams(array $query)
78
-	{
79
-		$new = clone $this;
80
-		$new->queryParams = $query;
81
-
82
-		return $new;
83
-	}
84
-
85
-	public function getParsedBody()
86
-	{
87
-		return $this->parsedBody;
88
-	}
89
-
90
-	public function withParsedBody($data)
91
-	{
92
-		if (!is_array($data) && !is_object($data) && null !== $data) {
93
-			throw new InvalidArgumentException('First parameter to withParsedBody MUST be object, array or null');
94
-		}
95
-
96
-		$this->parsedBody = $data;
97
-		return $this;
98
-	}
16
+    use ServerMessage;
17
+
18
+    protected array $cookieParams = [];
19
+
20
+    /** @var array|object|null */
21
+    protected $parsedBody;
22
+    protected array $queryParams = [];
23
+    protected array $serverParams;
24
+
25
+    /** @var UploadedFileInterface[] */
26
+    protected array $uploadedFiles = [];
27
+
28
+
29
+    public function __construct(
30
+        string $method,
31
+        UriInterface $uri,
32
+        array $headers = [],
33
+        $body = null,
34
+        string $version = '1.1',
35
+        array $serverParams = []
36
+    ) {
37
+        parent::__construct($method, $uri, $headers, $body, $version);
38
+        $this->serverParams = $serverParams;
39
+    }
40
+
41
+    public function getServerParams(): array
42
+    {
43
+        return $this->serverParams;
44
+    }
45
+
46
+    public function getUploadedFiles(): array
47
+    {
48
+        return $this->uploadedFiles;
49
+    }
50
+
51
+    public function withUploadedFiles(array $uploadedFiles)
52
+    {
53
+        $new = clone $this;
54
+        $new->uploadedFiles = $uploadedFiles;
55
+
56
+        return $new;
57
+    }
58
+
59
+    public function getCookieParams(): array
60
+    {
61
+        return $this->cookieParams;
62
+    }
63
+
64
+    public function withCookieParams(array $cookies)
65
+    {
66
+        $new = clone $this;
67
+        $new->cookieParams = $cookies;
68
+
69
+        return $new;
70
+    }
71
+
72
+    public function getQueryParams(): array
73
+    {
74
+        return $this->queryParams;
75
+    }
76
+
77
+    public function withQueryParams(array $query)
78
+    {
79
+        $new = clone $this;
80
+        $new->queryParams = $query;
81
+
82
+        return $new;
83
+    }
84
+
85
+    public function getParsedBody()
86
+    {
87
+        return $this->parsedBody;
88
+    }
89
+
90
+    public function withParsedBody($data)
91
+    {
92
+        if (!is_array($data) && !is_object($data) && null !== $data) {
93
+            throw new InvalidArgumentException('First parameter to withParsedBody MUST be object, array or null');
94
+        }
95
+
96
+        $this->parsedBody = $data;
97
+        return $this;
98
+    }
99 99
 }
Please login to merge, or discard this patch.
src/Message.php 1 patch
Indentation   +122 added lines, -122 removed lines patch added patch discarded remove patch
@@ -14,126 +14,126 @@
 block discarded – undo
14 14
 class Message implements MessageInterface
15 15
 {
16 16
 
17
-	/** @var array - all header name must be convert to lowercase */
18
-	protected array $headers = [];
19
-	protected string $protocol = '1.1';
20
-	protected ?StreamInterface $stream = null;
21
-
22
-	public function getProtocolVersion(): string
23
-	{
24
-		return $this->protocol;
25
-	}
26
-
27
-	public function withProtocolVersion($version): self
28
-	{
29
-		if ($this->protocol !== $version) {
30
-			$this->protocol = $version;
31
-		}
32
-
33
-		return $this;
34
-	}
35
-
36
-	public function getHeaders(): array
37
-	{
38
-		return $this->headers;
39
-	}
40
-
41
-	public function hasHeader($name): bool
42
-	{
43
-		$name = strtolower($name);
44
-		$hasHeader = $this->headers[$name] ?? null;
45
-		return $hasHeader !== null;
46
-	}
47
-
48
-	public function getHeader($name): array
49
-	{
50
-		$name = strtolower($name);
51
-		return $this->headers[$name] ?? [];
52
-	}
53
-
54
-	public function getHeaderLine($name): string
55
-	{
56
-		return implode(', ', $this->getHeader($name));
57
-	}
58
-
59
-	public function withHeader($name, $value): self
60
-	{
61
-		$name = strtolower($name);
62
-		$this->headers[$name] = $this->validateAndTrimHeader($name, (array)$value);
63
-		return $this;
64
-	}
65
-
66
-	public function withoutHeader($name): self
67
-	{
68
-		$name = strtolower($name);
69
-		unset($this->headers[$name]);
70
-		return $this;
71
-	}
72
-
73
-	public function getBody(): StreamInterface
74
-	{
75
-		if (!$this->stream) {
76
-			$this->stream = Stream::create('');
77
-		}
78
-
79
-		return $this->stream;
80
-	}
81
-
82
-	public function withBody(StreamInterface $body): self
83
-	{
84
-		$this->stream = $body;
85
-		return $this;
86
-	}
87
-
88
-	public function reset(): self
89
-	{
90
-		$this->headers = [];
91
-		if ($this->stream) {
92
-			$this->stream->close();
93
-			$this->stream = null;
94
-		}
95
-
96
-		return $this;
97
-	}
98
-
99
-	protected function validateAndTrimHeader(string $name, array $values): array
100
-	{
101
-		if (preg_match("@^[!#$%&'*+.^_`|~0-9A-Za-z-]+$@", $name) !== 1) {
102
-			throw new InvalidArgumentException('Header name must be an RFC 7230 compatible string.');
103
-		}
104
-
105
-		$returnValues = [];
106
-		foreach ($values as $v) {
107
-			if ((!is_numeric($v) && !is_string($v)) || 1 !== preg_match("@^[ \t\x21-\x7E\x80-\xFF]*$@", (string) $v)) {
108
-				throw new InvalidArgumentException('Header values must be RFC 7230 compatible strings.');
109
-			}
110
-
111
-			$returnValues[] = trim((string)$v);
112
-		}
113
-
114
-		return $returnValues;
115
-	}
116
-
117
-	public function withAddedHeader($name, $value): self
118
-	{
119
-		$this->setHeaders([$name => $value]);
120
-		return $this;
121
-	}
122
-
123
-	protected function setHeaders(array $headers): void
124
-	{
125
-		foreach ($headers as $name => $values) {
126
-			$values = (array)$values;
127
-			$name = strtolower((string)$name);
128
-
129
-			if (!$this->hasHeader($name)) {
130
-				$this->headers[$name] = [];
131
-			}
132
-
133
-			foreach ($values as $value) {
134
-				$value = $this->validateAndTrimHeader($name, (array)$value)[0];
135
-				$this->headers[$name][] = $value;
136
-			}
137
-		}
138
-	}
17
+    /** @var array - all header name must be convert to lowercase */
18
+    protected array $headers = [];
19
+    protected string $protocol = '1.1';
20
+    protected ?StreamInterface $stream = null;
21
+
22
+    public function getProtocolVersion(): string
23
+    {
24
+        return $this->protocol;
25
+    }
26
+
27
+    public function withProtocolVersion($version): self
28
+    {
29
+        if ($this->protocol !== $version) {
30
+            $this->protocol = $version;
31
+        }
32
+
33
+        return $this;
34
+    }
35
+
36
+    public function getHeaders(): array
37
+    {
38
+        return $this->headers;
39
+    }
40
+
41
+    public function hasHeader($name): bool
42
+    {
43
+        $name = strtolower($name);
44
+        $hasHeader = $this->headers[$name] ?? null;
45
+        return $hasHeader !== null;
46
+    }
47
+
48
+    public function getHeader($name): array
49
+    {
50
+        $name = strtolower($name);
51
+        return $this->headers[$name] ?? [];
52
+    }
53
+
54
+    public function getHeaderLine($name): string
55
+    {
56
+        return implode(', ', $this->getHeader($name));
57
+    }
58
+
59
+    public function withHeader($name, $value): self
60
+    {
61
+        $name = strtolower($name);
62
+        $this->headers[$name] = $this->validateAndTrimHeader($name, (array)$value);
63
+        return $this;
64
+    }
65
+
66
+    public function withoutHeader($name): self
67
+    {
68
+        $name = strtolower($name);
69
+        unset($this->headers[$name]);
70
+        return $this;
71
+    }
72
+
73
+    public function getBody(): StreamInterface
74
+    {
75
+        if (!$this->stream) {
76
+            $this->stream = Stream::create('');
77
+        }
78
+
79
+        return $this->stream;
80
+    }
81
+
82
+    public function withBody(StreamInterface $body): self
83
+    {
84
+        $this->stream = $body;
85
+        return $this;
86
+    }
87
+
88
+    public function reset(): self
89
+    {
90
+        $this->headers = [];
91
+        if ($this->stream) {
92
+            $this->stream->close();
93
+            $this->stream = null;
94
+        }
95
+
96
+        return $this;
97
+    }
98
+
99
+    protected function validateAndTrimHeader(string $name, array $values): array
100
+    {
101
+        if (preg_match("@^[!#$%&'*+.^_`|~0-9A-Za-z-]+$@", $name) !== 1) {
102
+            throw new InvalidArgumentException('Header name must be an RFC 7230 compatible string.');
103
+        }
104
+
105
+        $returnValues = [];
106
+        foreach ($values as $v) {
107
+            if ((!is_numeric($v) && !is_string($v)) || 1 !== preg_match("@^[ \t\x21-\x7E\x80-\xFF]*$@", (string) $v)) {
108
+                throw new InvalidArgumentException('Header values must be RFC 7230 compatible strings.');
109
+            }
110
+
111
+            $returnValues[] = trim((string)$v);
112
+        }
113
+
114
+        return $returnValues;
115
+    }
116
+
117
+    public function withAddedHeader($name, $value): self
118
+    {
119
+        $this->setHeaders([$name => $value]);
120
+        return $this;
121
+    }
122
+
123
+    protected function setHeaders(array $headers): void
124
+    {
125
+        foreach ($headers as $name => $values) {
126
+            $values = (array)$values;
127
+            $name = strtolower((string)$name);
128
+
129
+            if (!$this->hasHeader($name)) {
130
+                $this->headers[$name] = [];
131
+            }
132
+
133
+            foreach ($values as $value) {
134
+                $value = $this->validateAndTrimHeader($name, (array)$value)[0];
135
+                $this->headers[$name][] = $value;
136
+            }
137
+        }
138
+    }
139 139
 }
Please login to merge, or discard this patch.
src/Response/JsonResponseInterface.php 1 patch
Indentation   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -5,8 +5,8 @@
 block discarded – undo
5 5
 
6 6
 interface JsonResponseInterface extends ServerMessageInterface
7 7
 {
8
-	public function getData(): array;
9
-	public function setData(array $data): self;
10
-	public function reset(): self;
8
+    public function getData(): array;
9
+    public function setData(array $data): self;
10
+    public function reset(): self;
11 11
 
12 12
 }
13 13
\ No newline at end of file
Please login to merge, or discard this patch.
src/Response/JsonResponse.php 1 patch
Indentation   +51 added lines, -51 removed lines patch added patch discarded remove patch
@@ -10,64 +10,64 @@
 block discarded – undo
10 10
 
11 11
 class JsonResponse extends HttpResponse implements JsonResponseInterface
12 12
 {
13
-	protected array $data = [];
14
-	protected bool $isSyncBody = false;
13
+    protected array $data = [];
14
+    protected bool $isSyncBody = false;
15 15
 
16
-	public function __construct(
17
-		array $data,
18
-		int $status = 200,
19
-		array $headers = [],
20
-		string $version = '1.1'
21
-	) {
22
-		$headers['Content-Type'] = 'application/json';
23
-		parent::__construct($status, $headers, null, $version);
24
-		$this->data = $data;
25
-	}
16
+    public function __construct(
17
+        array $data,
18
+        int $status = 200,
19
+        array $headers = [],
20
+        string $version = '1.1'
21
+    ) {
22
+        $headers['Content-Type'] = 'application/json';
23
+        parent::__construct($status, $headers, null, $version);
24
+        $this->data = $data;
25
+    }
26 26
 
27
-	public function getData(): array
28
-	{
29
-		return $this->data;
30
-	}
27
+    public function getData(): array
28
+    {
29
+        return $this->data;
30
+    }
31 31
 
32
-	public function getBody(): StreamInterface
33
-	{
34
-		if (!$this->isSyncBody) {
35
-			$this->isSyncBody = true;
36
-			$data = json_encode($this->data, JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE, 512);
37
-			parent::withBody(Stream::create($data));
38
-		}
32
+    public function getBody(): StreamInterface
33
+    {
34
+        if (!$this->isSyncBody) {
35
+            $this->isSyncBody = true;
36
+            $data = json_encode($this->data, JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE, 512);
37
+            parent::withBody(Stream::create($data));
38
+        }
39 39
 
40
-		return parent::getBody();
41
-	}
40
+        return parent::getBody();
41
+    }
42 42
 
43
-	public function withBody(StreamInterface $body): Message
44
-	{
45
-		$this->data = json_decode((string)$body, true, 512, JSON_THROW_ON_ERROR);
46
-		$this->isSyncBody = true;
47
-		return parent::withBody($body);
48
-	}
43
+    public function withBody(StreamInterface $body): Message
44
+    {
45
+        $this->data = json_decode((string)$body, true, 512, JSON_THROW_ON_ERROR);
46
+        $this->isSyncBody = true;
47
+        return parent::withBody($body);
48
+    }
49 49
 
50
-	public function setData(array $data): self
51
-	{
52
-		$this->isSyncBody = false;
53
-		$this->data = $data;
54
-		return $this;
55
-	}
50
+    public function setData(array $data): self
51
+    {
52
+        $this->isSyncBody = false;
53
+        $this->data = $data;
54
+        return $this;
55
+    }
56 56
 
57
-	public function reset(): self
58
-	{
59
-		$this->setData([]);
60
-		$this->protocol = '1.1';
61
-		$this->statusCode = 200;
62
-		$this->attributes = [];
63
-		$this->headers = [];
64
-		$this->withHeader('Content-Type', 'application/json');
57
+    public function reset(): self
58
+    {
59
+        $this->setData([]);
60
+        $this->protocol = '1.1';
61
+        $this->statusCode = 200;
62
+        $this->attributes = [];
63
+        $this->headers = [];
64
+        $this->withHeader('Content-Type', 'application/json');
65 65
 
66
-		if ($this->stream) {
67
-			$this->stream->close();
68
-			unset($this->stream);
69
-		}
66
+        if ($this->stream) {
67
+            $this->stream->close();
68
+            unset($this->stream);
69
+        }
70 70
 
71
-		return $this;
72
-	}
71
+        return $this;
72
+    }
73 73
 }
74 74
\ No newline at end of file
Please login to merge, or discard this patch.
src/Response/ServerMessageInterface.php 1 patch
Indentation   +24 added lines, -24 removed lines patch added patch discarded remove patch
@@ -5,31 +5,31 @@
 block discarded – undo
5 5
 
6 6
 interface ServerMessageInterface
7 7
 {
8
-	/**
9
-	 * @return array
10
-	 */
11
-	public function getAttributes(): array;
8
+    /**
9
+     * @return array
10
+     */
11
+    public function getAttributes(): array;
12 12
 
13
-	/**
14
-	 * @param string $attribute
15
-	 * @param mixed $default
16
-	 *
17
-	 * @return mixed
18
-	 */
19
-	public function getAttribute($attribute, $default = null);
13
+    /**
14
+     * @param string $attribute
15
+     * @param mixed $default
16
+     *
17
+     * @return mixed
18
+     */
19
+    public function getAttribute($attribute, $default = null);
20 20
 
21
-	/**
22
-	 * @param string $attribute
23
-	 * @param mixed $value
24
-	 *
25
-	 * @return $this
26
-	 */
27
-	public function withAttribute($attribute, $value);
21
+    /**
22
+     * @param string $attribute
23
+     * @param mixed $value
24
+     *
25
+     * @return $this
26
+     */
27
+    public function withAttribute($attribute, $value);
28 28
 
29
-	/**
30
-	 * @param string $attribute
31
-	 *
32
-	 * @return $this
33
-	 */
34
-	public function withoutAttribute($attribute);
29
+    /**
30
+     * @param string $attribute
31
+     *
32
+     * @return $this
33
+     */
34
+    public function withoutAttribute($attribute);
35 35
 }
36 36
\ No newline at end of file
Please login to merge, or discard this patch.