vendor/swiftmailer/lib/classes/Swift/Transport/LoadBalancedTransport.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  * Redudantly and rotationally uses several Transports when sending.
       
    14  * 
       
    15  * @package Swift
       
    16  * @subpackage Transport
       
    17  * @author Chris Corbyn
       
    18  */
       
    19 class Swift_Transport_LoadBalancedTransport implements Swift_Transport
       
    20 {
       
    21   
       
    22   /** Transports which are deemed useless */
       
    23   private $_deadTransports = array();
       
    24   
       
    25   /**
       
    26    * The Transports which are used in rotation.
       
    27    * 
       
    28    * @var array Swift_Transport
       
    29    * @access protected
       
    30    */
       
    31   protected $_transports = array();
       
    32   
       
    33   /**
       
    34    * Creates a new LoadBalancedTransport.
       
    35    */
       
    36   public function __construct()
       
    37   {
       
    38   }
       
    39   
       
    40   /**
       
    41    * Set $transports to delegate to.
       
    42    * 
       
    43    * @param array $transports Swift_Transport
       
    44    */
       
    45   public function setTransports(array $transports)
       
    46   {
       
    47     $this->_transports = $transports;
       
    48     $this->_deadTransports = array();
       
    49   }
       
    50   
       
    51   /**
       
    52    * Get $transports to delegate to.
       
    53    * 
       
    54    * @return array Swift_Transport
       
    55    */
       
    56   public function getTransports(array $transports)
       
    57   {
       
    58     return array_merge($this->_transports, $this->_deadTransports);
       
    59   }
       
    60   
       
    61   /**
       
    62    * Test if this Transport mechanism has started.
       
    63    * 
       
    64    * @return boolean
       
    65    */
       
    66   public function isStarted()
       
    67   {
       
    68     return count($this->_transports) > 0;
       
    69   }
       
    70   
       
    71   /**
       
    72    * Start this Transport mechanism.
       
    73    */
       
    74   public function start()
       
    75   {
       
    76     $this->_transports = array_merge($this->_transports, $this->_deadTransports);
       
    77   }
       
    78   
       
    79   /**
       
    80    * Stop this Transport mechanism.
       
    81    */
       
    82   public function stop()
       
    83   {
       
    84     foreach ($this->_transports as $transport)
       
    85     {
       
    86       $transport->stop();
       
    87     }
       
    88   }
       
    89   
       
    90   /**
       
    91    * Send the given Message.
       
    92    * 
       
    93    * Recipient/sender data will be retreived from the Message API.
       
    94    * The return value is the number of recipients who were accepted for delivery.
       
    95    * 
       
    96    * @param Swift_Mime_Message $message
       
    97    * @param string[] &$failedRecipients to collect failures by-reference
       
    98    * @return int
       
    99    */
       
   100   public function send(Swift_Mime_Message $message, &$failedRecipients = null)
       
   101   {
       
   102     $maxTransports = count($this->_transports);
       
   103     $sent = 0;
       
   104     
       
   105     for ($i = 0; $i < $maxTransports
       
   106       && $transport = $this->_getNextTransport(); ++$i)
       
   107     {
       
   108       try
       
   109       {
       
   110         if (!$transport->isStarted())
       
   111         {
       
   112           $transport->start();
       
   113         }
       
   114         if ($sent = $transport->send($message, $failedRecipients))
       
   115         {
       
   116           break;
       
   117         }
       
   118       }
       
   119       catch (Swift_TransportException $e)
       
   120       {
       
   121         $this->_killCurrentTransport();
       
   122       }
       
   123     }
       
   124     
       
   125     if (count($this->_transports) == 0)
       
   126     {
       
   127       throw new Swift_TransportException(
       
   128         'All Transports in LoadBalancedTransport failed, or no Transports available'
       
   129         );
       
   130     }
       
   131     
       
   132     return $sent;
       
   133   }
       
   134   
       
   135   /**
       
   136    * Register a plugin.
       
   137    * 
       
   138    * @param Swift_Events_EventListener $plugin
       
   139    */
       
   140   public function registerPlugin(Swift_Events_EventListener $plugin)
       
   141   {
       
   142     foreach ($this->_transports as $transport)
       
   143     {
       
   144       $transport->registerPlugin($plugin);
       
   145     }
       
   146   }
       
   147   
       
   148   // -- Protected methods
       
   149   
       
   150   /**
       
   151    * Rotates the transport list around and returns the first instance.
       
   152    * 
       
   153    * @return Swift_Transport
       
   154    * @access protected
       
   155    */
       
   156   protected function _getNextTransport()
       
   157   {
       
   158     if ($next = array_shift($this->_transports))
       
   159     {
       
   160       $this->_transports[] = $next;
       
   161     }
       
   162     return $next;
       
   163   }
       
   164   
       
   165   /**
       
   166    * Tag the currently used (top of stack) transport as dead/useless.
       
   167    * 
       
   168    * @access protected
       
   169    */
       
   170   protected function _killCurrentTransport()
       
   171   {
       
   172     if ($transport = array_pop($this->_transports))
       
   173     {
       
   174       try
       
   175       {
       
   176         $transport->stop();
       
   177       }
       
   178       catch (Exception $e)
       
   179       {
       
   180       }
       
   181       $this->_deadTransports[] = $transport;
       
   182     }
       
   183   }
       
   184   
       
   185 }