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