From cf46aefd9d8be57722514ab0b6047fa573f46a36 Mon Sep 17 00:00:00 2001
From: Thomas Bruederli <thomas@roundcube.net>
Date: Sat, 28 Sep 2013 06:04:35 -0400
Subject: [PATCH] Make password plugin use the new 'settings_actions' hook to register its link in the settings navigation

---
 program/lib/Roundcube/rcube_imap_cache.php |   99 ++++++++++++++++++++++++++++++++-----------------
 1 files changed, 65 insertions(+), 34 deletions(-)

diff --git a/program/lib/Roundcube/rcube_imap_cache.php b/program/lib/Roundcube/rcube_imap_cache.php
index e2fd2a9..d72bfe0 100644
--- a/program/lib/Roundcube/rcube_imap_cache.php
+++ b/program/lib/Roundcube/rcube_imap_cache.php
@@ -56,6 +56,13 @@
     private $ttl;
 
     /**
+     * Maximum cached message size
+     *
+     * @var int
+     */
+    private $threshold;
+
+    /**
      * Internal (in-memory) cache
      *
      * @var array
@@ -96,9 +103,9 @@
      * @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);
@@ -109,6 +116,7 @@
         $this->userid       = $userid;
         $this->skip_deleted = $skip_deleted;
         $this->ttl          = $ttl;
+        $this->threshold    = $threshold;
     }
 
 
@@ -234,9 +242,7 @@
      * 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
      */
@@ -275,19 +281,11 @@
         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;
@@ -650,13 +648,13 @@
         $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());
     }
 
 
@@ -1106,17 +1104,18 @@
             }
         }
 
-        // 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);
         }
@@ -1164,13 +1163,13 @@
         // 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;
@@ -1180,12 +1179,19 @@
 
     /**
      * 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
@@ -1195,13 +1201,19 @@
             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);
+            }
+        }
     }
 
 
@@ -1224,6 +1236,25 @@
 
         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.

--
Gitblit v1.9.1