Branch 'dev/kolab3' - plugins/libkolab

Thomas Brüderli bruederli at kolabsys.com
Thu May 3 10:28:35 CEST 2012


 plugins/libkolab/lib/kolab_storage_cache.php  |   78 ++++++++++++++++++--------
 plugins/libkolab/lib/kolab_storage_folder.php |   41 ++++++++++++-
 2 files changed, 92 insertions(+), 27 deletions(-)

New commits:
commit c9963d279c0b58348b54d72f004af06f48b5dda7
Author: Thomas B <roundcube at gmail.com>
Date:   Thu May 3 10:28:42 2012 +0200

    Correctly handle object moving in kolab cache

diff --git a/plugins/libkolab/lib/kolab_storage_cache.php b/plugins/libkolab/lib/kolab_storage_cache.php
index ff11d63..9f80691 100644
--- a/plugins/libkolab/lib/kolab_storage_cache.php
+++ b/plugins/libkolab/lib/kolab_storage_cache.php
@@ -66,22 +66,8 @@ class kolab_storage_cache
             return;
         }
 
-        // strip namespace prefix from folder name
-        $ns = $this->folder->get_namespace();
-        $nsdata = $this->imap->get_namespace($ns);
-        if (is_array($nsdata[0]) && strpos($this->folder->name, $nsdata[0][0]) === 0) {
-            $subpath = substr($this->folder->name, strlen($nsdata[0][0]));
-            if ($ns == 'other') {
-                list($user, $suffix) = explode($nsdata[0][1], $subpath);
-                $subpath = $suffix;
-            }
-        }
-        else {
-            $subpath = $this->folder->name;
-        }
-
         // compose fully qualified ressource uri for this instance
-        $this->resource_uri = 'imap://' . urlencode($this->folder->get_owner()) . '@' . $this->imap->options['host'] . '/' . $subpath;
+        $this->resource_uri = $this->folder->get_resource_uri();
         $this->ready = $this->enabled;
     }
 
@@ -140,14 +126,22 @@ class kolab_storage_cache
 
     /**
      * Read a single entry from cache or
+     *
+     * @param string Related IMAP message UID
+     * @param string Object type to read
+     * @param string IMAP folder name the entry relates to
+     * @param array  Hash array with object properties or null if not found
      */
-    public function get($msguid, $type = null, $folder = null)
+    public function get($msguid, $type = null, $foldername = null)
     {
+        // delegate to another cache instance
+        if ($foldername && $foldername != $this->folder->name) {
+            return kolab_storage::get_folder($foldername)->cache->get($msguid, $object);
+        }
+
         // load object if not in memory
         if (!isset($this->objects[$msguid])) {
             if ($this->ready) {
-                // TODO: handle $folder != $this->folder->name situations
-                
                 $sql_result = $this->db->query(
                     "SELECT * FROM kolab_cache ".
                     "WHERE resource=? AND msguid=?",
@@ -162,7 +156,7 @@ class kolab_storage_cache
 
             // fetch from IMAP if not present in cache
             if (empty($this->objects[$msguid])) {
-                $result = $this->_fetch(array($msguid), $type, $folder);
+                $result = $this->_fetch(array($msguid), $type, $foldername);
                 $this->objects[$msguid] = $result[0];
             }
         }
@@ -172,14 +166,22 @@ class kolab_storage_cache
 
 
     /**
+     * Insert/Update a cache entry
      *
+     * @param string Related IMAP message UID
+     * @param mixed  Hash array with object properties to save or false to delete the cache entry
+     * @param string IMAP folder name the entry relates to
      */
-    public function set($msguid, $object, $folder = null)
+    public function set($msguid, $object, $foldername = null)
     {
+        // delegate to another cache instance
+        if ($foldername && $foldername != $this->folder->name) {
+            kolab_storage::get_folder($foldername)->cache->set($msguid, $object);
+            return;
+        }
+        
         // write to cache
         if ($this->ready) {
-            // TODO: handle $folder != $this->folder->name situations
-
             // remove old entry
             $this->db->query("DELETE FROM kolab_cache WHERE resource=? AND msguid=?",
                 $this->resource_uri, $msguid);
@@ -219,6 +221,36 @@ class kolab_storage_cache
             $this->uid2msg[$object['uid']] = $msguid;
     }
 
+    /**
+     * Move an existing cache entry to a new resource
+     *
+     * @param string Entry's IMAP message UID
+     * @param string Entry's Object UID
+     * @param string Target IMAP folder to move it to
+     */
+    public function move($msguid, $objuid, $target_folder)
+    {
+        $target = kolab_storage::get_folder($target_folder);
+
+        // resolve new message UID in target folder
+        if ($new_msguid = $target->cache->uid2msguid($objuid)) {
+            $this->db->query(
+                "UPDATE kolab_cache SET resource=?, msguid=? ".
+                "WHERE resource=? AND msguid=?",
+                $target->get_resource_uri(),
+                $new_msguid,
+                $this->resource_uri,
+                $msguid
+            );
+        }
+        else {
+            // just clear cache entry
+            $this->set($msguid, false);
+        }
+
+        unset($this->uid2msg[$uid]);
+    }
+
 
     /**
      * Remove all objects from local cache
@@ -365,7 +397,7 @@ class kolab_storage_cache
 
         // set type specific values
         if ($this->folder->type == 'event') {
-            // database runs in server's timetone so using date() is safe
+            // database runs in server's timezone so using date() is what we want
             $sql_data['dtstart'] = date('Y-m-d H:i:s', is_object($object['start']) ? $object['start']->format('U') : $object['start']);
             $sql_data['dtend']   = date('Y-m-d H:i:s', is_object($object['end'])   ? $object['end']->format('U')   : $object['end']);
         }
diff --git a/plugins/libkolab/lib/kolab_storage_folder.php b/plugins/libkolab/lib/kolab_storage_folder.php
index 69770ab..a0c12c4 100644
--- a/plugins/libkolab/lib/kolab_storage_folder.php
+++ b/plugins/libkolab/lib/kolab_storage_folder.php
@@ -27,23 +27,27 @@ class kolab_storage_folder
 
     /**
      * The folder name.
-     *
      * @var string
      */
     public $name;
 
     /**
      * The type of this folder.
-     *
      * @var string
      */
     public $type;
 
+    /**
+    * The attached cache object
+    * @var kolab_storage_cache
+     */
+    public $cache;
+
     private $type_annotation;
     private $imap;
     private $info;
     private $owner;
-    private $cache;
+    private $resource_uri;
     private $uid2msg = array();
 
 
@@ -72,6 +76,7 @@ class kolab_storage_folder
         $metadata = $this->imap->get_metadata($this->name, array(kolab_storage::CTYPE_KEY));
         $this->type_annotation = $metadata[$this->name][kolab_storage::CTYPE_KEY];
         $this->type = reset(explode('.', $this->type_annotation));
+        $this->resource_uri = null;
 
         $this->cache->set_folder($this);
     }
@@ -181,6 +186,34 @@ class kolab_storage_folder
 
 
     /**
+     * Compose a unique resource URI for this IMAP folder
+     */
+    public function get_resource_uri()
+    {
+        if (!empty($this->resource_uri))
+            return $this->resource_uri;
+
+        // strip namespace prefix from folder name
+        $ns = $this->get_namespace();
+        $nsdata = $this->imap->get_namespace($ns);
+        if (is_array($nsdata[0]) && strpos($this->name, $nsdata[0][0]) === 0) {
+            $subpath = substr($this->name, strlen($nsdata[0][0]));
+            if ($ns == 'other') {
+                list($user, $suffix) = explode($nsdata[0][1], $subpath);
+                $subpath = $suffix;
+            }
+        }
+        else {
+            $subpath = $this->name;
+        }
+
+        // compose fully qualified ressource uri for this instance
+        $this->resource_uri = 'imap://' . urlencode($this->get_owner()) . '@' . $this->imap->options['host'] . '/' . $subpath;
+        return $this->resource_uri;
+    }
+
+
+    /**
      * Check subscription status of this folder
      *
      * @param string Subscription type (kolab_storage::SERVERSIDE_SUBSCRIPTION or kolab_storage::CLIENTSIDE_SUBSCRIPTION)
@@ -532,7 +565,7 @@ class kolab_storage_folder
     {
         if ($msguid = $this->cache->uid2msguid($uid)) {
             if ($success = $this->imap->move_message($msguid, $target_folder, $this->name)) {
-                // TODO: update cache
+                $this->cache->move($msguid, $uid, $target_folder);
                 return true;
             }
             else {





More information about the commits mailing list