1<?php 2 3/** 4 * Swift Mailer Rotating Connection Controller 5 * Please read the LICENSE file 6 * @author Chris Corbyn <chris@w3style.co.uk> 7 * @package Swift_Plugin 8 * @license GNU Lesser General Public License 9 */ 10 11require_once dirname(__FILE__) . "/../ClassLoader.php"; 12Swift_ClassLoader::load("Swift_Events_SendListener"); 13Swift_ClassLoader::load("Swift_Events_DisconnectListener"); 14 15/** 16 * Swift Rotating Connection Controller 17 * Invokes the nextConnection() method of Swift_Connection_Rotator upon sending a given number of messages 18 * @package Swift_Plugin 19 * @author Chris Corbyn <chris@w3style.co.uk> 20 */ 21class Swift_Plugin_ConnectionRotator implements Swift_Events_SendListener, Swift_Events_DisconnectListener 22{ 23 /** 24 * The number of emails which must be sent before the connection is rotated 25 * @var int Threshold number of emails 26 */ 27 protected $threshold = 1; 28 /** 29 * The total number of emails sent on this connection 30 * @var int 31 */ 32 protected $count = 0; 33 /** 34 * The connections we have used thus far 35 * @var array 36 */ 37 protected $used = array(); 38 /** 39 * Internal check to see if this plugin has yet been invoked 40 * @var boolean 41 */ 42 protected $called = false; 43 44 /** 45 * Constructor 46 * @param int The number of emails to send before rotating 47 */ 48 public function __construct($threshold=1) 49 { 50 $this->setThreshold($threshold); 51 } 52 /** 53 * Set the number of emails to send before a connection rotation is tried 54 * @param int Number of emails 55 */ 56 public function setThreshold($threshold) 57 { 58 $this->threshold = (int) $threshold; 59 } 60 /** 61 * Get the number of emails which must be sent before a rotation occurs 62 * @return int 63 */ 64 public function getThreshold() 65 { 66 return $this->threshold; 67 } 68 /** 69 * Swift's SendEvent listener. 70 * Invoked when Swift sends a message 71 * @param Swift_Events_SendEvent The event information 72 * @throws Swift_ConnectionException If the connection cannot be rotated 73 */ 74 public function sendPerformed(Swift_Events_SendEvent $e) 75 { 76 if (!method_exists($e->getSwift()->connection, "nextConnection")) 77 { 78 throw new Swift_ConnectionException("The ConnectionRotator plugin cannot be used with connections other than Swift_Connection_Rotator."); 79 } 80 if (!$this->called) 81 { 82 $this->used[] = $e->getSwift()->connection->getActive(); 83 } 84 $this->count++; 85 if ($this->count >= $this->getThreshold()) 86 { 87 $e->getSwift()->connection->nextConnection(); 88 if (!in_array(($id = $e->getSwift()->connection->getActive()), $this->used)) 89 { 90 $e->getSwift()->connect(); 91 $this->used[] = $id; 92 } 93 $this->count = 0; 94 } 95 $this->called = true; 96 } 97 /** 98 * Disconnect all the other connections 99 * @param Swift_Events_DisconnectEvent The event info 100 */ 101 public function disconnectPerformed(Swift_Events_DisconnectEvent $e) 102 { 103 $active = $e->getConnection()->getActive(); 104 $e->getConnection()->nextConnection(); 105 while ($e->getConnection()->getActive() != $active) 106 { 107 $e->getSwift()->command("QUIT", 221); 108 $e->getConnection()->stop(); 109 $e->getConnection()->nextConnection(); 110 } 111 $this->used = array(); 112 } 113} 114