/** * Return all messages in the result. * * @return array List of message identifiers */ public function get_compressed() { if (empty($this->raw_data)) { return ''; } return rcube_imap_generic::compressMessageSet($this->get()); }
/** * Checks index/thread validity */ private function validate($mailbox, $index, &$exists = true) { $object = $index['object']; $is_thread = is_a($object, 'rcube_result_thread'); // sanity check if (empty($object)) { return false; } $index['validated'] = true; // Get mailbox data (UIDVALIDITY, counters, etc.) for status check $mbox_data = $this->imap->folder_data($mailbox); // @TODO: Think about skipping validation checks. // If we could check only every 10 minutes, we would be able to skip // expensive checks, mailbox selection or even IMAP connection, this would require // additional logic to force cache invalidation in some cases // and many rcube_imap changes to connect when needed // Check UIDVALIDITY if ($index['validity'] != $mbox_data['UIDVALIDITY']) { $this->clear($mailbox); $exists = false; return false; } // Folder is empty but cache isn't if (empty($mbox_data['EXISTS'])) { if (!$object->is_empty()) { $this->clear($mailbox); $exists = false; return false; } } else { if ($object->is_empty()) { unset($this->icache[$mailbox][$is_thread ? 'thread' : 'index']); return false; } } // Validation flag if (!$is_thread && empty($index['valid'])) { unset($this->icache[$mailbox]['index']); return false; } // Index was created with different skip_deleted setting if ($this->skip_deleted != $index['deleted']) { return false; } // Check HIGHESTMODSEQ if (!empty($index['modseq']) && !empty($mbox_data['HIGHESTMODSEQ']) && $index['modseq'] == $mbox_data['HIGHESTMODSEQ']) { return true; } // Check UIDNEXT if ($index['uidnext'] != $mbox_data['UIDNEXT']) { unset($this->icache[$mailbox][$is_thread ? 'thread' : 'index']); return false; } // @TODO: find better validity check for threaded index if ($is_thread) { // check messages number... if (!$this->skip_deleted && $mbox_data['EXISTS'] != $object->count_messages()) { return false; } return true; } // The rest of checks, more expensive if (!empty($this->skip_deleted)) { // compare counts if available if (!empty($mbox_data['UNDELETED']) && $mbox_data['UNDELETED']->count() != $object->count()) { return false; } // compare UID sets if (!empty($mbox_data['UNDELETED'])) { $uids_new = $mbox_data['UNDELETED']->get(); $uids_old = $object->get(); if (count($uids_new) != count($uids_old)) { return false; } sort($uids_new, SORT_NUMERIC); sort($uids_old, SORT_NUMERIC); if ($uids_old != $uids_new) { return false; } } else { // get all undeleted messages excluding cached UIDs $ids = $this->imap->search_once($mailbox, 'ALL UNDELETED NOT UID ' . rcube_imap_generic::compressMessageSet($object->get())); if (!$ids->is_empty()) { return false; } } } else { // check messages number... if ($mbox_data['EXISTS'] != $object->count()) { return false; } // ... and max UID if ($object->max() != $this->imap->id2uid($mbox_data['EXISTS'], $mailbox)) { return false; } } return true; }
/** * Checks if the cache is up-to-date * * @param string $mailbox Mailbox name * @param string $cache_key Internal cache key * @return int Cache status: -3 = off, -2 = incomplete, -1 = dirty, 1 = OK */ private function check_cache_status($mailbox, $cache_key) { if (!$this->caching_enabled) { return -3; } $cache_index = $this->get_message_cache_index($cache_key); $msg_count = $this->_messagecount($mailbox); $cache_count = count($cache_index); // empty mailbox if (!$msg_count) { return $cache_count ? -2 : 1; } if ($cache_count == $msg_count) { if ($this->skip_deleted) { if (!empty($this->icache['all_undeleted_idx'])) { $uids = rcube_imap_generic::uncompressMessageSet($this->icache['all_undeleted_idx']); $uids = array_flip($uids); foreach ($cache_index as $uid) { unset($uids[$uid]); } } else { // get all undeleted messages excluding cached UIDs $uids = $this->search_once($mailbox, 'ALL UNDELETED NOT UID ' . rcube_imap_generic::compressMessageSet($cache_index)); } if (empty($uids)) { return 1; } } else { // get UID of the message with highest index $uid = $this->_id2uid($msg_count, $mailbox); $cache_uid = array_pop($cache_index); // uids of highest message matches -> cache seems OK if ($cache_uid == $uid) { return 1; } } // cache is dirty return -1; } // if cache count differs less than 10% report as dirty return abs($msg_count - $cache_count) < $msg_count / 10 ? -1 : -2; }