Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.
   1  <?php
   2  /**
   3   * Copyright 2007-2017 Horde LLC (http://www.horde.org/)
   4   *
   5   * See the enclosed file LICENSE for license information (BSD). If you
   6   * did not receive this file, see http://www.horde.org/licenses/bsd.
   7   *
   8   * @category  Horde
   9   * @copyright 2007-2017 Horde LLC
  10   * @license   http://www.horde.org/licenses/bsd BSD
  11   * @package   Stream_Wrapper
  12   */
  13  
  14  /**
  15   * A stream wrapper that will treat a native PHP string as a stream.
  16   *
  17   * @author    Chuck Hagenbuch <chuck@horde.org>
  18   * @author    Michael Slusarz <slusarz@horde.org>
  19   * @category  Horde
  20   * @copyright 2007-2017 Horde LLC
  21   * @license   http://www.horde.org/licenses/bsd BSD
  22   * @package   Stream_Wrapper
  23   */
  24  class Horde_Stream_Wrapper_String
  25  {
  26      /**/
  27      const WRAPPER_NAME = 'horde-stream-wrapper-string';
  28  
  29      /**
  30       * The current context.
  31       *
  32       * @var resource
  33       */
  34      public $context;
  35  
  36      /**
  37       * String position.
  38       *
  39       * @var integer
  40       */
  41      protected $_pos;
  42  
  43      /**
  44       * The string.
  45       *
  46       * @var string
  47       */
  48      protected $_string;
  49  
  50      /**
  51       * Unique ID tracker for the streams.
  52       *
  53       * @var integer
  54       */
  55      private static $_id = 0;
  56  
  57      /**
  58       * Create a stream from a PHP string.
  59       *
  60       * @since 2.1.0
  61       *
  62       * @param string &$string  A PHP string variable.
  63       *
  64       * @return resource  A PHP stream pointing to the variable.
  65       */
  66      public static function getStream(&$string)
  67      {
  68          if (!self::$_id) {
  69              stream_wrapper_register(self::WRAPPER_NAME, __CLASS__);
  70          }
  71  
  72          /* Needed to keep reference. */
  73          $ob = new stdClass;
  74          $ob->string = &$string;
  75  
  76          return fopen(
  77              self::WRAPPER_NAME . '://' . ++self::$_id,
  78              'wb',
  79              false,
  80              stream_context_create(array(
  81                  self::WRAPPER_NAME => array(
  82                      'string' => $ob
  83                  )
  84              ))
  85          );
  86      }
  87  
  88      /**
  89       * @see streamWrapper::stream_open()
  90       */
  91      public function stream_open($path, $mode, $options, &$opened_path)
  92      {
  93          $opts = stream_context_get_options($this->context);
  94  
  95          if (isset($opts[self::WRAPPER_NAME]['string'])) {
  96              $this->_string =& $opts[self::WRAPPER_NAME]['string']->string;
  97          } elseif (isset($opts['horde-string']['string'])) {
  98              // @deprecated
  99              $this->_string =& $opts['horde-string']['string']->getString();
 100          } else {
 101              throw new Exception('Use ' . __CLASS__ . '::getStream() to initialize the stream.');
 102          }
 103  
 104          if (is_null($this->_string)) {
 105              return false;
 106          }
 107  
 108          $this->_pos = 0;
 109  
 110          return true;
 111      }
 112  
 113      /**
 114       * @see streamWrapper::stream_close()
 115       */
 116      public function stream_close()
 117      {
 118          $this->_string = '';
 119          $this->_pos = 0;
 120      }
 121  
 122      /**
 123       * @see streamWrapper::stream_read()
 124       */
 125      public function stream_read($count)
 126      {
 127          $curr = $this->_pos;
 128          $this->_pos += $count;
 129          return substr($this->_string, $curr, $count);
 130      }
 131  
 132      /**
 133       * @see streamWrapper::stream_write()
 134       */
 135      public function stream_write($data)
 136      {
 137          $len = strlen($data);
 138  
 139          $this->_string = substr_replace($this->_string, $data, $this->_pos, $len);
 140          $this->_pos += $len;
 141  
 142          return $len;
 143      }
 144  
 145      /**
 146       * @see streamWrapper::stream_tell()
 147       */
 148      public function stream_tell()
 149      {
 150          return $this->_pos;
 151      }
 152  
 153      /**
 154       * @see streamWrapper::stream_eof()
 155       */
 156      public function stream_eof()
 157      {
 158          return ($this->_pos > strlen($this->_string));
 159      }
 160  
 161      /**
 162       * @see streamWrapper::stream_stat()
 163       */
 164      public function stream_stat()
 165      {
 166          return array(
 167              'dev' => 0,
 168              'ino' => 0,
 169              'mode' => 0,
 170              'nlink' => 0,
 171              'uid' => 0,
 172              'gid' => 0,
 173              'rdev' => 0,
 174              'size' => strlen($this->_string),
 175              'atime' => 0,
 176              'mtime' => 0,
 177              'ctime' => 0,
 178              'blksize' => 0,
 179              'blocks' => 0
 180          );
 181      }
 182  
 183      /**
 184       * @see streamWrapper::stream_seek()
 185       */
 186      public function stream_seek($offset, $whence)
 187      {
 188          switch ($whence) {
 189          case SEEK_SET:
 190              $pos = $offset;
 191              break;
 192  
 193          case SEEK_CUR:
 194              $pos = $this->_pos + $offset;
 195              break;
 196  
 197          case SEEK_END:
 198              $pos = strlen($this->_string) + $offset;
 199              break;
 200          }
 201  
 202          if (($pos < 0) || ($pos > strlen($this->_string))) {
 203              return false;
 204          }
 205  
 206          $this->_pos = $pos;
 207  
 208          return true;
 209      }
 210  
 211  }