Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.2.x will end 22 April 2024 (12 months).
  • Bug fixes for security issues in 4.2.x will end 7 October 2024 (18 months).
  • PHP version: minimum PHP 8.0.0 Note: minimum PHP version has increased since Moodle 4.1. PHP 8.1.x is supported too.
   1  <?php
   2  
   3  declare(strict_types=1);
   4  
   5  namespace GuzzleHttp\Psr7;
   6  
   7  use Psr\Http\Message\StreamInterface;
   8  
   9  /**
  10   * Stream decorator trait
  11   *
  12   * @property StreamInterface $stream
  13   */
  14  trait StreamDecoratorTrait
  15  {
  16      /**
  17       * @param StreamInterface $stream Stream to decorate
  18       */
  19      public function __construct(StreamInterface $stream)
  20      {
  21          $this->stream = $stream;
  22      }
  23  
  24      /**
  25       * Magic method used to create a new stream if streams are not added in
  26       * the constructor of a decorator (e.g., LazyOpenStream).
  27       *
  28       * @return StreamInterface
  29       */
  30      public function __get(string $name)
  31      {
  32          if ($name === 'stream') {
  33              $this->stream = $this->createStream();
  34              return $this->stream;
  35          }
  36  
  37          throw new \UnexpectedValueException("$name not found on class");
  38      }
  39  
  40      public function __toString(): string
  41      {
  42          try {
  43              if ($this->isSeekable()) {
  44                  $this->seek(0);
  45              }
  46              return $this->getContents();
  47          } catch (\Throwable $e) {
  48              if (\PHP_VERSION_ID >= 70400) {
  49                  throw $e;
  50              }
  51              trigger_error(sprintf('%s::__toString exception: %s', self::class, (string) $e), E_USER_ERROR);
  52              return '';
  53          }
  54      }
  55  
  56      public function getContents(): string
  57      {
  58          return Utils::copyToString($this);
  59      }
  60  
  61      /**
  62       * Allow decorators to implement custom methods
  63       *
  64       * @return mixed
  65       */
  66      public function __call(string $method, array $args)
  67      {
  68          /** @var callable $callable */
  69          $callable = [$this->stream, $method];
  70          $result = call_user_func_array($callable, $args);
  71  
  72          // Always return the wrapped object if the result is a return $this
  73          return $result === $this->stream ? $this : $result;
  74      }
  75  
  76      public function close(): void
  77      {
  78          $this->stream->close();
  79      }
  80  
  81      /**
  82       * {@inheritdoc}
  83       *
  84       * @return mixed
  85       */
  86      public function getMetadata($key = null)
  87      {
  88          return $this->stream->getMetadata($key);
  89      }
  90  
  91      public function detach()
  92      {
  93          return $this->stream->detach();
  94      }
  95  
  96      public function getSize(): ?int
  97      {
  98          return $this->stream->getSize();
  99      }
 100  
 101      public function eof(): bool
 102      {
 103          return $this->stream->eof();
 104      }
 105  
 106      public function tell(): int
 107      {
 108          return $this->stream->tell();
 109      }
 110  
 111      public function isReadable(): bool
 112      {
 113          return $this->stream->isReadable();
 114      }
 115  
 116      public function isWritable(): bool
 117      {
 118          return $this->stream->isWritable();
 119      }
 120  
 121      public function isSeekable(): bool
 122      {
 123          return $this->stream->isSeekable();
 124      }
 125  
 126      public function rewind(): void
 127      {
 128          $this->seek(0);
 129      }
 130  
 131      public function seek($offset, $whence = SEEK_SET): void
 132      {
 133          $this->stream->seek($offset, $whence);
 134      }
 135  
 136      public function read($length): string
 137      {
 138          return $this->stream->read($length);
 139      }
 140  
 141      public function write($string): int
 142      {
 143          return $this->stream->write($string);
 144      }
 145  
 146      /**
 147       * Implement in subclasses to dynamically create streams when requested.
 148       *
 149       * @throws \BadMethodCallException
 150       */
 151      protected function createStream(): StreamInterface
 152      {
 153          throw new \BadMethodCallException('Not implemented');
 154      }
 155  }