TYPO3CMS  8
 All Classes Namespaces Files Functions Variables Pages
Stream.php
Go to the documentation of this file.
1 <?php
2 namespace TYPO3\CMS\Core\Http;
3 
4 /*
5  * This file is part of the TYPO3 CMS project.
6  *
7  * It is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU General Public License, either version 2
9  * of the License, or any later version.
10  *
11  * For the full copyright and license information, please read the
12  * LICENSE.txt file that was distributed with this source code.
13  *
14  * The TYPO3 project - inspiring people to share!
15  */
16 
17 use Psr\Http\Message\StreamInterface;
18 
27 class Stream implements StreamInterface
28 {
33  protected $resource;
34 
38  protected $stream;
39 
47  public function __construct($stream, $mode = 'r')
48  {
49  $this->stream = $stream;
50  if (is_resource($stream)) {
51  $this->resource = $stream;
52  } elseif (is_string($stream)) {
53  $this->resource = fopen($stream, $mode);
54  } else {
55  throw new \InvalidArgumentException('Invalid stream provided; must be a string stream identifier or resource', 1436717284);
56  }
57  }
58 
73  public function __toString()
74  {
75  if (!$this->isReadable()) {
76  return '';
77  }
78  try {
79  $this->rewind();
80  return $this->getContents();
81  } catch (\RuntimeException $e) {
82  return '';
83  }
84  }
85 
91  public function close()
92  {
93  if (!$this->resource) {
94  return;
95  }
96  $resource = $this->detach();
97  fclose($resource);
98  }
99 
107  public function detach()
108  {
110  $this->resource = null;
111  return $resource;
112  }
113 
119  public function getSize()
120  {
121  if ($this->resource === null) {
122  return null;
123  }
124  $stats = fstat($this->resource);
125  return $stats['size'];
126  }
127 
134  public function tell()
135  {
136  if (!$this->resource) {
137  throw new \RuntimeException('No resource available; cannot tell position', 1436717285);
138  }
139  $result = ftell($this->resource);
140  if (!is_int($result)) {
141  throw new \RuntimeException('Error occurred during tell operation', 1436717286);
142  }
143  return $result;
144  }
145 
151  public function eof()
152  {
153  if (!$this->resource) {
154  return true;
155  }
156  return feof($this->resource);
157  }
158 
164  public function isSeekable()
165  {
166  if (!$this->resource) {
167  return false;
168  }
169  return (bool)$this->getMetadata('seekable');
170  }
171 
186  public function seek($offset, $whence = SEEK_SET)
187  {
188  if (!$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()
212  {
213  $this->seek(0);
214  }
215 
221  public function isWritable()
222  {
223  if (!$this->resource) {
224  return false;
225  }
226  $uri = $this->getMetadata('uri');
227  return is_writable($uri);
228  }
229 
237  public function write($string)
238  {
239  if (!$this->resource) {
240  throw new \RuntimeException('No resource available; cannot write', 1436717290);
241  }
242  $result = fwrite($this->resource, $string);
243  if ($result === false) {
244  throw new \RuntimeException('Error writing to stream', 1436717291);
245  }
246  return $result;
247  }
248 
254  public function isReadable()
255  {
256  if (!$this->resource) {
257  return false;
258  }
259  $mode = $this->getMetadata('mode');
260  return strpos($mode, 'r') !== false || strpos($mode, '+') !== false;
261  }
262 
273  public function read($length)
274  {
275  if (!$this->resource) {
276  throw new \RuntimeException('No resource available; cannot read', 1436717292);
277  }
278  if (!$this->isReadable()) {
279  throw new \RuntimeException('Stream is not readable', 1436717293);
280  }
281  $result = fread($this->resource, $length);
282  if ($result === false) {
283  throw new \RuntimeException('Error reading stream', 1436717294);
284  }
285  return $result;
286  }
287 
295  public function getContents()
296  {
297  if (!$this->isReadable()) {
298  return '';
299  }
300  $result = stream_get_contents($this->resource);
301  if ($result === false) {
302  throw new \RuntimeException('Error reading from stream', 1436717295);
303  }
304  return $result;
305  }
306 
321  public function getMetadata($key = null)
322  {
323  $metadata = stream_get_meta_data($this->resource);
324  if ($key === null) {
325  return $metadata;
326  }
327  if (!isset($metadata[$key])) {
328  return null;
329  }
330  return $metadata[$key];
331  }
332 
341  public function attach($resource, $mode = 'r')
342  {
343  $error = null;
344  if (!is_resource($resource) && is_string($resource)) {
345  set_error_handler(function ($e) use (&$error) {
346  $error = $e;
347  }, E_WARNING);
348  $resource = fopen($resource, $mode);
349  restore_error_handler();
350  }
351  if ($error) {
352  throw new \InvalidArgumentException('Invalid stream reference provided', 1436717296);
353  }
354  if (!is_resource($resource)) {
355  throw new \InvalidArgumentException('Invalid stream provided; must be a string stream identifier or resource', 1436717297);
356  }
357  $this->resource = $resource;
358  }
359 }
attach($resource, $mode= 'r')
Definition: Stream.php:341
seek($offset, $whence=SEEK_SET)
Definition: Stream.php:186
__construct($stream, $mode= 'r')
Definition: Stream.php:47