File indexing completed on 2025-05-04 05:28:03
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_Maildir 0036 */ 0037 // require_once 'Zend/Mail/Storage/Maildir.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_Maildir extends Zend_Mail_Storage_Maildir 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 * delim char for subfolders 0069 * @var string 0070 */ 0071 protected $_delim; 0072 0073 /** 0074 * Create instance with parameters 0075 * Supported parameters are: 0076 * - dirname rootdir of maildir structure 0077 * - delim delim char for folder structur, default is '.' 0078 * - folder intial selected folder, default is 'INBOX' 0079 * 0080 * @param array $params mail reader specific parameters 0081 * @throws Zend_Mail_Storage_Exception 0082 */ 0083 public function __construct($params) 0084 { 0085 if (is_array($params)) { 0086 $params = (object)$params; 0087 } 0088 0089 if (!isset($params->dirname) || !is_dir($params->dirname)) { 0090 /** 0091 * @see Zend_Mail_Storage_Exception 0092 */ 0093 // require_once 'Zend/Mail/Storage/Exception.php'; 0094 throw new Zend_Mail_Storage_Exception('no valid dirname given in params'); 0095 } 0096 0097 $this->_rootdir = rtrim($params->dirname, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; 0098 0099 $this->_delim = isset($params->delim) ? $params->delim : '.'; 0100 0101 $this->_buildFolderTree(); 0102 $this->selectFolder(!empty($params->folder) ? $params->folder : 'INBOX'); 0103 $this->_has['top'] = true; 0104 $this->_has['flags'] = true; 0105 } 0106 0107 /** 0108 * find all subfolders and mbox files for folder structure 0109 * 0110 * Result is save in Zend_Mail_Storage_Folder instances with the root in $this->_rootFolder. 0111 * $parentFolder and $parentGlobalName are only used internally for recursion. 0112 * 0113 * @return null 0114 * @throws Zend_Mail_Storage_Exception 0115 */ 0116 protected function _buildFolderTree() 0117 { 0118 $this->_rootFolder = new Zend_Mail_Storage_Folder('/', '/', false); 0119 $this->_rootFolder->INBOX = new Zend_Mail_Storage_Folder('INBOX', 'INBOX', true); 0120 0121 $dh = @opendir($this->_rootdir); 0122 if (!$dh) { 0123 /** 0124 * @see Zend_Mail_Storage_Exception 0125 */ 0126 // require_once 'Zend/Mail/Storage/Exception.php'; 0127 throw new Zend_Mail_Storage_Exception("can't read folders in maildir"); 0128 } 0129 $dirs = array(); 0130 while (($entry = readdir($dh)) !== false) { 0131 // maildir++ defines folders must start with . 0132 if ($entry[0] != '.' || $entry == '.' || $entry == '..') { 0133 continue; 0134 } 0135 if ($this->_isMaildir($this->_rootdir . $entry)) { 0136 $dirs[] = $entry; 0137 } 0138 } 0139 closedir($dh); 0140 0141 sort($dirs); 0142 $stack = array(null); 0143 $folderStack = array(null); 0144 $parentFolder = $this->_rootFolder; 0145 $parent = '.'; 0146 0147 foreach ($dirs as $dir) { 0148 do { 0149 if (strpos($dir, $parent) === 0) { 0150 $local = substr($dir, strlen($parent)); 0151 if (strpos($local, $this->_delim) !== false) { 0152 /** 0153 * @see Zend_Mail_Storage_Exception 0154 */ 0155 // require_once 'Zend/Mail/Storage/Exception.php'; 0156 throw new Zend_Mail_Storage_Exception('error while reading maildir'); 0157 } 0158 array_push($stack, $parent); 0159 $parent = $dir . $this->_delim; 0160 $folder = new Zend_Mail_Storage_Folder($local, substr($dir, 1), true); 0161 $parentFolder->$local = $folder; 0162 array_push($folderStack, $parentFolder); 0163 $parentFolder = $folder; 0164 break; 0165 } else if ($stack) { 0166 $parent = array_pop($stack); 0167 $parentFolder = array_pop($folderStack); 0168 } 0169 } while ($stack); 0170 if (!$stack) { 0171 /** 0172 * @see Zend_Mail_Storage_Exception 0173 */ 0174 // require_once 'Zend/Mail/Storage/Exception.php'; 0175 throw new Zend_Mail_Storage_Exception('error while reading maildir'); 0176 } 0177 } 0178 } 0179 0180 /** 0181 * get root folder or given folder 0182 * 0183 * @param string $rootFolder get folder structure for given folder, else root 0184 * @return Zend_Mail_Storage_Folder root or wanted folder 0185 * @throws Zend_Mail_Storage_Exception 0186 */ 0187 public function getFolders($rootFolder = null) 0188 { 0189 if (!$rootFolder || $rootFolder == 'INBOX') { 0190 return $this->_rootFolder; 0191 } 0192 0193 // rootdir is same as INBOX in maildir 0194 if (strpos($rootFolder, 'INBOX' . $this->_delim) === 0) { 0195 $rootFolder = substr($rootFolder, 6); 0196 } 0197 $currentFolder = $this->_rootFolder; 0198 $subname = trim($rootFolder, $this->_delim); 0199 while ($currentFolder) { 0200 @list($entry, $subname) = @explode($this->_delim, $subname, 2); 0201 $currentFolder = $currentFolder->$entry; 0202 if (!$subname) { 0203 break; 0204 } 0205 } 0206 0207 if ($currentFolder->getGlobalName() != rtrim($rootFolder, $this->_delim)) { 0208 /** 0209 * @see Zend_Mail_Storage_Exception 0210 */ 0211 // require_once 'Zend/Mail/Storage/Exception.php'; 0212 throw new Zend_Mail_Storage_Exception("folder $rootFolder not found"); 0213 } 0214 return $currentFolder; 0215 } 0216 0217 /** 0218 * select given folder 0219 * 0220 * folder must be selectable! 0221 * 0222 * @param Zend_Mail_Storage_Folder|string $globalName global name of folder or instance for subfolder 0223 * @return null 0224 * @throws Zend_Mail_Storage_Exception 0225 */ 0226 public function selectFolder($globalName) 0227 { 0228 $this->_currentFolder = (string)$globalName; 0229 0230 // getting folder from folder tree for validation 0231 $folder = $this->getFolders($this->_currentFolder); 0232 0233 try { 0234 $this->_openMaildir($this->_rootdir . '.' . $folder->getGlobalName()); 0235 } catch(Zend_Mail_Storage_Exception $e) { 0236 // check what went wrong 0237 if (!$folder->isSelectable()) { 0238 /** 0239 * @see Zend_Mail_Storage_Exception 0240 */ 0241 // require_once 'Zend/Mail/Storage/Exception.php'; 0242 throw new Zend_Mail_Storage_Exception("{$this->_currentFolder} is not selectable", 0, $e); 0243 } 0244 // seems like file has vanished; rebuilding folder tree - but it's still an exception 0245 $this->_buildFolderTree($this->_rootdir); 0246 /** 0247 * @see Zend_Mail_Storage_Exception 0248 */ 0249 // require_once 'Zend/Mail/Storage/Exception.php'; 0250 throw new Zend_Mail_Storage_Exception('seems like the maildir has vanished, I\'ve rebuild the ' . 0251 'folder tree, search for an other folder and try again', 0, $e); 0252 } 0253 } 0254 0255 /** 0256 * get Zend_Mail_Storage_Folder instance for current folder 0257 * 0258 * @return Zend_Mail_Storage_Folder instance of current folder 0259 * @throws Zend_Mail_Storage_Exception 0260 */ 0261 public function getCurrentFolder() 0262 { 0263 return $this->_currentFolder; 0264 } 0265 }