PageRenderTime 44ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/app/classes/Zend/Mail/Storage/Folder/Maildir.php

https://gitlab.com/jalon/doadoronline
PHP | 211 lines | 151 code | 14 blank | 46 comment | 6 complexity | 6961bee8df85773aca476db9a85d41a3 MD5 | raw file
  1. <?php
  2. /**
  3. * Zend Framework (http://framework.zend.com/)
  4. *
  5. * @link http://github.com/zendframework/zf2 for the canonical source repository
  6. * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
  7. * @license http://framework.zend.com/license/new-bsd New BSD License
  8. */
  9. namespace Zend\Mail\Storage\Folder;
  10. use Zend\Mail\Storage;
  11. use Zend\Mail\Storage\Exception;
  12. use Zend\Stdlib\ErrorHandler;
  13. class Maildir extends Storage\Maildir implements FolderInterface
  14. {
  15. /**
  16. * root folder for folder structure
  17. * @var \Zend\Mail\Storage\Folder
  18. */
  19. protected $rootFolder;
  20. /**
  21. * rootdir of folder structure
  22. * @var string
  23. */
  24. protected $rootdir;
  25. /**
  26. * name of current folder
  27. * @var string
  28. */
  29. protected $currentFolder;
  30. /**
  31. * delim char for subfolders
  32. * @var string
  33. */
  34. protected $delim;
  35. /**
  36. * Create instance with parameters
  37. * Supported parameters are:
  38. * - dirname rootdir of maildir structure
  39. * - delim delim char for folder structure, default is '.'
  40. * - folder initial selected folder, default is 'INBOX'
  41. *
  42. * @param $params array mail reader specific parameters
  43. * @throws \Zend\Mail\Storage\Exception\InvalidArgumentException
  44. */
  45. public function __construct($params)
  46. {
  47. if (is_array($params)) {
  48. $params = (object) $params;
  49. }
  50. if (!isset($params->dirname) || !is_dir($params->dirname)) {
  51. throw new Exception\InvalidArgumentException('no valid dirname given in params');
  52. }
  53. $this->rootdir = rtrim($params->dirname, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
  54. $this->delim = isset($params->delim) ? $params->delim : '.';
  55. $this->_buildFolderTree();
  56. $this->selectFolder(!empty($params->folder) ? $params->folder : 'INBOX');
  57. $this->has['top'] = true;
  58. $this->has['flags'] = true;
  59. }
  60. /**
  61. * find all subfolders and mbox files for folder structure
  62. *
  63. * Result is save in \Zend\Mail\Storage\Folder instances with the root in $this->rootFolder.
  64. * $parentFolder and $parentGlobalName are only used internally for recursion.
  65. *
  66. * @throws \Zend\Mail\Storage\Exception\RuntimeException
  67. */
  68. protected function _buildFolderTree()
  69. {
  70. $this->rootFolder = new Storage\Folder('/', '/', false);
  71. $this->rootFolder->INBOX = new Storage\Folder('INBOX', 'INBOX', true);
  72. ErrorHandler::start(E_WARNING);
  73. $dh = opendir($this->rootdir);
  74. $error = ErrorHandler::stop();
  75. if (!$dh) {
  76. throw new Exception\RuntimeException("can't read folders in maildir", 0, $error);
  77. }
  78. $dirs = array();
  79. while (($entry = readdir($dh)) !== false) {
  80. // maildir++ defines folders must start with .
  81. if ($entry[0] != '.' || $entry == '.' || $entry == '..') {
  82. continue;
  83. }
  84. if ($this->_isMaildir($this->rootdir . $entry)) {
  85. $dirs[] = $entry;
  86. }
  87. }
  88. closedir($dh);
  89. sort($dirs);
  90. $stack = array(null);
  91. $folderStack = array(null);
  92. $parentFolder = $this->rootFolder;
  93. $parent = '.';
  94. foreach ($dirs as $dir) {
  95. do {
  96. if (strpos($dir, $parent) === 0) {
  97. $local = substr($dir, strlen($parent));
  98. if (strpos($local, $this->delim) !== false) {
  99. throw new Exception\RuntimeException('error while reading maildir');
  100. }
  101. array_push($stack, $parent);
  102. $parent = $dir . $this->delim;
  103. $folder = new Storage\Folder($local, substr($dir, 1), true);
  104. $parentFolder->$local = $folder;
  105. array_push($folderStack, $parentFolder);
  106. $parentFolder = $folder;
  107. break;
  108. } elseif ($stack) {
  109. $parent = array_pop($stack);
  110. $parentFolder = array_pop($folderStack);
  111. }
  112. } while ($stack);
  113. if (!$stack) {
  114. throw new Exception\RuntimeException('error while reading maildir');
  115. }
  116. }
  117. }
  118. /**
  119. * get root folder or given folder
  120. *
  121. * @param string $rootFolder get folder structure for given folder, else root
  122. * @throws \Zend\Mail\Storage\Exception\InvalidArgumentException
  123. * @return \Zend\Mail\Storage\Folder root or wanted folder
  124. */
  125. public function getFolders($rootFolder = null)
  126. {
  127. if (!$rootFolder || $rootFolder == 'INBOX') {
  128. return $this->rootFolder;
  129. }
  130. // rootdir is same as INBOX in maildir
  131. if (strpos($rootFolder, 'INBOX' . $this->delim) === 0) {
  132. $rootFolder = substr($rootFolder, 6);
  133. }
  134. $currentFolder = $this->rootFolder;
  135. $subname = trim($rootFolder, $this->delim);
  136. while ($currentFolder) {
  137. ErrorHandler::start(E_NOTICE);
  138. list($entry, $subname) = explode($this->delim, $subname, 2);
  139. ErrorHandler::stop();
  140. $currentFolder = $currentFolder->$entry;
  141. if (!$subname) {
  142. break;
  143. }
  144. }
  145. if ($currentFolder->getGlobalName() != rtrim($rootFolder, $this->delim)) {
  146. throw new Exception\InvalidArgumentException("folder $rootFolder not found");
  147. }
  148. return $currentFolder;
  149. }
  150. /**
  151. * select given folder
  152. *
  153. * folder must be selectable!
  154. *
  155. * @param \Zend\Mail\Storage\Folder|string $globalName global name of folder or instance for subfolder
  156. * @throws \Zend\Mail\Storage\Exception\RuntimeException
  157. */
  158. public function selectFolder($globalName)
  159. {
  160. $this->currentFolder = (string) $globalName;
  161. // getting folder from folder tree for validation
  162. $folder = $this->getFolders($this->currentFolder);
  163. try {
  164. $this->_openMaildir($this->rootdir . '.' . $folder->getGlobalName());
  165. } catch (Exception\ExceptionInterface $e) {
  166. // check what went wrong
  167. if (!$folder->isSelectable()) {
  168. throw new Exception\RuntimeException("{$this->currentFolder} is not selectable", 0, $e);
  169. }
  170. // seems like file has vanished; rebuilding folder tree - but it's still an exception
  171. $this->_buildFolderTree();
  172. throw new Exception\RuntimeException('seems like the maildir has vanished, I\'ve rebuild the ' .
  173. 'folder tree, search for an other folder and try again', 0, $e);
  174. }
  175. }
  176. /**
  177. * get \Zend\Mail\Storage\Folder instance for current folder
  178. *
  179. * @return \Zend\Mail\Storage\Folder instance of current folder
  180. */
  181. public function getCurrentFolder()
  182. {
  183. return $this->currentFolder;
  184. }
  185. }