From fec2d8e1309d1f16f9cd772b82b28627d9359354 Mon Sep 17 00:00:00 2001
From: thomascube <thomas@roundcube.net>
Date: Tue, 21 Feb 2012 16:43:39 -0500
Subject: [PATCH] Refactored IMAP cache expunge: delegate to storage object; don't rely on deprecated 'enable_caching' config option

---
 program/include/main.inc             |   27 -------------
 program/include/rcube_imap.php       |   17 ++++++++
 program/include/rcmail.php           |   21 +++++++++-
 program/include/rcube_imap_cache.php |   21 ++++++++++
 program/include/rcube_storage.php    |    5 ++
 program/include/rcube_session.php    |   11 ++++-
 6 files changed, 68 insertions(+), 34 deletions(-)

diff --git a/program/include/main.inc b/program/include/main.inc
index 1e84e2d..68719e8 100644
--- a/program/include/main.inc
+++ b/program/include/main.inc
@@ -158,33 +158,6 @@
 }
 
 
-/**
- * Garbage collector for cache entries.
- * Remove all expired message cache records
- * @return void
- */
-function rcmail_cache_gc()
-{
-  $rcmail = rcmail::get_instance();
-  $db = $rcmail->get_dbh();
-
-  // get target timestamp
-  $ts = get_offset_time($rcmail->config->get('message_cache_lifetime', '30d'), -1);
-
-  $db->query("DELETE FROM ".get_table_name('cache_messages')
-        ." WHERE changed < " . $db->fromunixtime($ts));
-
-  $db->query("DELETE FROM ".get_table_name('cache_index')
-        ." WHERE changed < " . $db->fromunixtime($ts));
-
-  $db->query("DELETE FROM ".get_table_name('cache_thread')
-        ." WHERE changed < " . $db->fromunixtime($ts));
-
-  $db->query("DELETE FROM ".get_table_name('cache')
-        ." WHERE created < " . $db->fromunixtime($ts));
-}
-
-
 // Deprecated
 function rcube_charset_convert($str, $from, $to=NULL)
 {
diff --git a/program/include/rcmail.php b/program/include/rcmail.php
index 3d5915e..9d1190a 100644
--- a/program/include/rcmail.php
+++ b/program/include/rcmail.php
@@ -129,6 +129,7 @@
   private $caches = array();
   private $action_map = array();
   private $shutdown_functions = array();
+  private $expunge_cache = false;
 
 
   /**
@@ -767,8 +768,7 @@
     $this->session = new rcube_session($this->get_dbh(), $this->config);
 
     $this->session->register_gc_handler('rcmail_temp_gc');
-    if ($this->config->get('enable_caching'))
-      $this->session->register_gc_handler('rcmail_cache_gc');
+    $this->session->register_gc_handler(array($this, 'cache_gc'));
 
     // start PHP session (if not in CLI mode)
     if ($_SERVER['REMOTE_ADDR'])
@@ -1278,8 +1278,11 @@
             $cache->close();
     }
 
-    if (is_object($this->storage))
+    if (is_object($this->storage)) {
+        if ($this->expunge_cache)
+            $this->storage->expunge_cache();
       $this->storage->close();
+  }
 
     // before closing the database connection, write session data
     if ($_SERVER['REMOTE_ADDR'] && is_object($this->session)) {
@@ -1316,6 +1319,18 @@
 
 
   /**
+   * Garbage collector for cache entries.
+   * Set flag to expunge caches on shutdown
+   */
+  function cache_gc()
+  {
+    // because this gc function is called before storage is initialized,
+    // we just set a flag to expunge storage cache on shutdown.
+    $this->expunge_cache = true;
+  }
+
+
+  /**
    * Generate a unique token to be used in a form request
    *
    * @return string The request token
diff --git a/program/include/rcube_imap.php b/program/include/rcube_imap.php
index 56b5e59..70b410f 100644
--- a/program/include/rcube_imap.php
+++ b/program/include/rcube_imap.php
@@ -3527,7 +3527,8 @@
     {
         if ($this->caching && !$this->cache) {
             $rcmail = rcmail::get_instance();
-            $this->cache = $rcmail->get_cache('IMAP', $this->caching);
+            $ttl = $rcmail->config->get('message_cache_lifetime', '10d') - mktime();
+            $this->cache = $rcmail->get_cache('IMAP', $this->caching, $ttl);
         }
 
         return $this->cache;
@@ -3574,6 +3575,20 @@
         }
     }
 
+    /**
+     * Delete outdated cache entries
+     */
+    public function expunge_cache()
+    {
+        if ($this->mcache) {
+            $ttl = rcmail::get_instance()->config->get('message_cache_lifetime', '10d');
+            $this->mcache->expunge($ttl);
+        }
+
+        if ($this->cache)
+            $this->cache->expunge();
+    }
+
 
     /* --------------------------------
      *   message caching methods
diff --git a/program/include/rcube_imap_cache.php b/program/include/rcube_imap_cache.php
index 96c49f7..655979d 100644
--- a/program/include/rcube_imap_cache.php
+++ b/program/include/rcube_imap_cache.php
@@ -599,6 +599,27 @@
 
 
     /**
+     * Delete cache entries older than TTL
+     *
+     * @param string $ttl  Lifetime of message cache entries
+     */
+    function expunge($ttl)
+    {
+        // get expiration timestamp
+        $ts = get_offset_time($ttl, -1);
+
+        $this->db->query("DELETE FROM ".get_table_name('cache_messages')
+              ." WHERE changed < " . $this->db->fromunixtime($ts));
+
+        $this->db->query("DELETE FROM ".get_table_name('cache_index')
+              ." WHERE changed < " . $this->db->fromunixtime($ts));
+
+        $this->db->query("DELETE FROM ".get_table_name('cache_thread')
+              ." WHERE changed < " . $this->db->fromunixtime($ts));
+    }
+
+
+    /**
      * Fetches index data from database
      */
     private function get_index_row($mailbox)
diff --git a/program/include/rcube_session.php b/program/include/rcube_session.php
index 1f5290c..5ec9f33 100644
--- a/program/include/rcube_session.php
+++ b/program/include/rcube_session.php
@@ -332,10 +332,15 @@
    *
    * @param mixed Callback function
    */
-  public function register_gc_handler($func_name)
+  public function register_gc_handler($func)
   {
-    if ($func_name && !in_array($func_name, $this->gc_handlers))
-      $this->gc_handlers[] = $func_name;
+    foreach ($this->gc_handlers as $handler) {
+      if ($handler == $func) {
+        return;
+      }
+    }
+
+    $this->gc_handlers[] = $func;
   }
 
 
diff --git a/program/include/rcube_storage.php b/program/include/rcube_storage.php
index 54e58ec..cef773c 100644
--- a/program/include/rcube_storage.php
+++ b/program/include/rcube_storage.php
@@ -971,6 +971,11 @@
      */
     abstract function get_cache($key);
 
+    /**
+     * Delete outdated cache entries
+     */
+    abstract function expunge_cache();
+
 }  // end class rcube_storage
 
 

--
Gitblit v1.9.1