Have IMP_Imap_Tree implement Serializable
authorMichael M Slusarz <slusarz@curecanti.org>
Sat, 4 Sep 2010 07:06:34 +0000 (01:06 -0600)
committerMichael M Slusarz <slusarz@curecanti.org>
Mon, 6 Sep 2010 20:31:15 +0000 (14:31 -0600)
Slightly more compact way of storing serialized data.  Also, implement
versioning in order to invalidate cache when upgrading in future.

imp/lib/Imap/Tree.php
imp/lib/Injector/Binder/Imaptree.php

index b22f482..f8bdcfa 100644 (file)
  * @license  http://www.fsf.org/copyleft/gpl.html GPL
  * @package  IMP
  */
-class IMP_Imap_Tree implements ArrayAccess, Iterator
+class IMP_Imap_Tree implements ArrayAccess, Iterator, Serializable
 {
+    /* Serialized version. */
+    const VERSION = 1;
+
     /* Constants for mailboxElt attributes. */
     const ELT_NOSELECT = 1;
     const ELT_NAMESPACE = 2;
@@ -174,17 +177,6 @@ class IMP_Imap_Tree implements ArrayAccess, Iterator
     }
 
     /**
-     * Do cleanup prior to serialization and provide a list of variables
-     * to serialize.
-     */
-    public function __sleep()
-    {
-        return array(
-            '_tree', '_showunsub', '_parent', '_delimiter', '_namespaces'
-        );
-    }
-
-    /**
      * Initalize the tree.
      */
     public function init()
@@ -1839,4 +1831,47 @@ class IMP_Imap_Tree implements ArrayAccess, Iterator
         );
     }
 
+    /* Serializable methods. */
+
+    /**
+     * Serialization.
+     *
+     * @return string  Serialized data.
+     */
+    public function serialize()
+    {
+        return serialize(array(
+            // Serialized data ID.
+            self::VERSION,
+            $this->_delimiter,
+            $this->_namespaces,
+            $this->_parent,
+            $this->_showunsub,
+            $this->_tree
+        ));
+    }
+
+    /**
+     * Unserialization.
+     *
+     * @param string $data  Serialized data.
+     *
+     * @throws Exception
+     */
+    public function unserialize($data)
+    {
+        $data = @unserialize($data);
+        if (!is_array($data) ||
+            !isset($data[0]) ||
+            ($data[0] != self::VERSION)) {
+            throw new Exception('Cache version change');
+        }
+
+        $this->_delimiter = $data[1];
+        $this->_namespaces = $data[2];
+        $this->_parent = $data[3];
+        $this->_showunsub = $data[4];
+        $this->_tree = $data[5];
+    }
+
 }
index 09eed79..c465ea8 100644 (file)
@@ -29,18 +29,23 @@ class IMP_Injector_Binder_Imaptree implements Horde_Injector_Binder
     {
         $this->_injector = $injector;
 
+        $instance = null;
+
         if (empty($_SESSION['imp']['cache']['tree'])) {
             $_SESSION['imp']['cache']['tree'] = strval(new Horde_Support_Randomid());
-            $instance = null;
         } else {
             /* Since IMAP tree generation is so expensive/time-consuming,
              * fallback to storing in the session even if no permanent cache
              * backend is setup. */
             $cache = $injector->getInstance('Horde_Cache_Factory')->getCache(array('session' => true));
-            $instance = @unserialize($cache->get($_SESSION['imp']['cache']['tree'], 86400));
+            try {
+                $instance = @unserialize($cache->get($_SESSION['imp']['cache']['tree'], 86400));
+            } catch (Exception $e) {
+                Horde::logMessage('Could not unserialize stored IMP_Imap_Tree object.', 'DEBUG');
+            }
         }
 
-        if (empty($instance)) {
+        if (is_null($instance)) {
             $instance = new IMP_Imap_Tree();
         }