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