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