Copyright upgraded to 2010
[core.git] / inc / classes / third_party / php_mailer / class.pop3.php
1 <?php
2 /*~ class.pop3.php
3 .---------------------------------------------------------------------------.
4 |  Software: PHPMailer - PHP email class                                    |
5 |   Version: 2.3                                                            |
6 |   Contact: via sourceforge.net support pages (also www.codeworxtech.com)  |
7 |      Info: http://phpmailer.sourceforge.net                               |
8 |   Support: http://sourceforge.net/projects/phpmailer/                     |
9 | ------------------------------------------------------------------------- |
10 |    Author: Andy Prevost (project admininistrator)                         |
11 |    Author: Brent R. Matzelle (original founder)                           |
12 | Copyright (c) 2004-2007, Andy Prevost. All Rights Reserved.               |
13 | Copyright (c) 2001-2003, Brent R. Matzelle                                |
14 | ------------------------------------------------------------------------- |
15 |   License: Distributed under the Lesser General Public License (LGPL)     |
16 |            http://www.gnu.org/copyleft/lesser.html                        |
17 | This program is distributed in the hope that it will be useful - WITHOUT  |
18 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or     |
19 | FITNESS FOR A PARTICULAR PURPOSE.                                         |
20 | ------------------------------------------------------------------------- |
21 | We offer a number of paid services (www.codeworxtech.com):                |
22 | - Web Hosting on highly optimized fast and secure servers                 |
23 | - Technology Consulting                                                   |
24 | - Oursourcing (highly qualified programmers and graphic designers)        |
25 '---------------------------------------------------------------------------'
26
27 /**
28  * POP Before SMTP Authentication Class
29  * Version 2.3
30  *
31  * Author: Richard Davey (rich@corephp.co.uk)
32  * Modifications: Andy Prevost
33  * License: LGPL, see PHPMailer License
34  *
35  * Specifically for PHPMailer to allow POP before SMTP authentication.
36  * Does not yet work with APOP - if you have an APOP account, contact me
37  * and we can test changes to this script.
38  *
39  * This class is based on the structure of the SMTP class by Chris Ryan
40  *
41  * This class is rfc 1939 compliant and implements all the commands
42  * required for POP3 connection, authentication and disconnection.
43  *
44  * @package PHPMailer
45  * @author Richard Davey
46  */
47
48 class POP3 {
49   /**
50    * Default POP3 port
51    * @var int
52    */
53   public $POP3_PORT = 110;
54
55   /**
56    * Default Timeout
57    * @var int
58    */
59   public $POP3_TIMEOUT = 30;
60
61   /**
62    * POP3 Carriage Return + Line Feed
63    * @var string
64    */
65   public $CRLF = "\r\n";
66
67   /**
68    * Displaying Debug warnings? (0 = now, 1+ = yes)
69    * @var int
70    */
71   public $do_debug = 2;
72
73   /**
74    * POP3 Mail Server
75    * @var string
76    */
77   public $host;
78
79   /**
80    * POP3 Port
81    * @var int
82    */
83   public $port;
84
85   /**
86    * POP3 Timeout Value
87    * @var int
88    */
89   public $tval;
90
91   /**
92    * POP3 Username
93    * @var string
94    */
95   public $username;
96
97   /**
98    * POP3 Password
99    * @var string
100    */
101   public $password;
102
103   /**#@+
104    * @access private
105    */
106   private $pop_conn;
107   private $connected;
108   private $error;     //  Error log array
109   /**#@-*/
110
111   /**
112    * Constructor, sets the initial values
113    * @access public
114    * @return POP3
115    */
116   public function __construct() {
117     $this->pop_conn  = 0;
118     $this->connected = false;
119     $this->error     = null;
120   }
121
122   /**
123    * Combination of public events - connect, login, disconnect
124    * @access public
125    * @param string $host
126    * @param integer $port
127    * @param integer $tval
128    * @param string $username
129    * @param string $password
130    */
131   public function Authorise ($host, $port = false, $tval = false, $username, $password, $debug_level = 0) {
132     $this->host = $host;
133
134     //  If no port value is passed, retrieve it
135     if ($port == false) {
136       $this->port = $this->POP3_PORT;
137     } else {
138       $this->port = $port;
139     }
140
141     //  If no port value is passed, retrieve it
142     if ($tval == false) {
143       $this->tval = $this->POP3_TIMEOUT;
144     } else {
145       $this->tval = $tval;
146     }
147
148     $this->do_debug = $debug_level;
149     $this->username = $username;
150     $this->password = $password;
151
152     //  Refresh the error log
153     $this->error = null;
154
155     //  Connect
156     $result = $this->Connect($this->host, $this->port, $this->tval);
157
158     if ($result) {
159       $login_result = $this->Login($this->username, $this->password);
160
161       if ($login_result) {
162         $this->Disconnect();
163
164         return true;
165       }
166
167     }
168
169     //  We need to disconnect regardless if the login succeeded
170     $this->Disconnect();
171
172     return false;
173   }
174
175   /**
176    * Connect to the POP3 server
177    * @access public
178    * @param string $host
179    * @param integer $port
180    * @param integer $tval
181    * @return boolean
182    */
183   public function Connect ($host, $port = false, $tval = 30) {
184     //  Are we already connected?
185     if ($this->connected) {
186       return true;
187     }
188
189     /*
190     On Windows this will raise a PHP Warning error if the hostname doesn't exist.
191     Rather than supress it with @fsockopen, let's capture it cleanly instead
192     */
193
194     set_error_handler(array(&$this, 'catchWarning'));
195
196     //  Connect to the POP3 server
197     $this->pop_conn = fsockopen($host,    //  POP3 Host
198                   $port,    //  Port #
199                   $errno,   //  Error Number
200                   $errstr,  //  Error Message
201                   $tval);   //  Timeout (seconds)
202
203     //  Restore the error handler
204     restore_error_handler();
205
206     //  Does the Error Log now contain anything?
207     if ($this->error && $this->do_debug >= 1) {
208       $this->displayErrors();
209     }
210
211     //  Did we connect?
212     if ($this->pop_conn == false) {
213       //  It would appear not...
214       $this->error = array(
215         'error' => "Failed to connect to server $host on port $port",
216         'errno' => $errno,
217         'errstr' => $errstr
218       );
219
220       if ($this->do_debug >= 1) {
221         $this->displayErrors();
222       }
223
224       return false;
225     }
226
227     //  Increase the stream time-out
228
229     //  Check for PHP 4.3.0 or later
230     if (version_compare(phpversion(), '5.0.0', 'ge')) {
231       stream_set_timeout($this->pop_conn, $tval, 0);
232     } else {
233       //  Does not work on Windows
234       if (substr(PHP_OS, 0, 3) !== 'WIN') {
235         socket_set_timeout($this->pop_conn, $tval, 0);
236       }
237     }
238
239     //  Get the POP3 server response
240     $pop3_response = $this->getResponse();
241
242     //  Check for the +OK
243     if ($this->checkResponse($pop3_response)) {
244     //  The connection is established and the POP3 server is talking
245     $this->connected = true;
246       return true;
247     }
248
249   }
250
251   /**
252    * Login to the POP3 server (does not support APOP yet)
253    * @access public
254    * @param string $username
255    * @param string $password
256    * @return boolean
257    */
258   public function Login ($username = '', $password = '') {
259     if ($this->connected == false) {
260       $this->error = 'Not connected to POP3 server';
261
262       if ($this->do_debug >= 1) {
263         $this->displayErrors();
264       }
265     }
266
267     if (empty($username)) {
268       $username = $this->username;
269     }
270
271     if (empty($password)) {
272       $password = $this->password;
273     }
274
275     $pop_username = "USER $username" . $this->CRLF;
276     $pop_password = "PASS $password" . $this->CRLF;
277
278     //  Send the Username
279     $this->sendString($pop_username);
280     $pop3_response = $this->getResponse();
281
282     if ($this->checkResponse($pop3_response)) {
283       //  Send the Password
284       $this->sendString($pop_password);
285       $pop3_response = $this->getResponse();
286
287       if ($this->checkResponse($pop3_response)) {
288         return true;
289       } else {
290         return false;
291       }
292     } else {
293       return false;
294     }
295   }
296
297   /**
298    * Disconnect from the POP3 server
299    * @access public
300    */
301   public function Disconnect () {
302     $this->sendString('QUIT');
303
304     fclose($this->pop_conn);
305   }
306
307   /////////////////////////////////////////////////
308   //  Private Methods
309   /////////////////////////////////////////////////
310
311   /**
312    * Get the socket response back.
313    * $size is the maximum number of bytes to retrieve
314    * @access private
315    * @param integer $size
316    * @return string
317    */
318   private function getResponse ($size = 128) {
319     $pop3_response = fgets($this->pop_conn, $size);
320
321     return $pop3_response;
322   }
323
324   /**
325    * Send a string down the open socket connection to the POP3 server
326    * @access private
327    * @param string $string
328    * @return integer
329    */
330   private function sendString ($string) {
331     $bytes_sent = fwrite($this->pop_conn, $string, strlen($string));
332
333     return $bytes_sent;
334   }
335
336   /**
337    * Checks the POP3 server response for +OK or -ERR
338    * @access private
339    * @param string $string
340    * @return boolean
341    */
342   private function checkResponse ($string) {
343     if (substr($string, 0, 3) !== '+OK') {
344       $this->error = array(
345         'error' => "Server reported an error: $string",
346         'errno' => 0,
347         'errstr' => ''
348       );
349
350       if ($this->do_debug >= 1) {
351         $this->displayErrors();
352       }
353
354       return false;
355     } else {
356       return true;
357     }
358
359   }
360
361   /**
362    * If debug is enabled, display the error message array
363    * @access private
364    */
365   private function displayErrors () {
366     echo '<pre>';
367
368     foreach ($this->error as $single_error) {
369       print_r($single_error);
370     }
371
372     echo '</pre>';
373   }
374
375   /**
376    * Takes over from PHP for the socket warning handler
377    * @access private
378    * @param integer $errno
379    * @param string $errstr
380    * @param string $errfile
381    * @param integer $errline
382    */
383   private function catchWarning ($errno, $errstr, $errfile, $errline) {
384     $this->error[] = array(
385       'error' => "Connecting to the POP3 server raised a PHP warning: ",
386       'errno' => $errno,
387       'errstr' => $errstr
388     );
389   }
390
391   //  End of class
392 }
393 ?>