PageRenderTime 26ms CodeModel.GetById 1ms RepoModel.GetById 1ms app.codeStats 0ms

/library/Mail/Storage/Folder/Maildir.php

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