[ Index ]

MailPress 544

[ Index ]     [ Classes ]     [ Functions ]     [ Variables ]     [ Constants ]     [ Statistics ]    

title

Body

[close]

/mp-includes/Swiftmailer/classes/Swift/ByteStream/ -> FileByteStream.php (source)

   1  <?php
   2  
   3  /*
   4   * This file is part of SwiftMailer.
   5   * (c) 2004-2009 Chris Corbyn
   6   *
   7   * For the full copyright and license information, please view the LICENSE
   8   * file that was distributed with this source code.
   9   */
  10  
  11  /**
  12   * Allows reading and writing of bytes to and from a file.
  13   *
  14   * @author Chris Corbyn
  15   */
  16  class Swift_ByteStream_FileByteStream extends Swift_ByteStream_AbstractFilterableInputStream implements Swift_FileStream
  17  {
  18      /** The internal pointer offset */
  19      private $_offset = 0;
  20  
  21      /** The path to the file */
  22      private $_path;
  23  
  24      /** The mode this file is opened in for writing */
  25      private $_mode;
  26  
  27      /** A lazy-loaded resource handle for reading the file */
  28      private $_reader;
  29  
  30      /** A lazy-loaded resource handle for writing the file */
  31      private $_writer;
  32  
  33      /** If magic_quotes_runtime is on, this will be true */
  34      private $_quotes = false;
  35  
  36      /** If stream is seekable true/false, or null if not known */
  37      private $_seekable = null;
  38  
  39      /**
  40       * Create a new FileByteStream for $path.
  41       *
  42       * @param string $path
  43       * @param bool   $writable if true
  44       */
  45      public function __construct($path, $writable = false)
  46      {
  47          if (empty($path)) {
  48              throw new Swift_IoException('The path cannot be empty');
  49          }
  50          $this->_path = $path;
  51          $this->_mode = $writable ? 'w+b' : 'rb';
  52  
  53          if (function_exists('get_magic_quotes_runtime') && @get_magic_quotes_runtime() == 1) {
  54              $this->_quotes = true;
  55          }
  56      }
  57  
  58      /**
  59       * Get the complete path to the file.
  60       *
  61       * @return string
  62       */
  63      public function getPath()
  64      {
  65          return $this->_path;
  66      }
  67  
  68      /**
  69       * Reads $length bytes from the stream into a string and moves the pointer
  70       * through the stream by $length.
  71       *
  72       * If less bytes exist than are requested the
  73       * remaining bytes are given instead. If no bytes are remaining at all, boolean
  74       * false is returned.
  75       *
  76       * @param int $length
  77       *
  78       * @throws Swift_IoException
  79       *
  80       * @return string|bool
  81       */
  82      public function read($length)
  83      {
  84          $fp = $this->_getReadHandle();
  85          if (!feof($fp)) {
  86              if ($this->_quotes) {
  87                  ini_set('magic_quotes_runtime', 0);
  88              }
  89              $bytes = fread($fp, $length);
  90              if ($this->_quotes) {
  91                  ini_set('magic_quotes_runtime', 1);
  92              }
  93              $this->_offset = ftell($fp);
  94  
  95              // If we read one byte after reaching the end of the file
  96              // feof() will return false and an empty string is returned
  97              if ($bytes === '' && feof($fp)) {
  98                  $this->_resetReadHandle();
  99  
 100                  return false;
 101              }
 102  
 103              return $bytes;
 104          }
 105  
 106          $this->_resetReadHandle();
 107  
 108          return false;
 109      }
 110  
 111      /**
 112       * Move the internal read pointer to $byteOffset in the stream.
 113       *
 114       * @param int $byteOffset
 115       *
 116       * @return bool
 117       */
 118      public function setReadPointer($byteOffset)
 119      {
 120          if (isset($this->_reader)) {
 121              $this->_seekReadStreamToPosition($byteOffset);
 122          }
 123          $this->_offset = $byteOffset;
 124      }
 125  
 126      /** Just write the bytes to the file */
 127      protected function _commit($bytes)
 128      {
 129          fwrite($this->_getWriteHandle(), $bytes);
 130          $this->_resetReadHandle();
 131      }
 132  
 133      /** Not used */
 134      protected function _flush()
 135      {
 136      }
 137  
 138      /** Get the resource for reading */
 139      private function _getReadHandle()
 140      {
 141          if (!isset($this->_reader)) {
 142              if (!$this->_reader = fopen($this->_path, 'rb')) {
 143                  throw new Swift_IoException(
 144                      'Unable to open file for reading ['.$this->_path.']'
 145                  );
 146              }
 147              if ($this->_offset != 0) {
 148                  $this->_getReadStreamSeekableStatus();
 149                  $this->_seekReadStreamToPosition($this->_offset);
 150              }
 151          }
 152  
 153          return $this->_reader;
 154      }
 155  
 156      /** Get the resource for writing */
 157      private function _getWriteHandle()
 158      {
 159          if (!isset($this->_writer)) {
 160              if (!$this->_writer = fopen($this->_path, $this->_mode)) {
 161                  throw new Swift_IoException(
 162                      'Unable to open file for writing ['.$this->_path.']'
 163                  );
 164              }
 165          }
 166  
 167          return $this->_writer;
 168      }
 169  
 170      /** Force a reload of the resource for reading */
 171      private function _resetReadHandle()
 172      {
 173          if (isset($this->_reader)) {
 174              fclose($this->_reader);
 175              $this->_reader = null;
 176          }
 177      }
 178  
 179      /** Check if ReadOnly Stream is seekable */
 180      private function _getReadStreamSeekableStatus()
 181      {
 182          $metas = stream_get_meta_data($this->_reader);
 183          $this->_seekable = $metas['seekable'];
 184      }
 185  
 186      /** Streams in a readOnly stream ensuring copy if needed */
 187      private function _seekReadStreamToPosition($offset)
 188      {
 189          if ($this->_seekable === null) {
 190              $this->_getReadStreamSeekableStatus();
 191          }
 192          if ($this->_seekable === false) {
 193              $currentPos = ftell($this->_reader);
 194              if ($currentPos < $offset) {
 195                  $toDiscard = $offset - $currentPos;
 196                  fread($this->_reader, $toDiscard);
 197  
 198                  return;
 199              }
 200              $this->_copyReadStream();
 201          }
 202          fseek($this->_reader, $offset, SEEK_SET);
 203      }
 204  
 205      /** Copy a readOnly Stream to ensure seekability */
 206      private function _copyReadStream()
 207      {
 208          if ($tmpFile = fopen('php://temp/maxmemory:4096', 'w+b')) {
 209              /* We have opened a php:// Stream Should work without problem */
 210          } elseif (function_exists('sys_get_temp_dir') && is_writable(sys_get_temp_dir()) && ($tmpFile = tmpfile())) {
 211              /* We have opened a tmpfile */
 212          } else {
 213              throw new Swift_IoException('Unable to copy the file to make it seekable, sys_temp_dir is not writable, php://memory not available');
 214          }
 215          $currentPos = ftell($this->_reader);
 216          fclose($this->_reader);
 217          $source = fopen($this->_path, 'rb');
 218          if (!$source) {
 219              throw new Swift_IoException('Unable to open file for copying ['.$this->_path.']');
 220          }
 221          fseek($tmpFile, 0, SEEK_SET);
 222          while (!feof($source)) {
 223              fwrite($tmpFile, fread($source, 4096));
 224          }
 225          fseek($tmpFile, $currentPos, SEEK_SET);
 226          fclose($source);
 227          $this->_reader = $tmpFile;
 228      }
 229  }


Generated: Thu Apr 28 18:38:52 2016 Cross-referenced by PHPXref 0.7.1