From 3ebac0167bf20104fb7a2a55934765117760264c Mon Sep 17 00:00:00 2001
From: Thomas Bruederli <thomas@roundcube.net>
Date: Mon, 18 Aug 2014 03:53:18 -0400
Subject: [PATCH] Only add zen-mode text labels in compose step

---
 program/lib/Roundcube/rcube_imap_cache.php |  179 +++++++++++++++++++++++++++++++++++++++++------------------
 1 files changed, 124 insertions(+), 55 deletions(-)

diff --git a/program/lib/Roundcube/rcube_imap_cache.php b/program/lib/Roundcube/rcube_imap_cache.php
index a505d12..e49e778 100644
--- a/program/lib/Roundcube/rcube_imap_cache.php
+++ b/program/lib/Roundcube/rcube_imap_cache.php
@@ -27,6 +27,9 @@
  */
 class rcube_imap_cache
 {
+    const MODE_INDEX   = 1;
+    const MODE_MESSAGE = 2;
+
     /**
      * Instance of rcube_imap
      *
@@ -56,6 +59,13 @@
     private $ttl;
 
     /**
+     * Maximum cached message size
+     *
+     * @var int
+     */
+    private $threshold;
+
+    /**
      * Internal (in-memory) cache
      *
      * @var array
@@ -63,6 +73,7 @@
     private $icache = array();
 
     private $skip_deleted = false;
+    private $mode;
 
     /**
      * List of known flags. Thanks to this we can handle flag changes
@@ -88,6 +99,7 @@
     );
 
 
+
     /**
      * Object constructor.
      *
@@ -96,9 +108,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 +121,10 @@
         $this->userid       = $userid;
         $this->skip_deleted = $skip_deleted;
         $this->ttl          = $ttl;
+        $this->threshold    = $threshold;
+
+        // cache all possible information by default
+        $this->mode = self::MODE_INDEX | self::MODE_MESSAGE;
     }
 
 
@@ -119,6 +135,17 @@
     {
         $this->save_icache();
         $this->icache = null;
+    }
+
+
+    /**
+     * Set cache mode
+     *
+     * @param int $mode Cache mode
+     */
+    public function set_mode($mode)
+    {
+        $this->mode = $mode;
     }
 
 
@@ -144,7 +171,7 @@
         // Seek in internal cache
         if (array_key_exists('index', $this->icache[$mailbox])) {
             // The index was fetched from database already, but not validated yet
-            if (!array_key_exists('object', $this->icache[$mailbox]['index'])) {
+            if (empty($this->icache[$mailbox]['index']['validated'])) {
                 $index = $this->icache[$mailbox]['index'];
             }
             // We've got a valid index
@@ -221,6 +248,7 @@
         }
 
         $this->icache[$mailbox]['index'] = array(
+            'validated'  => true,
             'object'     => $data,
             'sort_field' => $sort_field,
             'modseq'     => !empty($index['modseq']) ? $index['modseq'] : $mbox_data['HIGHESTMODSEQ']
@@ -300,38 +328,46 @@
             return array();
         }
 
-        // Fetch messages from cache
-        $sql_result = $this->db->query(
-            "SELECT uid, data, flags"
-            ." FROM ".$this->db->table_name('cache_messages')
-            ." WHERE user_id = ?"
-                ." AND mailbox = ?"
-                ." AND uid IN (".$this->db->array2list($msgs, 'integer').")",
-            $this->userid, $mailbox);
-
-        $msgs   = array_flip($msgs);
         $result = array();
 
-        while ($sql_arr = $this->db->fetch_assoc($sql_result)) {
-            $uid          = intval($sql_arr['uid']);
-            $result[$uid] = $this->build_message($sql_arr);
+        if ($this->mode & self::MODE_MESSAGE) {
+            // Fetch messages from cache
+            $sql_result = $this->db->query(
+                "SELECT uid, data, flags"
+                ." FROM ".$this->db->table_name('cache_messages')
+                ." WHERE user_id = ?"
+                    ." AND mailbox = ?"
+                    ." AND uid IN (".$this->db->array2list($msgs, 'integer').")",
+                $this->userid, $mailbox);
 
-            if (!empty($result[$uid])) {
-                // save memory, we don't need message body here (?)
-                $result[$uid]->body = null;
+            $msgs = array_flip($msgs);
 
-                unset($msgs[$uid]);
+            while ($sql_arr = $this->db->fetch_assoc($sql_result)) {
+                $uid          = intval($sql_arr['uid']);
+                $result[$uid] = $this->build_message($sql_arr);
+
+                if (!empty($result[$uid])) {
+                    // save memory, we don't need message body here (?)
+                    $result[$uid]->body = null;
+
+                    unset($msgs[$uid]);
+                }
             }
+
+            $msgs = array_flip($msgs);
         }
 
         // Fetch not found messages from IMAP server
         if (!empty($msgs)) {
-            $messages = $this->imap->fetch_headers($mailbox, array_keys($msgs), false, true);
+            $messages = $this->imap->fetch_headers($mailbox, $msgs, false, true);
 
             // Insert to DB and add to result list
             if (!empty($messages)) {
                 foreach ($messages as $msg) {
-                    $this->add_message($mailbox, $msg, !array_key_exists($msg->uid, $result));
+                    if ($this->mode & self::MODE_MESSAGE) {
+                        $this->add_message($mailbox, $msg, !array_key_exists($msg->uid, $result));
+                    }
+
                     $result[$msg->uid] = $msg;
                 }
             }
@@ -362,23 +398,29 @@
             return $this->icache['__message']['object'];
         }
 
-        $sql_result = $this->db->query(
-            "SELECT flags, data"
-            ." FROM ".$this->db->table_name('cache_messages')
-            ." WHERE user_id = ?"
-                ." AND mailbox = ?"
-                ." AND uid = ?",
-                $this->userid, $mailbox, (int)$uid);
+        if ($this->mode & self::MODE_MESSAGE) {
+            $sql_result = $this->db->query(
+                "SELECT flags, data"
+                ." FROM ".$this->db->table_name('cache_messages')
+                ." WHERE user_id = ?"
+                    ." AND mailbox = ?"
+                    ." AND uid = ?",
+                    $this->userid, $mailbox, (int)$uid);
 
-        if ($sql_arr = $this->db->fetch_assoc($sql_result)) {
-            $message = $this->build_message($sql_arr);
-            $found   = true;
+            if ($sql_arr = $this->db->fetch_assoc($sql_result)) {
+                $message = $this->build_message($sql_arr);
+                $found   = true;
+            }
         }
 
         // Get the message from IMAP server
         if (empty($message) && $update) {
             $message = $this->imap->get_message_headers($uid, $mailbox, true);
             // cache will be updated in close(), see below
+        }
+
+        if (!($this->mode & self::MODE_MESSAGE)) {
+            return $message;
         }
 
         // Save the message in internal cache, will be written to DB in close()
@@ -413,6 +455,10 @@
     function add_message($mailbox, $message, $force = false)
     {
         if (!is_object($message) || empty($message->uid)) {
+            return;
+        }
+
+        if (!($this->mode & self::MODE_MESSAGE)) {
             return;
         }
 
@@ -487,6 +533,10 @@
             return;
         }
 
+        if (!($this->mode & self::MODE_MESSAGE)) {
+            return;
+        }
+
         $flag = strtoupper($flag);
         $idx  = (int) array_search($flag, $this->flags);
         $uids = (array) $uids;
@@ -527,6 +577,10 @@
      */
     function remove_message($mailbox = null, $uids = null)
     {
+        if (!($this->mode & self::MODE_MESSAGE)) {
+            return;
+        }
+
         if (!strlen($mailbox)) {
             $this->db->query(
                 "DELETE FROM ".$this->db->table_name('cache_messages')
@@ -640,13 +694,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());
     }
 
 
@@ -836,6 +890,8 @@
         if (empty($object)) {
             return false;
         }
+
+        $index['validated'] = true;
 
         // Get mailbox data (UIDVALIDITY, counters, etc.) for status check
         $mbox_data = $this->imap->folder_data($mailbox);
@@ -1028,15 +1084,17 @@
         $removed = array();
 
         // Get known UIDs
-        $sql_result = $this->db->query(
-            "SELECT uid"
-            ." FROM ".$this->db->table_name('cache_messages')
-            ." WHERE user_id = ?"
-                ." AND mailbox = ?",
-            $this->userid, $mailbox);
+        if ($this->mode & self::MODE_MESSAGE) {
+            $sql_result = $this->db->query(
+                "SELECT uid"
+                ." FROM ".$this->db->table_name('cache_messages')
+                ." WHERE user_id = ?"
+                    ." AND mailbox = ?",
+                $this->userid, $mailbox);
 
-        while ($sql_arr = $this->db->fetch_assoc($sql_result)) {
-            $uids[] = $sql_arr['uid'];
+            while ($sql_arr = $this->db->fetch_assoc($sql_result)) {
+                $uids[] = $sql_arr['uid'];
+            }
         }
 
         // Synchronize messages data
@@ -1155,13 +1213,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;
@@ -1171,12 +1229,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
@@ -1186,13 +1251,17 @@
             list($msg->ctype_primary, $msg->ctype_secondary) = explode('/', $msg->mimetype);
         }
 
-        if (is_array($msg->structure->parts)) {
-            foreach ($msg->structure->parts as $idx => $part) {
-                $msg->structure->parts[$idx] = $this->message_object_prepare($part);
-            }
+        unset($msg->replaces);
+
+        if (is_object($msg->structure)) {
+            $this->message_object_prepare($msg->structure, $size);
         }
 
-        return $msg;
+        if (is_array($msg->parts)) {
+            foreach ($msg->parts as $part) {
+                $this->message_object_prepare($part, $size);
+            }
+        }
     }
 
 

--
Gitblit v1.9.1