First stab at caching the Horde_Share listcache, instead of the entire horde_share...
authorMichael J. Rubinsky <mrubinsk@horde.org>
Fri, 12 Nov 2010 18:57:19 +0000 (13:57 -0500)
committerMichael J. Rubinsky <mrubinsk@horde.org>
Fri, 12 Nov 2010 18:57:19 +0000 (13:57 -0500)
17 files changed:
ansel/lib/Gallery.php
framework/Core/lib/Horde/Core/Factory/Share.php
framework/Core/lib/Horde/Core/Factory/ShareBase.php [new file with mode: 0644]
framework/Core/lib/Horde/Core/Share/Driver.php
framework/Core/lib/Horde/Core/Share/FactoryCallback.php [new file with mode: 0644]
framework/Core/package.xml
framework/Share/lib/Horde/Share.php
framework/Share/lib/Horde/Share/Datatree.php
framework/Share/lib/Horde/Share/Kolab.php
framework/Share/lib/Horde/Share/Object.php
framework/Share/lib/Horde/Share/Object/Datatree.php
framework/Share/lib/Horde/Share/Object/Kolab.php
framework/Share/lib/Horde/Share/Object/Sql.php
framework/Share/lib/Horde/Share/Object/Sql/Hierarchical.php
framework/Share/lib/Horde/Share/Sql.php
framework/Share/lib/Horde/Share/Sql/Hierarchical.php
framework/Share/package.xml

index a214ec1..fa84e87 100644 (file)
@@ -11,7 +11,7 @@
  * @author  Michael J. Rubinsky <mrubinsk@horde.org>
  * @package Ansel
  */
-class Ansel_Gallery extends Horde_Share_Object_Sql_Hierarchical
+class Ansel_Gallery extends Horde_Share_Object_Sql_Hierarchical implements Serializable
 {
     /**
      * The gallery mode helper
@@ -965,11 +965,25 @@ class Ansel_Gallery extends Horde_Share_Object_Sql_Hierarchical
     {
         return $this->_modeHelper->getGalleryCrumbData();
     }
+/**
+     * Serialize this object.
+     *
+     * @return string  The serialized data.
+     */
+    public function serialize()
+    {
+        $data = array(
+            self::VERSION,
+            $this->data,
+            $this->_shareCallback,
+        );
+
+        return serialize($data);
+    }
 
     public function unserialize($data)
     {
         parent::unserialize($data);
-        $GLOBALS['injector']->getInstance('Ansel_Injector_Factory_Storage')->create()->shares->initShareObject($this);
         $this->_setModeHelper($this->get('view_mode'));
     }
 }
index dcff45c..e3fb7a6 100644 (file)
 class Horde_Core_Factory_Share
 {
     /**
-     * Instances.
-     *
-     * @var array
-     */
-    private $_instances = array();
-
-    /**
      * The injector.
      *
      * @var Horde_Injector
@@ -53,56 +46,12 @@ class Horde_Core_Factory_Share
      * @param string $driver  The share driver. Either empty (use default
      *                        driver from $conf) or a driver name.
      *
-     * @return Horde_Share  The Horde_Share instance.
+     * @return Horde_Core_Share_Driver  The Horde_Share instance.
      * @throws Horde_Exception
      */
     public function create($app = null, $driver = null)
     {
-        if (empty($driver)) {
-            $driver = $GLOBALS['conf']['share']['driver'];
-        }
-        if (empty($app)) {
-            $app = $this->_injector->getInstance('Horde_Registry')->getApp();
-        }
-
-        $sig = $app . '_' . $driver;
-
-        if (isset($this->_instances[$sig])) {
-            return $this->_instances[$sig];
-        }
-
-        if (!empty($GLOBALS['conf']['share']['cache'])) {
-            $cache_sig = 'horde_share/' . $app . '/' . $driver . '1';
-            $ob = $GLOBALS['session']->retrieve($cache_sig);
-        }
-
-        if (empty($ob)) {
-            $class = 'Horde_Share_' . ucfirst(basename($driver));
-            if (!class_exists($class)) {
-                throw new Horde_Exception(sprintf(Horde_Core_Translation::t("\"%s\" share driver not found."), $driver));
-            }
-            $sob = new $class($app, $GLOBALS['registry']->getAuth(), $this->_injector->getInstance('Horde_Perms'), $this->_injector->getInstance('Horde_Group'));
-            $ob = new Horde_Core_Share_Driver($sob);
-        }
-
-        if (!empty($GLOBALS['conf']['share']['cache'])) {
-            register_shutdown_function(array($this, 'shutdown'), $cache_sig, $ob);
-        }
-
-        $this->_instances[$sig] = $ob;
-
-        return $ob;
-    }
-
-    /**
-     * Shutdown function.
-     *
-     * @param string $sig         Cache signature.
-     * @param Horde_Share $share  Horde_Share object to cache.
-     */
-    public function shutdown($sig, $share)
-    {
-        $GLOBALS['session']->store($share, false, $sig);
+        return new Horde_Core_Share_Driver($this->_injector->getInstance('Horde_Core_Factory_ShareBase')->create($app, $driver));
     }
 
 }
diff --git a/framework/Core/lib/Horde/Core/Factory/ShareBase.php b/framework/Core/lib/Horde/Core/Factory/ShareBase.php
new file mode 100644 (file)
index 0000000..1f21ef4
--- /dev/null
@@ -0,0 +1,71 @@
+<?php
+/**
+ * A Horde_Injector:: based Horde_Share:: factory.
+ *
+ * @category Horde
+ * @package  Core
+ * @author   Michael J. Rubinsky <mrubinsk@horde.org>
+ */
+
+/**
+ * A Horde_Injector:: based Horde_Share:: factory.
+ *
+ * Copyright 2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @category Horde
+ * @package  Core
+ * @author   Michael J. Rubinsky <mrubinsk@horde.org>
+ */
+class Horde_Core_Factory_ShareBase
+{
+    public function create($app = null, $driver = null)
+    {
+        if (empty($driver)) {
+            $driver = $GLOBALS['conf']['share']['driver'];
+        }
+        if (empty($app)) {
+            $app = $GLOBALS['injector']->getInstance('Horde_Registry')->getApp();
+        }
+
+        $sig = $app . '_' . $driver;
+        if (isset($this->_instances[$sig])) {
+            return $this->_instances[$sig];
+        }
+
+        $class = 'Horde_Share_' . ucfirst(basename($driver));
+        if (!class_exists($class)) {
+            throw new Horde_Exception(sprintf(Horde_Core_Translation::t("\"%s\" share driver not found."), $driver));
+        }
+
+        $ob = new $class($app, $GLOBALS['registry']->getAuth(), $GLOBALS['injector']->getInstance('Horde_Perms'), $GLOBALS['injector']->getInstance('Horde_Group'));
+        $cb = new Horde_Core_Share_FactoryCallback($app, $driver);
+        $ob->setShareCallback(array($cb, 'create'));
+        if (!empty($GLOBALS['conf']['share']['cache'])) {
+            $cache_sig = 'horde_share/' . $app . '/' . $driver;
+            $listCache = $GLOBALS['session']->retrieve($cache_sig);
+            $ob->setListCache($listCache);
+        }
+
+        if (!empty($GLOBALS['conf']['share']['cache'])) {
+            register_shutdown_function(array($this, 'shutdown'), $cache_sig, $ob);
+        }
+        $this->_instances[$sig] = $ob;
+
+        return $ob;
+    }
+
+    /**
+     * Shutdown function.
+     *
+     * @param string $sig         Cache signature.
+     * @param Horde_Share $share  Horde_Share object to cache.
+     */
+    public function shutdown($sig, $share)
+    {
+        $GLOBALS['session']->store($share->getListCache(), false, $sig);
+    }
+
+}
\ No newline at end of file
index 64b095e..9dbefdd 100644 (file)
@@ -1,7 +1,6 @@
 <?php
 /**
- * Horde specific wrapper for Horde_Share drivers. Adds serializable interface,
- * Horde hook calls etc...
+ * Horde specific wrapper for Horde_Share drivers. Adds Horde hook calls etc...
  *
  * Copyright 2002-2010 The Horde Project (http://www.horde.org/)
  *
  * @license  http://opensource.org/licenses/lgpl-2.1.php LGPL
  * @package  Core
  */
-class Horde_Core_Share_Driver implements Serializable
+class Horde_Core_Share_Driver
 {
-    /** Serializable version **/
-    const VERSION = 1;
-
     /**
      * The composed Horde_Share driver
      *
@@ -65,45 +61,6 @@ class Horde_Core_Share_Driver implements Serializable
     }
 
     /**
-     * Serializes the object.
-     *
-     * @return string  The serialized object.
-     */
-    public function serialize()
-    {
-        $data = array(
-            self::VERSION,
-            $this->_share);
-
-        return serialize($data);
-    }
-
-    /**
-     * Reconstructs object from serialized properties.
-     *
-     * @param <type> $serialized
-     */
-    public function unserialize($data)
-    {
-        // Rebuild the object
-        $data = @unserialize($data);
-        if (!is_array($data) ||
-            !isset($data[0]) ||
-            ($data[0] != self::VERSION)) {
-            throw new Exception('Cache version change');
-        }
-        $this->_share = $data[1];
-
-        // Set the storage adapter.
-        $this->_share->setStorage($GLOBALS['injector']->getInstance($this->_storageMap[get_class($this->_share)]));
-
-        // Call the init hook
-         try {
-            Horde::callHook('share_init', array($this, $this->_share->getApp()));
-        } catch (Horde_Exception_HookNotSet $e) {}
-    }
-
-    /**
      * Lock an item belonging to a share, or an entire share itself.
      *
      * @param Horde_Lock $locks          The lock object
diff --git a/framework/Core/lib/Horde/Core/Share/FactoryCallback.php b/framework/Core/lib/Horde/Core/Share/FactoryCallback.php
new file mode 100644 (file)
index 0000000..48e0923
--- /dev/null
@@ -0,0 +1,28 @@
+<?php
+/* 
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+/**
+ * Description of FactoryCallback
+ *
+ * @author mrubinsk
+ */
+class Horde_Core_Share_FactoryCallback
+{
+    protected $_app;
+    protected $_driver;
+
+    public function __construct($app, $driver)
+    {
+        $this->_app = $app;
+        $this->_driver = $driver;
+    }
+
+    public function create()
+    {
+        return $GLOBALS['injector']->getInstance('Horde_Core_Factory_ShareBase')->create($this->_app, $this->_driver);
+    }
+
+}
index 176aac2..17f49b0 100644 (file)
@@ -23,8 +23,8 @@ Application Framework.</description>
   <email>slusarz@horde.org</email>
   <active>yes</active>
  </developer>
- <date>2010-11-04</date>
- <time>01:53:57</time>
+ <date>2010-11-12</date>
+ <time>13:50:27</time>
  <version>
   <release>0.1.0</release>
   <api>0.1.0</api>
@@ -161,6 +161,7 @@ Application Framework.</description>
        <file name="Secret.php" role="php" />
        <file name="SessionHandler.php" role="php" />
        <file name="Share.php" role="php" />
+       <file name="ShareBase.php" role="php" />
        <file name="Template.php" role="php" />
        <file name="TextFilter.php" role="php" />
        <file name="Token.php" role="php" />
@@ -205,6 +206,7 @@ Application Framework.</description>
       </dir> <!-- /lib/Horde/Core/Prefs -->
       <dir name="Share">
        <file name="Driver.php" role="php" />
+       <file name="FactoryCallback.php" role="php" />
       </dir> <!-- /lib/Horde/Core/Share -->
       <dir name="Text">
        <dir name="Filter">
@@ -776,6 +778,7 @@ Application Framework.</description>
    <install as="Horde/Core/Factory/Secret.php" name="lib/Horde/Core/Factory/Secret.php" />
    <install as="Horde/Core/Factory/SessionHandler.php" name="lib/Horde/Core/Factory/SessionHandler.php" />
    <install as="Horde/Core/Factory/Share.php" name="lib/Horde/Core/Factory/Share.php" />
+   <install as="Horde/Core/Factory/ShareBase.php" name="lib/Horde/Core/Factory/ShareBase.php" />
    <install as="Horde/Core/Factory/Template.php" name="lib/Horde/Core/Factory/Template.php" />
    <install as="Horde/Core/Factory/TextFilter.php" name="lib/Horde/Core/Factory/TextFilter.php" />
    <install as="Horde/Core/Factory/Token.php" name="lib/Horde/Core/Factory/Token.php" />
@@ -796,6 +799,7 @@ Application Framework.</description>
    <install as="Horde/Core/Prefs/Storage/Session.php" name="lib/Horde/Core/Prefs/Storage/Session.php" />
    <install as="Horde/Core/Prefs/Ui/Widgets.php" name="lib/Horde/Core/Prefs/Ui/Widgets.php" />
    <install as="Horde/Core/Share/Driver.php" name="lib/Horde/Core/Share/Driver.php" />
+   <install as="Horde/Core/Share/FactoryCallback.php" name="lib/Horde/Core/Share/FactoryCallback.php" />
    <install as="Horde/Core/Text/Filter/Bbcode.php" name="lib/Horde/Core/Text/Filter/Bbcode.php" />
    <install as="Horde/Core/Text/Filter/Emails.php" name="lib/Horde/Core/Text/Filter/Emails.php" />
    <install as="Horde/Core/Text/Filter/Emoticons.php" name="lib/Horde/Core/Text/Filter/Emoticons.php" />
@@ -945,7 +949,7 @@ Initial packaging
     <release>beta</release>
     <api>beta</api>
    </stability>
-   <date>2010-11-04</date>
+   <date>2010-11-12</date>
    <license uri="http://www.gnu.org/copyleft/lesser.html">LGPL</license>
    <notes>
 * Add Horde_Session.
index 2fa5273..8d3c559 100644 (file)
@@ -92,6 +92,8 @@ class Horde_Share
      */
     protected $_groups;
 
+    protected $_shareCallback;
+
     /**
      * Configured callbacks. We currently support:
      *<pre>
@@ -130,15 +132,24 @@ class Horde_Share
     }
 
     /**
-     * (re)connect the share object to this share driver. Userful for when
-     * share objects are unserialized from a cache separate from the share
-     * driver.
+     * (re)connect the share object to this share driver.
      *
      * @param Horde_Share_Object $object
      */
-    public function initShareObject($object)
+    public function initShareObject(Horde_Share_Object $object)
     {
-        // noop
+        $object->setShareOb($this->_shareCallback);
+        $this->_initShareObject($object);
+    }
+
+    protected function _initShareObject(Horde_Share_Object $object)
+    {
+        // noop here
+    }
+
+    public function setShareCallback($callback)
+    {
+        $this->_shareCallback = $callback;
     }
 
     /**
@@ -166,7 +177,6 @@ class Horde_Share
         }
 
         $share = $this->_getShare($name);
-        $share->setShareOb($this);
         $this->_shareMap[$share->getId()] = $name;
         $this->_cache[$name] = $share;
 
@@ -185,7 +195,6 @@ class Horde_Share
     {
         if (!isset($this->_shareMap[$cid])) {
             $share = $this->_getShareById($cid);
-            $share->setShareOb($this);
             $name = $share->getName();
             $this->_cache[$name] = $share;
             $this->_shareMap[$cid] = $name;
@@ -217,7 +226,6 @@ class Horde_Share
             $shares = $this->_getShares($missing_ids);
             foreach (array_keys($shares) as $key) {
                 $this->_cache[$key] = $shares[$key];
-                $this->_cache[$key]->setShareOb($this);
                 $this->_shareMap[$shares[$key]->getId()] = $key;
                 $all_shares[$key] = $this->_cache[$key];
             }
@@ -327,14 +335,11 @@ class Horde_Share
      * @return Horde_Share_Object  A new share object.
      * @throws Horde_Share_Exception
      */
-    public function newShare($owner, $name)
+    public function newShare($owner, $name = '')
     {
-        if (empty($name)) {
-            throw new Horde_Share_Exception('Share names must be non-empty');
-        }
         $share = $this->_newShare($name);
-        $this->initShareObject($share);
         $share->set('owner', $owner);
+        $share->setShareOb(empty($this->_shareCallback) ? $this : $this->_shareCallback);
 
         return $share;
     }
@@ -473,6 +478,26 @@ class Horde_Share
     }
 
     /**
+     * Returns an opaque value representing this share's listcache.
+     *
+     * @return string
+     */
+    public function getListCache()
+    {
+        return serialize($this->_listcache);
+    }
+
+    /**
+     * Set the list cache by passing in a previously retrieved listcache.
+     *
+     * @param string $cache
+     */
+    public function setListCache($cache)
+    {
+        $this->_listcache = unserialize($cache);
+    }
+
+    /**
      * Give public access to call the share callbacks. Needed to run the
      * callbacks from the Horde_Share_Object objects.
      *
index 7e2a26b..2b63e7e 100644 (file)
@@ -79,7 +79,7 @@ class Horde_Share_Datatree extends Horde_Share
         if ($datatreeObject instanceof PEAR_Error) {
             throw new Horde_Share_Exception($datatreeObject->getMessage());
         }
-        $share = new $this->_shareObject($datatreeObject);
+        $share = $this->_createObject($datatreeObject);
 
         return $share;
     }
@@ -99,7 +99,7 @@ class Horde_Share_Datatree extends Horde_Share
         if (is_a($datatreeObject, 'PEAR_Error')) {
             throw new Horde_Share_Exception($datatreeObject->getMessage());
         }
-        $share = new $this->_shareObject($datatreeObject);
+        $share = $this->_createObject($datatreeObject);
 
         return $share;
     }
@@ -125,7 +125,7 @@ class Horde_Share_Datatree extends Horde_Share
             if (is_a($objects[$key], 'PEAR_Error')) {
                 return $objects[$key];
             }
-            $shares[$key] = new $this->_shareObject($objects[$key]);
+            $shares[$key] = $this->_createObject($objects[$key]);
         }
         return $shares;
     }
@@ -205,17 +205,21 @@ class Horde_Share_Datatree extends Horde_Share
     }
 
     /**
-     * Returns a new share object.
+     * Returns a new share object. Share objects should *ALWAYS* be instantiated
+     * via the Horde_Share object.
      *
      * @param string $name  The share's name.
      *
      * @return Horde_Share_Object_datatree  A new share object.
      */
-    protected function &_newShare($name)
+    protected function _newShare($name)
     {
+        if (empty($name)) {
+            throw new Horde_Share_Exception('Share names must be non-empty');
+        }
         $datatreeObject = new Horde_Share_Object_DataTree_Share($name);
         $datatreeObject->setDataTree($this->_datatree);
-        $share = new $this->_shareObject($datatreeObject);
+        $share = $this->_createObject($datatreeObject);
 
         return $share;
     }
index c762f78..2180259 100644 (file)
@@ -64,88 +64,6 @@ class Horde_Share_kolab extends Horde_Share
         }
     }
 
-//    /**
-//     * Returns the properties that need to be serialized.
-//     *
-//     * @return array  List of serializable properties.
-//     */
-//    public function __sleep()
-//    {
-//        $properties = get_object_vars($this);
-//        unset($properties['_sortList'], $properties['_list']);
-//        $properties = array_keys($properties);
-//        return $properties;
-//    }
-//    /**
-//     * Initializes the object.
-//     *
-//     * @throws Horde_Exception
-//     */
-//    public function __wakeup()
-//    {
-//        if (empty($GLOBALS['conf']['kolab']['enabled'])) {
-//            throw new Horde_Exception('You must enable the kolab settings to use the Kolab Share driver.');
-//        }
-//        $this->_type = $this->_getFolderType($this->_app);
-//        $this->_list = $GLOBALS['injector']->getInstance('Horde_Kolab_Storage');
-//
-//        parent::__wakeup();
-//    }
-
-    /**
-     * Serialize the object. You *MUST* call setStorage() after unserialized.
-     *
-     * @return string
-     */
-    public function serialize()
-    {
-        $data = array(
-            self::VERSION,
-            $this->_app,
-            $this->_root,
-            $this->_cache,
-            $this->_shareMap,
-            $this->_listcache,
-            $this->_shareObject,
-            $this->_permsObject,
-            $this->_type,
-            $this->_listCacheValidity,
-            $this->_session);
-
-        return serialize($data);
-    }
-
-    /**
-     * Reconstruct object from serialized data. You MUST call setStorage()
-     * after unserialize.
-     *
-     * @param <type> $data
-     */
-    public function unserialize($data)
-    {
-        // Rebuild the object
-        $data = @unserialize($data);
-        if (!is_array($data) ||
-            !isset($data[0]) ||
-            ($data[0] != self::VERSION)) {
-            throw new Exception('Cache version change');
-        }
-        $this->_app = $data[1];
-        $this->_root = $data[2];
-        $this->_cache = $data[3];
-        $this->_shareMap = $data[4];
-        $this->_listcache = $data[5];
-        $this->_shareObject = $data[6];
-        $this->_permsObject = $data [7];
-        $this->_type = $data[8];
-        $this->_listCacheValidity = $data[9];
-        $this->_session = $data[10];
-
-        foreach (array_keys($this->_cache) as $name) {
-            $this->_initShareObject($this->_cache[$name]);
-        }
-    }
-
     /**
      * (re)connect the share object to this share driver. Userful for when
      * share objects are unserialized from a cache separate from the share
@@ -328,6 +246,9 @@ class Horde_Share_kolab extends Horde_Share
      */
     protected function &_newShare($name)
     {
+        if (empty($name)) {
+            throw new Horde_Share_Exception('Share names must be non-empty');
+        }
         $storageObject = new Horde_Share_Object_Kolab($name, $this->_type);
         return $storageObject;
     }
index 4e63ce7..cb012f4 100644 (file)
 abstract class Horde_Share_Object implements Serializable
 {
     /**
-     * The Horde_Share object which this share is associated with.
+     * A function to be called when a Horde_Share object is needed and not
+     * available.
      *
-     * @var Horde_Share
+     * @var callback
      */
-    protected $_shareOb;
+    protected $_shareCallback;
 
     /**
-     * Associates a Share object with this share.
+     * The Horde_Share object which this share is associated with.
+     * If this is empty, the $_shareCallback is called to obtain it.
      *
-     * @param Horde_Share $shareOb  The Share object.
+     * @var Horde_Share
      */
-    public function setShareOb(Horde_Share $shareOb)
-    {
-        $this->_shareOb = $shareOb;
-    }
+    protected $_shareOb;
 
     /**
-     * Sets any additional storage driver this object may need.
+     * Associates a Share object with this share, or provides a callback that
+     * knows how to provide it.
      *
-     * @param mixed $driver  The storage driver. 
+     * @param mixed Horde_Share | Callback $shareOb  The Share object.
      */
-    public function setStorage($driver)
+    public function setShareOb($shareOb)
     {
-        // Noop
+        if ($shareOb instanceof Horde_Share) {
+            $this->_shareOb = $shareOb;
+        } else {
+            $this->_shareCallback = $shareOb;
+        }
     }
 
     /**
@@ -45,6 +49,10 @@ abstract class Horde_Share_Object implements Serializable
      */
     public function getShareOb()
     {
+        if (empty($this->_shareOb)) {
+            $this->_shareOb = call_user_func($this->_shareCallback);
+        }
+
         return $this->_shareOb;
     }
 
@@ -101,7 +109,7 @@ abstract class Horde_Share_Object implements Serializable
      */
     public function save()
     {
-        $this->_shareOb->runCallback('modify', array($this));
+        $this->getShareOb()->runCallback('modify', array($this));
         return $this->_save();
     }
 
index d772806..f5737f4 100644 (file)
@@ -98,7 +98,7 @@ class Horde_Share_Object_Datatree extends Horde_Share_Object
             return true;
         }
 
-        return $this->_shareOb->getPermsObject()->hasPermission($this->getPermission(), $userid, $permission, $creator);
+        return $this->getShareOb()->getPermsObject()->hasPermission($this->getPermission(), $userid, $permission, $creator);
     }
 
     /**
index 9f83249..6f95894 100644 (file)
@@ -10,7 +10,7 @@
 class Horde_Share_Object_Kolab extends Horde_Share_Object implements Serializable
 {
     /** Serializable version **/
-    const VERSION = 1;
+    const VERSION = 2;
 
     /**
      * The Kolab folder this share is based on.
@@ -79,12 +79,14 @@ class Horde_Share_Object_Kolab extends Horde_Share_Object implements Serializabl
         $data = array(
             self::VERSION,
             $this->_data,
-            $this->_folder_name
+            $this->_folder_name,
+            $this->_shareCallback
         );
     }
 
     /**
-     * Unserialize object. You MUST call setShareOb() after unserializtion.
+     * Unserialize object.
+     *
      * @param <type> $data
      */
     public function unserialize($data)
@@ -98,16 +100,11 @@ class Horde_Share_Object_Kolab extends Horde_Share_Object implements Serializabl
 
         $this->_data = $data[1];
         $this->_folder_name = $data[2];
-    }
-
-    /**
-     * Sets the kolab storage object.
-     *
-     * @param Horde_Kolab_Storage $driver
-     */
-    public function setStorage($driver)
-    {
-        $this->_list = $driver;
+        if (empty($data[3])) {
+            throw new Exception('Missing callback for unserializing Horde_Share_Object');
+        }
+        $this->_shareCallback = $data[3];
+        $this->setShareOb(call_user_func($this->_shareCallback));
     }
 
     /**
index 3fcfed5..72e0950 100644 (file)
@@ -7,10 +7,10 @@
  * @author  Michael J. Rubinsky <mrubinsk@horde.org>
  * @package Horde_Share
  */
-class Horde_Share_Object_Sql extends Horde_Share_Object
+class Horde_Share_Object_Sql extends Horde_Share_Object implements Serializable
 {
     /** Serializable version **/
-    const VERSION = 1;
+    const VERSION = 2;
 
     /**
      * The actual storage object that holds the data.
@@ -46,7 +46,7 @@ class Horde_Share_Object_Sql extends Horde_Share_Object
     }
 
     /**
-     * Serialize this object. You *MUST* call setShareOb() after unserializing.
+     * Serialize this object.
      *
      * @return string  The serialized data.
      */
@@ -55,6 +55,7 @@ class Horde_Share_Object_Sql extends Horde_Share_Object
         $data = array(
             self::VERSION,
             $this->data,
+            $this->_shareCallback,
         );
 
         return serialize($data);
@@ -63,8 +64,6 @@ class Horde_Share_Object_Sql extends Horde_Share_Object
     /**
      * Reconstruct the object from serialized data.
      *
-     * You *MUST* call setShareOb() after unserializing.
-     *
      * @param string $data  The serialized data.
      */
     public function unserialize($data)
@@ -77,6 +76,10 @@ class Horde_Share_Object_Sql extends Horde_Share_Object
         }
 
         $this->data = $data[1];
+        if (empty($data[2])) {
+            throw new Exception('Missing callback for Horde_Share_Object unserializing');
+        }
+        $this->_shareCallback = $data[2];
     }
 
     /**
@@ -138,14 +141,14 @@ class Horde_Share_Object_Sql extends Horde_Share_Object
      */
     protected function _save()
     {
-        $db = $this->_shareOb->getStorage();
-        $table = $this->_shareOb->getTable();
+        $db = $this->getShareOb()->getStorage();
+        $table = $this->getShareOb()->getTable();
 
         $fields = array();
         $params = array();
 
         // Build the parameter arrays for the sql statement.
-        foreach ($this->_shareOb->toDriverCharset($this->data) as $key => $value) {
+        foreach ($this->getShareOb()->toDriverCharset($this->data) as $key => $value) {
             if ($key != 'share_id' && $key != 'perm' && $key != 'share_flags') {
                 $fields[] = $key;
                 $params[] = $value;
@@ -224,7 +227,7 @@ class Horde_Share_Object_Sql extends Horde_Share_Object
         if ($userid == $this->data['share_owner']) {
             return true;
         }
-        return $this->_shareOb->getPermsObject()->hasPermission($this->getPermission(), $userid, $permission, $creator);
+        return $this->getShareOb()->getPermsObject()->hasPermission($this->getPermission(), $userid, $permission, $creator);
     }
 
     /**
index 3b88e3d..27a858b 100644 (file)
@@ -36,7 +36,7 @@ class Horde_Share_Object_Sql_Hierarchical extends Horde_Share_Object_Sql
      */
     public function countChildren($user, $perm = Horde_Perms::SHOW, $allLevels = true)
     {
-        return $this->_shareOb->countShares($user, $perm, null, $this, $allLevels);
+        return $this->getShareOb()->countShares($user, $perm, null, $this, $allLevels);
     }
 
     /**
@@ -51,7 +51,7 @@ class Horde_Share_Object_Sql_Hierarchical extends Horde_Share_Object_Sql
      */
     public function getChildren($user, $perm = Horde_Perms::SHOW, $allLevels = true)
     {
-        return $this->_shareOb->listShares(
+        return $this->getShareOb()->listShares(
             $user, array('perm' => $perm,
                          'direction' => 1,
                          'parent' => $this,
@@ -66,7 +66,7 @@ class Horde_Share_Object_Sql_Hierarchical extends Horde_Share_Object_Sql
      */
     public function getParent()
     {
-        return $this->_shareOb->getParent($this);
+        return $this->getShareOb()->getParent($this);
     }
 
     /**
@@ -96,12 +96,12 @@ class Horde_Share_Object_Sql_Hierarchical extends Horde_Share_Object_Sql
     public function setParent($parent)
     {
         if (!is_null($parent) && !is_a($parent, 'Horde_Share_Object')) {
-            $parent = $this->_shareOb->getShareById($parent);
+            $parent = $this->getShareOb()->getShareById($parent);
         }
 
         /* If we are an existing share, check for any children */
         if ($this->getId()) {
-            $children = $this->_shareOb->listShares(null,
+            $children = $this->getShareOb()->listShares(null,
                 array('perm' => Horde_Perms::EDIT,
                       'parent' => $this,
                       'all_levels' => true,
@@ -121,9 +121,9 @@ class Horde_Share_Object_Sql_Hierarchical extends Horde_Share_Object_Sql
             $parent_string = null;
         }
         $this->data['share_parents'] = $parent_string;
-        $sql = 'UPDATE ' . $this->_shareOb->getTable() . ' SET share_parents = ? WHERE share_id = ?';
+        $sql = 'UPDATE ' . $this->getShareOb()->getTable() . ' SET share_parents = ? WHERE share_id = ?';
         try {
-            $this->_shareOb->getStorage()->update($sql, array($this->data['share_parents'], $this->getId()));
+            $this->getShareOb()->getStorage()->update($sql, array($this->data['share_parents'], $this->getId()));
         } catch (Horde_Db_Exception $e) {
             throw new Horde_Share_Exception($e->getMessage());
         }
index 8f3e1c7..e7c836d 100644 (file)
@@ -16,7 +16,7 @@
 /**
  * @package Horde_Share
  */
-class Horde_Share_Sql extends Horde_Share implements Serializable
+class Horde_Share_Sql extends Horde_Share
 {
     /* Share has user perms */
     const SQL_FLAG_USERS = 1;
@@ -59,75 +59,6 @@ class Horde_Share_Sql extends Horde_Share implements Serializable
     }
 
     /**
-     * Serializes the object. Includes all properties except _table (this can
-     * be determined by _app), and _db (which is injected when unserialized).
-     * Note that you MUST set the db adapter after unserializing, but calling
-     * the setDb() method.
-     *
-     * @return string  The serialized object.
-     */
-    public function serialize()
-    {
-        $data = array(
-            self::VERSION,
-            $this->_app,
-            $this->_root,
-            $this->_cache,
-            $this->_shareMap,
-            $this->_listcache,
-            $this->_shareObject,
-            $this->_permsObject,
-            $this->_groups
-        );
-
-        return serialize($data);
-    }
-
-    /**
-     * Reconstructs object from serialized properties.
-     * Note: You MUST set the db adapter via setDb() after unserializing this
-     * object.
-     *
-     * @param string $serialized
-     */
-    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->_app = $data[1];
-        $this->_root = $data[2];
-        $this->_cache = $data[3];
-        $this->_shareMap = $data[4];
-        $this->_listcache = $data[5];
-        $this->_shareObject = $data[6];
-        $this->_permsObject = $data[7];
-        $this->_groups = $data[8];
-
-        $this->_table = $this->_app . '_shares';
-
-        foreach (array_keys($this->_cache) as $name) {
-            $this->initShareObject($this->_cache[$name]);
-        }
-    }
-
-    /**
-     * (re)connect the share object to this share driver. Userful for when
-     * share objects are unserialized from a cache separate from the share
-     * driver.
-     *
-     * @param Horde_Share_Object $object
-     */
-    public function initShareObject($object)
-    {
-        $object->setShareOb($this);
-    }
-
-    /**
      * Get storage table
      *
      * @return string
@@ -232,7 +163,15 @@ class Horde_Share_Sql extends Horde_Share implements Serializable
         $data = $this->_fromDriverCharset($results);
         $this->_loadPermissions($data);
 
-        return new $this->_shareObject($data);
+        return $this->_createObject($data);
+    }
+
+    protected function _createObject($data = array())
+    {
+        $object = new $this->_shareObject($data);
+        $this->initShareObject($object);
+
+        return $object;
     }
 
     /**
@@ -279,7 +218,7 @@ class Horde_Share_Sql extends Horde_Share implements Serializable
         $data = $this->_fromDriverCharset($results);
         $this->_loadPermissions($data);
 
-        return new $this->_shareObject($data);
+        return $this->_createObject($data);
     }
 
     /**
@@ -342,7 +281,7 @@ class Horde_Share_Sql extends Horde_Share implements Serializable
         $sharelist = array();
         foreach ($shares as $id => $data) {
             $this->_getSharePerms($data);
-            $sharelist[$data['share_name']] = new $this->_shareObject($data);
+            $sharelist[$data['share_name']] = $this->_createObject($data);
         }
 
         return $sharelist;
@@ -408,8 +347,7 @@ class Horde_Share_Sql extends Horde_Share implements Serializable
         $sharelist = array();
         foreach ($shares as $id => $data) {
             $this->_getSharePerms($data);
-            $sharelist[$data['share_name']] = new $this->_shareObject($data);
-            $sharelist[$data['share_name']]->setShareOb($this);
+            $sharelist[$data['share_name']] = $this->_createObject($data);
         }
 
         return $sharelist;
@@ -433,7 +371,6 @@ class Horde_Share_Sql extends Horde_Share implements Serializable
      */
     public function listShares($userid, $params = array())
     {
-        //var_dump($params);
         $params = array_merge(array('perm' => Horde_Perms::SHOW,
                                     'attributes' => null,
                                     'from' => 0,
@@ -441,6 +378,11 @@ class Horde_Share_Sql extends Horde_Share implements Serializable
                                     'sort_by' => null,
                                     'direction' => 0),
                               $params);
+
+        $key = md5(serialize(array($userid, $params)));
+        if (!empty($this->_listcache[$key])) {
+            return $this->_listcache[$key];
+        }
         $shares = array();
         if (is_null($params['sort_by'])) {
             $sortfield = 's.share_name';
@@ -510,17 +452,17 @@ class Horde_Share_Sql extends Horde_Share implements Serializable
         $sharelist = array();
         foreach ($shares as $id => $data) {
             $this->_getSharePerms($data);
-            $sharelist[$data['share_name']] = new $this->_shareObject($data);
-            $sharelist[$data['share_name']]->setShareOb($this);
+            $sharelist[$data['share_name']] = $this->_createObject($data);
         }
         unset($shares);
 
         // Run the results through the callback, if configured.
         if (!empty($this->_callbacks['list'])) {
-            return $this->runCallback('list', array($userid, $sharelist, $params));
+            $sharelist = $this->runCallback('list', array($userid, $sharelist, $params));
         }
+        $this->_listcache[$key] = $sharelist;
 
-        return $sharelist;
+        return $this->_listcache[$key];
     }
 
     /**
@@ -544,8 +486,7 @@ class Horde_Share_Sql extends Horde_Share implements Serializable
         foreach ($rows as $share) {
             $data = $this->_fromDriverCharset($share);
             $this->_getSharePerms($data);
-            $sharelist[$data['share_name']] = new $this->_shareObject($data);
-            $sharelist[$data['share_name']]->setShareOb($this);
+            $sharelist[$data['share_name']] = $this->_createObject($data);
         }
 
         return $sharelist;
@@ -582,7 +523,10 @@ class Horde_Share_Sql extends Horde_Share implements Serializable
      */
     protected function _newShare($name)
     {
-        return new $this->_shareObject(array('share_name' => $name));
+        if (empty($name)) {
+            throw new Horde_Share_Exception('Share names must be non-empty');
+        }
+        return $this->_createObject(array('share_name' => $name));
     }
 
     /**
index d0b3222..0889d81 100644 (file)
@@ -17,21 +17,6 @@ class Horde_Share_Sql_Hierarchical extends Horde_Share_Sql
     protected $_shareObject = 'Horde_Share_Object_Sql_Hierarchical';
 
     /**
-     * Override new share creation so we can allow for shares with empty
-     * share_names.
-     *
-     * @see Horde_Share::newShare
-     */
-    public function newShare($owner, $name = '')
-    {
-        $share = $this->_newShare();
-        $this->initShareObject($share);
-        $share->set('owner', $owner);
-
-        return $share;
-    }
-
-    /**
      * Returns a new share object.
      *
      * @param string $name  The share's name.
@@ -40,8 +25,7 @@ class Horde_Share_Sql_Hierarchical extends Horde_Share_Sql
      */
     protected function _newShare()
     {
-        $share = new $this->_shareObject();
-        return $share;
+        return $this->_createObject();
     }
 
     /**
@@ -76,6 +60,10 @@ class Horde_Share_Sql_Hierarchical extends Horde_Share_Sql
                                     'all_levels' => true,
                                     'ignore_perms' => false),
                               $params);
+        $key = md5(serialize(array($userid, $params)));
+        if (!empty($this->_listcache[$key])) {
+            return $this->_listcache[$key];
+        }
         $shares = array();
         if (is_null($params['sort_by'])) {
             $sortfield = 's.share_id';
@@ -145,16 +133,17 @@ class Horde_Share_Sql_Hierarchical extends Horde_Share_Sql
         $sharelist = array();
         foreach ($shares as $id => $data) {
             $this->_getSharePerms($data);
-            $sharelist[$id] = new $this->_shareObject($data);
-            $sharelist[$id]->setShareOb($this);
+            $sharelist[$id] = $this->_createObject($data);
         }
         unset($shares);
 
         // Run the results through the callback, if configured.
         if (!empty($this->_callbacks['list'])) {
-            return $this->runCallback('list', array($userid, $sharelist, $params));
+            $sharelist = $this->runCallback('list', array($userid, $sharelist, $params));
         }
 
+        $this->_listcache[$key] = $sharelist;
+
         return $sharelist;
     }
 
@@ -189,7 +178,7 @@ class Horde_Share_Sql_Hierarchical extends Horde_Share_Sql
         }
         $key = hash('sha1', serialize(array($userid, $perm, $parent_id, $allLevels, $attributes, $ignorePerms)));
         if (isset($criteria[$key])) {
-            //return $criteria[$key];
+            return $criteria[$key];
         }
 
         $query = ' FROM ' . $this->_table . ' s ';
@@ -381,8 +370,7 @@ class Horde_Share_Sql_Hierarchical extends Horde_Share_Sql
     {
         if (!isset($this->_cache[$cid])) {
             $share = $this->_getShareById($cid);
-            $share->setShareOb($this);
-            $this->_cache[$cid] = &$share;
+            $this->_cache[$cid] = $share;
         }
 
         return $this->_cache[$cid];
@@ -403,7 +391,7 @@ class Horde_Share_Sql_Hierarchical extends Horde_Share_Sql
         $missing_ids = array();
         foreach ($cids as $cid) {
             if (isset($this->_cache[$cid])) {
-                $all_shares[] = &$this->_cache[$cid];
+                $all_shares[] = $this->_cache[$cid];
             } else {
                 $missing_ids[] = $cid;
             }
@@ -412,9 +400,8 @@ class Horde_Share_Sql_Hierarchical extends Horde_Share_Sql
         if (count($missing_ids)) {
             $shares = $this->_getShares($missing_ids);
             foreach (array_keys($shares) as $key) {
-                $this->_cache[$key] = &$shares[$key];
-                $this->_cache[$key]->setShareOb($this);
-                $all_shares[$key] = &$this->_cache[$key];
+                $this->_cache[$key] = $shares[$key];
+                $all_shares[$key] = $this->_cache[$key];
             }
         }
 
@@ -507,7 +494,7 @@ class Horde_Share_Sql_Hierarchical extends Horde_Share_Sql
 
         $sharelist = array();
         foreach ($shares as $id => $data) {
-            $sharelist[$id] = new $this->_shareObject($data);
+            $sharelist[$id] = $this->_createObject($data);
         }
 
         return $sharelist;
index 5d6ba47..337ae18 100644 (file)
@@ -11,8 +11,8 @@ resources a user owns or has access to.</description>
   <email>chuck@horde.org</email>
   <active>yes</active>
  </lead>
- <date>2010-10-29</date>
- <time>13:19:48</time>
+ <date>2010-11-12</date>
+ <time>13:50:22</time>
  <version>
   <release>0.0.4</release>
   <api>0.0.4</api>
@@ -450,6 +450,11 @@ resources a user owns or has access to.</description>
    <install as="locale/zh_CN/LC_MESSAGES/Horde_Share.po" name="locale/zh_CN/LC_MESSAGES/Horde_Share.po" />
    <install as="locale/zh_TW/LC_MESSAGES/Horde_Share.mo" name="locale/zh_TW/LC_MESSAGES/Horde_Share.mo" />
    <install as="locale/zh_TW/LC_MESSAGES/Horde_Share.po" name="locale/zh_TW/LC_MESSAGES/Horde_Share.po" />
+   <install as="tests/kolab_createdefault.phpt" name="tests/kolab_createdefault.phpt" />
+   <install as="tests/kolab_list.phpt" name="tests/kolab_list.phpt" />
+   <install as="tests/kolab_simple.phpt" name="tests/kolab_simple.phpt" />
+   <install as="Horde/Share/AllTests.php" name="tests/Horde/Share/AllTests.php" />
+   <install as="Horde/Share/KolabScenarioTest.php" name="tests/Horde/Share/KolabScenarioTest.php" />
   </filelist>
  </phprelease>
  <changelog>
@@ -518,7 +523,7 @@ Initial release as a PEAR package
     <release>beta</release>
     <api>beta</api>
    </stability>
-   <date>2010-10-29</date>
+   <date>2010-11-12</date>
    <license uri="http://www.gnu.org/copyleft/lesser.html">LGPL</license>
    <notes>
 * Converted to Horde 4 coding standards