TYPO3 API  SVNRelease
LoadBalancedTransport.php
Go to the documentation of this file.
00001 <?php
00002 
00003 /*
00004  * This file is part of SwiftMailer.
00005  * (c) 2004-2009 Chris Corbyn
00006  *
00007  * For the full copyright and license information, please view the LICENSE
00008  * file that was distributed with this source code.
00009  */
00010 
00011 //@require 'Swift/Transport.php';
00012 //@require 'Swift/Mime/Message.php';
00013 //@require 'Swift/Events/EventListener.php';
00014 
00015 /**
00016  * Redudantly and rotationally uses several Transports when sending.
00017  *
00018  * @package Swift
00019  * @subpackage Transport
00020  * @author Chris Corbyn
00021  */
00022 class Swift_Transport_LoadBalancedTransport implements Swift_Transport
00023 {
00024 
00025   /** Transports which are deemed useless */
00026   private $_deadTransports = array();
00027 
00028   /**
00029    * The Transports which are used in rotation.
00030    *
00031    * @var array Swift_Transport
00032    * @access protected
00033    */
00034   protected $_transports = array();
00035 
00036   /**
00037    * Creates a new LoadBalancedTransport.
00038    */
00039   public function __construct()
00040   {
00041   }
00042 
00043   /**
00044    * Set $transports to delegate to.
00045    *
00046    * @param array $transports Swift_Transport
00047    */
00048   public function setTransports(array $transports)
00049   {
00050     $this->_transports = $transports;
00051     $this->_deadTransports = array();
00052   }
00053 
00054   /**
00055    * Get $transports to delegate to.
00056    *
00057    * @return array Swift_Transport
00058    */
00059   public function getTransports(array $transports)
00060   {
00061     return array_merge($this->_transports, $this->_deadTransports);
00062   }
00063 
00064   /**
00065    * Test if this Transport mechanism has started.
00066    *
00067    * @return boolean
00068    */
00069   public function isStarted()
00070   {
00071     return count($this->_transports) > 0;
00072   }
00073 
00074   /**
00075    * Start this Transport mechanism.
00076    */
00077   public function start()
00078   {
00079     $this->_transports = array_merge($this->_transports, $this->_deadTransports);
00080   }
00081 
00082   /**
00083    * Stop this Transport mechanism.
00084    */
00085   public function stop()
00086   {
00087     foreach ($this->_transports as $transport)
00088     {
00089       $transport->stop();
00090     }
00091   }
00092 
00093   /**
00094    * Send the given Message.
00095    *
00096    * Recipient/sender data will be retreived from the Message API.
00097    * The return value is the number of recipients who were accepted for delivery.
00098    *
00099    * @param Swift_Mime_Message $message
00100    * @param string[] &$failedRecipients to collect failures by-reference
00101    * @return int
00102    */
00103   public function send(Swift_Mime_Message $message, &$failedRecipients = null)
00104   {
00105     $maxTransports = count($this->_transports);
00106     $sent = 0;
00107 
00108     for ($i = 0; $i < $maxTransports
00109       && $transport = $this->_getNextTransport(); ++$i)
00110     {
00111       try
00112       {
00113         if (!$transport->isStarted())
00114         {
00115           $transport->start();
00116         }
00117         if ($sent = $transport->send($message, $failedRecipients))
00118         {
00119           break;
00120         }
00121       }
00122       catch (Swift_TransportException $e)
00123       {
00124         $this->_killCurrentTransport();
00125       }
00126     }
00127 
00128     if (count($this->_transports) == 0)
00129     {
00130       throw new Swift_TransportException(
00131         'All Transports in LoadBalancedTransport failed, or no Transports available'
00132         );
00133     }
00134 
00135     return $sent;
00136   }
00137 
00138   /**
00139    * Register a plugin.
00140    *
00141    * @param Swift_Events_EventListener $plugin
00142    */
00143   public function registerPlugin(Swift_Events_EventListener $plugin)
00144   {
00145     foreach ($this->_transports as $transport)
00146     {
00147       $transport->registerPlugin($plugin);
00148     }
00149   }
00150 
00151   // -- Protected methods
00152 
00153   /**
00154    * Rotates the transport list around and returns the first instance.
00155    *
00156    * @return Swift_Transport
00157    * @access protected
00158    */
00159   protected function _getNextTransport()
00160   {
00161     if ($next = array_shift($this->_transports))
00162     {
00163       $this->_transports[] = $next;
00164     }
00165     return $next;
00166   }
00167 
00168   /**
00169    * Tag the currently used (top of stack) transport as dead/useless.
00170    *
00171    * @access protected
00172    */
00173   protected function _killCurrentTransport()
00174   {
00175     if ($transport = array_pop($this->_transports))
00176     {
00177       try
00178       {
00179         $transport->stop();
00180       }
00181       catch (Exception $e)
00182       {
00183       }
00184       $this->_deadTransports[] = $transport;
00185     }
00186   }
00187 
00188 }