File indexing completed on 2024-12-22 05:36:51

0001 <?php
0002 /**
0003  * Zend Framework
0004  *
0005  * LICENSE
0006  *
0007  * This source file is subject to the new BSD license that is bundled
0008  * with this package in the file LICENSE.txt.
0009  * It is also available through the world-wide-web at this URL:
0010  * http://framework.zend.com/license/new-bsd
0011  * If you did not receive a copy of the license and are unable to
0012  * obtain it through the world-wide-web, please send an email
0013  * to license@zend.com so we can send you a copy immediately.
0014  *
0015  * @category   Zend
0016  * @package    Zend_Mail
0017  * @subpackage Storage
0018  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0019  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0020  * @version    $Id$
0021  */
0022 
0023 
0024 /**
0025  * @see Zend_Mail_Storage_Abstract
0026  */
0027 // require_once 'Zend/Mail/Storage/Abstract.php';
0028 
0029 /**
0030  * @see Zend_Mail_Protocol_Pop3
0031  */
0032 // require_once 'Zend/Mail/Protocol/Pop3.php';
0033 
0034 /**
0035  * @see Zend_Mail_Message
0036  */
0037 // require_once 'Zend/Mail/Message.php';
0038 
0039 
0040 /**
0041  * @category   Zend
0042  * @package    Zend_Mail
0043  * @subpackage Storage
0044  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0045  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0046  */
0047 class Zend_Mail_Storage_Pop3 extends Zend_Mail_Storage_Abstract
0048 {
0049     /**
0050      * protocol handler
0051      * @var null|Zend_Mail_Protocol_Pop3
0052      */
0053     protected $_protocol;
0054 
0055 
0056     /**
0057      * Count messages all messages in current box
0058      *
0059      * @return int number of messages
0060      * @throws Zend_Mail_Storage_Exception
0061      * @throws Zend_Mail_Protocol_Exception
0062      */
0063     public function countMessages()
0064     {
0065         $this->_protocol->status($count, $null);
0066         return (int)$count;
0067     }
0068 
0069     /**
0070      * get a list of messages with number and size
0071      *
0072      * @param int $id number of message
0073      * @return int|array size of given message of list with all messages as array(num => size)
0074      * @throws Zend_Mail_Protocol_Exception
0075      */
0076     public function getSize($id = 0)
0077     {
0078         $id = $id ? $id : null;
0079         return $this->_protocol->getList($id);
0080     }
0081 
0082     /**
0083      * Fetch a message
0084      *
0085      * @param int $id number of message
0086      * @return Zend_Mail_Message
0087      * @throws Zend_Mail_Protocol_Exception
0088      */
0089     public function getMessage($id)
0090     {
0091         $bodyLines = 0;
0092         $message = $this->_protocol->top($id, $bodyLines, true);
0093 
0094         return new $this->_messageClass(array('handler' => $this, 'id' => $id, 'headers' => $message,
0095                                               'noToplines' => $bodyLines < 1));
0096     }
0097 
0098     /*
0099      * Get raw header of message or part
0100      *
0101      * @param  int               $id       number of message
0102      * @param  null|array|string $part     path to part or null for messsage header
0103      * @param  int               $topLines include this many lines with header (after an empty line)
0104      * @return string raw header
0105      * @throws Zend_Mail_Protocol_Exception
0106      * @throws Zend_Mail_Storage_Exception
0107      */
0108     public function getRawHeader($id, $part = null, $topLines = 0)
0109     {
0110         if ($part !== null) {
0111             // TODO: implement
0112             /**
0113              * @see Zend_Mail_Storage_Exception
0114              */
0115             // require_once 'Zend/Mail/Storage/Exception.php';
0116             throw new Zend_Mail_Storage_Exception('not implemented');
0117         }
0118 
0119         return $this->_protocol->top($id, 0, true);
0120     }
0121 
0122     /*
0123      * Get raw content of message or part
0124      *
0125      * @param  int               $id   number of message
0126      * @param  null|array|string $part path to part or null for messsage content
0127      * @return string raw content
0128      * @throws Zend_Mail_Protocol_Exception
0129      * @throws Zend_Mail_Storage_Exception
0130      */
0131     public function getRawContent($id, $part = null)
0132     {
0133         if ($part !== null) {
0134             // TODO: implement
0135             /**
0136              * @see Zend_Mail_Storage_Exception
0137              */
0138             // require_once 'Zend/Mail/Storage/Exception.php';
0139             throw new Zend_Mail_Storage_Exception('not implemented');
0140         }
0141 
0142         $content = $this->_protocol->retrieve($id);
0143         // TODO: find a way to avoid decoding the headers
0144         Zend_Mime_Decode::splitMessage($content, $null, $body);
0145         return $body;
0146     }
0147 
0148     /**
0149      * create instance with parameters
0150      * Supported paramters are
0151      *   - host hostname or ip address of POP3 server
0152      *   - user username
0153      *   - password password for user 'username' [optional, default = '']
0154      *   - port port for POP3 server [optional, default = 110]
0155      *   - ssl 'SSL' or 'TLS' for secure sockets
0156      *
0157      * @param array $params mail reader specific parameters
0158      * @throws Zend_Mail_Storage_Exception
0159      * @throws Zend_Mail_Protocol_Exception
0160      */
0161     public function __construct($params)
0162     {
0163         if (is_array($params)) {
0164             $params = (object)$params;
0165         }
0166 
0167         $this->_has['fetchPart'] = false;
0168         $this->_has['top']       = null;
0169         $this->_has['uniqueid']  = null;
0170 
0171         if ($params instanceof Zend_Mail_Protocol_Pop3) {
0172             $this->_protocol = $params;
0173             return;
0174         }
0175 
0176         if (!isset($params->user)) {
0177             /**
0178              * @see Zend_Mail_Storage_Exception
0179              */
0180             // require_once 'Zend/Mail/Storage/Exception.php';
0181             throw new Zend_Mail_Storage_Exception('need at least user in params');
0182         }
0183 
0184         $host     = isset($params->host)     ? $params->host     : 'localhost';
0185         $password = isset($params->password) ? $params->password : '';
0186         $port     = isset($params->port)     ? $params->port     : null;
0187         $ssl      = isset($params->ssl)      ? $params->ssl      : false;
0188 
0189         $this->_protocol = new Zend_Mail_Protocol_Pop3();
0190         $this->_protocol->connect($host, $port, $ssl);
0191         $this->_protocol->login($params->user, $password);
0192     }
0193 
0194     /**
0195      * Close resource for mail lib. If you need to control, when the resource
0196      * is closed. Otherwise the destructor would call this.
0197      *
0198      * @return null
0199      */
0200     public function close()
0201     {
0202         $this->_protocol->logout();
0203     }
0204 
0205     /**
0206      * Keep the server busy.
0207      *
0208      * @return null
0209      * @throws Zend_Mail_Protocol_Exception
0210      */
0211     public function noop()
0212     {
0213         return $this->_protocol->noop();
0214     }
0215 
0216     /**
0217      * Remove a message from server. If you're doing that from a web enviroment
0218      * you should be careful and use a uniqueid as parameter if possible to
0219      * identify the message.
0220      *
0221      * @param  int $id number of message
0222      * @return null
0223      * @throws Zend_Mail_Protocol_Exception
0224      */
0225     public function removeMessage($id)
0226     {
0227         $this->_protocol->delete($id);
0228     }
0229 
0230     /**
0231      * get unique id for one or all messages
0232      *
0233      * if storage does not support unique ids it's the same as the message number
0234      *
0235      * @param int|null $id message number
0236      * @return array|string message number for given message or all messages as array
0237      * @throws Zend_Mail_Storage_Exception
0238      */
0239     public function getUniqueId($id = null)
0240     {
0241         if (!$this->hasUniqueid) {
0242             if ($id) {
0243                 return $id;
0244             }
0245             $count = $this->countMessages();
0246             if ($count < 1) {
0247                 return array();
0248             }
0249             $range = range(1, $count);
0250             return array_combine($range, $range);
0251         }
0252 
0253         return $this->_protocol->uniqueid($id);
0254     }
0255 
0256     /**
0257      * get a message number from a unique id
0258      *
0259      * I.e. if you have a webmailer that supports deleting messages you should use unique ids
0260      * as parameter and use this method to translate it to message number right before calling removeMessage()
0261      *
0262      * @param string $id unique id
0263      * @return int message number
0264      * @throws Zend_Mail_Storage_Exception
0265      */
0266     public function getNumberByUniqueId($id)
0267     {
0268         if (!$this->hasUniqueid) {
0269             return $id;
0270         }
0271 
0272         $ids = $this->getUniqueId();
0273         foreach ($ids as $k => $v) {
0274             if ($v == $id) {
0275                 return $k;
0276             }
0277         }
0278 
0279         /**
0280          * @see Zend_Mail_Storage_Exception
0281          */
0282         // require_once 'Zend/Mail/Storage/Exception.php';
0283         throw new Zend_Mail_Storage_Exception('unique id not found');
0284     }
0285 
0286     /**
0287      * Special handling for hasTop and hasUniqueid. The headers of the first message is
0288      * retrieved if Top wasn't needed/tried yet.
0289      *
0290      * @see Zend_Mail_Storage_Abstract:__get()
0291      * @param  string $var
0292      * @return string
0293      * @throws Zend_Mail_Storage_Exception
0294      */
0295     public function __get($var)
0296     {
0297         $result = parent::__get($var);
0298         if ($result !== null) {
0299             return $result;
0300         }
0301 
0302         if (strtolower($var) == 'hastop') {
0303             if ($this->_protocol->hasTop === null) {
0304                 // need to make a real call, because not all server are honest in their capas
0305                 try {
0306                     $this->_protocol->top(1, 0, false);
0307                 } catch(Zend_Mail_Exception $e) {
0308                     // ignoring error
0309                 }
0310             }
0311             $this->_has['top'] = $this->_protocol->hasTop;
0312             return $this->_protocol->hasTop;
0313         }
0314 
0315         if (strtolower($var) == 'hasuniqueid') {
0316             $id = null;
0317             try {
0318                 $id = $this->_protocol->uniqueid(1);
0319             } catch(Zend_Mail_Exception $e) {
0320                 // ignoring error
0321             }
0322             $this->_has['uniqueid'] = $id ? true : false;
0323             return $this->_has['uniqueid'];
0324         }
0325 
0326         return $result;
0327     }
0328 }