PageRenderTime 38ms CodeModel.GetById 12ms app.highlight 18ms RepoModel.GetById 2ms app.codeStats 0ms

/framework/vendor/swift/lib/classes/Swift/Plugins/PopBeforeSmtpPlugin.php

http://zoop.googlecode.com/
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}