Search for messages within a given UID range. Only one message range
can be specified per query.
public ids ( Horde_Imap_Client_Ids $ids, boolean $not = false, array $opts = [] ) | ||
$ids | Horde_Imap_Client_Ids | The list of UIDs to search. |
$not | boolean | If true, do a 'NOT' search of the UIDs. |
$opts | array | Additional options: - fuzzy: (boolean) If true, perform a fuzzy search. The IMAP server MUST support RFC 6203. |
/** * Query the validity of a charset. * * @param string $charset The charset to query. * @param boolean $cached If true, only query cached values. * * @return boolean True if the charset is valid for searching. */ public function query($charset, $cached = false) { $charset = Horde_String::upper($charset); if (isset($this->_charsets[$charset])) { return $this->_charsets[$charset]; } elseif ($cached) { return null; } if (!$this->_baseob) { throw new RuntimeException('Base object needs to be defined to query for charset.'); } /* Use a dummy search query and search for BADCHARSET response. */ $query = new Horde_Imap_Client_Search_Query(); $query->charset($charset, false); $query->ids($this->_baseob->getIdsOb(1, true)); $query->text('a'); try { $this->_baseob->search('INBOX', $query, array('nocache' => true, 'sequence' => true)); $this->_charsets[$charset] = true; } catch (Horde_Imap_Client_Exception $e) { $this->_charsets[$charset] = $e->getCode() !== Horde_Imap_Client_Exception::BADCHARSET; } $this->notify(); return $this->_charsets[$charset]; }
public function testBug13971() { $ob = new Horde_Imap_Client_Search_Query(); $ob->ids(new Horde_Imap_Client_Ids(array())); $ob->text('foo'); $this->assertEquals('', strval($ob)); $ob2 = new Horde_Imap_Client_Search_Query(); $ob2->text('foo2'); $ob2->andSearch($ob); $this->assertEquals('', strval($ob2)); $ob3 = new Horde_Imap_Client_Search_Query(); $ob3->text('foo3'); $ob3->orSearch($ob); $this->assertEquals('BODY foo3', strval($ob3)); $ob2->orSearch($ob3); $this->assertEquals('BODY foo3', strval($ob2)); /* A NOT qualifier on an empty ID list should ignore the list. */ $ob->ids(new Horde_Imap_Client_Ids(array()), true); $this->assertEquals('BODY foo', strval($ob)); }
/** */ protected function _expunge($options) { $expunged_ob = $modseq = null; $ids = $options['ids']; $list_msgs = !empty($options['list']); $uidplus = $this->queryCapability('UIDPLUS'); $unflag = array(); $use_cache = $this->_initCache(true); if ($ids->all) { if (!$uidplus || $list_msgs || $use_cache) { $ids = $this->resolveIds($this->_selected, $ids, 2); } } elseif ($uidplus) { /* If QRESYNC is not available, and we are returning the list of * expunged messages (or we are caching), we have to make sure we * have a mapping of Sequence -> UIDs. If we have QRESYNC, the * server SHOULD return a VANISHED response with UIDs. However, * even if the server returns EXPUNGEs instead, we can use * vanished() to grab the list. */ unset($this->_temp['search_save']); if (isset($this->_temp['enabled']['QRESYNC'])) { $ids = $this->resolveIds($this->_selected, $ids, 1); if ($list_msgs) { $modseq = $this->_mailboxOb()->getStatus(Horde_Imap_Client::STATUS_HIGHESTMODSEQ); } } else { $ids = $this->resolveIds($this->_selected, $ids, $list_msgs || $use_cache ? 2 : 1); } if (!empty($this->_temp['search_save'])) { $ids = $this->getIdsOb(Horde_Imap_Client_Ids::SEARCH_RES); } } else { /* Without UIDPLUS, need to temporarily unflag all messages marked * as deleted but not a part of requested IDs to delete. Use NOT * searches to accomplish this goal. */ $squery = new Horde_Imap_Client_Search_Query(); $squery->flag(Horde_Imap_Client::FLAG_DELETED, true); $squery->ids($ids, true); $s_res = $this->search($this->_selected, $squery, array('results' => array(Horde_Imap_Client::SEARCH_RESULTS_MATCH, Horde_Imap_Client::SEARCH_RESULTS_SAVE))); $this->store($this->_selected, array('ids' => empty($s_res['save']) ? $s_res['match'] : $this->getIdsOb(Horde_Imap_Client_Ids::SEARCH_RES), 'remove' => array(Horde_Imap_Client::FLAG_DELETED))); $unflag = $s_res['match']; } if ($list_msgs) { $expunged_ob = $this->getIdsOb(); $this->_temp['expunged'] = $expunged_ob; } /* Always use UID EXPUNGE if available. */ if ($uidplus) { /* We can only pipeline STORE w/ EXPUNGE if using UIDs and UIDPLUS * is available. */ if (empty($options['delete'])) { $pipeline = $this->_pipeline(); } else { $pipeline = $this->_storeCmd(array('add' => array(Horde_Imap_Client::FLAG_DELETED), 'ids' => $ids)); } foreach ($ids->split(2000) as $val) { $pipeline->add($this->_command('UID EXPUNGE')->add($val)); } $resp = $this->_sendCmd($pipeline); } else { if (!empty($options['delete'])) { $this->store($this->_selected, array('add' => array(Horde_Imap_Client::FLAG_DELETED), 'ids' => $ids)); } if ($use_cache || $list_msgs) { $this->_sendCmd($this->_command('EXPUNGE')); } else { /* This is faster than an EXPUNGE because the server will not * return untagged EXPUNGE responses. We can only do this if * we are not updating cache information. */ $this->close(array('expunge' => true)); } } unset($this->_temp['expunged']); if (!empty($unflag)) { $this->store($this->_selected, array('add' => array(Horde_Imap_Client::FLAG_DELETED), 'ids' => $unflag)); } if (!is_null($modseq) && !empty($resp->data['expunge_seen'])) { /* There's a chance we actually did a full map of sequence -> UID, * but this code should never be reached in the first place so * be ultra-safe and just do a full VANISHED search. */ $expunged_ob = $this->vanished($this->_selected, $modseq, array('ids' => $ids)); $this->_deleteMsgs($this->_selected, $expunged_ob, array('pipeline' => $resp)); } return $expunged_ob; }
/** * Move a mail message * * @param string $folderid The existing folderid. * @param array $ids The message UIDs of the messages to move. * @param string $newfolderid The folder id to move $id to. * * @return array An hash of oldUID => newUID. * * @throws Horde_ActiveSync_Exception */ public function moveMessage($folderid, array $ids, $newfolderid) { $imap = $this->_getImapOb(); $from = new Horde_Imap_Client_Mailbox($folderid); $to = new Horde_Imap_Client_Mailbox($newfolderid); $ids_obj = new Horde_Imap_Client_Ids($ids); // Need to ensure the source message exists so we may properly notify // the client of the error. $search_q = new Horde_Imap_Client_Search_Query(); $search_q->ids($ids_obj); $fetch_res = $imap->search($from, $search_q); if ($fetch_res['count'] != count($ids)) { $ids_obj = $fetch_res['match']; } try { return $imap->copy($from, $to, array('ids' => $ids_obj, 'move' => true, 'force_map' => true)); } catch (Horde_Imap_Client_Exception $e) { // We already got rid of the missing ids, must be something else. $this->_logger->err($e->getMessage()); throw new Horde_ActiveSync_Exception($e); } }
/** */ protected function _expunge($options) { $unflag = array(); $mailbox = clone $this->_selected; $s_res = null; $uidplus = $this->queryCapability('UIDPLUS'); $use_cache = $this->_initCache(true); if ($options['ids']->all) { $uid_string = strval($options['ids']); } elseif ($uidplus) { /* UID EXPUNGE command needs UIDs. */ if ($options['ids']->sequence) { $results = array(Horde_Imap_Client::SEARCH_RESULTS_MATCH); if ($this->queryCapability('SEARCHRES')) { $results[] = Horde_Imap_Client::SEARCH_RESULTS_SAVE; } $s_res = $this->search($mailbox, null, array('results' => $results)); $uid_string = in_array(Horde_Imap_Client::SEARCH_RESULTS_SAVE, $results) && !empty($s_res['save']) ? '$' : strval($s_res['match']); } else { $uid_string = strval($options['ids']); } } else { /* Without UIDPLUS, need to temporarily unflag all messages marked * as deleted but not a part of requested IDs to delete. Use NOT * searches to accomplish this goal. */ $search_query = new Horde_Imap_Client_Search_Query(); $search_query->flag(Horde_Imap_Client::FLAG_DELETED, true); if ($options['ids']->search_res) { $search_query->previousSearch(true); } else { $search_query->ids($options['ids'], true); } $res = $this->search($mailbox, $search_query); $this->store($mailbox, array('ids' => $res['match'], 'remove' => array(Horde_Imap_Client::FLAG_DELETED))); $unflag = $res['match']; } $list_msgs = !empty($options['list']); $tmp =& $this->_temp; $tmp['expunge'] = $tmp['vanished'] = array(); /* We need to get sequence num -> UID lookup table if we are caching. * There is no guarantee that if we are using QRESYNC that we will get * VANISHED responses, so this is unfortunately necessary. */ if (is_null($s_res) && ($list_msgs || $use_cache)) { $s_res = $uidplus ? $this->_getSeqUidLookup($options['ids'], true) : $this->_getSeqUidLookup($this->getIdsOb(Horde_Imap_Client_Ids::ALL, true)); } /* Always use UID EXPUNGE if available. */ if ($uidplus) { $cmd = $this->_clientCommand(array('UID', 'EXPUNGE', $uid_string)); $this->_sendLine($cmd); } elseif ($use_cache || $list_msgs) { $this->_sendLine($this->_clientCommand('EXPUNGE')); } else { /* This is faster than an EXPUNGE because the server will not * return untagged EXPUNGE responses. We can only do this if * we are not updating cache information. */ $this->close(array('expunge' => true)); } if (!empty($unflag)) { $this->store($mailbox, array('add' => array(Horde_Imap_Client::FLAG_DELETED), 'ids' => $unflag)); } if (!$use_cache && !$list_msgs) { return null; } $expunged = array(); if (!empty($tmp['vanished'])) { $expunged = $tmp['vanished']->ids; } elseif (!empty($tmp['expunge'])) { $lookup = $s_res['lookup']; /* Expunge responses can come in any order. Thus, we need to * reindex anytime we have an index that appears equal to or * after a previously seen index. If an IMAP server is smart, * it will expunge in reverse order instead. */ foreach ($tmp['expunge'] as &$val) { $found = false; $tmp2 = array(); foreach (array_keys($lookup) as $i => $seq) { if ($found) { $tmp2[$seq - 1] = $lookup[$seq]; } elseif ($seq == $val) { $expunged[] = $lookup[$seq]; $tmp2 = array_slice($lookup, 0, $i, true); $found = true; } } $lookup = $tmp2; } } if (empty($expunged)) { return null; } if ($use_cache) { $this->_deleteMsgs($mailbox, $expunged); } /* Update MODSEQ if active for mailbox (QRESYNC only; CONDSTORE * requires us to re-SELECT/EXAMINE the mailbox). */ if (!empty($this->_temp['mailbox']['highestmodseq']) && isset($this->_init['enabled']['QRESYNC'])) { $this->_updateMetaData($mailbox, array(self::CACHE_MODSEQ => $this->_temp['mailbox']['highestmodseq']), isset($this->_temp['mailbox']['uidvalidity']) ? $this->_temp['mailbox']['uidvalidity'] : null); } return $list_msgs ? $this->getIdsOb($expunged, $options['ids']->sequence) : null; }
/** * 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']; }
/** * Constructor. * * @param Horde_Imap_Client_Base $base_ob Base driver object. * @param mixed $mailbox Mailbox to sync. * @param array $sync Token sync data. * @param array $curr Current sync data. * @param integer $criteria Mask of criteria to return. * @param Horde_Imap_Client_Ids $ids List of known UIDs. * * @throws Horde_Imap_Client_Exception * @throws Horde_Imap_Client_Exception_Sync */ public function __construct(Horde_Imap_Client_Base $base_ob, $mailbox, $sync, $curr, $criteria, $ids) { foreach (self::$map as $key => $val) { if (isset($sync[$key])) { $this->{$val} = $sync[$key]; } } /* Check uidvalidity. */ if (!$this->uidvalidity || $curr['V'] != $this->uidvalidity) { throw new Horde_Imap_Client_Exception_Sync('UIDs in cached mailbox have changed.', Horde_Imap_Client_Exception_Sync::UIDVALIDITY_CHANGED); } $this->mailbox = $mailbox; /* This was a UIDVALIDITY check only. */ if (!$criteria) { return; } $sync_all = $criteria & Horde_Imap_Client::SYNC_ALL; /* New messages. */ if ($sync_all || $criteria & Horde_Imap_Client::SYNC_NEWMSGS || $criteria & Horde_Imap_Client::SYNC_NEWMSGSUIDS) { $this->newmsgs = empty($this->uidnext) ? !empty($curr['U']) : !empty($curr['U']) && $curr['U'] > $this->uidnext; if ($this->newmsgs && ($sync_all || $criteria & Horde_Imap_Client::SYNC_NEWMSGSUIDS)) { $new_ids = empty($this->uidnext) ? Horde_Imap_Client_Ids::ALL : $this->uidnext . ':' . $curr['U']; $squery = new Horde_Imap_Client_Search_Query(); $squery->ids(new Horde_Imap_Client_Ids($new_ids)); $sres = $base_ob->search($mailbox, $squery); $this->_newmsgsuids = $sres['match']; } } /* Do single status call to get all necessary data. */ if ($this->highestmodseq && ($sync_all || $criteria & Horde_Imap_Client::SYNC_FLAGS || $criteria & Horde_Imap_Client::SYNC_FLAGSUIDS || $criteria & Horde_Imap_Client::SYNC_VANISHED || $criteria & Horde_Imap_Client::SYNC_VANISHEDUIDS)) { $status_sync = $base_ob->status($mailbox, Horde_Imap_Client::STATUS_SYNCMODSEQ | Horde_Imap_Client::STATUS_SYNCFLAGUIDS | Horde_Imap_Client::STATUS_SYNCVANISHED); if (!is_null($ids)) { $ids = $base_ob->resolveIds($mailbox, $ids); } } /* Flag changes. */ if ($sync_all || $criteria & Horde_Imap_Client::SYNC_FLAGS) { $this->flags = $this->highestmodseq ? $this->highestmodseq != $curr['H'] : true; } if ($sync_all || $criteria & Horde_Imap_Client::SYNC_FLAGSUIDS) { if ($this->highestmodseq) { if ($this->highestmodseq == $status_sync['syncmodseq']) { $this->_flagsuids = is_null($ids) ? $status_sync['syncflaguids'] : $base_ob->getIdsOb(array_intersect($ids->ids, $status_sync['syncflaguids']->ids)); } else { $squery = new Horde_Imap_Client_Search_Query(); $squery->modseq($this->highestmodseq + 1); $sres = $base_ob->search($mailbox, $squery, array('ids' => $ids)); $this->_flagsuids = $sres['match']; } } else { /* Without MODSEQ, need to mark all FLAGS as changed. */ $this->_flagsuids = $base_ob->resolveIds($mailbox, is_null($ids) ? $base_ob->getIdsOb(Horde_Imap_Client_Ids::ALL) : $ids); } } /* Vanished messages. */ if ($sync_all || $criteria & Horde_Imap_Client::SYNC_VANISHED || $criteria & Horde_Imap_Client::SYNC_VANISHEDUIDS) { if ($this->highestmodseq && $this->highestmodseq == $status_sync['syncmodseq']) { $vanished = is_null($ids) ? $status_sync['syncvanished'] : $base_ob->getIdsOb(array_intersect($ids->ids, $status_sync['syncvanished']->ids)); } else { $vanished = $base_ob->vanished($mailbox, $this->highestmodseq ? $this->highestmodseq : 1, array('ids' => $ids)); } $this->vanished = (bool) count($vanished); $this->_vanisheduids = $vanished; } }
/** * @depends testOptimizedSearches */ public function testMailboxThreadByReferences() { if (!self::$live->capability->query('THREAD', 'REFERENCES')) { $this->markTestSkipped('Server does not support THREAD=REFERENCES'); } $res = self::$live->thread(self::$test_mbox, array('criteria' => Horde_Imap_Client::THREAD_REFERENCES, 'sequence' => true)); $this->assertInstanceOf('Horde_Imap_Client_Data_Thread', $res); $this->assertEquals(4, count($res)); // Thread order: (1,4)(2)(3) $thread = $res->getThread(2); $this->assertArrayHasKey(2, $thread); $this->assertNull($thread[2]->base); $thread = $res->getThread(4); $this->assertArrayHasKey(1, $thread); $this->assertArrayHasKey(4, $thread); $this->assertEquals(1, $thread[1]->base); $this->assertEquals(1, $thread[4]->base); // Sort 1st 2 messages in test mailbox by thread - references // algorithm (UIDs). $ten_query = new Horde_Imap_Client_Search_Query(); $ten_query->ids(new Horde_Imap_Client_Ids('1:2', true)); $res = self::$live->thread(self::$test_mbox, array('criteria' => Horde_Imap_Client::THREAD_REFERENCES, 'search' => $ten_query)); $this->assertInstanceOf('Horde_Imap_Client_Data_Thread', $res); // Thread order: (1)(2) $thread = $res->getThread(1); $this->assertArrayHasKey(1, $thread); $this->assertNull($thread[1]->base); }
/** * Synchrozine using a token provided by the IMAP client. * * @param string $folder The folder to synchronize. * @param string $token The sync token provided by the IMAP client. * @param array $ids The list of IMAP message UIDs we currently know * about. If omitted, the server will return * VANISHED data only if it supports QRESYNC. * * @return array An array containing the following keys and values: * Horde_Kolab_Storage_Folder_Stamp_Uids::DELETED - Contains the UIDs that * have VANISHED from the IMAP server. * Horde_Kolab_Storage_Folder_Stamp_Uids::ADDED - Contains the UIDs that * have been added to the IMAP server since the last sync. */ public function sync($folder, $token, array $ids = array()) { $mbox = new Horde_Imap_Client_Mailbox($folder); $options = array('ids' => new Horde_Imap_Client_Ids($ids)); $sync_data = $this->getBackend()->sync($mbox, $token, $options); if ($sync_data->flags) { // Flag changes, we must check for /deleted since some Kolab clients // like e.g., Kontact only flag as /deleted and do not automatially // expunge. $query = new Horde_Imap_Client_Search_Query(); $query->flag(Horde_Imap_Client::FLAG_DELETED); $query->ids($sync_data->flagsuids); $search_ret = $this->getBackend()->search($mbox, $query); $deleted = array_merge($sync_data->vanisheduids->ids, $search_ret['match']->ids); } else { $deleted = $sync_data->vanisheduids->ids; } return array(Horde_Kolab_Storage_Folder_Stamp_Uids::DELETED => $deleted, Horde_Kolab_Storage_Folder_Stamp_Uids::ADDED => $sync_data->newmsgsuids->ids); }
/** * Return message UIDs that are now within the cureent FILTERTYPE value. * * @param array $options Options array. * @param boolean $is_delete If true, return messages * to SOFTDELETE. * * @return Horde_Imap_Client_Search_Results */ protected function _searchQuery($options, $is_delete) { $query = new Horde_Imap_Client_Search_Query(); $query->dateSearch(new Horde_Date($options['sincedate']), $is_delete ? Horde_Imap_Client_Search_Query::DATE_BEFORE : Horde_Imap_Client_Search_Query::DATE_SINCE); $query->ids(new Horde_Imap_Client_Ids($this->_folder->messages()), !$is_delete); try { return $this->_imap_ob->search($this->_mbox, $query, array('results' => array(Horde_Imap_Client::SEARCH_RESULTS_MATCH))); } catch (Horde_Imap_Client_Exception $e) { $this->_logger->err($e->getMessage()); throw new Horde_ActiveSync_Exception($e); } }
public function testSerialize() { $ob = new Horde_Imap_Client_Search_Query(); $ob->ids(new Horde_Imap_Client_Ids('1:3'), true); $ob->text('foo'); $ob->charset('US-ASCII', false); $this->assertEquals('BODY foo NOT UID 1:3', strval(unserialize(serialize($ob)))); }
/** * Determines if the given charset is valid for search-related queries. * This check pertains just to the basic IMAP SEARCH command. * * @param string $charset The query charset. * * @return boolean True if server supports this charset. */ public function validSearchCharset($charset) { $charset = strtoupper($charset); if ($charset == 'US-ASCII') { return true; } if (!isset($this->_init['s_charset'][$charset])) { $s_charset = $this->_init['s_charset']; /* Use a dummy search query and search for BADCHARSET response. */ $query = new Horde_Imap_Client_Search_Query(); $query->charset($charset, false); $query->ids($this->getIdsOb(1, true)); $query->text('a'); try { $this->search('INBOX', $query, array('nocache' => true, 'sequence' => true)); $s_charset[$charset] = true; } catch (Horde_Imap_Client_Exception $e) { $s_charset[$charset] = $e->getCode() !== Horde_Imap_Client_Exception::BADCHARSET; } $this->_setInit('s_charset', $s_charset); } return $this->_init['s_charset'][$charset]; }
/** * Synchronizes the current mailbox cache with the server. */ protected function _syncMailbox() { $status = $this->status($this->_selected, Horde_Imap_Client::STATUS_UIDVALIDITY | Horde_Imap_Client::STATUS_HIGHESTMODSEQ); /* Check that modseqs are available in mailbox. */ if (empty($status['highestmodseq'])) { return; } /* Grab all flags updated since the cached modseq. */ $md = $this->_cache->getMetaData($this->_selected, $status['uidvalidity'], array(self::CACHE_MODSEQ)); if (!isset($md[self::CACHE_MODSEQ]) || $md[self::CACHE_MODSEQ] == $status['highestmodseq']) { return; } $uids = $this->_cache->get($this->_selected, array(), array(), $status['uidvalidity']); if (!empty($uids)) { $uids_ob = $this->getIdsOb($uids); /* Are we caching flags? */ if (array_key_exists(Horde_Imap_Client::FETCH_FLAGS, $this->_cacheFields())) { $fquery = new Horde_Imap_Client_Fetch_Query(); $fquery->flags(); /* Update flags in cache. Cache will be updated in _fetch(). */ $this->_fetch(new Horde_Imap_Client_Fetch_Results(), $fquery, array('changedsince' => $md[self::CACHE_MODSEQ], 'ids' => $uids_ob)); } /* Search for deleted messages, and remove from cache. */ $squery = new Horde_Imap_Client_Search_Query(); $squery->ids($this->getIdsOb($uids_ob->range_string)); $search = $this->search($this->_selected, $squery, array('nocache' => true)); $deleted = array_diff($uids_ob->ids, $search['match']->ids); if (!empty($deleted)) { $this->_deleteMsgs($this->_selected, $deleted); } } $this->_updateMetaData($this->_selected, array(self::CACHE_MODSEQ => $status['highestmodseq']), $status['uidvalidity']); }