File indexing completed on 2024-12-29 05:27:23
0001 <?php 0002 namespace GuzzleHttp\Psr7; 0003 0004 use Psr\Http\Message\StreamInterface; 0005 0006 /** 0007 * Stream decorator trait 0008 * @property StreamInterface stream 0009 */ 0010 trait StreamDecoratorTrait 0011 { 0012 /** 0013 * @param StreamInterface $stream Stream to decorate 0014 */ 0015 public function __construct(StreamInterface $stream) 0016 { 0017 $this->stream = $stream; 0018 } 0019 0020 /** 0021 * Magic method used to create a new stream if streams are not added in 0022 * the constructor of a decorator (e.g., LazyOpenStream). 0023 * 0024 * @param string $name Name of the property (allows "stream" only). 0025 * 0026 * @return StreamInterface 0027 */ 0028 public function __get($name) 0029 { 0030 if ($name == 'stream') { 0031 $this->stream = $this->createStream(); 0032 return $this->stream; 0033 } 0034 0035 throw new \UnexpectedValueException("$name not found on class"); 0036 } 0037 0038 public function __toString() 0039 { 0040 try { 0041 if ($this->isSeekable()) { 0042 $this->seek(0); 0043 } 0044 return $this->getContents(); 0045 } catch (\Exception $e) { 0046 // Really, PHP? https://bugs.php.net/bug.php?id=53648 0047 trigger_error('StreamDecorator::__toString exception: ' 0048 . (string) $e, E_USER_ERROR); 0049 return ''; 0050 } 0051 } 0052 0053 public function getContents() 0054 { 0055 return copy_to_string($this); 0056 } 0057 0058 /** 0059 * Allow decorators to implement custom methods 0060 * 0061 * @param string $method Missing method name 0062 * @param array $args Method arguments 0063 * 0064 * @return mixed 0065 */ 0066 public function __call($method, array $args) 0067 { 0068 $result = call_user_func_array([$this->stream, $method], $args); 0069 0070 // Always return the wrapped object if the result is a return $this 0071 return $result === $this->stream ? $this : $result; 0072 } 0073 0074 public function close() 0075 { 0076 $this->stream->close(); 0077 } 0078 0079 public function getMetadata($key = null) 0080 { 0081 return $this->stream->getMetadata($key); 0082 } 0083 0084 public function detach() 0085 { 0086 return $this->stream->detach(); 0087 } 0088 0089 public function getSize() 0090 { 0091 return $this->stream->getSize(); 0092 } 0093 0094 public function eof() 0095 { 0096 return $this->stream->eof(); 0097 } 0098 0099 public function tell() 0100 { 0101 return $this->stream->tell(); 0102 } 0103 0104 public function isReadable() 0105 { 0106 return $this->stream->isReadable(); 0107 } 0108 0109 public function isWritable() 0110 { 0111 return $this->stream->isWritable(); 0112 } 0113 0114 public function isSeekable() 0115 { 0116 return $this->stream->isSeekable(); 0117 } 0118 0119 public function rewind() 0120 { 0121 $this->seek(0); 0122 } 0123 0124 public function seek($offset, $whence = SEEK_SET) 0125 { 0126 $this->stream->seek($offset, $whence); 0127 } 0128 0129 public function read($length) 0130 { 0131 return $this->stream->read($length); 0132 } 0133 0134 public function write($string) 0135 { 0136 return $this->stream->write($string); 0137 } 0138 0139 /** 0140 * Implement in subclasses to dynamically create streams when requested. 0141 * 0142 * @return StreamInterface 0143 * @throws \BadMethodCallException 0144 */ 0145 protected function createStream() 0146 { 0147 throw new \BadMethodCallException('Not implemented'); 0148 } 0149 }