From 71f72f928b2e637471268416131841b4ddca2bd0 Mon Sep 17 00:00:00 2001
From: alecpl <alec@alec.pl>
Date: Thu, 08 Sep 2011 04:31:13 -0400
Subject: [PATCH] - Fix new caching issue when broken/misleading object data was stored in database.   The object must be cleaned up before storing in DB, because some code   (out of rcube_message and rcube_imap classes) is changing objects data   e.g. parts mimetype or body. Now it's become a problem because we're   saving the object in cache at shutdown (after all modifications). - Make stored message object smaller by removing some redundant data.

---
 program/include/rcube_imap.php       |    5 ++---
 program/include/rcube_imap_cache.php |   32 ++++++++++++++++++++++++++++----
 2 files changed, 30 insertions(+), 7 deletions(-)

diff --git a/program/include/rcube_imap.php b/program/include/rcube_imap.php
index a15a592..d14a643 100644
--- a/program/include/rcube_imap.php
+++ b/program/include/rcube_imap.php
@@ -1999,12 +1999,11 @@
         }
 
         $struct = &$this->_structure_part($structure, 0, '', $headers);
-        $struct->headers = get_object_vars($headers);
 
         // don't trust given content-type
-        if (empty($struct->parts) && !empty($struct->headers['ctype'])) {
+        if (empty($struct->parts) && !empty($headers->ctype)) {
             $struct->mime_id = '1';
-            $struct->mimetype = strtolower($struct->headers['ctype']);
+            $struct->mimetype = strtolower($headers->ctype);
             list($struct->ctype_primary, $struct->ctype_secondary) = explode('/', $struct->mimetype);
         }
 
diff --git a/program/include/rcube_imap_cache.php b/program/include/rcube_imap_cache.php
index f0c3fbb..9767d56 100644
--- a/program/include/rcube_imap_cache.php
+++ b/program/include/rcube_imap_cache.php
@@ -888,10 +888,8 @@
     {
         // Save current message from internal cache
         if ($message = $this->icache['message']) {
-            $object = $message['object'];
-            // remove body too big (>500kB)
-            if ($object->body && strlen($object->body) > 500 * 1024)
-                $object->body = null;
+            // clean up some object's data
+            $object = $this->message_object_prepare($message['object']);
 
             // calculate current md5 sum
             $md5sum = md5(serialize($object));
@@ -904,4 +902,30 @@
         }
     }
 
+
+    /**
+     * Prepares message object to be stored in database.
+     */
+    private function message_object_prepare($msg, $recursive = false)
+    {
+        // Remove body too big (>500kB)
+        if ($recursive || ($msg->body && strlen($msg->body) > 500 * 1024)) {
+            unset($msg->body);
+        }
+
+        // Fix mimetype which might be broken by some code when message is displayed
+        // Another solution would be to use object's copy in rcube_message class
+        // to prevent related issues, however I'm not sure which is better
+        if ($msg->mimetype) {
+            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, true);
+            }
+        }
+
+        return $msg;
+    }
 }

--
Gitblit v1.9.1