1<?php
2
3/**
4 * Swift Mailer PopB4Smtp Pop3 Connection component
5 * Please read the LICENSE file
6 * @author Chris Corbyn <chris@w3style.co.uk>
7 * @package Swift_Authenticator
8 * @license GNU Lesser General Public License
9 */
10
11require_once dirname(__FILE__) . "/../../ClassLoader.php";
12
13/**
14 * Swift PopB4Smtp Authenticator Connection Component for the POP3 server
15 * Provides a I/O wrapper for the POP3 connection
16 * @package Swift_Authenticator
17 * @author Chris Corbyn <chris@w3style.co.uk>
18 */
19class Swift_Authenticator_PopB4Smtp_Pop3Connection
20{
21  /**
22   * Constant for no encyption
23   */
24  const ENC_OFF = 0;
25  /**
26   * Constant for SSL encryption
27   */
28  const ENC_SSL = 1;
29  /**
30   * The server to connect to (IP or FQDN)
31   * @var string
32   */
33  protected $server = null;
34  /**
35   * The port to connect to
36   * @var int
37   */
38  protected $port = null;
39  /**
40   * The open connection resource from fsockopen()
41   * @var resource
42   */
43  protected $handle = null;
44
45  /**
46   * Constructor
47   * @param string The name of the POP3 server
48   * @param int The port for the POP3 service
49   * @param int The level of encryption to use
50   */
51  public function __construct($server="localhost", $port=110, $encryption=0)
52  {
53    $this->setServer($server);
54    $this->setPort($port);
55    $this->setEncryption($encryption);
56  }
57  /**
58   * Set the server name
59   * @param string The IP or FQDN of the POP3 server
60   */
61  public function setServer($server)
62  {
63    $this->server = (string) $server;
64  }
65  /**
66   * Set the port number for the POP3 server
67   * @param int
68   */
69  public function setPort($port)
70  {
71    $this->port = (int) $port;
72  }
73  /**
74   * Get the server name
75   * @return string
76   */
77  public function getServer()
78  {
79    return $this->server;
80  }
81  /**
82   * Get the remote port number
83   * @return int
84   */
85  public function getPort()
86  {
87    return $this->port;
88  }
89  /**
90   * Set the level of enryption to use (see ENC_OFF or ENC_SSL)
91   * @param int The constant for the encryption level
92   */
93  public function setEncryption($enc)
94  {
95    $this->encryption = (int) $enc;
96  }
97  /**
98   * Get the current encryption level set (corresponds to ENC_SSL or ENC_OFF)
99   * @return int
100   */
101  public function getEncryption()
102  {
103    return $this->encryption;
104  }
105  /**
106   * Check if the response is a +OK response
107   * @throws Swift_ConnectionException Upon bad response
108   */
109  public function assertOk($line)
110  {
111    if (substr($line, 0, 3) != "+OK")
112    {
113      Swift_ClassLoader::load("Swift_ConnectionException");
114      throw new Swift_ConnectionException("The POP3 server did not suitably respond with a +OK response. " .
115      "[" . $line . "]");
116    }
117  }
118  /**
119   * Try to open the connection
120   * @throws Swift_ConnectionException If the connection will not start
121   */
122  public function start()
123  {
124    $url = $this->getServer();
125    if ($this->getEncryption() == self::ENC_SSL) $url = "ssl://" . $url;
126
127    $log = Swift_LogContainer::getLog();
128    if ($log->hasLevel(Swift_Log::LOG_NETWORK))
129    {
130      $log->add("Trying to connect to POP3 server ".$url." on port ".$this->getPort());
131    }
132
133    if ((false === $this->handle = @fsockopen($url, $this->getPort(), $errno, $errstr, 5)))
134    {
135      Swift_ClassLoader::load("Swift_ConnectionException");
136      throw new Swift_ConnectionException("The POP3 connection failed to start.  The error string returned from fsockopen() is [" . $errstr . "] #" . $errno);
137    }
138  }
139  /**
140   * Try to close the connection
141   * @throws Swift_ConnectionException If the connection won't close
142   */
143  public function stop()
144  {
145    if ($this->handle !== null)
146    {
147      if (false === fclose($this->handle))
148      {
149        Swift_ClassLoader::load("Swift_ConnectionException");
150        throw new Swift_ConnectionException("The POP3 connection did not close successfully.");
151      }
152    }
153    $this->handle = null;
154  }
155  /**
156   * Return the unread buffer contents
157   * @return string
158   * @throws Swift_ConnectionException If the connection will not allow data to be read
159   */
160  public function read()
161  {
162    if (false === $response = fgets($this->handle))
163    {
164      Swift_ClassLoader::load("Swift_ConnectionException");
165      throw new Swift_ConnectionException("Data could not be read from the POP3 connection.");
166    }
167    $response = trim($response);
168
169    $log = Swift_LogContainer::getLog();
170    if ($log->hasLevel(Swift_Log::LOG_NETWORK))
171    {
172      $log->add($response,Swift_Log::RESPONSE);
173    }
174    return $response;
175  }
176  /**
177   * Write a command to the remote socket
178   * @param string the command to send (without CRLF)
179   * @throws Swift_ConnectionException If the command cannot be written
180   */
181  public function write($command)
182  {
183    if (false === fwrite($this->handle, $command . "\r\n"))
184    {
185      Swift_ClassLoader::load("Swift_ConnectionException");
186      throw new Swift_ConnectionException("Data could not be written to the POP3 connection.");
187    }
188
189    $log = Swift_LogContainer::getLog();
190    if ($log->hasLevel(Swift_Log::LOG_NETWORK))
191    {
192      $log->add($command,Swift_Log::COMMAND);
193    }
194  }
195}
196