PageRenderTime 77ms CodeModel.GetById 33ms app.highlight 13ms RepoModel.GetById 27ms app.codeStats 0ms

/library/Zend/Mail/Protocol/Pop3.php

https://bitbucket.org/baruffaldi/webapp-urltube
PHP | 464 lines | 209 code | 64 blank | 191 comment | 35 complexity | 24c11520d1eff2bff1676adc382fdfea MD5 | raw file
  1<?php
  2/**
  3 * Zend Framework
  4 *
  5 * LICENSE
  6 *
  7 * This source file is subject to the new BSD license that is bundled
  8 * with this package in the file LICENSE.txt.
  9 * It is also available through the world-wide-web at this URL:
 10 * http://framework.zend.com/license/new-bsd
 11 * If you did not receive a copy of the license and are unable to
 12 * obtain it through the world-wide-web, please send an email
 13 * to license@zend.com so we can send you a copy immediately.
 14 * 
 15 * @category   Zend
 16 * @package    Zend_Mail
 17 * @subpackage Protocol
 18 * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
 19 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 20 * @version    $Id: Pop3.php 11468 2008-09-21 18:31:29Z nico $
 21 */
 22
 23
 24/**
 25 * @category   Zend
 26 * @package    Zend_Mail
 27 * @subpackage Protocol
 28 * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
 29 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 30 */
 31class Zend_Mail_Protocol_Pop3
 32{
 33    /**
 34     * saves if server supports top
 35     * @var null|bool
 36     */
 37    public $hasTop = null;
 38
 39    /**
 40     * socket to pop3
 41     * @var null|resource
 42     */
 43    protected $_socket;
 44
 45    /**
 46     * greeting timestamp for apop
 47     * @var null|string
 48     */
 49    protected $_timestamp;
 50
 51
 52    /**
 53     * Public constructor
 54     *
 55     * @param  string      $host  hostname of IP address of POP3 server, if given connect() is called
 56     * @param  int|null    $port  port of POP3 server, null for default (110 or 995 for ssl)
 57     * @param  bool|string $ssl   use ssl? 'SSL', 'TLS' or false
 58     * @throws Zend_Mail_Protocol_Exception
 59     */
 60    public function __construct($host = '', $port = null, $ssl = false)
 61    {
 62        if ($host) {
 63            $this->connect($host, $port, $ssl);
 64        }
 65    }
 66
 67
 68    /**
 69     * Public destructor
 70     */
 71    public function __destruct()
 72    {
 73        $this->logout();
 74    }
 75
 76
 77    /**
 78     * Open connection to POP3 server
 79     *
 80     * @param  string      $host  hostname of IP address of POP3 server
 81     * @param  int|null    $port  of POP3 server, default is 110 (995 for ssl)
 82     * @param  string|bool $ssl   use 'SSL', 'TLS' or false
 83     * @return string welcome message
 84     * @throws Zend_Mail_Protocol_Exception
 85     */
 86    public function connect($host, $port = null, $ssl = false)
 87    {
 88        if ($ssl == 'SSL') {
 89            $host = 'ssl://' . $host;
 90        }
 91
 92        if ($port === null) {
 93            $port = $ssl == 'SSL' ? 995 : 110;
 94        }
 95
 96        $this->_socket = @fsockopen($host, $port);
 97        if (!$this->_socket) {
 98            /**
 99             * @see Zend_Mail_Protocol_Exception
100             */
101            require_once 'Zend/Mail/Protocol/Exception.php';
102            throw new Zend_Mail_Protocol_Exception('cannot connect to host');
103        }
104
105        $welcome = $this->readResponse();
106
107        strtok($welcome, '<');
108        $this->_timestamp = strtok('>');
109        if (!strpos($this->_timestamp, '@')) {
110            $this->_timestamp = null;
111        } else {
112            $this->_timestamp = '<' . $this->_timestamp . '>';
113        }
114
115        if ($ssl === 'TLS') {
116            $this->request('STLS');
117            $result = stream_socket_enable_crypto($this->_socket, true, STREAM_CRYPTO_METHOD_TLS_CLIENT);
118            if (!$result) {
119                /**
120                 * @see Zend_Mail_Protocol_Exception
121                 */
122                require_once 'Zend/Mail/Protocol/Exception.php';
123                throw new Zend_Mail_Protocol_Exception('cannot enable TLS');
124            }
125        }
126
127        return $welcome;
128    }
129
130
131    /**
132     * Send a request
133     *
134     * @param string $request your request without newline
135     * @return null
136     * @throws Zend_Mail_Protocol_Exception
137     */
138    public function sendRequest($request)
139    {
140        $result = @fputs($this->_socket, $request . "\r\n");
141        if (!$result) {
142            /**
143             * @see Zend_Mail_Protocol_Exception
144             */
145            require_once 'Zend/Mail/Protocol/Exception.php';
146            throw new Zend_Mail_Protocol_Exception('send failed - connection closed?');
147        }
148    }
149
150
151    /**
152     * read a response
153     *
154     * @param  boolean $multiline response has multiple lines and should be read until "<nl>.<nl>"
155     * @return string response
156     * @throws Zend_Mail_Protocol_Exception
157     */
158    public function readResponse($multiline = false)
159    {
160        $result = @fgets($this->_socket);
161        if (!is_string($result)) {
162            /**
163             * @see Zend_Mail_Protocol_Exception
164             */
165            require_once 'Zend/Mail/Protocol/Exception.php';
166            throw new Zend_Mail_Protocol_Exception('read failed - connection closed?');
167        }
168
169        $result = trim($result);
170        if (strpos($result, ' ')) {
171            list($status, $message) = explode(' ', $result, 2);
172        } else {
173            $status = $result;
174            $message = '';
175        }
176
177        if ($status != '+OK') {
178            /**
179             * @see Zend_Mail_Protocol_Exception
180             */
181            require_once 'Zend/Mail/Protocol/Exception.php';
182            throw new Zend_Mail_Protocol_Exception('last request failed');
183        }
184
185        if ($multiline) {
186            $message = '';
187            $line = fgets($this->_socket);
188            while ($line && rtrim($line, "\r\n") != '.') {
189            	if ($line[0] == '.') {
190            		$line = substr($line, 1);
191            	}
192                $message .= $line;
193                $line = fgets($this->_socket);
194            };
195        }
196
197        return $message;
198    }
199
200
201    /**
202     * Send request and get resposne
203     *
204     * @see sendRequest(), readResponse()
205     *
206     * @param  string $request    request
207     * @param  bool   $multiline  multiline response?
208     * @return string             result from readResponse()
209     * @throws Zend_Mail_Protocol_Exception
210     */
211    public function request($request, $multiline = false)
212    {
213        $this->sendRequest($request);
214        return $this->readResponse($multiline);
215    }
216
217
218    /**
219     * End communication with POP3 server (also closes socket)
220     *
221     * @return null
222     */
223    public function logout()
224    {
225        if (!$this->_socket) {
226            return;
227        }
228
229        try {
230            $this->request('QUIT');
231        } catch (Zend_Mail_Protocol_Exception $e) {
232            // ignore error - we're closing the socket anyway
233        }
234
235        fclose($this->_socket);
236        $this->_socket = null;
237    }
238
239
240    /**
241     * Get capabilities from POP3 server
242     *
243     * @return array list of capabilities
244     * @throws Zend_Mail_Protocol_Exception
245     */
246    public function capa()
247    {
248        $result = $this->request('CAPA', true);
249        return explode("\n", $result);
250    }
251
252
253    /**
254     * Login to POP3 server. Can use APOP
255     *
256     * @param  string $user      username
257     * @param  string $password  password
258     * @param  bool   $try_apop  should APOP be tried?
259     * @return void
260     * @throws Zend_Mail_Protocol_Exception
261     */
262    public function login($user, $password, $tryApop = true)
263    {
264        if ($tryApop && $this->_timestamp) {
265            try {
266                $this->request("APOP $user " . md5($this->_timestamp . $password));
267                return;
268            } catch (Zend_Mail_Protocol_Exception $e) {
269                // ignore
270            }
271        }
272
273        $result = $this->request("USER $user");
274        $result = $this->request("PASS $password");
275    }
276
277
278    /**
279     * Make STAT call for message count and size sum
280     *
281     * @param  int $messages  out parameter with count of messages
282     * @param  int $octets    out parameter with size in octects of messages
283     * @return void
284     * @throws Zend_Mail_Protocol_Exception
285     */
286    public function status(&$messages, &$octets)
287    {
288        $messages = 0;
289        $octets = 0;
290        $result = $this->request('STAT');
291
292        list($messages, $octets) = explode(' ', $result);
293    }
294
295
296    /**
297     * Make LIST call for size of message(s)
298     *
299     * @param  int|null $msgno number of message, null for all
300     * @return int|array size of given message or list with array(num => size)
301     * @throws Zend_Mail_Protocol_Exception
302     */
303    public function getList($msgno = null)
304    {
305        if ($msgno !== null) {
306            $result = $this->request("LIST $msgno");
307
308            list(, $result) = explode(' ', $result);
309            return (int)$result;
310        }
311
312        $result = $this->request('LIST', true);
313        $messages = array();
314        $line = strtok($result, "\n");
315        while ($line) {
316            list($no, $size) = explode(' ', trim($line));
317            $messages[(int)$no] = (int)$size;
318            $line = strtok("\n");
319        }
320
321        return $messages;
322    }
323
324
325    /**
326     * Make UIDL call for getting a uniqueid
327     *
328     * @param  int|null $msgno number of message, null for all
329     * @return string|array uniqueid of message or list with array(num => uniqueid)
330     * @throws Zend_Mail_Protocol_Exception
331     */
332    public function uniqueid($msgno = null)
333    {
334        if ($msgno !== null) {
335            $result = $this->request("UIDL $msgno");
336
337            list(, $result) = explode(' ', $result);
338            return $result;
339        }
340
341        $result = $this->request('UIDL', true);
342
343        $result = explode("\n", $result);
344        $messages = array();
345        foreach ($result as $line) {
346            if (!$line) {
347                continue;
348            }
349            list($no, $id) = explode(' ', trim($line), 2);
350            $messages[(int)$no] = $id;
351        }
352
353        return $messages;
354
355    }
356
357
358    /**
359     * Make TOP call for getting headers and maybe some body lines
360     * This method also sets hasTop - before it it's not known if top is supported
361     *
362     * The fallback makes normale RETR call, which retrieves the whole message. Additional
363     * lines are not removed.
364     *
365     * @param  int  $msgno    number of message
366     * @param  int  $lines    number of wanted body lines (empty line is inserted after header lines)
367     * @param  bool $fallback fallback with full retrieve if top is not supported
368     * @return string message headers with wanted body lines
369     * @throws Zend_Mail_Protocol_Exception
370     */
371    public function top($msgno, $lines = 0, $fallback = false)
372    {
373        if ($this->hasTop === false) {
374            if ($fallback) {
375                return $this->retrieve($msgno);
376            } else {
377                /**
378                 * @see Zend_Mail_Protocol_Exception
379                 */
380                require_once 'Zend/Mail/Protocol/Exception.php';
381                throw new Zend_Mail_Protocol_Exception('top not supported and no fallback wanted');
382            }
383        }
384        $this->hasTop = true;
385
386        $lines = (!$lines || $lines < 1) ? 0 : (int)$lines;
387
388        try {
389            $result = $this->request("TOP $msgno $lines", true);
390        } catch (Zend_Mail_Protocol_Exception $e) {
391            $this->hasTop = false;
392            if ($fallback) {
393                $result = $this->retrieve($msgno);
394            } else {
395                throw $e;
396            }
397        }
398
399        return $result;
400    }
401
402
403    /**
404     * Make a RETR call for retrieving a full message with headers and body
405     *
406     * @deprecated since 1.1.0; this method has a typo - please use retrieve()
407     * @param  int $msgno  message number
408     * @return string message
409     * @throws Zend_Mail_Protocol_Exception
410     */
411    public function retrive($msgno)
412    {
413        return $this->retrieve($msgno);
414    }
415
416
417    /**
418     * Make a RETR call for retrieving a full message with headers and body
419     *
420     * @param  int $msgno  message number
421     * @return string message
422     * @throws Zend_Mail_Protocol_Exception
423     */
424    public function retrieve($msgno)
425    {
426        $result = $this->request("RETR $msgno", true);
427        return $result;
428    }
429
430    /**
431     * Make a NOOP call, maybe needed for keeping the server happy
432     *
433     * @return null
434     * @throws Zend_Mail_Protocol_Exception
435     */
436    public function noop()
437    {
438        $this->request('NOOP');
439    }
440
441
442    /**
443     * Make a DELE count to remove a message
444     *
445     * @return null
446     * @throws Zend_Mail_Protocol_Exception
447     */
448    public function delete($msgno)
449    {
450        $this->request("DELE $msgno");
451    }
452
453
454    /**
455     * Make RSET call, which rollbacks delete requests
456     *
457     * @return null
458     * @throws Zend_Mail_Protocol_Exception
459     */
460    public function undelete()
461    {
462        $this->request('RSET');
463    }
464}