/framework/vendor/swift/lib/classes/Swift/Plugins/PopBeforeSmtpPlugin.php
PHP | 288 lines | 160 code | 38 blank | 90 comment | 14 complexity | 5661bc27faa15b2d3a3e3b1b63398078 MD5 | raw file
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/Events/TransportChangeListener.php'; 12//@require 'Swift/Events/TransportChangeEvent.php'; 13 14/** 15 * Makes sure a connection to a POP3 host has been established prior to connecting to SMTP. 16 * 17 * @package Swift 18 * @subpackage Plugins 19 * 20 * @author Chris Corbyn 21 */ 22class Swift_Plugins_PopBeforeSmtpPlugin 23 implements Swift_Events_TransportChangeListener, Swift_Plugins_Pop_Pop3Connection 24{ 25 26 /** A delegate connection to use (mostly a test hook) */ 27 private $_connection; 28 29 /** Hostname of the POP3 server */ 30 private $_host; 31 32 /** Port number to connect on */ 33 private $_port; 34 35 /** Encryption type to use (if any) */ 36 private $_crypto; 37 38 /** Username to use (if any) */ 39 private $_username; 40 41 /** Password to use (if any) */ 42 private $_password; 43 44 /** Established connection via TCP socket */ 45 private $_socket; 46 47 /** Connect timeout in seconds */ 48 private $_timeout = 10; 49 50 /** SMTP Transport to bind to */ 51 private $_transport; 52 53 /** 54 * Create a new PopBeforeSmtpPlugin for $host and $port. 55 * 56 * @param string $host 57 * @param int $port 58 * @param string $cypto as "tls" or "ssl" 59 */ 60 public function __construct($host, $port = 110, $crypto = null) 61 { 62 $this->_host = $host; 63 $this->_port = $port; 64 $this->_crypto = $crypto; 65 } 66 67 /** 68 * Create a new PopBeforeSmtpPlugin for $host and $port. 69 * 70 * @param string $host 71 * @param int $port 72 * @param string $cypto as "tls" or "ssl" 73 * 74 * @return Swift_Plugins_PopBeforeSmtpPlugin 75 */ 76 public static function newInstance($host, $port = 110, $crypto = null) 77 { 78 return new self($host, $port, $crypto); 79 } 80 81 /** 82 * Set a Pop3Connection to delegate to instead of connecting directly. 83 * 84 * @param Swift_Plugins_Pop_Pop3Connection $connection 85 */ 86 public function setConnection(Swift_Plugins_Pop_Pop3Connection $connection) 87 { 88 $this->_connection = $connection; 89 return $this; 90 } 91 92 /** 93 * Bind this plugin to a specific SMTP transport instance. 94 * 95 * @param Swift_Transport 96 */ 97 public function bindSmtp(Swift_Transport $smtp) 98 { 99 $this->_transport = $smtp; 100 } 101 102 /** 103 * Set the connection timeout in seconds (default 10). 104 * 105 * @param int $timeout 106 */ 107 public function setTimeout($timeout) 108 { 109 $this->_timeout = (int) $timeout; 110 return $this; 111 } 112 113 /** 114 * Set the username to use when connecting (if needed). 115 * 116 * @param string $username 117 */ 118 public function setUsername($username) 119 { 120 $this->_username = $username; 121 return $this; 122 } 123 124 /** 125 * Set the password to use when connecting (if needed). 126 * 127 * @param string $password 128 */ 129 public function setPassword($password) 130 { 131 $this->_password = $password; 132 return $this; 133 } 134 135 /** 136 * Connect to the POP3 host and authenticate. 137 * 138 * @throws Swift_Plugins_Pop_Pop3Exception if connection fails 139 */ 140 public function connect() 141 { 142 if (isset($this->_connection)) 143 { 144 $this->_connection->connect(); 145 } 146 else 147 { 148 if (!isset($this->_socket)) 149 { 150 if (!$socket = fsockopen( 151 $this->_getHostString(), $this->_port, $errno, $errstr, $this->_timeout)) 152 { 153 throw new Swift_Plugins_Pop_Pop3Exception( 154 sprintf('Failed to connect to POP3 host [%s]: %s', $this->_host, $errstr) 155 ); 156 } 157 $this->_socket = $socket; 158 159 if (false === $greeting = fgets($this->_socket)) 160 { 161 throw new Swift_Plugins_Pop_Pop3Exception( 162 sprintf('Failed to connect to POP3 host [%s]', trim($greeting)) 163 ); 164 } 165 166 $this->_assertOk($greeting); 167 168 if ($this->_username) 169 { 170 $this->_command(sprintf("USER %s\r\n", $this->_username)); 171 $this->_command(sprintf("PASS %s\r\n", $this->_password)); 172 } 173 } 174 } 175 } 176 177 /** 178 * Disconnect from the POP3 host. 179 */ 180 public function disconnect() 181 { 182 if (isset($this->_connection)) 183 { 184 $this->_connection->disconnect(); 185 } 186 else 187 { 188 $this->_command("QUIT\r\n"); 189 if (!fclose($this->_socket)) 190 { 191 throw new Swift_Plugins_Pop_Pop3Exception( 192 sprintf('POP3 host [%s] connection could not be stopped', $this->_host) 193 ); 194 } 195 $this->_socket = null; 196 } 197 } 198 199 /** 200 * Invoked just before a Transport is started. 201 * 202 * @param Swift_Events_TransportChangeEvent $evt 203 */ 204 public function beforeTransportStarted(Swift_Events_TransportChangeEvent $evt) 205 { 206 if (isset($this->_transport)) 207 { 208 if ($this->_transport !== $evt->getTransport()) 209 { 210 return; 211 } 212 } 213 214 $this->connect(); 215 $this->disconnect(); 216 } 217 218 /** 219 * Not used. 220 */ 221 public function transportStarted(Swift_Events_TransportChangeEvent $evt) 222 { 223 } 224 225 /** 226 * Not used. 227 */ 228 public function beforeTransportStopped(Swift_Events_TransportChangeEvent $evt) 229 { 230 } 231 232 /** 233 * Not used. 234 */ 235 public function transportStopped(Swift_Events_TransportChangeEvent $evt) 236 { 237 } 238 239 // -- Private Methods 240 241 private function _command($command) 242 { 243 if (!fwrite($this->_socket, $command)) 244 { 245 throw new Swift_Plugins_Pop_Pop3Exception( 246 sprintf('Failed to write command [%s] to POP3 host', trim($command)) 247 ); 248 } 249 250 if (false === $response = fgets($this->_socket)) 251 { 252 throw new Swift_Plugins_Pop_Pop3Exception( 253 sprintf('Failed to read from POP3 host after command [%s]', trim($command)) 254 ); 255 } 256 257 $this->_assertOk($response); 258 259 return $response; 260 } 261 262 private function _assertOk($response) 263 { 264 if (substr($response, 0, 3) != '+OK') 265 { 266 throw new Swift_Plugins_Pop_Pop3Exception( 267 sprintf('POP3 command failed [%s]', trim($response)) 268 ); 269 } 270 } 271 272 private function _getHostString() 273 { 274 $host = $this->_host; 275 switch (strtolower($this->_crypto)) 276 { 277 case 'ssl': 278 $host = 'ssl://' . $host; 279 break; 280 281 case 'tls': 282 $host = 'tls://' . $host; 283 break; 284 } 285 return $host; 286 } 287 288}