From 3253b296c21c54df228de39ff3e4775974df81d5 Mon Sep 17 00:00:00 2001
From: alecpl <alec@alec.pl>
Date: Fri, 20 May 2011 05:17:27 -0400
Subject: [PATCH] - Clear properly mailboxes cache on folder subscription change

---
 program/include/rcube_cache.php |   55 ++++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 50 insertions(+), 5 deletions(-)

diff --git a/program/include/rcube_cache.php b/program/include/rcube_cache.php
index d38c237..abadeed 100644
--- a/program/include/rcube_cache.php
+++ b/program/include/rcube_cache.php
@@ -51,17 +51,22 @@
     /**
      * Object constructor.
      *
-     * @param string $type   Engine type ('db' or 'memcache')
+     * @param string $type   Engine type ('db' or 'memcache' or 'apc')
      * @param int    $userid User identifier
      * @param string $prefix Key name prefix
      */
     function __construct($type, $userid, $prefix='')
     {
         $rcmail = rcmail::get_instance();
+        $type   = strtolower($type);
     
-        if (strtolower($type) == 'memcache') {
+        if ($type == 'memcache') {
             $this->type = 'memcache';
             $this->db   = $rcmail->get_memcache();
+        }
+        else if ($type == 'apc') {
+            $this->type = 'apc';
+            $this->db   = function_exists('apc_exists'); // APC 3.1.4 required
         }
         else {
             $this->type = 'db';
@@ -147,7 +152,14 @@
             $this->cache_changes = array();
         }
         else if ($pattern_mode) {
-            $key = $this->prefix.$key;
+            // add cache prefix into PCRE expression
+            if (preg_match('/^(.)([^a-z0-9]*).*/i', $key, $matches)) {
+                $key = $matches[1] . $matches[2] . preg_quote($this->prefix, $matches[1])
+                    . substr($key, strlen($matches[1].$matches[2]));
+            }
+            else {
+                $key = $this->prefix.$key;
+            }
 
             foreach (array_keys($this->cache) as $k) {
                 if (preg_match($key, $k)) {
@@ -208,7 +220,17 @@
         }
 
         if ($this->type == 'memcache') {
-            $data = $this->db->get($key);
+            $data = $this->db->get($this->ckey($key));
+	        
+            if ($data) {
+                $this->cache_sums[$key] = md5($data);
+                $data = unserialize($data);
+            }
+            return $this->cache[$key] = $data;
+        }
+
+        if ($this->type == 'apc') {
+            $data = apc_fetch($this->ckey($key));
 	        
             if ($data) {
                 $this->cache_sums[$key] = md5($data);
@@ -263,10 +285,18 @@
         }
 
         if ($this->type == 'memcache') {
+            $key = $this->ckey($key);
             $result = $this->db->replace($key, $data, MEMCACHE_COMPRESSED);
             if (!$result)
                 $result = $this->db->set($key, $data, MEMCACHE_COMPRESSED);
             return $result;
+        }
+
+        if ($this->type == 'apc') {
+            $key = $this->ckey($key);
+            if (apc_exists($key))
+                apc_delete($key);
+            return apc_store($key, $data);
         }
 
         // update existing cache record
@@ -313,7 +343,11 @@
         }
 
         if ($this->type == 'memcache') {
-            return $this->db->delete($key);
+            return $this->db->delete($this->ckey($key));
+        }
+
+        if ($this->type == 'apc') {
+            return apc_delete($this->ckey($key));
         }
 
         $this->db->query(
@@ -325,4 +359,15 @@
         unset($this->cache_keys[$key]);
     }
 
+
+    /**
+     * Creates per-user cache key (for memcache and apc)
+     *
+     * @param string $key Cache key
+     * @access private
+     */
+    private function ckey($key)
+    {
+        return sprintf('[%d]%s', $this->userid, $key);
+    }
 }

--
Gitblit v1.9.1