vendor/swiftmailer/lib/classes/Swift/KeyCache/DiskKeyCache.php
changeset 0 7f95f8617b0b
equal deleted inserted replaced
-1:000000000000 0:7f95f8617b0b
       
     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 /**
       
    13  * A KeyCache which streams to and from disk.
       
    14  * @package Swift
       
    15  * @subpackage KeyCache
       
    16  * @author Chris Corbyn
       
    17  */
       
    18 class Swift_KeyCache_DiskKeyCache implements Swift_KeyCache
       
    19 {
       
    20 
       
    21   /** Signal to place pointer at start of file */
       
    22   const POSITION_START = 0;
       
    23 
       
    24   /** Signal to place pointer at end of file */
       
    25   const POSITION_END = 1;
       
    26   
       
    27   /** Signal to leave pointer in whatever position it currently is */
       
    28   const POSITION_CURRENT = 2;
       
    29 
       
    30   /**
       
    31    * An InputStream for cloning.
       
    32    * @var Swift_KeyCache_KeyCacheInputStream
       
    33    * @access private
       
    34    */
       
    35   private $_stream;
       
    36 
       
    37   /**
       
    38    * A path to write to.
       
    39    * @var string
       
    40    * @access private
       
    41    */
       
    42   private $_path;
       
    43 
       
    44   /**
       
    45    * Stored keys.
       
    46    * @var array
       
    47    * @access private
       
    48    */
       
    49   private $_keys = array();
       
    50 
       
    51   /**
       
    52    * Will be true if magic_quotes_runtime is turned on.
       
    53    * @var boolean
       
    54    * @access private
       
    55    */
       
    56   private $_quotes = false;
       
    57 
       
    58   /**
       
    59    * Create a new DiskKeyCache with the given $stream for cloning to make
       
    60    * InputByteStreams, and the given $path to save to.
       
    61    * @param Swift_KeyCache_KeyCacheInputStream $stream
       
    62    * @param string $path to save to
       
    63    */
       
    64   public function __construct(Swift_KeyCache_KeyCacheInputStream $stream, $path)
       
    65   {
       
    66     $this->_stream = $stream;
       
    67     $this->_path = $path;
       
    68     $this->_quotes = ini_get('magic_quotes_runtime');
       
    69   }
       
    70 
       
    71   /**
       
    72    * Set a string into the cache under $itemKey for the namespace $nsKey.
       
    73    * @param string $nsKey
       
    74    * @param string $itemKey
       
    75    * @param string $string
       
    76    * @param int $mode
       
    77    * @throws Swift_IoException
       
    78    * @see MODE_WRITE, MODE_APPEND
       
    79    */
       
    80   public function setString($nsKey, $itemKey, $string, $mode)
       
    81   {
       
    82     $this->_prepareCache($nsKey);
       
    83     switch ($mode)
       
    84     {
       
    85       case self::MODE_WRITE:
       
    86         $fp = $this->_getHandle($nsKey, $itemKey, self::POSITION_START);
       
    87         break;
       
    88       case self::MODE_APPEND:
       
    89         $fp = $this->_getHandle($nsKey, $itemKey, self::POSITION_END);
       
    90         break;
       
    91       default:
       
    92         throw new Swift_SwiftException(
       
    93           'Invalid mode [' . $mode . '] used to set nsKey='.
       
    94           $nsKey . ', itemKey=' . $itemKey
       
    95           );
       
    96         break;
       
    97     }
       
    98     fwrite($fp, $string);
       
    99     $this->_freeHandle($nsKey, $itemKey);
       
   100   }
       
   101 
       
   102   /**
       
   103    * Set a ByteStream into the cache under $itemKey for the namespace $nsKey.
       
   104    * @param string $nsKey
       
   105    * @param string $itemKey
       
   106    * @param Swift_OutputByteStream $os
       
   107    * @param int $mode
       
   108    * @see MODE_WRITE, MODE_APPEND
       
   109    * @throws Swift_IoException
       
   110    */
       
   111   public function importFromByteStream($nsKey, $itemKey, Swift_OutputByteStream $os,
       
   112     $mode)
       
   113   {
       
   114     $this->_prepareCache($nsKey);
       
   115     switch ($mode)
       
   116     {
       
   117       case self::MODE_WRITE:
       
   118         $fp = $this->_getHandle($nsKey, $itemKey, self::POSITION_START);
       
   119         break;
       
   120       case self::MODE_APPEND:
       
   121         $fp = $this->_getHandle($nsKey, $itemKey, self::POSITION_END);
       
   122         break;
       
   123       default:
       
   124         throw new Swift_SwiftException(
       
   125           'Invalid mode [' . $mode . '] used to set nsKey='.
       
   126           $nsKey . ', itemKey=' . $itemKey
       
   127           );
       
   128         break;
       
   129     }
       
   130     while (false !== $bytes = $os->read(8192))
       
   131     {
       
   132       fwrite($fp, $bytes);
       
   133     }
       
   134     $this->_freeHandle($nsKey, $itemKey);
       
   135   }
       
   136 
       
   137   /**
       
   138    * Provides a ByteStream which when written to, writes data to $itemKey.
       
   139    * NOTE: The stream will always write in append mode.
       
   140    * @param string $nsKey
       
   141    * @param string $itemKey
       
   142    * @return Swift_InputByteStream
       
   143    */
       
   144   public function getInputByteStream($nsKey, $itemKey,
       
   145     Swift_InputByteStream $writeThrough = null)
       
   146   {
       
   147     $is = clone $this->_stream;
       
   148     $is->setKeyCache($this);
       
   149     $is->setNsKey($nsKey);
       
   150     $is->setItemKey($itemKey);
       
   151     if (isset($writeThrough))
       
   152     {
       
   153       $is->setWriteThroughStream($writeThrough);
       
   154     }
       
   155     return $is;
       
   156   }
       
   157 
       
   158   /**
       
   159    * Get data back out of the cache as a string.
       
   160    * @param string $nsKey
       
   161    * @param string $itemKey
       
   162    * @return string
       
   163    * @throws Swift_IoException
       
   164    */
       
   165   public function getString($nsKey, $itemKey)
       
   166   {
       
   167     $this->_prepareCache($nsKey);
       
   168     if ($this->hasKey($nsKey, $itemKey))
       
   169     {
       
   170       $fp = $this->_getHandle($nsKey, $itemKey, self::POSITION_START);
       
   171       if ($this->_quotes)
       
   172       {
       
   173         ini_set('magic_quotes_runtime', 0);
       
   174       }
       
   175       $str = '';
       
   176       while (!feof($fp) && false !== $bytes = fread($fp, 8192))
       
   177       {
       
   178         $str .= $bytes;
       
   179       }
       
   180       if ($this->_quotes)
       
   181       {
       
   182         ini_set('magic_quotes_runtime', 1);
       
   183       }
       
   184       $this->_freeHandle($nsKey, $itemKey);
       
   185       return $str;
       
   186     }
       
   187   }
       
   188 
       
   189   /**
       
   190    * Get data back out of the cache as a ByteStream.
       
   191    * @param string $nsKey
       
   192    * @param string $itemKey
       
   193    * @param Swift_InputByteStream $is to write the data to
       
   194    */
       
   195   public function exportToByteStream($nsKey, $itemKey, Swift_InputByteStream $is)
       
   196   {
       
   197     if ($this->hasKey($nsKey, $itemKey))
       
   198     {
       
   199       $fp = $this->_getHandle($nsKey, $itemKey, self::POSITION_START);
       
   200       if ($this->_quotes)
       
   201       {
       
   202         ini_set('magic_quotes_runtime', 0);
       
   203       }
       
   204       while (!feof($fp) && false !== $bytes = fread($fp, 8192))
       
   205       {
       
   206         $is->write($bytes);
       
   207       }
       
   208       if ($this->_quotes)
       
   209       {
       
   210         ini_set('magic_quotes_runtime', 1);
       
   211       }
       
   212       $this->_freeHandle($nsKey, $itemKey);
       
   213     }
       
   214   }
       
   215 
       
   216   /**
       
   217    * Check if the given $itemKey exists in the namespace $nsKey.
       
   218    * @param string $nsKey
       
   219    * @param string $itemKey
       
   220    * @return boolean
       
   221    */
       
   222   public function hasKey($nsKey, $itemKey)
       
   223   {
       
   224     return is_file($this->_path . '/' . $nsKey . '/' . $itemKey);
       
   225   }
       
   226 
       
   227   /**
       
   228    * Clear data for $itemKey in the namespace $nsKey if it exists.
       
   229    * @param string $nsKey
       
   230    * @param string $itemKey
       
   231    */
       
   232   public function clearKey($nsKey, $itemKey)
       
   233   {
       
   234     if ($this->hasKey($nsKey, $itemKey))
       
   235     {
       
   236       $this->_freeHandle($nsKey, $itemKey);
       
   237       unlink($this->_path . '/' . $nsKey . '/' . $itemKey);
       
   238     }
       
   239   }
       
   240 
       
   241   /**
       
   242    * Clear all data in the namespace $nsKey if it exists.
       
   243    * @param string $nsKey
       
   244    */
       
   245   public function clearAll($nsKey)
       
   246   {
       
   247     if (array_key_exists($nsKey, $this->_keys))
       
   248     {
       
   249       foreach ($this->_keys[$nsKey] as $itemKey=>$null)
       
   250       {
       
   251         $this->clearKey($nsKey, $itemKey);
       
   252       }
       
   253       rmdir($this->_path . '/' . $nsKey);
       
   254       unset($this->_keys[$nsKey]);
       
   255     }
       
   256   }
       
   257 
       
   258   // -- Private methods
       
   259 
       
   260   /**
       
   261    * Initialize the namespace of $nsKey if needed.
       
   262    * @param string $nsKey
       
   263    * @access private
       
   264    */
       
   265   private function _prepareCache($nsKey)
       
   266   {
       
   267     $cacheDir = $this->_path . '/' . $nsKey;
       
   268     if (!is_dir($cacheDir))
       
   269     {
       
   270       if (!mkdir($cacheDir))
       
   271       {
       
   272         throw new Swift_IoException('Failed to create cache directory ' . $cacheDir);
       
   273       }
       
   274       $this->_keys[$nsKey] = array();
       
   275     }
       
   276   }
       
   277 
       
   278   /**
       
   279    * Get a file handle on the cache item.
       
   280    * @param string $nsKey
       
   281    * @param string $itemKey
       
   282    * @param int $position
       
   283    * @return resource
       
   284    * @access private
       
   285    */
       
   286   private function _getHandle($nsKey, $itemKey, $position)
       
   287   {
       
   288     if (!isset($this->_keys[$nsKey][$itemKey]))
       
   289     {
       
   290       $openMode = $this->hasKey($nsKey, $itemKey)
       
   291         ? 'r+b'
       
   292         : 'w+b'
       
   293         ;
       
   294       $fp = fopen($this->_path . '/' . $nsKey . '/' . $itemKey, $openMode);
       
   295       $this->_keys[$nsKey][$itemKey] = $fp;
       
   296     }
       
   297     if (self::POSITION_START == $position)
       
   298     {
       
   299       fseek($this->_keys[$nsKey][$itemKey], 0, SEEK_SET);
       
   300     }
       
   301     elseif (self::POSITION_END == $position)
       
   302     {
       
   303       fseek($this->_keys[$nsKey][$itemKey], 0, SEEK_END);
       
   304     }
       
   305     return $this->_keys[$nsKey][$itemKey];
       
   306   }
       
   307   
       
   308   private function _freeHandle($nsKey, $itemKey)
       
   309   {
       
   310     $fp = $this->_getHandle($nsKey, $itemKey, self::POSITION_CURRENT);
       
   311     fclose($fp);
       
   312     $this->_keys[$nsKey][$itemKey] = null;
       
   313   }
       
   314 
       
   315   /**
       
   316    * Destructor.
       
   317    */
       
   318   public function __destruct()
       
   319   {
       
   320     foreach ($this->_keys as $nsKey=>$null)
       
   321     {
       
   322       $this->clearAll($nsKey);
       
   323     }
       
   324   }
       
   325 
       
   326 }