|
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 Storage |
|
18 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) |
|
19 * @license http://framework.zend.com/license/new-bsd New BSD License |
|
20 * @version $Id: Maildir.php 20096 2010-01-06 02:05:09Z bkarwin $ |
|
21 */ |
|
22 |
|
23 |
|
24 /** |
|
25 * @see Zend_Mail_Storage_Folder |
|
26 */ |
|
27 require_once 'Zend/Mail/Storage/Folder.php'; |
|
28 |
|
29 /** |
|
30 * @see Zend_Mail_Storage_Folder_Interface |
|
31 */ |
|
32 require_once 'Zend/Mail/Storage/Folder/Interface.php'; |
|
33 |
|
34 /** |
|
35 * @see Zend_Mail_Storage_Maildir |
|
36 */ |
|
37 require_once 'Zend/Mail/Storage/Maildir.php'; |
|
38 |
|
39 |
|
40 /** |
|
41 * @category Zend |
|
42 * @package Zend_Mail |
|
43 * @subpackage Storage |
|
44 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) |
|
45 * @license http://framework.zend.com/license/new-bsd New BSD License |
|
46 */ |
|
47 class Zend_Mail_Storage_Folder_Maildir extends Zend_Mail_Storage_Maildir implements Zend_Mail_Storage_Folder_Interface |
|
48 { |
|
49 /** |
|
50 * Zend_Mail_Storage_Folder root folder for folder structure |
|
51 * @var Zend_Mail_Storage_Folder |
|
52 */ |
|
53 protected $_rootFolder; |
|
54 |
|
55 /** |
|
56 * rootdir of folder structure |
|
57 * @var string |
|
58 */ |
|
59 protected $_rootdir; |
|
60 |
|
61 /** |
|
62 * name of current folder |
|
63 * @var string |
|
64 */ |
|
65 protected $_currentFolder; |
|
66 |
|
67 /** |
|
68 * delim char for subfolders |
|
69 * @var string |
|
70 */ |
|
71 protected $_delim; |
|
72 |
|
73 /** |
|
74 * Create instance with parameters |
|
75 * Supported parameters are: |
|
76 * - dirname rootdir of maildir structure |
|
77 * - delim delim char for folder structur, default is '.' |
|
78 * - folder intial selected folder, default is 'INBOX' |
|
79 * |
|
80 * @param $params array mail reader specific parameters |
|
81 * @throws Zend_Mail_Storage_Exception |
|
82 */ |
|
83 public function __construct($params) |
|
84 { |
|
85 if (is_array($params)) { |
|
86 $params = (object)$params; |
|
87 } |
|
88 |
|
89 if (!isset($params->dirname) || !is_dir($params->dirname)) { |
|
90 /** |
|
91 * @see Zend_Mail_Storage_Exception |
|
92 */ |
|
93 require_once 'Zend/Mail/Storage/Exception.php'; |
|
94 throw new Zend_Mail_Storage_Exception('no valid dirname given in params'); |
|
95 } |
|
96 |
|
97 $this->_rootdir = rtrim($params->dirname, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; |
|
98 |
|
99 $this->_delim = isset($params->delim) ? $params->delim : '.'; |
|
100 |
|
101 $this->_buildFolderTree(); |
|
102 $this->selectFolder(!empty($params->folder) ? $params->folder : 'INBOX'); |
|
103 $this->_has['top'] = true; |
|
104 $this->_has['flags'] = true; |
|
105 } |
|
106 |
|
107 /** |
|
108 * find all subfolders and mbox files for folder structure |
|
109 * |
|
110 * Result is save in Zend_Mail_Storage_Folder instances with the root in $this->_rootFolder. |
|
111 * $parentFolder and $parentGlobalName are only used internally for recursion. |
|
112 * |
|
113 * @return null |
|
114 * @throws Zend_Mail_Storage_Exception |
|
115 */ |
|
116 protected function _buildFolderTree() |
|
117 { |
|
118 $this->_rootFolder = new Zend_Mail_Storage_Folder('/', '/', false); |
|
119 $this->_rootFolder->INBOX = new Zend_Mail_Storage_Folder('INBOX', 'INBOX', true); |
|
120 |
|
121 $dh = @opendir($this->_rootdir); |
|
122 if (!$dh) { |
|
123 /** |
|
124 * @see Zend_Mail_Storage_Exception |
|
125 */ |
|
126 require_once 'Zend/Mail/Storage/Exception.php'; |
|
127 throw new Zend_Mail_Storage_Exception("can't read folders in maildir"); |
|
128 } |
|
129 $dirs = array(); |
|
130 while (($entry = readdir($dh)) !== false) { |
|
131 // maildir++ defines folders must start with . |
|
132 if ($entry[0] != '.' || $entry == '.' || $entry == '..') { |
|
133 continue; |
|
134 } |
|
135 if ($this->_isMaildir($this->_rootdir . $entry)) { |
|
136 $dirs[] = $entry; |
|
137 } |
|
138 } |
|
139 closedir($dh); |
|
140 |
|
141 sort($dirs); |
|
142 $stack = array(null); |
|
143 $folderStack = array(null); |
|
144 $parentFolder = $this->_rootFolder; |
|
145 $parent = '.'; |
|
146 |
|
147 foreach ($dirs as $dir) { |
|
148 do { |
|
149 if (strpos($dir, $parent) === 0) { |
|
150 $local = substr($dir, strlen($parent)); |
|
151 if (strpos($local, $this->_delim) !== false) { |
|
152 /** |
|
153 * @see Zend_Mail_Storage_Exception |
|
154 */ |
|
155 require_once 'Zend/Mail/Storage/Exception.php'; |
|
156 throw new Zend_Mail_Storage_Exception('error while reading maildir'); |
|
157 } |
|
158 array_push($stack, $parent); |
|
159 $parent = $dir . $this->_delim; |
|
160 $folder = new Zend_Mail_Storage_Folder($local, substr($dir, 1), true); |
|
161 $parentFolder->$local = $folder; |
|
162 array_push($folderStack, $parentFolder); |
|
163 $parentFolder = $folder; |
|
164 break; |
|
165 } else if ($stack) { |
|
166 $parent = array_pop($stack); |
|
167 $parentFolder = array_pop($folderStack); |
|
168 } |
|
169 } while ($stack); |
|
170 if (!$stack) { |
|
171 /** |
|
172 * @see Zend_Mail_Storage_Exception |
|
173 */ |
|
174 require_once 'Zend/Mail/Storage/Exception.php'; |
|
175 throw new Zend_Mail_Storage_Exception('error while reading maildir'); |
|
176 } |
|
177 } |
|
178 } |
|
179 |
|
180 /** |
|
181 * get root folder or given folder |
|
182 * |
|
183 * @param string $rootFolder get folder structure for given folder, else root |
|
184 * @return Zend_Mail_Storage_Folder root or wanted folder |
|
185 * @throws Zend_Mail_Storage_Exception |
|
186 */ |
|
187 public function getFolders($rootFolder = null) |
|
188 { |
|
189 if (!$rootFolder || $rootFolder == 'INBOX') { |
|
190 return $this->_rootFolder; |
|
191 } |
|
192 |
|
193 // rootdir is same as INBOX in maildir |
|
194 if (strpos($rootFolder, 'INBOX' . $this->_delim) === 0) { |
|
195 $rootFolder = substr($rootFolder, 6); |
|
196 } |
|
197 $currentFolder = $this->_rootFolder; |
|
198 $subname = trim($rootFolder, $this->_delim); |
|
199 while ($currentFolder) { |
|
200 @list($entry, $subname) = @explode($this->_delim, $subname, 2); |
|
201 $currentFolder = $currentFolder->$entry; |
|
202 if (!$subname) { |
|
203 break; |
|
204 } |
|
205 } |
|
206 |
|
207 if ($currentFolder->getGlobalName() != rtrim($rootFolder, $this->_delim)) { |
|
208 /** |
|
209 * @see Zend_Mail_Storage_Exception |
|
210 */ |
|
211 require_once 'Zend/Mail/Storage/Exception.php'; |
|
212 throw new Zend_Mail_Storage_Exception("folder $rootFolder not found"); |
|
213 } |
|
214 return $currentFolder; |
|
215 } |
|
216 |
|
217 /** |
|
218 * select given folder |
|
219 * |
|
220 * folder must be selectable! |
|
221 * |
|
222 * @param Zend_Mail_Storage_Folder|string $globalName global name of folder or instance for subfolder |
|
223 * @return null |
|
224 * @throws Zend_Mail_Storage_Exception |
|
225 */ |
|
226 public function selectFolder($globalName) |
|
227 { |
|
228 $this->_currentFolder = (string)$globalName; |
|
229 |
|
230 // getting folder from folder tree for validation |
|
231 $folder = $this->getFolders($this->_currentFolder); |
|
232 |
|
233 try { |
|
234 $this->_openMaildir($this->_rootdir . '.' . $folder->getGlobalName()); |
|
235 } catch(Zend_Mail_Storage_Exception $e) { |
|
236 // check what went wrong |
|
237 if (!$folder->isSelectable()) { |
|
238 /** |
|
239 * @see Zend_Mail_Storage_Exception |
|
240 */ |
|
241 require_once 'Zend/Mail/Storage/Exception.php'; |
|
242 throw new Zend_Mail_Storage_Exception("{$this->_currentFolder} is not selectable", 0, $e); |
|
243 } |
|
244 // seems like file has vanished; rebuilding folder tree - but it's still an exception |
|
245 $this->_buildFolderTree($this->_rootdir); |
|
246 /** |
|
247 * @see Zend_Mail_Storage_Exception |
|
248 */ |
|
249 require_once 'Zend/Mail/Storage/Exception.php'; |
|
250 throw new Zend_Mail_Storage_Exception('seems like the maildir has vanished, I\'ve rebuild the ' . |
|
251 'folder tree, search for an other folder and try again', 0, $e); |
|
252 } |
|
253 } |
|
254 |
|
255 /** |
|
256 * get Zend_Mail_Storage_Folder instance for current folder |
|
257 * |
|
258 * @return Zend_Mail_Storage_Folder instance of current folder |
|
259 * @throws Zend_Mail_Storage_Exception |
|
260 */ |
|
261 public function getCurrentFolder() |
|
262 { |
|
263 return $this->_currentFolder; |
|
264 } |
|
265 } |