File indexing completed on 2025-03-02 05:29:34

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_Folder
0026  */
0027 // require_once 'Zend/Mail/Storage/Folder.php';
0028 
0029 /**
0030  * @see Zend_Mail_Storage_Folder_Interface
0031  */
0032 // require_once 'Zend/Mail/Storage/Folder/Interface.php';
0033 
0034 /**
0035  * @see Zend_Mail_Storage_Mbox
0036  */
0037 // require_once 'Zend/Mail/Storage/Mbox.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_Folder_Mbox extends Zend_Mail_Storage_Mbox implements Zend_Mail_Storage_Folder_Interface
0048 {
0049     /**
0050      * Zend_Mail_Storage_Folder root folder for folder structure
0051      * @var Zend_Mail_Storage_Folder
0052      */
0053     protected $_rootFolder;
0054 
0055     /**
0056      * rootdir of folder structure
0057      * @var string
0058      */
0059     protected $_rootdir;
0060 
0061     /**
0062      * name of current folder
0063      * @var string
0064      */
0065     protected $_currentFolder;
0066 
0067     /**
0068      * Create instance with parameters
0069      *
0070      * Disallowed parameters are:
0071      *   - filename use Zend_Mail_Storage_Mbox for a single file
0072      * Supported parameters are:
0073      *   - dirname rootdir of mbox structure
0074      *   - folder intial selected folder, default is 'INBOX'
0075      *
0076      * @param array $params mail reader specific parameters
0077      * @throws Zend_Mail_Storage_Exception
0078      */
0079     public function __construct($params)
0080     {
0081         if (is_array($params)) {
0082             $params = (object)$params;
0083         }
0084 
0085         if (isset($params->filename)) {
0086             /**
0087              * @see Zend_Mail_Storage_Exception
0088              */
0089             // require_once 'Zend/Mail/Storage/Exception.php';
0090             throw new Zend_Mail_Storage_Exception('use Zend_Mail_Storage_Mbox for a single file');
0091         }
0092 
0093         if (!isset($params->dirname) || !is_dir($params->dirname)) {
0094             /**
0095              * @see Zend_Mail_Storage_Exception
0096              */
0097             // require_once 'Zend/Mail/Storage/Exception.php';
0098             throw new Zend_Mail_Storage_Exception('no valid dirname given in params');
0099         }
0100 
0101         $this->_rootdir = rtrim($params->dirname, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
0102 
0103         $this->_buildFolderTree($this->_rootdir);
0104         $this->selectFolder(!empty($params->folder) ? $params->folder : 'INBOX');
0105         $this->_has['top']      = true;
0106         $this->_has['uniqueid'] = false;
0107     }
0108 
0109     /**
0110      * find all subfolders and mbox files for folder structure
0111      *
0112      * Result is save in Zend_Mail_Storage_Folder instances with the root in $this->_rootFolder.
0113      * $parentFolder and $parentGlobalName are only used internally for recursion.
0114      *
0115      * @param string $currentDir call with root dir, also used for recursion.
0116      * @param Zend_Mail_Storage_Folder|null $parentFolder used for recursion
0117      * @param string $parentGlobalName used for rescursion
0118      * @return null
0119      * @throws Zend_Mail_Storage_Exception
0120      */
0121     protected function _buildFolderTree($currentDir, $parentFolder = null, $parentGlobalName = '')
0122     {
0123         if (!$parentFolder) {
0124             $this->_rootFolder = new Zend_Mail_Storage_Folder('/', '/', false);
0125             $parentFolder = $this->_rootFolder;
0126         }
0127 
0128         $dh = @opendir($currentDir);
0129         if (!$dh) {
0130             /**
0131              * @see Zend_Mail_Storage_Exception
0132              */
0133             // require_once 'Zend/Mail/Storage/Exception.php';
0134             throw new Zend_Mail_Storage_Exception("can't read dir $currentDir");
0135         }
0136         while (($entry = readdir($dh)) !== false) {
0137             // ignore hidden files for mbox
0138             if ($entry[0] == '.') {
0139                 continue;
0140             }
0141             $absoluteEntry = $currentDir . $entry;
0142             $globalName = $parentGlobalName . DIRECTORY_SEPARATOR . $entry;
0143             if (is_file($absoluteEntry) && $this->_isMboxFile($absoluteEntry)) {
0144                 $parentFolder->$entry = new Zend_Mail_Storage_Folder($entry, $globalName);
0145                 continue;
0146             }
0147             if (!is_dir($absoluteEntry) /* || $entry == '.' || $entry == '..' */) {
0148                 continue;
0149             }
0150             $folder = new Zend_Mail_Storage_Folder($entry, $globalName, false);
0151             $parentFolder->$entry = $folder;
0152             $this->_buildFolderTree($absoluteEntry . DIRECTORY_SEPARATOR, $folder, $globalName);
0153         }
0154 
0155         closedir($dh);
0156     }
0157 
0158     /**
0159      * get root folder or given folder
0160      *
0161      * @param string $rootFolder get folder structure for given folder, else root
0162      * @return Zend_Mail_Storage_Folder root or wanted folder
0163      * @throws Zend_Mail_Storage_Exception
0164      */
0165     public function getFolders($rootFolder = null)
0166     {
0167         if (!$rootFolder) {
0168             return $this->_rootFolder;
0169         }
0170 
0171         $currentFolder = $this->_rootFolder;
0172         $subname = trim($rootFolder, DIRECTORY_SEPARATOR);
0173         while ($currentFolder) {
0174             @list($entry, $subname) = @explode(DIRECTORY_SEPARATOR, $subname, 2);
0175             $currentFolder = $currentFolder->$entry;
0176             if (!$subname) {
0177                 break;
0178             }
0179         }
0180 
0181         if ($currentFolder->getGlobalName() != DIRECTORY_SEPARATOR . trim($rootFolder, DIRECTORY_SEPARATOR)) {
0182             /**
0183              * @see Zend_Mail_Storage_Exception
0184              */
0185             // require_once 'Zend/Mail/Storage/Exception.php';
0186             throw new Zend_Mail_Storage_Exception("folder $rootFolder not found");
0187         }
0188         return $currentFolder;
0189     }
0190 
0191     /**
0192      * select given folder
0193      *
0194      * folder must be selectable!
0195      *
0196      * @param Zend_Mail_Storage_Folder|string $globalName global name of folder or instance for subfolder
0197      * @return null
0198      * @throws Zend_Mail_Storage_Exception
0199      */
0200     public function selectFolder($globalName)
0201     {
0202         $this->_currentFolder = (string)$globalName;
0203 
0204         // getting folder from folder tree for validation
0205         $folder = $this->getFolders($this->_currentFolder);
0206 
0207         try {
0208             $this->_openMboxFile($this->_rootdir . $folder->getGlobalName());
0209         } catch(Zend_Mail_Storage_Exception $e) {
0210             // check what went wrong
0211             if (!$folder->isSelectable()) {
0212                 /**
0213                  * @see Zend_Mail_Storage_Exception
0214                  */
0215                 // require_once 'Zend/Mail/Storage/Exception.php';
0216                 throw new Zend_Mail_Storage_Exception("{$this->_currentFolder} is not selectable", 0, $e);
0217             }
0218             // seems like file has vanished; rebuilding folder tree - but it's still an exception
0219             $this->_buildFolderTree($this->_rootdir);
0220             /**
0221              * @see Zend_Mail_Storage_Exception
0222              */
0223             // require_once 'Zend/Mail/Storage/Exception.php';
0224             throw new Zend_Mail_Storage_Exception('seems like the mbox file has vanished, I\'ve rebuild the ' .
0225                                                          'folder tree, search for an other folder and try again', 0, $e);
0226         }
0227     }
0228 
0229     /**
0230      * get Zend_Mail_Storage_Folder instance for current folder
0231      *
0232      * @return Zend_Mail_Storage_Folder instance of current folder
0233      * @throws Zend_Mail_Storage_Exception
0234      */
0235     public function getCurrentFolder()
0236     {
0237         return $this->_currentFolder;
0238     }
0239 
0240     /**
0241      * magic method for serialize()
0242      *
0243      * with this method you can cache the mbox class
0244      *
0245      * @return array name of variables
0246      */
0247     public function __sleep()
0248     {
0249         return array_merge(parent::__sleep(), array('_currentFolder', '_rootFolder', '_rootdir'));
0250     }
0251 
0252     /**
0253      * magic method for unserialize()
0254      *
0255      * with this method you can cache the mbox class
0256      *
0257      * @return null
0258      */
0259     public function __wakeup()
0260     {
0261         // if cache is stall selectFolder() rebuilds the tree on error
0262         parent::__wakeup();
0263     }
0264 }