Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.11.x will end 14 Nov 2022 (12 months plus 6 months extension).
  • Bug fixes for security issues in 3.11.x will end 13 Nov 2023 (18 months plus 12 months extension).
  • PHP version: minimum PHP 7.3.0 Note: minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is supported too.
   1  <?php
   2  /**
   3   * Copyright 2012-2017 Horde LLC (http://www.horde.org/)
   4   *
   5   * See the enclosed file LICENSE for license information (LGPL). If you
   6   * did not receive this file, see http://www.horde.org/licenses/lgpl21.
   7   *
   8   * @category  Horde
   9   * @copyright 2012-2017 Horde LLC
  10   * @license   http://www.horde.org/licenses/lgpl21 LGPL 2.1
  11   * @package   Imap_Client
  12   */
  13  
  14  /**
  15   * Object representation of an IMAP string (RFC 3501 [4.3]).
  16   *
  17   * @author    Michael Slusarz <slusarz@horde.org>
  18   * @category  Horde
  19   * @copyright 2012-2017 Horde LLC
  20   * @license   http://www.horde.org/licenses/lgpl21 LGPL 2.1
  21   * @package   Imap_Client
  22   */
  23  class Horde_Imap_Client_Data_Format_String
  24  extends Horde_Imap_Client_Data_Format
  25  {
  26      /**
  27       * String filter parameters.
  28       *
  29       * @var string
  30       */
  31      protected $_filter;
  32  
  33      /**
  34       * @param array $opts  Additional options:
  35       *   - eol: (boolean) If true, normalize EOLs in input. @since 2.2.0
  36       *   - skipscan: (boolean) If true, don't scan input for
  37       *               binary/literal/quoted data. @since 2.2.0
  38       *
  39       * @throws Horde_Imap_Client_Data_Format_Exception
  40       */
  41      public function __construct($data, array $opts = array())
  42      {
  43          /* String data is stored in a stream. */
  44          $this->_data = new Horde_Stream_Temp();
  45  
  46          if (empty($opts['skipscan'])) {
  47              $this->_filter = $this->_filterParams();
  48              stream_filter_register('horde_imap_client_string', 'Horde_Imap_Client_Data_Format_Filter_String');
  49              $res = stream_filter_append($this->_data->stream, 'horde_imap_client_string', STREAM_FILTER_WRITE, $this->_filter);
  50          } else {
  51              $res = null;
  52          }
  53  
  54          if (empty($opts['eol'])) {
  55              $res2 = null;
  56          } else {
  57              stream_filter_register('horde_eol', 'Horde_Stream_Filter_Eol');
  58              $res2 = stream_filter_append($this->_data->stream, 'horde_eol', STREAM_FILTER_WRITE);
  59          }
  60  
  61          $this->_data->add($data);
  62  
  63          if (!is_null($res)) {
  64              stream_filter_remove($res);
  65          }
  66          if (!is_null($res2)) {
  67              stream_filter_remove($res2);
  68          }
  69  
  70          if (isset($this->_filter) &&
  71              $this->_filter->nonascii &&
  72              !($this instanceof Horde_Imap_Client_Data_Format_String_Support_Nonascii)) {
  73              throw new Horde_Imap_Client_Data_Format_Exception(
  74                  'String contains non-ASCII characters.'
  75              );
  76          }
  77      }
  78  
  79      /**
  80       * Return the base string filter parameters.
  81       *
  82       * @return object  Filter parameters.
  83       */
  84      protected function _filterParams()
  85      {
  86          return new stdClass;
  87      }
  88  
  89      /**
  90       */
  91      public function __toString()
  92      {
  93          return $this->_data->getString(0);
  94      }
  95  
  96      /**
  97       */
  98      public function escape()
  99      {
 100          if ($this->literal()) {
 101              throw new Horde_Imap_Client_Data_Format_Exception('String requires literal to output.');
 102          }
 103  
 104          return $this->quoted()
 105              ? stream_get_contents($this->escapeStream())
 106              : $this->_data->getString(0);
 107      }
 108  
 109      /**
 110       * Return the escaped string as a stream.
 111       *
 112       * @return resource  The IMAP escaped stream.
 113       */
 114      public function escapeStream()
 115      {
 116          if ($this->literal()) {
 117              throw new Horde_Imap_Client_Data_Format_Exception('String requires literal to output.');
 118          }
 119  
 120          rewind($this->_data->stream);
 121  
 122          $stream = new Horde_Stream_Temp();
 123          $stream->add($this->_data, true);
 124  
 125          stream_filter_register('horde_imap_client_string_quote', 'Horde_Imap_Client_Data_Format_Filter_Quote');
 126          stream_filter_append($stream->stream, 'horde_imap_client_string_quote', STREAM_FILTER_READ);
 127  
 128          return $stream->stream;
 129      }
 130  
 131      /**
 132       * Does this data item require quoted string output?
 133       *
 134       * @return boolean  True if quoted output is required.
 135       */
 136      public function quoted()
 137      {
 138          /* IMAP strings MUST be quoted if they are not a literal. */
 139          return (!isset($this->_filter) || !$this->_filter->literal);
 140      }
 141  
 142      /**
 143       * Force item to be output quoted.
 144       */
 145      public function forceQuoted()
 146      {
 147          $this->_filter = $this->_filterParams();
 148          $this->_filter->binary = false;
 149          $this->_filter->literal = false;
 150          $this->_filter->quoted = true;
 151      }
 152  
 153      /**
 154       * Does this data item require literal string output?
 155       *
 156       * @return boolean  True if literal output is required.
 157       */
 158      public function literal()
 159      {
 160          return (isset($this->_filter) && $this->_filter->literal);
 161      }
 162  
 163      /**
 164       * Force item to be output as a literal.
 165       */
 166      public function forceLiteral()
 167      {
 168          $this->_filter = $this->_filterParams();
 169          // Keep binary status, if set
 170          $this->_filter->literal = true;
 171          $this->_filter->quoted = false;
 172      }
 173  
 174      /**
 175       * If literal output, is the data binary?
 176       *
 177       * @return boolean  True if the literal output is binary.
 178       */
 179      public function binary()
 180      {
 181          return (isset($this->_filter) && !empty($this->_filter->binary));
 182      }
 183  
 184      /**
 185       * Force item to be output as a binary literal.
 186       */
 187      public function forceBinary()
 188      {
 189          $this->_filter = $this->_filterParams();
 190          $this->_filter->binary = true;
 191          $this->_filter->literal = true;
 192          $this->_filter->quoted = false;
 193      }
 194  
 195      /**
 196       * Return the length of the data.
 197       *
 198       * @since 2.2.0
 199       *
 200       * @return integer  Data length.
 201       */
 202      public function length()
 203      {
 204          return $this->_data->length();
 205      }
 206  
 207      /**
 208       * Return the contents of the string as a stream object.
 209       *
 210       * @since 2.3.0
 211       *
 212       * @return Horde_Stream  The stream object.
 213       */
 214      public function getStream()
 215      {
 216          return $this->_data;
 217      }
 218  
 219  }