00001 <?php
00027 require_once 'Zend/Mail/Storage/Abstract.php';
00028
00032 require_once 'Zend/Mail/Message/File.php';
00033
00037 require_once 'Zend/Mail/Storage.php';
00038
00039
00047 class Zend_Mail_Storage_Maildir extends Zend_Mail_Storage_Abstract
00048 {
00053 protected $_messageClass = 'Zend_Mail_Message_File';
00054
00059 protected $_files = array();
00060
00068 protected static $_knownFlags = array('D' => Zend_Mail_Storage::FLAG_DRAFT,
00069 'F' => Zend_Mail_Storage::FLAG_FLAGGED,
00070 'P' => Zend_Mail_Storage::FLAG_PASSED,
00071 'R' => Zend_Mail_Storage::FLAG_ANSWERED,
00072 'S' => Zend_Mail_Storage::FLAG_SEEN,
00073 'T' => Zend_Mail_Storage::FLAG_DELETED);
00074
00075
00076
00083 public function countMessages($flags = null)
00084 {
00085 if ($flags === null) {
00086 return count($this->_files);
00087 }
00088
00089 $count = 0;
00090 if (!is_array($flags)) {
00091 foreach ($this->_files as $file) {
00092 if (isset($file['flaglookup'][$flags])) {
00093 ++$count;
00094 }
00095 }
00096 return $count;
00097 }
00098
00099 $flags = array_flip($flags);
00100 foreach ($this->_files as $file) {
00101 foreach ($flags as $flag => $v) {
00102 if (!isset($file['flaglookup'][$flag])) {
00103 continue 2;
00104 }
00105 }
00106 ++$count;
00107 }
00108 return $count;
00109 }
00110
00119 protected function _getFileData($id, $field = null)
00120 {
00121 if (!isset($this->_files[$id - 1])) {
00125 require_once 'Zend/Mail/Storage/Exception.php';
00126 throw new Zend_Mail_Storage_Exception('id does not exist');
00127 }
00128
00129 if (!$field) {
00130 return $this->_files[$id - 1];
00131 }
00132
00133 if (!isset($this->_files[$id - 1][$field])) {
00137 require_once 'Zend/Mail/Storage/Exception.php';
00138 throw new Zend_Mail_Storage_Exception('field does not exist');
00139 }
00140
00141 return $this->_files[$id - 1][$field];
00142 }
00143
00151 public function getSize($id = null)
00152 {
00153 if ($id !== null) {
00154 $filedata = $this->_getFileData($id);
00155 return isset($filedata['size']) ? $filedata['size'] : filesize($filedata['filename']);
00156 }
00157
00158 $result = array();
00159 foreach ($this->_files as $num => $data) {
00160 $result[$num + 1] = isset($data['size']) ? $data['size'] : filesize($data['filename']);
00161 }
00162
00163 return $result;
00164 }
00165
00166
00167
00175 public function getMessage($id)
00176 {
00177
00178 if (strtolower($this->_messageClass) == 'zend_mail_message_file' || is_subclass_of($this->_messageClass, 'zend_mail_message_file')) {
00179 return new $this->_messageClass(array('file' => $this->_getFileData($id, 'filename'),
00180 'flags' => $this->_getFileData($id, 'flags')));
00181 }
00182
00183 return new $this->_messageClass(array('handler' => $this, 'id' => $id, 'headers' => $this->getRawHeader($id),
00184 'flags' => $this->_getFileData($id, 'flags')));
00185 }
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196 public function getRawHeader($id, $part = null, $topLines = 0)
00197 {
00198 if ($part !== null) {
00199
00203 require_once 'Zend/Mail/Storage/Exception.php';
00204 throw new Zend_Mail_Storage_Exception('not implemented');
00205 }
00206
00207 $fh = fopen($this->_getFileData($id, 'filename'), 'r');
00208
00209 $content = '';
00210 while (!feof($fh)) {
00211 $line = fgets($fh);
00212 if (!trim($line)) {
00213 break;
00214 }
00215 $content .= $line;
00216 }
00217
00218 fclose($fh);
00219 return $content;
00220 }
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230 public function getRawContent($id, $part = null)
00231 {
00232 if ($part !== null) {
00233
00237 require_once 'Zend/Mail/Storage/Exception.php';
00238 throw new Zend_Mail_Storage_Exception('not implemented');
00239 }
00240
00241 $fh = fopen($this->_getFileData($id, 'filename'), 'r');
00242
00243 while (!feof($fh)) {
00244 $line = fgets($fh);
00245 if (!trim($line)) {
00246 break;
00247 }
00248 }
00249
00250 $content = stream_get_contents($fh);
00251 fclose($fh);
00252 return $content;
00253 }
00254
00263 public function __construct($params)
00264 {
00265 if (is_array($params)) {
00266 $params = (object)$params;
00267 }
00268
00269 if (!isset($params->dirname) || !is_dir($params->dirname)) {
00273 require_once 'Zend/Mail/Storage/Exception.php';
00274 throw new Zend_Mail_Storage_Exception('no valid dirname given in params');
00275 }
00276
00277 if (!$this->_isMaildir($params->dirname)) {
00281 require_once 'Zend/Mail/Storage/Exception.php';
00282 throw new Zend_Mail_Storage_Exception('invalid maildir given');
00283 }
00284
00285 $this->_has['top'] = true;
00286 $this->_has['flags'] = true;
00287 $this->_openMaildir($params->dirname);
00288 }
00289
00296 protected function _isMaildir($dirname)
00297 {
00298 if (file_exists($dirname . '/new') && !is_dir($dirname . '/new')) {
00299 return false;
00300 }
00301 if (file_exists($dirname . '/tmp') && !is_dir($dirname . '/tmp')) {
00302 return false;
00303 }
00304 return is_dir($dirname . '/cur');
00305 }
00306
00314 protected function _openMaildir($dirname)
00315 {
00316 if ($this->_files) {
00317 $this->close();
00318 }
00319
00320 $dh = @opendir($dirname . '/cur/');
00321 if (!$dh) {
00325 require_once 'Zend/Mail/Storage/Exception.php';
00326 throw new Zend_Mail_Storage_Exception('cannot open maildir');
00327 }
00328 $this->_getMaildirFiles($dh, $dirname . '/cur/');
00329 closedir($dh);
00330
00331 $dh = @opendir($dirname . '/new/');
00332 if ($dh) {
00333 $this->_getMaildirFiles($dh, $dirname . '/new/', array(Zend_Mail_Storage::FLAG_RECENT));
00334 closedir($dh);
00335 } else if (file_exists($dirname . '/new/')) {
00339 require_once 'Zend/Mail/Storage/Exception.php';
00340 throw new Zend_Mail_Storage_Exception('cannot read recent mails in maildir');
00341 }
00342 }
00343
00352 protected function _getMaildirFiles($dh, $dirname, $default_flags = array())
00353 {
00354 while (($entry = readdir($dh)) !== false) {
00355 if ($entry[0] == '.' || !is_file($dirname . $entry)) {
00356 continue;
00357 }
00358
00359 @list($uniq, $info) = explode(':', $entry, 2);
00360 @list(,$size) = explode(',', $uniq, 2);
00361 if ($size && $size[0] == 'S' && $size[1] == '=') {
00362 $size = substr($size, 2);
00363 }
00364 if (!ctype_digit($size)) {
00365 $size = null;
00366 }
00367 @list($version, $flags) = explode(',', $info, 2);
00368 if ($version != 2) {
00369 $flags = '';
00370 }
00371
00372 $named_flags = $default_flags;
00373 $length = strlen($flags);
00374 for ($i = 0; $i < $length; ++$i) {
00375 $flag = $flags[$i];
00376 $named_flags[$flag] = isset(self::$_knownFlags[$flag]) ? self::$_knownFlags[$flag] : $flag;
00377 }
00378
00379 $data = array('uniq' => $uniq,
00380 'flags' => $named_flags,
00381 'flaglookup' => array_flip($named_flags),
00382 'filename' => $dirname . $entry);
00383 if ($size !== null) {
00384 $data['size'] = (int)$size;
00385 }
00386 $this->_files[] = $data;
00387 }
00388 }
00389
00390
00397 public function close()
00398 {
00399 $this->_files = array();
00400 }
00401
00402
00408 public function noop()
00409 {
00410 return true;
00411 }
00412
00413
00420 public function removeMessage($id)
00421 {
00425 require_once 'Zend/Mail/Storage/Exception.php';
00426 throw new Zend_Mail_Storage_Exception('maildir is (currently) read-only');
00427 }
00428
00438 public function getUniqueId($id = null)
00439 {
00440 if ($id) {
00441 return $this->_getFileData($id, 'uniq');
00442 }
00443
00444 $ids = array();
00445 foreach ($this->_files as $num => $file) {
00446 $ids[$num + 1] = $file['uniq'];
00447 }
00448 return $ids;
00449 }
00450
00461 public function getNumberByUniqueId($id)
00462 {
00463 foreach ($this->_files as $num => $file) {
00464 if ($file['uniq'] == $id) {
00465 return $num + 1;
00466 }
00467 }
00468
00472 require_once 'Zend/Mail/Storage/Exception.php';
00473 throw new Zend_Mail_Storage_Exception('unique id not found');
00474 }
00475 }