00001 <?php
00027 require_once 'Zend/Mail/Storage/Abstract.php';
00028
00032 require_once 'Zend/Mail/Protocol/Imap.php';
00033
00037 require_once 'Zend/Mail/Storage/Writable/Interface.php';
00038
00042 require_once 'Zend/Mail/Storage/Folder/Interface.php';
00043
00047 require_once 'Zend/Mail/Storage/Folder.php';
00048
00052 require_once 'Zend/Mail/Message.php';
00053
00057 require_once 'Zend/Mail/Storage.php';
00058
00066 class Zend_Mail_Storage_Imap extends Zend_Mail_Storage_Abstract
00067 implements Zend_Mail_Storage_Folder_Interface, Zend_Mail_Storage_Writable_Interface
00068 {
00069
00070
00071
00076 protected $_protocol;
00077
00082 protected $_currentFolder = '';
00083
00088 protected static $_knownFlags = array('\Passed' => Zend_Mail_Storage::FLAG_PASSED,
00089 '\Answered' => Zend_Mail_Storage::FLAG_ANSWERED,
00090 '\Seen' => Zend_Mail_Storage::FLAG_SEEN,
00091 '\Deleted' => Zend_Mail_Storage::FLAG_DELETED,
00092 '\Draft' => Zend_Mail_Storage::FLAG_DRAFT,
00093 '\Flagged' => Zend_Mail_Storage::FLAG_FLAGGED);
00094
00099 protected static $_searchFlags = array('\Recent' => 'RECENT',
00100 '\Answered' => 'ANSWERED',
00101 '\Seen' => 'SEEN',
00102 '\Deleted' => 'DELETED',
00103 '\Draft' => 'DRAFT',
00104 '\Flagged' => 'FLAGGED');
00105
00113 public function countMessages($flags = null)
00114 {
00115 if (!$this->_currentFolder) {
00119 require_once 'Zend/Mail/Storage/Exception.php';
00120 throw new Zend_Mail_Storage_Exception('No selected folder to count');
00121 }
00122
00123 if ($flags === null) {
00124 return count($this->_protocol->search(array('ALL')));
00125 }
00126
00127 $params = array();
00128 foreach ((array)$flags as $flag) {
00129 if (isset(self::$_searchFlags[$flag])) {
00130 $params[] = self::$_searchFlags[$flag];
00131 } else {
00132 $params[] = 'KEYWORD';
00133 $params[] = $this->_protocol->escapeString($flag);
00134 }
00135 }
00136 return count($this->_protocol->search($params));
00137 }
00138
00146 public function getSize($id = 0)
00147 {
00148 if ($id) {
00149 return $this->_protocol->fetch('RFC822.SIZE', $id);
00150 }
00151 return $this->_protocol->fetch('RFC822.SIZE', 1, INF);
00152 }
00153
00161 public function getMessage($id)
00162 {
00163 $data = $this->_protocol->fetch(array('FLAGS', 'RFC822.HEADER'), $id);
00164 $header = $data['RFC822.HEADER'];
00165
00166 $flags = array();
00167 foreach ($data['FLAGS'] as $flag) {
00168 $flags[] = isset(self::$_knownFlags[$flag]) ? self::$_knownFlags[$flag] : $flag;
00169 }
00170
00171 return new $this->_messageClass(array('handler' => $this, 'id' => $id, 'headers' => $header, 'flags' => $flags));
00172 }
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185 public function getRawHeader($id, $part = null, $topLines = 0)
00186 {
00187 if ($part !== null) {
00188
00192 require_once 'Zend/Mail/Storage/Exception.php';
00193 throw new Zend_Mail_Storage_Exception('not implemented');
00194 }
00195
00196
00197 return $this->_protocol->fetch('RFC822.HEADER', $id);
00198 }
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209 public function getRawContent($id, $part = null)
00210 {
00211 if ($part !== null) {
00212
00216 require_once 'Zend/Mail/Storage/Exception.php';
00217 throw new Zend_Mail_Storage_Exception('not implemented');
00218 }
00219
00220 return $this->_protocol->fetch('RFC822.TEXT', $id);
00221 }
00222
00237 public function __construct($params)
00238 {
00239 if (is_array($params)) {
00240 $params = (object)$params;
00241 }
00242
00243 $this->_has['flags'] = true;
00244
00245 if ($params instanceof Zend_Mail_Protocol_Imap) {
00246 $this->_protocol = $params;
00247 try {
00248 $this->selectFolder('INBOX');
00249 } catch(Zend_Mail_Storage_Exception $e) {
00253 require_once 'Zend/Mail/Storage/Exception.php';
00254 throw new Zend_Mail_Storage_Exception('cannot select INBOX, is this a valid transport?');
00255 }
00256 return;
00257 }
00258
00259 if (!isset($params->user)) {
00263 require_once 'Zend/Mail/Storage/Exception.php';
00264 throw new Zend_Mail_Storage_Exception('need at least user in params');
00265 }
00266
00267 $host = isset($params->host) ? $params->host : 'localhost';
00268 $password = isset($params->password) ? $params->password : '';
00269 $port = isset($params->port) ? $params->port : null;
00270 $ssl = isset($params->ssl) ? $params->ssl : false;
00271
00272 $this->_protocol = new Zend_Mail_Protocol_Imap();
00273 $this->_protocol->connect($host, $port, $ssl);
00274 if (!$this->_protocol->login($params->user, $password)) {
00278 require_once 'Zend/Mail/Storage/Exception.php';
00279 throw new Zend_Mail_Storage_Exception('cannot login, user or password wrong');
00280 }
00281 $this->selectFolder(isset($params->folder) ? $params->folder : 'INBOX');
00282 }
00283
00290 public function close()
00291 {
00292 $this->_currentFolder = '';
00293 $this->_protocol->logout();
00294 }
00295
00302 public function noop()
00303 {
00304 if (!$this->_protocol->noop()) {
00308 require_once 'Zend/Mail/Storage/Exception.php';
00309 throw new Zend_Mail_Storage_Exception('could not do nothing');
00310 }
00311 }
00312
00322 public function removeMessage($id)
00323 {
00324 if (!$this->_protocol->store(array(Zend_Mail_Storage::FLAG_DELETED), $id, null, '+')) {
00328 require_once 'Zend/Mail/Storage/Exception.php';
00329 throw new Zend_Mail_Storage_Exception('cannot set deleted flag');
00330 }
00331
00332 if (!$this->_protocol->expunge()) {
00336 require_once 'Zend/Mail/Storage/Exception.php';
00337 throw new Zend_Mail_Storage_Exception('message marked as deleted, but could not expunge');
00338 }
00339 }
00340
00350 public function getUniqueId($id = null)
00351 {
00352 if ($id) {
00353 return $this->_protocol->fetch('UID', $id);
00354 }
00355
00356 return $this->_protocol->fetch('UID', 1, INF);
00357 }
00358
00369 public function getNumberByUniqueId($id)
00370 {
00371
00372 $ids = $this->getUniqueId();
00373 foreach ($ids as $k => $v) {
00374 if ($v == $id) {
00375 return $k;
00376 }
00377 }
00378
00382 require_once 'Zend/Mail/Storage/Exception.php';
00383 throw new Zend_Mail_Storage_Exception('unique id not found');
00384 }
00385
00386
00395 public function getFolders($rootFolder = null)
00396 {
00397 $folders = $this->_protocol->listMailbox((string)$rootFolder);
00398 if (!$folders) {
00402 require_once 'Zend/Mail/Storage/Exception.php';
00403 throw new Zend_Mail_Storage_Exception('folder not found');
00404 }
00405
00406 ksort($folders, SORT_STRING);
00407 $root = new Zend_Mail_Storage_Folder('/', '/', false);
00408 $stack = array(null);
00409 $folderStack = array(null);
00410 $parentFolder = $root;
00411 $parent = '';
00412
00413 foreach ($folders as $globalName => $data) {
00414 do {
00415 if (!$parent || strpos($globalName, $parent) === 0) {
00416 $pos = strrpos($globalName, $data['delim']);
00417 if ($pos === false) {
00418 $localName = $globalName;
00419 } else {
00420 $localName = substr($globalName, $pos + 1);
00421 }
00422 $selectable = !$data['flags'] || !in_array('\\Noselect', $data['flags']);
00423
00424 array_push($stack, $parent);
00425 $parent = $globalName . $data['delim'];
00426 $folder = new Zend_Mail_Storage_Folder($localName, $globalName, $selectable);
00427 $parentFolder->$localName = $folder;
00428 array_push($folderStack, $parentFolder);
00429 $parentFolder = $folder;
00430 break;
00431 } else if ($stack) {
00432 $parent = array_pop($stack);
00433 $parentFolder = array_pop($folderStack);
00434 }
00435 } while ($stack);
00436 if (!$stack) {
00440 require_once 'Zend/Mail/Storage/Exception.php';
00441 throw new Zend_Mail_Storage_Exception('error while constructing folder tree');
00442 }
00443 }
00444
00445 return $root;
00446 }
00447
00458 public function selectFolder($globalName)
00459 {
00460 $this->_currentFolder = $globalName;
00461 if (!$this->_protocol->select($this->_currentFolder)) {
00462 $this->_currentFolder = '';
00466 require_once 'Zend/Mail/Storage/Exception.php';
00467 throw new Zend_Mail_Storage_Exception('cannot change folder, maybe it does not exist');
00468 }
00469 }
00470
00471
00478 public function getCurrentFolder()
00479 {
00480 return $this->_currentFolder;
00481 }
00482
00494 public function createFolder($name, $parentFolder = null)
00495 {
00496
00497 if ($parentFolder instanceof Zend_Mail_Storage_Folder) {
00498 $folder = $parentFolder->getGlobalName() . '/' . $name;
00499 } else if ($parentFolder != null) {
00500 $folder = $parentFolder . '/' . $name;
00501 } else {
00502 $folder = $name;
00503 }
00504
00505 if (!$this->_protocol->create($folder)) {
00509 require_once 'Zend/Mail/Storage/Exception.php';
00510 throw new Zend_Mail_Storage_Exception('cannot create folder');
00511 }
00512 }
00513
00521 public function removeFolder($name)
00522 {
00523 if ($name instanceof Zend_Mail_Storage_Folder) {
00524 $name = $name->getGlobalName();
00525 }
00526
00527 if (!$this->_protocol->delete($name)) {
00531 require_once 'Zend/Mail/Storage/Exception.php';
00532 throw new Zend_Mail_Storage_Exception('cannot delete folder');
00533 }
00534 }
00535
00546 public function renameFolder($oldName, $newName)
00547 {
00548 if ($oldName instanceof Zend_Mail_Storage_Folder) {
00549 $oldName = $oldName->getGlobalName();
00550 }
00551
00552 if (!$this->_protocol->rename($oldName, $newName)) {
00556 require_once 'Zend/Mail/Storage/Exception.php';
00557 throw new Zend_Mail_Storage_Exception('cannot rename folder');
00558 }
00559 }
00560
00569
00570 public function appendMessage($message, $folder = null, $flags = null)
00571 {
00572 if ($folder === null) {
00573 $folder = $this->_currentFolder;
00574 }
00575
00576 if ($flags === null) {
00577 $flags = array(Zend_Mail_Storage::FLAG_SEEN);
00578 }
00579
00580
00581 if (!$this->_protocol->append($folder, $message, $flags)) {
00585 require_once 'Zend/Mail/Storage/Exception.php';
00586 throw new Zend_Mail_Storage_Exception('cannot create message, please check if the folder exists and your flags');
00587 }
00588 }
00589
00598 public function copyMessage($id, $folder)
00599 {
00600 if (!$this->_protocol->copy($folder, $id)) {
00604 require_once 'Zend/Mail/Storage/Exception.php';
00605 throw new Zend_Mail_Storage_Exception('cannot copy message, does the folder exist?');
00606 }
00607 }
00608
00619 public function moveMessage($id, $folder) {
00620 $this->copyMessage($id, $folder);
00621 $this->removeMessage($id);
00622 }
00623
00633 public function setFlags($id, $flags)
00634 {
00635 if (!$this->_protocol->store($flags, $id)) {
00639 require_once 'Zend/Mail/Storage/Exception.php';
00640 throw new Zend_Mail_Storage_Exception('cannot set flags, have you tried to set the recent flag or special chars?');
00641 }
00642 }
00643 }
00644