From 4f7ab00dfbd9d6c8493988dd517d182accbfd56e Mon Sep 17 00:00:00 2001
From: Thomas Bruederli <thomas@roundcube.net>
Date: Mon, 14 May 2012 14:53:51 -0400
Subject: [PATCH] Respect all arguments when caching IMAP metadata (#1488475)

---
 program/include/rcube_imap.php |   41 +++++++++++++++++++++++++++++++++--------
 1 files changed, 33 insertions(+), 8 deletions(-)

diff --git a/program/include/rcube_imap.php b/program/include/rcube_imap.php
index 24043c5..cec0ad8 100644
--- a/program/include/rcube_imap.php
+++ b/program/include/rcube_imap.php
@@ -3398,7 +3398,7 @@
             return false;
         }
 
-        $this->clear_cache('mailboxes.metadata.' . $folder);
+        $this->clear_cache($this->metadata_cache_key($folder));
 
         if ($this->get_capability('METADATA') ||
             (!strlen($folder) && $this->get_capability('METADATA-SERVER'))
@@ -3432,7 +3432,7 @@
             return false;
         }
 
-        $this->clear_cache('mailboxes.metadata.' . $folder);
+        $this->clear_cache($this->metadata_cache_key($folder));
 
         if ($this->get_capability('METADATA') || 
             (!strlen($folder) && $this->get_capability('METADATA-SERVER'))
@@ -3467,15 +3467,30 @@
             return null;
         }
 
-        $cache_key = 'mailboxes.metadata.' . $folder;
-        if ($cached = $this->get_cache($cache_key))
-            return $cached;
+        $entries = (array)$entries;
+
+        // check cached data
+        $cache_key = $this->metadata_cache_key($folder);
+        $cached_data = (array)$this->get_cache($cache_key);
+        $cached_result = array();
+        $cached_count = 0;
+        foreach ($entries as $entry_key) {
+            if (isset($cached_data[$folder][$entry_key])) {
+                $cached_result[$folder][$entry_key] = $cached_data[$folder][$entry_key];
+                $cached_count++;
+            }
+        }
+
+        // all requested entries are cached
+        if ($cached_count == count($entries)) {
+            return $cached_result;
+        }
 
         if ($this->get_capability('METADATA') ||
             (!strlen($folder) && $this->get_capability('METADATA-SERVER'))
         ) {
             $res = $this->conn->getMetadata($folder, $entries, $options);
-            $this->update_cache($cache_key, $res);
+            $this->update_cache($cache_key, array_merge_recursive($cached_data, $res));
             return $res;
         }
         else if ($this->get_capability('ANNOTATEMORE') || $this->get_capability('ANNOTATEMORE2')) {
@@ -3483,7 +3498,7 @@
             $res     = array();
 
             // Convert entry names
-            foreach ((array)$entries as $entry) {
+            foreach ($entries as $entry) {
                 list($ent, $attr) = $this->md2annotate($entry);
                 $queries[$attr][] = $ent;
             }
@@ -3495,7 +3510,7 @@
                 }
             }
 
-            $this->update_cache($cache_key, $res);
+            $this->update_cache($cache_key, array_merge_recursive($cached_data, $res));
             return $res;
         }
 
@@ -3504,6 +3519,16 @@
 
 
     /**
+     * Helper method to compose the cache key for the given folder metadata
+     */
+    protected function metadata_cache_key($folder)
+    {
+        $suffix = $folder == '' ? '[SERVER]' : (strpos($folder, '*') === false ? $folder : '');
+        return 'mailboxes.metadata.' . $suffix;
+    }
+
+
+    /**
      * Converts the METADATA extension entry name into the correct
      * entry-attrib names for older ANNOTATEMORE version.
      *

--
Gitblit v1.9.1