protected function _getMailboxList($pattern, $mode, $options, $subscribed = null)
{
// Setup entry for use in _parseList().
$pipeline = $this->_pipeline();
$pipeline->data['mailboxlist'] = array('ext' => false, 'mode' => $mode, 'opts' => $options, 'sub' => is_null($subscribed) ? null : array_flip(array_map('strval', $subscribed)) + array('INBOX' => true));
$pipeline->data['listresponse'] = array();
$cmds = array();
$return_opts = new Horde_Imap_Client_Data_Format_List();
if ($this->_capability('LIST-EXTENDED') && empty($options['no_listext'])) {
$cmd = $this->_command('LIST');
$pipeline->data['mailboxlist']['ext'] = true;
$select_opts = new Horde_Imap_Client_Data_Format_List();
$subscribed = false;
switch ($mode) {
case Horde_Imap_Client::MBOX_ALL_SUBSCRIBED:
case Horde_Imap_Client::MBOX_UNSUBSCRIBED:
$return_opts->add('SUBSCRIBED');
break;
case Horde_Imap_Client::MBOX_SUBSCRIBED:
case Horde_Imap_Client::MBOX_SUBSCRIBED_EXISTS:
$select_opts->add('SUBSCRIBED');
$return_opts->add('SUBSCRIBED');
$subscribed = true;
break;
}
if (!empty($options['remote'])) {
$select_opts->add('REMOTE');
}
if (!empty($options['recursivematch'])) {
$select_opts->add('RECURSIVEMATCH');
}
if (!empty($select_opts)) {
$cmd->add($select_opts);
}
$cmd->add('');
$tmp = new Horde_Imap_Client_Data_Format_List();
foreach ($pattern as $val) {
if ($subscribed && strcasecmp($val, 'INBOX') === 0) {
$cmds[] = $this->_command('LIST')->add(array('', 'INBOX'));
} else {
$tmp->add($this->_getMboxFormatOb($val, true));
}
}
if (count($tmp)) {
$cmd->add($tmp);
$cmds[] = $cmd;
}
if (!empty($options['children'])) {
$return_opts->add('CHILDREN');
}
if (!empty($options['special_use'])) {
$return_opts->add('SPECIAL-USE');
}
} else {
foreach ($pattern as $val) {
$cmds[] = $this->_command($mode == Horde_Imap_Client::MBOX_SUBSCRIBED ? 'LSUB' : 'LIST')->add(array('', $this->_getMboxFormatOb($val, true)));
}
}
/* LIST-STATUS does NOT depend on LIST-EXTENDED. */
if (!empty($options['status']) && $this->_capability('LIST-STATUS')) {
$available_status = array(Horde_Imap_Client::STATUS_MESSAGES, Horde_Imap_Client::STATUS_RECENT, Horde_Imap_Client::STATUS_UIDNEXT, Horde_Imap_Client::STATUS_UIDVALIDITY, Horde_Imap_Client::STATUS_UNSEEN, Horde_Imap_Client::STATUS_HIGHESTMODSEQ);
$status_opts = array();
foreach (array_intersect($this->_statusFields, $available_status) as $key => $val) {
if ($options['status'] & $val) {
$status_opts[] = $key;
}
}
if (count($status_opts)) {
$return_opts->add(array('STATUS', new Horde_Imap_Client_Data_Format_List(array_map('Horde_String::upper', $status_opts))));
}
}
foreach ($cmds as $val) {
if (count($return_opts)) {
$val->add(array('RETURN', $return_opts));
}
$pipeline->add($val);
}
try {
$lr = $this->_sendCmd($pipeline)->data['listresponse'];
} catch (Horde_Imap_Client_Exception_ServerResponse $e) {
/* Archiveopteryx 3.1.3 can't process empty list-select-opts list.
* Retry using base IMAP4rev1 functionality. */
if ($e->status === Horde_Imap_Client_Interaction_Server::BAD && $this->_capability('LIST-EXTENDED')) {
$this->_capability()->remove('LIST-EXTENDED');
return $this->_listMailboxes($pattern, $mode, $options);
}
throw $e;
}
if (!empty($options['flat'])) {
return array_values($lr);
}
/* Add in STATUS return, if needed. */
if (!empty($options['status']) && $this->_capability('LIST-STATUS')) {
foreach ($pattern as $val) {
$val_utf8 = Horde_Imap_Client_Utf7imap::Utf7ImapToUtf8($val);
if (isset($lr[$val_utf8])) {
$lr[$val_utf8]['status'] = $this->_prepareStatusResponse($status_opts, $val_utf8);
}
}
}
return $lr;
}