| | |
| | | private $ttl; |
| | | |
| | | /** |
| | | * Maximum cached message size |
| | | * |
| | | * @var int |
| | | */ |
| | | private $threshold; |
| | | |
| | | /** |
| | | * Internal (in-memory) cache |
| | | * |
| | | * @var array |
| | |
| | | * @param int $userid User identifier |
| | | * @param bool $skip_deleted skip_deleted flag |
| | | * @param string $ttl Expiration time of memcache/apc items |
| | | * |
| | | * @param int $threshold Maximum cached message size |
| | | */ |
| | | function __construct($db, $imap, $userid, $skip_deleted, $ttl=0) |
| | | function __construct($db, $imap, $userid, $skip_deleted, $ttl=0, $threshold=0) |
| | | { |
| | | // convert ttl string to seconds |
| | | $ttl = get_offset_sec($ttl); |
| | |
| | | $this->userid = $userid; |
| | | $this->skip_deleted = $skip_deleted; |
| | | $this->ttl = $ttl; |
| | | $this->threshold = $threshold; |
| | | } |
| | | |
| | | |
| | |
| | | * Return messages thread. |
| | | * If threaded index doesn't exist or is invalid, will be updated. |
| | | * |
| | | * @param string $mailbox Folder name |
| | | * @param string $sort_field Sorting column |
| | | * @param string $sort_order Sorting order (ASC|DESC) |
| | | * @param string $mailbox Folder name |
| | | * |
| | | * @return array Messages threaded index |
| | | */ |
| | |
| | | if ($index === null) { |
| | | // Get mailbox data (UIDVALIDITY, counters, etc.) for status check |
| | | $mbox_data = $this->imap->folder_data($mailbox); |
| | | |
| | | if ($mbox_data['EXISTS']) { |
| | | // get all threads (default sort order) |
| | | $threads = $this->imap->fetch_threads($mailbox, true); |
| | | } |
| | | else { |
| | | $threads = new rcube_result_thread($mailbox, '* THREAD'); |
| | | } |
| | | |
| | | $index['object'] = $threads; |
| | | // Get THREADS result |
| | | $index['object'] = $this->get_thread_data($mailbox, $mbox_data); |
| | | |
| | | // insert/update |
| | | $this->add_thread_row($mailbox, $threads, $mbox_data, $exists); |
| | | $this->add_thread_row($mailbox, $index['object'], $mbox_data, $exists); |
| | | } |
| | | |
| | | $this->icache[$mailbox]['thread'] = $index; |
| | |
| | | $db = $rcube->get_dbh(); |
| | | |
| | | $db->query("DELETE FROM ".$db->table_name('cache_messages') |
| | | ." WHERE expired < " . $db->now()); |
| | | ." WHERE expires < " . $db->now()); |
| | | |
| | | $db->query("DELETE FROM ".$db->table_name('cache_index') |
| | | ." WHERE expired < " . $db->now()); |
| | | ." WHERE expires < " . $db->now()); |
| | | |
| | | $db->query("DELETE FROM ".$db->table_name('cache_thread') |
| | | ." WHERE expired < " . $db->now()); |
| | | ." WHERE expires < " . $db->now()); |
| | | } |
| | | |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | // Invalidate thread index (?) |
| | | if (!$index['valid']) { |
| | | $this->remove_thread($mailbox); |
| | | } |
| | | |
| | | $sort_field = $index['sort_field']; |
| | | $sort_order = $index['object']->get_parameters('ORDER'); |
| | | $exists = true; |
| | | |
| | | // Validate index |
| | | if (!$this->validate($mailbox, $index, $exists)) { |
| | | // Invalidate (remove) thread index |
| | | // if $exists=false it was already removed in validate() |
| | | if ($exists) { |
| | | $this->remove_thread($mailbox); |
| | | } |
| | | |
| | | // Update index |
| | | $data = $this->get_index_data($mailbox, $sort_field, $sort_order, $mbox_data); |
| | | } |
| | |
| | | // Save current message from internal cache |
| | | if ($message = $this->icache['__message']) { |
| | | // clean up some object's data |
| | | $object = $this->message_object_prepare($message['object']); |
| | | $this->message_object_prepare($message['object']); |
| | | |
| | | // calculate current md5 sum |
| | | $md5sum = md5(serialize($object)); |
| | | $md5sum = md5(serialize($message['object'])); |
| | | |
| | | if ($message['md5sum'] != $md5sum) { |
| | | $this->add_message($message['mailbox'], $object, !$message['exists']); |
| | | $this->add_message($message['mailbox'], $message['object'], !$message['exists']); |
| | | } |
| | | |
| | | $this->icache['__message']['md5sum'] = $md5sum; |
| | |
| | | |
| | | /** |
| | | * Prepares message object to be stored in database. |
| | | * |
| | | * @param rcube_message_header|rcube_message_part |
| | | */ |
| | | private function message_object_prepare($msg) |
| | | private function message_object_prepare(&$msg, &$size = 0) |
| | | { |
| | | // Remove body too big (>25kB) |
| | | if ($msg->body && strlen($msg->body) > 25 * 1024) { |
| | | unset($msg->body); |
| | | // Remove body too big |
| | | if ($msg->body && ($length = strlen($msg->body))) { |
| | | $size += $length; |
| | | |
| | | if ($size > $this->threshold * 1024) { |
| | | $size -= $length; |
| | | unset($msg->body); |
| | | } |
| | | } |
| | | |
| | | // Fix mimetype which might be broken by some code when message is displayed |
| | |
| | | list($msg->ctype_primary, $msg->ctype_secondary) = explode('/', $msg->mimetype); |
| | | } |
| | | |
| | | unset($msg->replaces); |
| | | |
| | | if (is_array($msg->structure->parts)) { |
| | | foreach ($msg->structure->parts as $idx => $part) { |
| | | $msg->structure->parts[$idx] = $this->message_object_prepare($part); |
| | | foreach ($msg->structure->parts as $part) { |
| | | $this->message_object_prepare($part, $size); |
| | | } |
| | | } |
| | | |
| | | return $msg; |
| | | if (is_array($msg->parts)) { |
| | | foreach ($msg->parts as $part) { |
| | | $this->message_object_prepare($part, $size); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | |
| | | |
| | | return $index; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Fetches thread data from IMAP server |
| | | */ |
| | | private function get_thread_data($mailbox, $mbox_data = array()) |
| | | { |
| | | if (empty($mbox_data)) { |
| | | $mbox_data = $this->imap->folder_data($mailbox); |
| | | } |
| | | |
| | | if ($mbox_data['EXISTS']) { |
| | | // get all threads (default sort order) |
| | | return $this->imap->threads_direct($mailbox); |
| | | } |
| | | |
| | | return new rcube_result_thread($mailbox, '* THREAD'); |
| | | } |
| | | |
| | | } |
| | | |
| | | // for backward compat. |