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