PluginProbe
Yoast SEO – Advanced SEO with real-time guidance and built-in AI / 28.5
Yoast SEO – Advanced SEO with real-time guidance and built-in AI v28.5
28.5 28.4 28.3 28.2 28.1 28.0 27.9 27.8 27.7 27.6 27.5 trunk 18.0 18.1 18.2 18.3 18.4 18.4.1 18.5 18.5.1 18.6 18.7 18.8 18.9 19.0 All 129 releases
wordpress-seo / vendor_prefixed / guzzlehttp / psr7 / src / Stream.php

Stream.php in Yoast SEO – Advanced SEO with real-time guidance and built-in AI 28.5, at vendor_prefixed/guzzlehttp/psr7/src/Stream.php

251 lines 8.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 declare (strict_types=1);
4 namespace YoastSEO_Vendor\GuzzleHttp\Psr7;
5
6 use YoastSEO_Vendor\Psr\Http\Message\StreamInterface;
7 /**
8 * PHP stream implementation.
9 */
10 class Stream implements \YoastSEO_Vendor\Psr\Http\Message\StreamInterface
11 {
12 /**
13 * @see https://www.php.net/manual/en/function.fopen.php
14 * @see https://www.php.net/manual/en/function.gzopen.php
15 */
16 private const READABLE_MODES = '/r|a\\+|ab\\+|w\\+|wb\\+|x\\+|xb\\+|c\\+|cb\\+/';
17 private const WRITABLE_MODES = '/a|w|r\\+|rb\\+|rw|x|c/';
18 /** @var resource */
19 private $stream;
20 /** @var int|null */
21 private $size;
22 /** @var bool */
23 private $seekable;
24 /** @var bool */
25 private $readable;
26 /** @var bool */
27 private $writable;
28 /** @var string|null */
29 private $uri;
30 /** @var mixed[] */
31 private $customMetadata;
32 /**
33 * This constructor accepts an associative array of options.
34 *
35 * - size: (int) If a read stream would otherwise have an indeterminate
36 * size, but the size is known due to foreknowledge, then you can
37 * provide that size, in bytes.
38 * - metadata: (array) Any additional metadata to return when the metadata
39 * of the stream is accessed.
40 *
41 * @param resource $stream Stream resource to wrap.
42 * @param array{size?: int, metadata?: array} $options Associative array of options.
43 *
44 * @throws \InvalidArgumentException if the stream is not a stream resource
45 */
46 public function __construct($stream, array $options = [])
47 {
48 if (!\is_resource($stream)) {
49 throw new \InvalidArgumentException('Stream must be a resource');
50 }
51 if (isset($options['size'])) {
52 $this->size = $options['size'];
53 }
54 $this->customMetadata = $options['metadata'] ?? [];
55 $this->stream = $stream;
56 $meta = \stream_get_meta_data($this->stream);
57 $this->seekable = $meta['seekable'];
58 $this->readable = (bool) \preg_match(self::READABLE_MODES, $meta['mode']);
59 $this->writable = (bool) \preg_match(self::WRITABLE_MODES, $meta['mode']);
60 $this->uri = $meta['uri'] ?? null;
61 }
62 /**
63 * Closes the stream when the destructed
64 */
65 public function __destruct()
66 {
67 $this->close();
68 }
69 public function __toString() : string
70 {
71 try {
72 if ($this->isSeekable()) {
73 $this->seek(0);
74 }
75 return $this->getContents();
76 } catch (\Throwable $e) {
77 if (\PHP_VERSION_ID >= 70400) {
78 throw $e;
79 }
80 \trigger_error(\sprintf('%s::__toString exception: %s', self::class, (string) $e), \E_USER_ERROR);
81 return '';
82 }
83 }
84 public function getContents() : string
85 {
86 if (!isset($this->stream)) {
87 throw new \RuntimeException('Stream is detached');
88 }
89 if (!$this->readable) {
90 throw new \RuntimeException('Cannot read from non-readable stream');
91 }
92 return \YoastSEO_Vendor\GuzzleHttp\Psr7\Utils::tryGetContents($this->stream);
93 }
94 public function close() : void
95 {
96 if (isset($this->stream)) {
97 if (\is_resource($this->stream)) {
98 \fclose($this->stream);
99 }
100 $this->detach();
101 }
102 }
103 public function detach()
104 {
105 if (!isset($this->stream)) {
106 return null;
107 }
108 $result = $this->stream;
109 unset($this->stream);
110 $this->size = $this->uri = null;
111 $this->readable = $this->writable = $this->seekable = \false;
112 return $result;
113 }
114 public function getSize() : ?int
115 {
116 if ($this->size !== null) {
117 return $this->size;
118 }
119 if (!isset($this->stream)) {
120 return null;
121 }
122 // Clear the stat cache if the stream has a URI
123 if ($this->uri) {
124 \clearstatcache(\true, $this->uri);
125 }
126 $stats = \fstat($this->stream);
127 if (\is_array($stats) && isset($stats['size'])) {
128 $this->size = $stats['size'];
129 return $this->size;
130 }
131 return null;
132 }
133 public function isReadable() : bool
134 {
135 return $this->readable;
136 }
137 public function isWritable() : bool
138 {
139 return $this->writable;
140 }
141 public function isSeekable() : bool
142 {
143 return $this->seekable;
144 }
145 public function eof() : bool
146 {
147 if (!isset($this->stream)) {
148 throw new \RuntimeException('Stream is detached');
149 }
150 return \feof($this->stream);
151 }
152 public function tell() : int
153 {
154 if (!isset($this->stream)) {
155 throw new \RuntimeException('Stream is detached');
156 }
157 $result = \ftell($this->stream);
158 if ($result === \false) {
159 throw new \RuntimeException('Unable to determine stream position');
160 }
161 return $result;
162 }
163 public function rewind() : void
164 {
165 $this->seek(0);
166 }
167 public function seek($offset, $whence = \SEEK_SET) : void
168 {
169 if (!\is_int($offset)) {
170 \YoastSEO_Vendor\trigger_deprecation('guzzlehttp/psr7', '2.11', 'Passing %s to StreamInterface::seek() is deprecated; guzzlehttp/psr7 3.0 requires int for $offset.', \get_debug_type($offset));
171 }
172 if (!\is_int($whence)) {
173 \YoastSEO_Vendor\trigger_deprecation('guzzlehttp/psr7', '2.11', 'Passing %s to StreamInterface::seek() is deprecated; guzzlehttp/psr7 3.0 requires int for $whence.', \get_debug_type($whence));
174 }
175 $whence = (int) $whence;
176 if (!isset($this->stream)) {
177 throw new \RuntimeException('Stream is detached');
178 }
179 if (!$this->seekable) {
180 throw new \RuntimeException('Stream is not seekable');
181 }
182 if (\fseek($this->stream, $offset, $whence) === -1) {
183 throw new \RuntimeException('Unable to seek to stream position ' . $offset . ' with whence ' . \var_export($whence, \true));
184 }
185 }
186 public function read($length) : string
187 {
188 if (!\is_int($length)) {
189 \YoastSEO_Vendor\trigger_deprecation('guzzlehttp/psr7', '2.11', 'Passing %s to StreamInterface::read() is deprecated; guzzlehttp/psr7 3.0 requires int for $length.', \get_debug_type($length));
190 }
191 if (!isset($this->stream)) {
192 throw new \RuntimeException('Stream is detached');
193 }
194 if (!$this->readable) {
195 throw new \RuntimeException('Cannot read from non-readable stream');
196 }
197 if ($length < 0) {
198 throw new \RuntimeException('Length parameter cannot be negative');
199 }
200 if (0 === $length) {
201 return '';
202 }
203 try {
204 $string = \fread($this->stream, $length);
205 } catch (\Exception $e) {
206 throw new \RuntimeException('Unable to read from stream', 0, $e);
207 }
208 if (\false === $string) {
209 throw new \RuntimeException('Unable to read from stream');
210 }
211 return $string;
212 }
213 public function write($string) : int
214 {
215 if (!\is_string($string)) {
216 \YoastSEO_Vendor\trigger_deprecation('guzzlehttp/psr7', '2.11', 'Passing %s to StreamInterface::write() is deprecated; guzzlehttp/psr7 3.0 requires string for $string.', \get_debug_type($string));
217 }
218 if (!isset($this->stream)) {
219 throw new \RuntimeException('Stream is detached');
220 }
221 if (!$this->writable) {
222 throw new \RuntimeException('Cannot write to a non-writable stream');
223 }
224 // We can't know the size after writing anything
225 $this->size = null;
226 $result = \fwrite($this->stream, $string);
227 if ($result === \false) {
228 throw new \RuntimeException('Unable to write to stream');
229 }
230 return $result;
231 }
232 /**
233 * @return mixed
234 */
235 public function getMetadata($key = null)
236 {
237 if ($key !== null && !\is_string($key)) {
238 \YoastSEO_Vendor\trigger_deprecation('guzzlehttp/psr7', '2.11', 'Passing %s to StreamInterface::getMetadata() is deprecated; guzzlehttp/psr7 3.0 requires string|null for $key.', \get_debug_type($key));
239 }
240 if (!isset($this->stream)) {
241 return $key ? null : [];
242 } elseif (!$key) {
243 return $this->customMetadata + \stream_get_meta_data($this->stream);
244 } elseif (isset($this->customMetadata[$key])) {
245 return $this->customMetadata[$key];
246 }
247 $meta = \stream_get_meta_data($this->stream);
248 return $meta[$key] ?? null;
249 }
250 }
251