‪TYPO3CMS  ‪main
Stream.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
18 namespace ‪TYPO3\CMS\Core\Http;
19 
20 use Psr\Http\Message\StreamInterface;
21 
30 class ‪Stream implements StreamInterface
31 {
36  protected ‪$resource;
37 
41  protected ‪$stream;
42 
50  public function ‪__construct(‪$stream, string $mode = 'r')
51  {
52  $this->stream = ‪$stream;
53  if (is_resource(‪$stream)) {
54  $this->resource = ‪$stream;
55  } elseif (is_string(‪$stream)) {
56  $this->resource = fopen(‪$stream, $mode) ?: null;
57  } else {
58  throw new \InvalidArgumentException('Invalid stream provided; must be a string stream identifier or resource', 1436717284);
59  }
60  }
61 
76  public function ‪__toString(): string
77  {
78  if (!$this->‪isReadable()) {
79  return '';
80  }
81  try {
82  $this->‪rewind();
83  return $this->‪getContents();
84  } catch (\RuntimeException $e) {
85  return '';
86  }
87  }
88 
92  public function ‪close(): void
93  {
94  if (!is_resource($this->resource)) {
95  return;
96  }
97  ‪$resource = $this->‪detach();
98  if (‪$resource === null) {
99  return;
100  }
101  fclose(‪$resource);
102  }
103 
111  public function ‪detach()
112  {
114  $this->resource = null;
115  return ‪$resource;
116  }
117 
123  public function ‪getSize(): ?int
124  {
125  if ($this->resource === null) {
126  return null;
127  }
128  $stats = fstat($this->resource);
129  return $stats['size'];
130  }
131 
138  public function ‪tell(): int
139  {
140  if (!is_resource($this->resource)) {
141  throw new \RuntimeException('No resource available; cannot tell position', 1436717285);
142  }
143  $result = ftell($this->resource);
144  if (!is_int($result)) {
145  throw new \RuntimeException('Error occurred during tell operation', 1436717286);
146  }
147  return $result;
148  }
149 
153  public function ‪eof(): bool
154  {
155  if (!is_resource($this->resource)) {
156  return true;
157  }
158  return feof($this->resource);
159  }
160 
164  public function ‪isSeekable(): bool
165  {
166  if (!is_resource($this->resource)) {
167  return false;
168  }
169  return (bool)$this->‪getMetadata('seekable');
170  }
171 
186  public function ‪seek(int $offset, int $whence = SEEK_SET): void
187  {
188  if (!is_resource($this->resource)) {
189  throw new \RuntimeException('No resource available; cannot seek position', 1436717287);
190  }
191 
192  if (!$this->‪isSeekable()) {
193  throw new \RuntimeException('Stream is not seekable', 1436717288);
194  }
195  $result = fseek($this->resource, $offset, $whence);
196  if ($result !== 0) {
197  throw new \RuntimeException('Error seeking within stream', 1436717289);
198  }
199  }
200 
211  public function ‪rewind(): void
212  {
213  $this->‪seek(0);
214  }
215 
219  public function ‪isWritable(): bool
220  {
221  if (!is_resource($this->resource)) {
222  return false;
223  }
224  $uri = $this->‪getMetadata('uri');
225  return is_writable($uri);
226  }
227 
235  public function ‪write(string $string): int
236  {
237  if (!is_resource($this->resource)) {
238  throw new \RuntimeException('No resource available; cannot write', 1436717290);
239  }
240  $result = fwrite($this->resource, $string);
241  if ($result === false) {
242  throw new \RuntimeException('Error writing to stream', 1436717291);
243  }
244  return $result;
245  }
246 
250  public function ‪isReadable(): bool
251  {
252  if (!is_resource($this->resource)) {
253  return false;
254  }
255  $mode = $this->‪getMetadata('mode');
256  return str_contains($mode, 'r') || str_contains($mode, '+');
257  }
258 
269  public function ‪read(int $length): string
270  {
271  if (!is_resource($this->resource)) {
272  throw new \RuntimeException('No resource available; cannot read', 1436717292);
273  }
274  if (!$this->‪isReadable()) {
275  throw new \RuntimeException('Stream is not readable', 1436717293);
276  }
277  $result = fread($this->resource, $length);
278  if ($result === false) {
279  throw new \RuntimeException('Error reading stream', 1436717294);
280  }
281  return $result;
282  }
283 
289  public function ‪getContents(): string
290  {
291  if (!is_resource($this->resource) || !$this->‪isReadable()) {
292  return '';
293  }
294  $result = stream_get_contents($this->resource);
295  if ($result === false) {
296  throw new \RuntimeException('Error reading from stream', 1436717295);
297  }
298  return $result;
299  }
300 
315  public function ‪getMetadata(?string $key = null)
316  {
317  if (!is_resource($this->resource)) {
318  return null;
319  }
320  $metadata = stream_get_meta_data($this->resource);
321  if ($key === null) {
322  return $metadata;
323  }
324  if (!isset($metadata[$key])) {
325  return null;
326  }
327  return $metadata[$key];
328  }
329 
338  public function ‪attach(‪$resource, string $mode = 'r')
339  {
340  $error = null;
341  if (!is_resource(‪$resource) && is_string(‪$resource)) {
342  set_error_handler(static function ($e) use (&$error): bool {
343  $error = $e;
344  return true;
345  }, E_WARNING);
346  ‪$resource = fopen(‪$resource, $mode);
347  restore_error_handler();
348  }
349  if ($error) {
350  throw new \InvalidArgumentException('Invalid stream reference provided', 1436717296);
351  }
352  if (!is_resource(‪$resource)) {
353  throw new \InvalidArgumentException('Invalid stream provided; must be a string stream identifier or resource', 1436717297);
354  }
355  $this->resource = ‪$resource;
356  }
357 }
‪TYPO3\CMS\Core\Http\Stream\rewind
‪rewind()
Definition: Stream.php:209
‪TYPO3\CMS\Core\Http\Stream\getContents
‪getContents()
Definition: Stream.php:287
‪TYPO3\CMS\Core\Http\Stream\isWritable
‪isWritable()
Definition: Stream.php:217
‪TYPO3\CMS\Core\Http\Stream\tell
‪int tell()
Definition: Stream.php:136
‪TYPO3\CMS\Core\Http\Stream\eof
‪eof()
Definition: Stream.php:151
‪TYPO3\CMS\Core\Http\Stream\__construct
‪__construct($stream, string $mode='r')
Definition: Stream.php:48
‪TYPO3\CMS\Core\Http\Stream\attach
‪attach($resource, string $mode='r')
Definition: Stream.php:336
‪TYPO3\CMS\Core\Http\Stream\seek
‪seek(int $offset, int $whence=SEEK_SET)
Definition: Stream.php:184
‪TYPO3\CMS\Core\Http\Stream\read
‪string read(int $length)
Definition: Stream.php:267
‪TYPO3\CMS\Core\Http\Stream
Definition: Stream.php:31
‪TYPO3\CMS\Core\Http\Stream\$stream
‪string resource $stream
Definition: Stream.php:39
‪TYPO3\CMS\Core\Http\Stream\__toString
‪string __toString()
Definition: Stream.php:74
‪TYPO3\CMS\Core\Http\Stream\getSize
‪int null getSize()
Definition: Stream.php:121
‪TYPO3\CMS\Core\Http\Stream\close
‪close()
Definition: Stream.php:90
‪TYPO3\CMS\Core\Http\Stream\isSeekable
‪isSeekable()
Definition: Stream.php:162
‪TYPO3\CMS\Core\Http\Stream\detach
‪resource null detach()
Definition: Stream.php:109
‪TYPO3\CMS\Core\Http\Stream\$resource
‪resource null $resource
Definition: Stream.php:35
‪TYPO3\CMS\Core\Http\Stream\isReadable
‪isReadable()
Definition: Stream.php:248
‪TYPO3\CMS\Core\Http\Stream\getMetadata
‪array mixed null getMetadata(?string $key=null)
Definition: Stream.php:313
‪TYPO3\CMS\Core\Http\Stream\write
‪int write(string $string)
Definition: Stream.php:233
‪TYPO3\CMS\Core\Http
Definition: AbstractApplication.php:18