Split prefs caching into separate class.
authorMichael M Slusarz <slusarz@curecanti.org>
Thu, 14 Oct 2010 22:32:03 +0000 (16:32 -0600)
committerMichael M Slusarz <slusarz@curecanti.org>
Fri, 15 Oct 2010 19:25:53 +0000 (13:25 -0600)
framework/Core/lib/Horde/Core/Factory/Prefs.php
framework/Prefs/lib/Horde/Prefs.php
framework/Prefs/lib/Horde/Prefs/Cache.php [new file with mode: 0644]
framework/Prefs/lib/Horde/Prefs/Cache/Null.php [new file with mode: 0644]
framework/Prefs/lib/Horde/Prefs/Cache/Session.php [new file with mode: 0644]
framework/Prefs/lib/Horde/Prefs/Imsp.php
framework/Prefs/lib/Horde/Prefs/KolabImap.php
framework/Prefs/lib/Horde/Prefs/Ldap.php
framework/Prefs/lib/Horde/Prefs/Sql.php
framework/Prefs/package.xml

index 16c7a1a..af1ccd2 100644 (file)
@@ -84,7 +84,7 @@ class Horde_Core_Factory_Prefs
         }
 
         $opts = array_merge(array(
-            'cache' => true,
+            'cache' => 'Horde_Prefs_Cache_Session',
             'charset' => 'UTF-8',
             'logger' => $this->_injector->getInstance('Horde_Log_Logger'),
             'password' => '',
index cc61186..ef50b70 100644 (file)
@@ -77,7 +77,7 @@ class Horde_Prefs implements ArrayAccess
      * @var array
      */
     protected $_opts = array(
-        'cache' => false,
+        'cache' => 'Horde_Prefs_Cache_Null',
         'logger' => null,
         'password' => '',
         'sizecallback' => null,
@@ -85,12 +85,11 @@ class Horde_Prefs implements ArrayAccess
     );
 
     /**
-     * Array to cache in. Usually a reference to an array in $_SESSION, but
-     * could be overridden by a subclass for testing or other users.
+     * Caching object.
      *
-     * @var array
+     * @var Horde_Prefs_Cache
      */
-    protected $_cache = array();
+    protected $_cache;
 
     /**
      * Hash holding preferences with hook functions defined.
@@ -119,8 +118,8 @@ class Horde_Prefs implements ArrayAccess
      * charset - (string) Default charset.
      * OPTIONAL:
      * ---------
-     * cache - (boolean) Should caching be used?
-     *         DEFAULT: false
+     * cache - (string) The class name defining the cache driver to use.
+     *         DEFAULT: Caching is not used
      * logger - (Horde_Log_Logger) Logging object.
      *          DEFAULT: NONE
      * password - (string) The password associated with 'user'.
@@ -180,20 +179,11 @@ class Horde_Prefs implements ArrayAccess
         $this->_params = $params;
         $this->_scope = $scope;
 
+        $this->_cache = new $this->_opts['cache']($this->getUser());
         $this->_dict = isset($this->_opts['translation'])
             ? $this->_opts['translation']
             : new Horde_Translation_Gettext('Horde_Prefs', dirname(__FILE__) . '/../../locale');
 
-        // Create a unique key that's safe to use for caching even if we want
-        // another user's preferences later, then register the cache array in
-        // $_SESSION.
-        if ($this->_opts['cache']) {
-            $cacheKey = 'horde_prefs_' . $this->getUser();
-
-            // Store a reference to the $_SESSION array.
-            $this->_cache = &$_SESSION[$cacheKey];
-        }
-
         register_shutdown_function(array($this, 'store'));
     }
 
@@ -244,10 +234,10 @@ class Horde_Prefs implements ArrayAccess
      */
     public function remove($pref)
     {
-        // FIXME not updated yet.
+        // FIXME not updated yet - not removed from backend.
         $scope = $this->_getPreferenceScope($pref);
         unset($this->_prefs[$pref]);
-        unset($this->_cache[$scope][$pref]);
+        $this->_cache->clear($scope, $pref);
     }
 
     /**
@@ -275,7 +265,9 @@ class Horde_Prefs implements ArrayAccess
 
         if ($result && $this->isDirty($pref)) {
             $scope = $this->_getPreferenceScope($pref);
-            $this->_cacheUpdate($scope, array($pref));
+            $this->_cache->update($scope, array(
+                $pref => $this->_scopes[$scope][$pref]
+            ));
 
             /* If this preference has a change hook, call it now. */
             try {
@@ -586,15 +578,16 @@ class Horde_Prefs implements ArrayAccess
         $this->_setDefaults($scope);
 
         // Now check the prefs cache for existing values.
-        if ($this->_cacheLookup($scope)) {
+        if (($cached = $this->_cache->get($scope)) !== false) {
+            $this->_scopes[$scope] = $cached;
             return;
         }
 
         $this->_retrieve($scope);
         $this->_callHooks($scope);
 
-        /* Update the session cache. */
-        $this->_cacheUpdate($scope, array_keys($this->_scopes[$scope]));
+        /* Update the cache. */
+        $this->_cache->update($scope, $this->_scopes[$scope]);
     }
 
     /**
@@ -631,10 +624,10 @@ class Horde_Prefs implements ArrayAccess
             $this->_prefs = array();
 
             /* Destroy the contents of the preferences cache. */
-            unset($this->_cache);
+            $this->_cache->clear();
         } else {
-            /* Remove this scope from the preferences cache, if it exists. */
-            unset($this->_cache[$this->getScope()]);
+            /* Remove this scope from the preferences cache. */
+            $this->_cache->clear($this->getScope());
         }
     }
 
@@ -697,41 +690,6 @@ class Horde_Prefs implements ArrayAccess
     }
 
     /**
-     * Updates the session-based preferences cache (if available).
-     *
-     * @param string $scope  The scope of the prefs being updated.
-     * @param array $prefs   The preferences to update.
-     */
-    protected function _cacheUpdate($scope, $prefs)
-    {
-        if ($this->_opts['cache'] && isset($this->_cache)) {
-            /* Place each preference in the cache according to its
-             * scope. */
-            foreach ($prefs as $name) {
-                if (isset($this->_scopes[$scope][$name])) {
-                    $this->_cache[$scope][$name] = $this->_scopes[$scope][$name];
-                }
-            }
-        }
-    }
-
-    /**
-     * Tries to find the requested preferences in the cache. If they
-     * exist, update the $_scopes hash with the cached values.
-     *
-     * @return boolean  True on success, false on failure.
-     */
-    protected function _cacheLookup($scope)
-    {
-        if ($this->_opts['cache'] && isset($this->_cache[$scope])) {
-            $this->_scopes[$scope] = $this->_cache[$scope];
-            return true;
-        }
-
-        return false;
-    }
-
-    /**
      * Populates the $_scopes hash with new entries and externally
      * defined default values.
      *
diff --git a/framework/Prefs/lib/Horde/Prefs/Cache.php b/framework/Prefs/lib/Horde/Prefs/Cache.php
new file mode 100644 (file)
index 0000000..469eea2
--- /dev/null
@@ -0,0 +1,61 @@
+<?php
+/**
+ * Cache driver for the preferences system.
+ *
+ * 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.
+ *
+ * @author   Michael Slusarz <slusarz@horde.org>
+ * @category Horde
+ * @license  http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @package  Prefs
+ */
+abstract class Horde_Prefs_Cache
+{
+    /**
+     * The username.
+     *
+     * @var string
+     */
+    protected $_user;
+
+    /**
+     * Constructor.
+     *
+     * @param string $user  The current username.
+     */
+    public function __construct($user)
+    {
+        $this->_user = $user;
+    }
+
+    /**
+     * Gets a cache entry.
+     *
+     * @param string $scope  The scope of the prefs to get.
+     *
+     * @return mixed  Prefs array on success, false on failure.
+     */
+    abstract public function get($scope);
+
+    /**
+     * Updates a cache entry.
+     *
+     * @param string $scope  The scope of the prefs being updated.
+     * @param array $prefs   The preferences to update.
+     */
+    abstract public function update($scope, $prefs);
+
+    /**
+     * Clear cache entries.
+     *
+     * @param string $scope  The scope of the prefs to clear. If null, clears
+     *                       entire cache.
+     * @param string $scope  The pref to clear. If null, clears the entire
+     *                       scope.
+     */
+    abstract public function clear($scope = null, $pref = null);
+
+}
diff --git a/framework/Prefs/lib/Horde/Prefs/Cache/Null.php b/framework/Prefs/lib/Horde/Prefs/Cache/Null.php
new file mode 100644 (file)
index 0000000..9737ba2
--- /dev/null
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Null cache driver for the preferences system.
+ *
+ * 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.
+ *
+ * @author   Michael Slusarz <slusarz@horde.org>
+ * @category Horde
+ * @license  http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @package  Prefs
+ */
+class Horde_Prefs_Cache_Null extends Horde_Prefs_Cache
+{
+    /**
+     */
+    public function get($scope)
+    {
+        return false;
+    }
+
+    /**
+     */
+    public function update($scope, $prefs)
+    {
+    }
+
+    /**
+     */
+    public function clear($scope = null, $pref = null)
+    {
+    }
+
+}
diff --git a/framework/Prefs/lib/Horde/Prefs/Cache/Session.php b/framework/Prefs/lib/Horde/Prefs/Cache/Session.php
new file mode 100644 (file)
index 0000000..1315c90
--- /dev/null
@@ -0,0 +1,64 @@
+<?php
+/**
+ * Session storage cache driver for the preferences system.
+ *
+ * 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.
+ *
+ * @author   Michael Slusarz <slusarz@horde.org>
+ * @category Horde
+ * @license  http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @package  Prefs
+ */
+class Horde_Prefs_Cache_Session extends Horde_Prefs_Cache
+{
+    /**
+     * Session key.
+     *
+     * @var string
+     */
+    protected $_key;
+
+    /**
+     */
+    public function __construct($user)
+    {
+        parent::__construct($user);
+
+        $this->_key = 'horde_prefs_' . $this->_user;
+    }
+
+    /**
+     */
+    public function get($scope)
+    {
+        return isset($_SESSION[$this->_key][$scope])
+            ? $_SESSION[$this->_key][$scope]
+            : false;
+    }
+
+    /**
+     */
+    public function update($scope, $prefs)
+    {
+        $_SESSION[$this->_key][$scope] = isset($_SESSION[$this->_key][$scope])
+            ? array_merge($_SESSION[$this->_key][$scope], $prefs)
+            : array();
+    }
+
+    /**
+     */
+    public function clear($scope = null, $pref = null)
+    {
+        if (is_null($scope)) {
+            unset($_SESSION[$this->_key]);
+        } elseif (is_null($pref)) {
+            unset($_SESSION[$this->_key][$scope]);
+        } else {
+            unset($_SESSION[$this->_key][$scope][$pref]);
+        }
+    }
+
+}
index 1502829..3ffebab 100644 (file)
@@ -77,6 +77,8 @@ class Horde_Prefs_Imsp extends Horde_Prefs_Base
         $this->_connect();
 
         foreach ($dirty_prefs as $scope => $prefs) {
+            $updated = array();
+
             foreach ($prefs as $name => $pref) {
                 // Don't store locked preferences.
                 if ($this->_scopes[$scope][$name]['m'] & self::LOCKED) {
@@ -98,10 +100,12 @@ class Horde_Prefs_Imsp extends Horde_Prefs_Base
 
                 // Clean the pref since it was just saved.
                 $this->_scopes[$scope][$name]['m'] &= ~self::DIRTY;
+
+                $updated[$name] = $this->_scopes[$scope][$name];
             }
 
             // Update the cache for this scope.
-            $this->_cacheUpdate($scope, array_keys($prefs));
+            $this->_cache->update($scope, $updated);
         }
     }
 
index 109749b..ac99fbb 100644 (file)
@@ -206,7 +206,7 @@ class Horde_Prefs_KolabImap extends Horde_Prefs_Base
             }
 
             // Update the cache for this scope.
-            $this->_cacheUpdate($scope, array_keys($prefs));
+            $this->_cache->update($scope, $prefs);
         }
     }
 
index 8a04c5a..950f322 100644 (file)
@@ -403,7 +403,7 @@ class Horde_Prefs_Ldap extends Horde_Prefs
             }
 
             // Update the cache for this scope.
-            $this->_cacheUpdate($scope, array_keys($prefs));
+            $this->_cache->update($scope, $prefs);
         }
     }
 
index 32a608c..d8416c9 100644 (file)
@@ -122,6 +122,8 @@ class Horde_Prefs_Sql extends Horde_Prefs
         // For each preference, check for an existing table row and
         // update it if it's there, or create a new one if it's not.
         foreach ($dirty_prefs as $scope => $prefs) {
+            $updated = array();
+
             foreach ($prefs as $name => $pref) {
                 // Don't store locked preferences.
                 if ($this->_scopes[$scope][$name]['m'] & self::LOCKED) {
@@ -189,10 +191,12 @@ class Horde_Prefs_Sql extends Horde_Prefs
 
                 // Clean the pref since it was just saved.
                 $this->_scopes[$scope][$name]['m'] &= ~self::DIRTY;
+
+                $updated[$name] = $this->_scopes[$scope][$name];
             }
 
             // Update the cache for this scope.
-            $this->_cacheUpdate($scope, array_keys($prefs));
+            $this->_cache->update($scope, $updated);
         }
     }
 
index f027999..0938065 100644 (file)
@@ -24,7 +24,8 @@ http://pear.php.net/dtd/package-2.0.xsd">
   <api>beta</api>
  </stability>
  <license uri="http://www.gnu.org/copyleft/lesser.html">LGPL</license>
- <notes>* Add array access API to Horde_Prefs.
+ <notes>* Abstract caching code into Horde_Prefs_Cache.
+ * Add array access API to Horde_Prefs.
  * Remove dependency on horde/Core.
  * Use Horde_Db as backend for Sql driver.
  * Moved UI code to horde/Core.
@@ -35,6 +36,11 @@ http://pear.php.net/dtd/package-2.0.xsd">
    <dir name="lib">
     <dir name="Horde">
      <dir name="Prefs">
+      <dir name="Cache">
+       <file name="Null.php" role="php" />
+       <file name="Session.php" role="php" />
+      </dir> <!-- /lib/Horde/Prefs/Cache -->
+      <file name="Cache.php" role="php" />
       <file name="CategoryManager.php" role="php" />
       <file name="Exception.php" role="php" />
       <file name="File.php" role="php" />
@@ -91,6 +97,9 @@ http://pear.php.net/dtd/package-2.0.xsd">
  </dependencies>
  <phprelease>
   <filelist>
+   <install name="lib/Horde/Prefs/Cache/Null.php" as="Horde/Prefs/Cache/Null.php" />
+   <install name="lib/Horde/Prefs/Cache/Session.php" as="Horde/Prefs/Cache/Session.php" />
+   <install name="lib/Horde/Prefs/Cache.php" as="Horde/Prefs/Cache.php" />
    <install name="lib/Horde/Prefs/CategoryManager.php" as="Horde/Prefs/CategoryManager.php" />
    <install name="lib/Horde/Prefs/Exception.php" as="Horde/Prefs/Exception.php" />
    <install name="lib/Horde/Prefs/File.php" as="Horde/Prefs/File.php" />