[ Index ]

MailPress 544

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

title

Body

[close]

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

   1  <?php
   2  
   3  /*
   4   * This file is part of SwiftMailer.
   5   * (c) 2009 Fabien Potencier <fabien.potencier@gmail.com>
   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   * Stores Messages on the filesystem.
  13   *
  14   * @author Fabien Potencier
  15   * @author Xavier De Cock <xdecock@gmail.com>
  16   */
  17  class Swift_FileSpool extends Swift_ConfigurableSpool
  18  {
  19      /** The spool directory */
  20      private $_path;
  21  
  22      /**
  23       * File WriteRetry Limit.
  24       *
  25       * @var int
  26       */
  27      private $_retryLimit = 10;
  28  
  29      /**
  30       * Create a new FileSpool.
  31       *
  32       * @param string $path
  33       *
  34       * @throws Swift_IoException
  35       */
  36      public function __construct($path)
  37      {
  38          $this->_path = $path;
  39  
  40          if (!file_exists($this->_path)) {
  41              if (!mkdir($this->_path, 0777, true)) {
  42                  throw new Swift_IoException('Unable to create Path ['.$this->_path.']');
  43              }
  44          }
  45      }
  46  
  47      /**
  48       * Tests if this Spool mechanism has started.
  49       *
  50       * @return bool
  51       */
  52      public function isStarted()
  53      {
  54          return true;
  55      }
  56  
  57      /**
  58       * Starts this Spool mechanism.
  59       */
  60      public function start()
  61      {
  62      }
  63  
  64      /**
  65       * Stops this Spool mechanism.
  66       */
  67      public function stop()
  68      {
  69      }
  70  
  71      /**
  72       * Allow to manage the enqueuing retry limit.
  73       *
  74       * Default, is ten and allows over 64^20 different fileNames
  75       *
  76       * @param int $limit
  77       */
  78      public function setRetryLimit($limit)
  79      {
  80          $this->_retryLimit = $limit;
  81      }
  82  
  83      /**
  84       * Queues a message.
  85       *
  86       * @param Swift_Mime_Message $message The message to store
  87       *
  88       * @throws Swift_IoException
  89       *
  90       * @return bool
  91       */
  92      public function queueMessage(Swift_Mime_Message $message)
  93      {
  94          $ser = serialize($message);
  95          $fileName = $this->_path.'/'.$this->getRandomString(10);
  96          for ($i = 0; $i < $this->_retryLimit; ++$i) {
  97              /* We try an exclusive creation of the file. This is an atomic operation, it avoid locking mechanism */
  98              $fp = @fopen($fileName.'.message', 'x');
  99              if (false !== $fp) {
 100                  if (false === fwrite($fp, $ser)) {
 101                      return false;
 102                  }
 103  
 104                  return fclose($fp);
 105              } else {
 106                  /* The file already exists, we try a longer fileName */
 107                  $fileName .= $this->getRandomString(1);
 108              }
 109          }
 110  
 111          throw new Swift_IoException('Unable to create a file for enqueuing Message');
 112      }
 113  
 114      /**
 115       * Execute a recovery if for any reason a process is sending for too long.
 116       *
 117       * @param int $timeout in second Defaults is for very slow smtp responses
 118       */
 119      public function recover($timeout = 900)
 120      {
 121          foreach (new DirectoryIterator($this->_path) as $file) {
 122              $file = $file->getRealPath();
 123  
 124              if (substr($file, -16) == '.message.sending') {
 125                  $lockedtime = filectime($file);
 126                  if ((time() - $lockedtime) > $timeout) {
 127                      rename($file, substr($file, 0, -8));
 128                  }
 129              }
 130          }
 131      }
 132  
 133      /**
 134       * Sends messages using the given transport instance.
 135       *
 136       * @param Swift_Transport $transport        A transport instance
 137       * @param string[]        $failedRecipients An array of failures by-reference
 138       *
 139       * @return int The number of sent e-mail's
 140       */
 141      public function flushQueue(Swift_Transport $transport, &$failedRecipients = null)
 142      {
 143          $directoryIterator = new DirectoryIterator($this->_path);
 144  
 145          /* Start the transport only if there are queued files to send */
 146          if (!$transport->isStarted()) {
 147              foreach ($directoryIterator as $file) {
 148                  if (substr($file->getRealPath(), -8) == '.message') {
 149                      $transport->start();
 150                      break;
 151                  }
 152              }
 153          }
 154  
 155          $failedRecipients = (array) $failedRecipients;
 156          $count = 0;
 157          $time = time();
 158          foreach ($directoryIterator as $file) {
 159              $file = $file->getRealPath();
 160  
 161              if (substr($file, -8) != '.message') {
 162                  continue;
 163              }
 164  
 165              /* We try a rename, it's an atomic operation, and avoid locking the file */
 166              if (rename($file, $file.'.sending')) {
 167                  $message = unserialize(file_get_contents($file.'.sending'));
 168  
 169                  $count += $transport->send($message, $failedRecipients);
 170  
 171                  unlink($file.'.sending');
 172              } else {
 173                  /* This message has just been catched by another process */
 174                  continue;
 175              }
 176  
 177              if ($this->getMessageLimit() && $count >= $this->getMessageLimit()) {
 178                  break;
 179              }
 180  
 181              if ($this->getTimeLimit() && (time() - $time) >= $this->getTimeLimit()) {
 182                  break;
 183              }
 184          }
 185  
 186          return $count;
 187      }
 188  
 189      /**
 190       * Returns a random string needed to generate a fileName for the queue.
 191       *
 192       * @param int $count
 193       *
 194       * @return string
 195       */
 196      protected function getRandomString($count)
 197      {
 198          // This string MUST stay FS safe, avoid special chars
 199          $base = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-';
 200          $ret = '';
 201          $strlen = strlen($base);
 202          for ($i = 0; $i < $count; ++$i) {
 203              $ret .= $base[((int) rand(0, $strlen - 1))];
 204          }
 205  
 206          return $ret;
 207      }
 208  }


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