/**
* Resolves an IDs object into a list of IDs.
*
* @param Horde_Imap_Client_Mailbox $mailbox The mailbox.
* @param Horde_Imap_Client_Ids $ids The Ids object.
* @param integer $convert Convert to UIDs?
* - 0: No
* - 1: Only if $ids is not already a UIDs object
* - 2: Always
*
* @return Horde_Imap_Client_Ids The list of IDs.
*/
public function resolveIds(Horde_Imap_Client_Mailbox $mailbox, Horde_Imap_Client_Ids $ids, $convert = 0)
{
$map = $this->_mailboxOb($mailbox)->map;
if ($ids->special) {
/* Optimization for ALL sequence searches. */
if (!$convert && $ids->all && $ids->sequence) {
$res = $this->status($mailbox, Horde_Imap_Client::STATUS_MESSAGES);
return $this->getIdsOb($res['messages'] ? '1:' . $res['messages'] : array(), true);
}
$convert = 2;
} elseif (!$convert || !$ids->sequence && $convert == 1 || $ids->isEmpty()) {
return clone $ids;
} else {
/* Do an all or nothing: either we have all the numbers/UIDs in
* memory and can return, or just send the whole ID query to the
* server. Any advantage we would get by a partial search are
* outweighed by the complexities needed to make the search and
* then merge back into the original results. */
$lookup = $map->lookup($ids);
if (count($lookup) === count($ids)) {
return $this->getIdsOb(array_values($lookup));
}
}
$query = new Horde_Imap_Client_Search_Query();
$query->ids($ids);
$res = $this->search($mailbox, $query, array('results' => array(Horde_Imap_Client::SEARCH_RESULTS_MATCH, Horde_Imap_Client::SEARCH_RESULTS_SAVE), 'sequence' => !$convert && $ids->sequence, 'sort' => array(Horde_Imap_Client::SORT_SEQUENCE)));
/* Update mapping. */
if ($convert) {
if ($ids->all) {
$ids = $this->getIdsOb('1:' . count($res['match']));
} elseif ($ids->special) {
return $res['match'];
}
/* Sanity checking (Bug #12911). */
$list1 = array_slice($ids->ids, 0, count($res['match']));
$list2 = $res['match']->ids;
if (!empty($list1) && !empty($list2) && count($list1) === count($list2)) {
$map->update(array_combine($list1, $list2));
}
}
return $res['match'];
}