1<?php 2 3/** 4 * Swift Mailer Multiple Redundant Connection component. 5 * Please read the LICENSE file 6 * @author Chris Corbyn <chris@w3style.co.uk> 7 * @package Swift_Connection 8 * @license GNU Lesser General Public License 9 */ 10 11require_once dirname(__FILE__) . "/../ClassLoader.php"; 12Swift_ClassLoader::load("Swift_ConnectionBase"); 13 14/** 15 * Swift Multi Connection 16 * Tries to connect to a number of connections until one works successfully 17 * @package Swift_Connection 18 * @author Chris Corbyn <chris@w3style.co.uk> 19 */ 20class Swift_Connection_Multi extends Swift_ConnectionBase 21{ 22 /** 23 * The list of available connections 24 * @var array 25 */ 26 protected $connections = array(); 27 /** 28 * The id of the active connection 29 * @var string 30 */ 31 protected $active = null; 32 33 /** 34 * Constructor 35 */ 36 public function __construct($connections=array()) 37 { 38 foreach ($connections as $id => $conn) 39 { 40 $this->addConnection($connections[$id], $id); 41 } 42 } 43 /** 44 * Add a connection to the list of options 45 * @param Swift_Connection An instance of the connection 46 * @param string An ID to assign to the connection 47 */ 48 public function addConnection(Swift_Connection $connection, $id=null) 49 { 50 $log = Swift_LogContainer::getLog(); 51 if ($log->hasLevel(Swift_Log::LOG_EVERYTHING)) 52 { 53 $log->add("Adding new connection of type '" . get_class($connection) . "' to the multi-redundant connection."); 54 } 55 if ($id !== null) $this->connections[$id] = $connection; 56 else $this->connections[] = $connection; 57 } 58 /** 59 * Read a full response from the buffer 60 * @return string 61 * @throws Swift_ConnectionException Upon failure to read 62 */ 63 public function read() 64 { 65 if ($this->active === null) 66 { 67 throw new Swift_ConnectionException("None of the connections set have been started"); 68 } 69 return $this->connections[$this->active]->read(); 70 } 71 /** 72 * Write a command to the server (leave off trailing CRLF) 73 * @param string The command to send 74 * @throws Swift_ConnectionException Upon failure to write 75 */ 76 public function write($command, $end="\r\n") 77 { 78 if ($this->active === null) 79 { 80 throw new Swift_ConnectionException("None of the connections set have been started"); 81 } 82 return $this->connections[$this->active]->write($command, $end); 83 } 84 /** 85 * Try to start the connection 86 * @throws Swift_ConnectionException Upon failure to start 87 */ 88 public function start() 89 { 90 $log = Swift_LogContainer::getLog(); 91 $fail_messages = array(); 92 foreach ($this->connections as $id => $conn) 93 { 94 try { 95 $this->connections[$id]->start(); 96 if ($this->connections[$id]->isAlive()) 97 { 98 $this->active = $id; 99 return true; 100 } 101 else 102 { 103 if ($log->hasLevel(Swift_Log::LOG_EVERYTHING)) 104 { 105 $log->add("Connection (" . $id . ") failed. Will try next connection if available."); 106 } 107 throw new Swift_ConnectionException("The connection started but reported that it was not active"); 108 } 109 } catch (Swift_ConnectionException $e) { 110 $fail_messages[] = $id . ": " . $e->getMessage(); 111 } 112 } 113 $failure = implode("<br />", $fail_messages); 114 throw new Swift_ConnectionException($failure); 115 } 116 /** 117 * Try to close the connection 118 * @throws Swift_ConnectionException Upon failure to close 119 */ 120 public function stop() 121 { 122 if ($this->active !== null) $this->connections[$this->active]->stop(); 123 $this->active = null; 124 } 125 /** 126 * Check if the current connection is alive 127 * @return boolean 128 */ 129 public function isAlive() 130 { 131 return (($this->active !== null) && $this->connections[$this->active]->isAlive()); 132 } 133 /** 134 * Call the current connection's postConnect() method 135 */ 136 public function postConnect(Swift $instance) 137 { 138 $this->connections[$this->active]->postConnect($instance); 139 } 140 /** 141 * Call the current connection's setExtension() method 142 */ 143 public function setExtension($extension, $attributes=array()) 144 { 145 $this->connections[$this->active]->setExtension($extension, $attributes); 146 } 147 /** 148 * Call the current connection's hasExtension() method 149 */ 150 public function hasExtension($name) 151 { 152 return $this->connections[$this->active]->hasExtension($name); 153 } 154 /** 155 * Call the current connection's getAttributes() method 156 */ 157 public function getAttributes($name) 158 { 159 return $this->connections[$this->active]->getAttributes($name); 160 } 161} 162