protected function _openMailbox(Horde_Imap_Client_Mailbox $mailbox, $mode)
{
$c = $this->_capability();
$qresync = $c->isEnabled('QRESYNC');
$cmd = $this->_command($mode == Horde_Imap_Client::OPEN_READONLY ? 'EXAMINE' : 'SELECT')->add($this->_getMboxFormatOb($mailbox));
$pipeline = $this->_pipeline($cmd);
/* If QRESYNC is available, synchronize the mailbox. */
if ($qresync) {
$this->_initCache();
$md = $this->_cache->getMetaData($mailbox, null, array(self::CACHE_MODSEQ, 'uidvalid'));
/* CACHE_MODSEQ can be set but 0 (NOMODSEQ was returned). */
if (!empty($md[self::CACHE_MODSEQ])) {
if ($uids = $this->_cache->get($mailbox)) {
$uids = $this->getIdsOb($uids);
/* Check for extra long UID string. Assume that any
* server that can handle QRESYNC can also handle long
* input strings (at least 8 KB), so 7 KB is as good as
* any guess as to an upper limit. If this occurs, provide
* a range string (min -> max) instead. */
if (strlen($uid_str = $uids->tostring_sort) > 7000) {
$uid_str = $uids->range_string;
}
} else {
$uid_str = null;
}
/* Several things can happen with a QRESYNC:
* 1. UIDVALIDITY may have changed. If so, we need to expire
* the cache immediately (done below).
* 2. NOMODSEQ may have been returned. We can keep current
* message cache data but won't be able to do flag caching.
* 3. VANISHED/FETCH information was returned. These responses
* will have already been handled by those response handlers.
* 4. We are already synced with the local server in which
* case it acts like a normal EXAMINE/SELECT. */
$cmd->add(new Horde_Imap_Client_Data_Format_List(array('QRESYNC', new Horde_Imap_Client_Data_Format_List(array_filter(array($md['uidvalid'], $md[self::CACHE_MODSEQ], $uid_str))))));
}
/* Let the 'CLOSED' response code handle mailbox switching if
* QRESYNC is active. */
if ($this->_selected) {
$pipeline->data['qresyncmbox'] = array($mailbox, $mode);
} else {
$this->_changeSelected($mailbox, $mode);
}
} else {
if (!$c->isEnabled('CONDSTORE') && $this->_initCache() && $c->query('CONDSTORE')) {
/* Activate CONDSTORE now if ENABLE is not available. */
$cmd->add(new Horde_Imap_Client_Data_Format_List('CONDSTORE'));
$c->enable('CONDSTORE');
}
$this->_changeSelected($mailbox, $mode);
}
try {
$this->_sendCmd($pipeline);
} catch (Horde_Imap_Client_Exception_ServerResponse $e) {
// An EXAMINE/SELECT failure with a return of 'NO' will cause the
// current mailbox to be unselected.
if ($e->status === Horde_Imap_Client_Interaction_Server::NO) {
$this->_changeSelected(null);
$this->_mode = 0;
if (!$e->getCode()) {
$e = new Horde_Imap_Client_Exception(Horde_Imap_Client_Translation::r("Could not open mailbox \"%s\"."), Horde_Imap_Client_Exception::MAILBOX_NOOPEN);
$e->messagePrintf(array($mailbox));
}
}
throw $e;
}
if ($qresync) {
/* Mailbox is fully sync'd. */
$this->_mailboxOb()->sync = true;
}
}