vendor/swiftmailer/lib/classes/Swift/Transport/LoadBalancedTransport.php
changeset 0 7f95f8617b0b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/swiftmailer/lib/classes/Swift/Transport/LoadBalancedTransport.php	Sat Sep 24 15:40:41 2011 +0200
@@ -0,0 +1,185 @@
+<?php
+
+/*
+ * This file is part of SwiftMailer.
+ * (c) 2004-2009 Chris Corbyn
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+
+/**
+ * Redudantly and rotationally uses several Transports when sending.
+ * 
+ * @package Swift
+ * @subpackage Transport
+ * @author Chris Corbyn
+ */
+class Swift_Transport_LoadBalancedTransport implements Swift_Transport
+{
+  
+  /** Transports which are deemed useless */
+  private $_deadTransports = array();
+  
+  /**
+   * The Transports which are used in rotation.
+   * 
+   * @var array Swift_Transport
+   * @access protected
+   */
+  protected $_transports = array();
+  
+  /**
+   * Creates a new LoadBalancedTransport.
+   */
+  public function __construct()
+  {
+  }
+  
+  /**
+   * Set $transports to delegate to.
+   * 
+   * @param array $transports Swift_Transport
+   */
+  public function setTransports(array $transports)
+  {
+    $this->_transports = $transports;
+    $this->_deadTransports = array();
+  }
+  
+  /**
+   * Get $transports to delegate to.
+   * 
+   * @return array Swift_Transport
+   */
+  public function getTransports(array $transports)
+  {
+    return array_merge($this->_transports, $this->_deadTransports);
+  }
+  
+  /**
+   * Test if this Transport mechanism has started.
+   * 
+   * @return boolean
+   */
+  public function isStarted()
+  {
+    return count($this->_transports) > 0;
+  }
+  
+  /**
+   * Start this Transport mechanism.
+   */
+  public function start()
+  {
+    $this->_transports = array_merge($this->_transports, $this->_deadTransports);
+  }
+  
+  /**
+   * Stop this Transport mechanism.
+   */
+  public function stop()
+  {
+    foreach ($this->_transports as $transport)
+    {
+      $transport->stop();
+    }
+  }
+  
+  /**
+   * Send the given Message.
+   * 
+   * Recipient/sender data will be retreived from the Message API.
+   * The return value is the number of recipients who were accepted for delivery.
+   * 
+   * @param Swift_Mime_Message $message
+   * @param string[] &$failedRecipients to collect failures by-reference
+   * @return int
+   */
+  public function send(Swift_Mime_Message $message, &$failedRecipients = null)
+  {
+    $maxTransports = count($this->_transports);
+    $sent = 0;
+    
+    for ($i = 0; $i < $maxTransports
+      && $transport = $this->_getNextTransport(); ++$i)
+    {
+      try
+      {
+        if (!$transport->isStarted())
+        {
+          $transport->start();
+        }
+        if ($sent = $transport->send($message, $failedRecipients))
+        {
+          break;
+        }
+      }
+      catch (Swift_TransportException $e)
+      {
+        $this->_killCurrentTransport();
+      }
+    }
+    
+    if (count($this->_transports) == 0)
+    {
+      throw new Swift_TransportException(
+        'All Transports in LoadBalancedTransport failed, or no Transports available'
+        );
+    }
+    
+    return $sent;
+  }
+  
+  /**
+   * Register a plugin.
+   * 
+   * @param Swift_Events_EventListener $plugin
+   */
+  public function registerPlugin(Swift_Events_EventListener $plugin)
+  {
+    foreach ($this->_transports as $transport)
+    {
+      $transport->registerPlugin($plugin);
+    }
+  }
+  
+  // -- Protected methods
+  
+  /**
+   * Rotates the transport list around and returns the first instance.
+   * 
+   * @return Swift_Transport
+   * @access protected
+   */
+  protected function _getNextTransport()
+  {
+    if ($next = array_shift($this->_transports))
+    {
+      $this->_transports[] = $next;
+    }
+    return $next;
+  }
+  
+  /**
+   * Tag the currently used (top of stack) transport as dead/useless.
+   * 
+   * @access protected
+   */
+  protected function _killCurrentTransport()
+  {
+    if ($transport = array_pop($this->_transports))
+    {
+      try
+      {
+        $transport->stop();
+      }
+      catch (Exception $e)
+      {
+      }
+      $this->_deadTransports[] = $transport;
+    }
+  }
+  
+}