<?php
/**
- * The Horde_Cache:: class provides the abstract class definition for
- * Horde_Cache drivers.
+ * This class provides the API interface to the cache storage drivers.
*
* Copyright 1999-2010 The Horde Project (http://www.horde.org/)
*
* @author Chuck Hagenbuch <chuck@horde.org>
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
* @package Cache
*/
-abstract class Horde_Cache
+class Horde_Cache
{
/**
* Cache parameters.
*/
protected $_params = array(
'compress' => false,
- 'lifetime' => 86400,
- 'prefix' => '',
+ 'lifetime' => 86400
);
/**
protected $_logger;
/**
- * Construct a new Horde_Cache object.
+ * Storage object.
*
- * @param array $params Parameter array:
+ * @var Horde_Cache_Storage
+ */
+ protected $_storage;
+
+ /**
+ * Constructor.
+ *
+ * @param Horde_Cache_Storage $storage The storage object.
+ * @param array $params Parameter array:
* <pre>
* 'compress' - (boolean) Compress data? Requires the 'lzf' PECL
* extension.
* 'logger' - (Horde_Log_Logger) Log object to use for log/debug messages.
* </pre>
*/
- public function __construct($params = array())
+ public function __construct(Horde_Cache_Storage $storage,
+ array $params = array())
{
if (isset($params['logger'])) {
$this->_logger = $params['logger'];
unset($params['logger']);
+
+ $storage->setLogger($this->_logger);
}
if (!empty($params['compress']) && !extension_loaded('lzf')) {
}
$this->_params = array_merge($this->_params, $params);
+ $this->_storage = $storage;
}
/**
*/
public function get($key, $lifetime = 1)
{
- $res = $this->_get($key, $lifetime);
+ $res = $this->_storage->get($key, $lifetime);
return ($this->_params['compress'] && ($res !== false))
// lzf_decompress() returns false on error
}
/**
- * @see get()
- */
- abstract protected function _get($key, $lifetime);
-
- /**
* Store an object in the cache.
*
* @param string $key Object ID used as the caching key.
- * @param mixed $data Data to store in the cache.
+ * @param string $data Data to store in the cache.
* @param integer $lifetime Object lifetime - i.e. the time before the
* data becomes available for garbage
* collection. If null use the default Horde GC
* time. If 0 will not be GC'd.
- *
- * @throws Horde_Cache_Exception
*/
public function set($key, $data, $lifetime = null)
{
- if (!is_string($data)) {
- throw new Horde_Cache_Exception('Cache data must be a string.');
- }
-
if ($this->_params['compress']) {
$data = lzf_compress($data);
}
+ $lifetime = is_null($lifetime)
+ ? $this->_params['lifetime']
+ : $lifetime;
- $res = $this->_set($key, $data, $lifetime);
+ $this->_storage->set($key, $data, $lifetime);
}
/**
- * @see set()
- */
- abstract protected function _set($key, $data, $lifetime);
-
- /**
* Checks if a given key exists in the cache, valid for the given
* lifetime.
*
*
* @return boolean Existence.
*/
- abstract public function exists($key, $lifetime = 1);
+ public function exists($key, $lifetime = 1)
+ {
+ return $this->_storage->exists($key, $lifetime);
+ }
/**
* Expire any existing data for the given key.
*
* @return boolean Success or failure.
*/
- abstract public function expire($key);
-
- /**
- * Determine the default lifetime for data.
- *
- * @param mixed $lifetime The lifetime to use or null for default.
- *
- * @return integer The lifetime, in seconds.
- */
- protected function _getLifetime($lifetime)
+ public function expire($key)
{
- return is_null($lifetime) ? $this->_params['lifetime'] : $lifetime;
+ return $this->_storage->expire($key);
}
}
+++ /dev/null
-<?php
-/**
- * The Horde_Cache_Apc:: class provides an Alternative PHP Cache
- * implementation of the Horde caching system.
- *
- * Copyright 2006-2007 Duck <duck@obala.net>
- *
- * 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 Duck <duck@obala.net>
- * @category Horde
- * @package Cache
- */
-class Horde_Cache_Apc extends Horde_Cache
-{
- /**
- */
- protected function _get($key, $lifetime)
- {
- $key = $this->_params['prefix'] . $key;
- $this->_setExpire($key, $lifetime);
- return apc_fetch($key);
- }
-
- /**
- */
- protected function _set($key, $data, $lifetime)
- {
- $key = $this->_params['prefix'] . $key;
- $lifetime = $this->_getLifetime($lifetime);
- if (apc_store($key . '_expire', time(), $lifetime)) {
- apc_store($key, $data, $lifetime);
- }
- }
-
- /**
- * Checks if a given key exists in the cache, valid for the given
- * lifetime.
- *
- * @param string $key Cache key to check.
- * @param integer $lifetime Lifetime of the key in seconds.
- *
- * @return boolean Existence.
- */
- public function exists($key, $lifetime = 1)
- {
- $key = $this->_params['prefix'] . $key;
- $this->_setExpire($key, $lifetime);
- return (apc_fetch($key) !== false);
- }
-
- /**
- * Expire any existing data for the given key.
- *
- * @param string $key Cache key to expire.
- *
- * @return boolean Success or failure.
- */
- public function expire($key)
- {
- $key = $this->_params['prefix'] . $key;
- apc_delete($key . '_expire');
- return apc_delete($key);
- }
-
- /**
- * Set expire time on each call since APC sets it on cache creation.
- *
- * @param string $key Cache key to expire.
- * @param integer $lifetime Lifetime of the data in seconds.
- */
- protected function _setExpire($key, $lifetime)
- {
- $key = $this->_params['prefix'] . $key;
- if ($lifetime == 0) {
- // Don't expire.
- return;
- }
-
- $expire = apc_fetch($key . '_expire');
-
- // Set prune period.
- if ($expire + $lifetime < time()) {
- // Expired
- apc_delete($key);
- apc_delete($key . '_expire');
- }
- }
-
-}
+++ /dev/null
-<?php
-/**
- * The Horde_Cache_Eaccelerator:: class provides a eAccelerator content cache
- * (version 0.9.5+) implementation of the Horde caching system.
- *
- * Copyright 2006-2007 Duck <duck@obala.net>
- *
- * 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 Duck <duck@obala.net>
- * @category Horde
- * @package Cache
- */
-class Horde_Cache_Eaccelerator extends Horde_Cache
-{
- /**
- * Construct a new Horde_Cache object.
- *
- * @param array $params Parameter array.
- *
- * @throws Horde_Cache_Exception
- */
- public function __construct($params = array())
- {
- if (!function_exists('eaccelerator_gc')) {
- throw new Horde_Cache_Exception('eAccelerator must be compiled with support for shared memory to use as caching backend.');
- }
-
- parent::__construct($params);
- }
-
- /**
- */
- protected function _get($key, $lifetime)
- {
- $key = $this->_params['prefix'] . $key;
- $this->_setExpire($key, $lifetime);
- return eaccelerator_get($key);
- }
-
- /**
- */
- protected function _set($key, $data, $lifetime)
- {
- $key = $this->_params['prefix'] . $key;
- $lifetime = $this->_getLifetime($lifetime);
- if (eaccelerator_put($key . '_expire', time(), $lifetime)) {
- eaccelerator_put($key, $data, $lifetime);
- }
- }
-
- /**
- * Checks if a given key exists in the cache, valid for the given
- * lifetime.
- *
- * @param string $key Cache key to check.
- * @param integer $lifetime Lifetime of the key in seconds.
- *
- * @return boolean Existence.
- */
- public function exists($key, $lifetime = 1)
- {
- $key = $this->_params['prefix'] . $key;
- $this->_setExpire($key, $lifetime);
- return eaccelerator_get($key) !== false;
- }
-
- /**
- * Expire any existing data for the given key.
- *
- * @param string $key Cache key to expire.
- *
- * @return boolean Success or failure.
- */
- public function expire($key)
- {
- $key = $this->_params['prefix'] . $key;
- eaccelerator_rm($key . '_expire');
- return eaccelerator_rm($key);
- }
-
- /**
- * Set expire time on each call since eAccelerator sets it on
- * cache creation.
- *
- * @param string $key Cache key to expire.
- * @param integer $lifetime Lifetime of the data in seconds.
- */
- protected function _setExpire($key, $lifetime)
- {
- if ($lifetime == 0) {
- // Don't expire.
- return;
- }
-
- $key = $this->_params['prefix'] . $key;
- $expire = eaccelerator_get($key . '_expire');
-
- // Set prune period.
- if ($expire + $lifetime < time()) {
- // Expired
- eaccelerator_rm($key);
- eaccelerator_rm($key . '_expire');
- }
- }
-
-}
+++ /dev/null
-<?php
-/**
- * This class provides a filesystem implementation of the Horde caching
- * system.
- *
- * Copyright 1999-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 Anil Madhavapeddy <anil@recoil.org>
- * @author Chuck Hagenbuch <chuck@horde.org>
- * @category Horde
- * @license http://www.fsf.org/copyleft/lgpl.html LGPL
- * @package Cache
- */
-class Horde_Cache_File extends Horde_Cache
-{
- /* Location of the garbage collection data file. */
- const GC_FILE = 'horde_cache_gc';
-
- /**
- * The location of the temp directory.
- *
- * @var string
- */
- protected $_dir;
-
- /**
- * List of key to filename mappings.
- *
- * @var array
- */
- protected $_file = array();
-
- /**
- * Constructor.
- *
- * @param array $params Optional parameters:
- * <pre>
- * 'dir' - (string) The base directory to store the cache files in.
- * DEFAULT: System default
- * 'prefix' - (string) The filename prefix to use for the cache files.
- * DEFAULT: 'cache_'
- * 'sub' - (integer) If non-zero, the number of subdirectories to create
- * to store the file (i.e. PHP's session.save_path).
- * DEFAULT: 0
- * </pre>
- */
- public function __construct(array $params = array())
- {
- $params = array_merge(array(
- 'prefix' => 'cache_',
- 'sub' => 0
- ), $params);
-
- $this->_dir = (isset($params['dir']) && @is_dir($params['dir']))
- ? $params['dir']
- : Horde_Util::getTempDir();
-
- parent::__construct($params);
- }
-
- /**
- * Destructor.
- */
- public function __destruct()
- {
- /* Only do garbage collection 0.1% of the time we create an object. */
- if (rand(0, 999) != 0) {
- return;
- }
-
- $filename = $this->_dir . '/' . self::GC_FILE;
- $excepts = array();
-
- if (file_exists($filename)) {
- $gc_file = file($filename, FILE_IGNORE_NEW_LINES);
- reset($gc_file);
- next($gc_file);
- while (list(,$data) = each($gc_file)) {
- $parts = explode("\t", $data, 2);
- $excepts[$parts[0]] = $parts[1];
- }
- }
-
- try {
- $it = empty($this->_params['sub'])
- ? new DirectoryIterator($this->_dir)
- : new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->_dir), RecursiveIteratorIterator::CHILD_FIRST);
- } catch (UnexpectedValueException $e) {
- return;
- }
-
- $c_time = time();
-
- foreach ($it as $key => $val) {
- if (!$val->isDir() &&
- (strpos($val->getFilename(), $this->_params['prefix']) === 0)) {
- $d_time = isset($excepts[$key])
- ? $excepts[$key]
- : $this->_params['lifetime'];
-
- if (!empty($d_time) &&
- (($c_time - $d_time) > filemtime($key))) {
- @unlink($key);
- unset($excepts[$key]);
- }
- }
- }
-
- $fp = fopen($filename, 'w');
- foreach ($excepts as $key => $val) {
- fwrite($fp, $key . "\t" . $val . "\n");
- }
- fclose($fp);
- }
-
- /**
- */
- protected function _get($key, $lifetime)
- {
- if (!$this->exists($key, $lifetime)) {
- /* Nothing cached, return failure. */
- return false;
- }
-
- $filename = $this->_keyToFile($key);
- $size = filesize($filename);
-
- return $size
- ? @file_get_contents($filename)
- : '';
- }
-
- /**
- */
- protected function _set($key, $data, $lifetime)
- {
- $filename = $this->_keyToFile($key, true);
- $tmp_file = Horde_Util::getTempFile('HordeCache', true, $this->_dir);
- if (isset($this->_params['umask'])) {
- chmod($tmp_file, 0666 & ~$this->_params['umask']);
- }
-
- if (file_put_contents($tmp_file, $data) === false) {
- throw new Horde_Cache_Exception('Cannot write to cache directory ' . $this->_dir);
- }
-
- @rename($tmp_file, $filename);
-
- $lifetime = $this->_getLifetime($lifetime);
- if (($lifetime != $this->_params['lifetime']) &&
- ($fp = @fopen($this->_dir . '/horde_cache_gc', 'a'))) {
- // This may result in duplicate entries in horde_cache_gc, but we
- // will take care of these whenever we do GC and this is quicker
- // than having to check every time we access the file.
- fwrite($fp, $filename . "\t" . (empty($lifetime) ? 0 : time() + $lifetime) . "\n");
- fclose($fp);
- }
- }
-
- /**
- */
- public function exists($key, $lifetime = 1)
- {
- $filename = $this->_keyToFile($key);
-
- /* Key exists in the cache */
- if (file_exists($filename)) {
- /* 0 means no expire.
- * Also, If the file was been created after the supplied value,
- * the data is valid (fresh). */
- if (($lifetime == 0) ||
- (time() - $lifetime <= filemtime($filename))) {
- return true;
- }
-
- @unlink($filename);
- }
-
- return false;
- }
-
- /**
- */
- public function expire($key)
- {
- $filename = $this->_keyToFile($key);
- return @unlink($filename);
- }
-
- /**
- */
- public function output($key, $lifetime = 1)
- {
- if (!$this->exists($key, $lifetime)) {
- return false;
- }
-
- $filename = $this->_keyToFile($key);
- return @readfile($filename);
- }
-
- /**
- * Map a cache key to a unique filename.
- *
- * @param string $key Cache key.
- * @param string $create Create path if it doesn't exist?
- *
- * @return string Fully qualified filename.
- */
- protected function _keyToFile($key, $create = false)
- {
- if ($create || !isset($this->_file[$key])) {
- $dir = $this->_dir . '/';
- $md5 = hash('md5', $key);
- $sub = '';
-
- if (!empty($this->_params['sub'])) {
- $max = min($this->_params['sub'], strlen($md5));
- for ($i = 0; $i < $max; $i++) {
- $sub .= $md5[$i];
- if ($create && !is_dir($dir . $sub)) {
- if (!mkdir($dir . $sub)) {
- $sub = '';
- break;
- }
- }
- $sub .= '/';
- }
- }
-
- $this->_file[$key] = $dir . $sub . $this->_params['prefix'] . $md5;
- }
-
- return $this->_file[$key];
- }
-
- /**
- * TODO
- *
- * @throws Horde_Cache_Exception
- */
- protected function _gcDir($dir, &$excepts)
- {
- }
-
-}
+++ /dev/null
-<?php
-/**
- * The Horde_Cache_Memcache:: class provides a memcached implementation of the
- * Horde caching system.
- *
- * Copyright 2006-2007 Duck <duck@obala.net>
- * Copyright 2007-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 Duck <duck@obala.net>
- * @author Michael Slusarz <slusarz@horde.org>
- * @category Horde
- * @package Cache
- */
-class Horde_Cache_Memcache extends Horde_Cache
-{
- /**
- * Memcache object.
- *
- * @var Horde_Memcache
- */
- protected $_memcache;
-
- /**
- * Cache results of expire() calls (since we will get the entire object
- * on an expire() call anyway).
- */
- protected $_expirecache = array();
-
- /**
- * Construct a new Horde_Cache_Memcache object.
- *
- * @param array $params Parameter array:
- * <pre>
- * 'memcache' - (Horde_Memcache) A Horde_Memcache object.
- * </pre>
- *
- * @throws InvalidArgumentException
- */
- public function __construct($params = array())
- {
- if (!isset($params['memcache'])) {
- throw new InvalidArgumentException('Missing memcache object');
- }
-
- $this->_memcache = $params['memcache'];
-
- parent::__construct($params);
- }
-
- /**
- * Do cleanup prior to serialization and provide a list of variables
- * to serialize.
- */
- public function __sleep()
- {
- return array('_memcache');
- }
-
- /**
- */
- protected function _get($key, $lifetime)
- {
- $key = $this->_params['prefix'] . $key;
- if (isset($this->_expirecache[$key])) {
- return $this->_expirecache[$key];
- }
-
- $key_list = array($key);
- if (!empty($lifetime)) {
- $key_list[] = $key . '_e';
- }
-
- $res = $this->_memcache->get($key_list);
-
- if ($res === false) {
- unset($this->_expirecache[$key]);
- } else {
- // If we can't find the expire time, assume we have exceeded it.
- if (empty($lifetime) ||
- (($res[$key . '_e'] !== false) && ($res[$key . '_e'] + $lifetime > time()))) {
- $this->_expirecache[$key] = $res[$key];
- } else {
- $res[$key] = false;
- $this->expire($key);
- }
- }
-
- return $res[$key];
- }
-
- /**
- */
- protected function _set($key, $data, $lifetime)
- {
- $key = $this->_params['prefix'] . $key;
- $lifetime = $this->_getLifetime($lifetime);
-
- if ($this->_memcache->set($key . '_e', time(), $lifetime) !== false) {
- $this->_memcache->set($key, $data, $lifetime);
- }
- }
-
- /**
- * Checks if a given key exists in the cache.
- *
- * @param string $key Cache key to check.
- * @param integer $lifetime Lifetime of the key in seconds.
- *
- * @return boolean Existence.
- */
- public function exists($key, $lifetime = 1)
- {
- $key = $this->_params['prefix'] . $key;
-
- return ($this->get($key, $lifetime) !== false);
- }
-
- /**
- * Expire any existing data for the given key.
- *
- * @param string $key Cache key to expire.
- *
- * @return boolean Success or failure.
- */
- public function expire($key)
- {
- $key = $this->_params['prefix'] . $key;
- unset($this->_expirecache[$key]);
- $this->_memcache->delete($key . '_e');
-
- return $this->_memcache->delete($key);
- }
-
-}
+++ /dev/null
-<?php
-/**
- * The Horde_Cache_Mock:: class provides a memory based implementation of the
- * Horde caching system. It persists only during a script run and ignores the
- * object lifetime because of that.
- *
- * 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 Gunnar Wrobel <wrobel@pardus.de>
- * @category Horde
- * @license http://www.fsf.org/copyleft/lgpl.html LGPL
- * @link http://pear.horde.org/index.php?package=Cache
- * @package Cache
- */
-class Horde_Cache_Mock extends Horde_Cache
-{
- /**
- * The storage location for this cache.
- *
- * @var array
- */
- private $_cache = array();
-
- /**
- * Construct a new Horde_Cache_Mock object.
- *
- * @param array $params Configuration parameters:
- */
- public function __construct($params = array())
- {
- parent::__construct($params);
- }
-
- /**
- */
- protected function _get($key, $lifetime)
- {
- return isset($this->_cache[$key])
- ? $this->_cache[$key]
- : false;
- }
-
- /**
- */
- protected function _set($key, $data, $lifetime)
- {
- $this->_cache[$key] = $data;
- }
-
- /**
- * Checks if a given key exists in the cache, valid for the given
- * lifetime.
- *
- * @param string $key Cache key to check.
- * @param integer $lifetime Lifetime of the key in seconds.
- *
- * @return boolean Existence.
- */
- public function exists($key, $lifetime = 1)
- {
- return isset($this->_cache[$key]);
- }
-
- /**
- * Expire any existing data for the given key.
- *
- * @param string $key Cache key to expire.
- *
- * @return boolean Success or failure.
- */
- public function expire($key)
- {
- unset($this->_cache[$key]);
- }
-
-}
+++ /dev/null
-<?php
-/**
- * The Horde_Cache_Null:: class provides a null implementation of the Horde
- * caching system.
- *
- * Copyright 2006-2007 Duck <duck@obala.net>
- *
- * 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 Duck <duck@obala.net>
- * @category Horde
- * @package Cache
- */
-class Horde_Cache_Null extends Horde_Cache
-{
- /**
- */
- protected function _get($key, $lifetime)
- {
- return false;
- }
-
- /**
- */
- protected function _set($key, $data, $lifetime)
- {
- }
-
- /**
- * Checks if a given key exists in the cache, valid for the given
- * lifetime.
- *
- * @param string $key Cache key to check.
- * @param integer $lifetime Lifetime of the key in seconds.
- *
- * @return boolean Existence.
- */
- public function exists($key, $lifetime = 1)
- {
- return false;
- }
-
- /**
- * Expire any existing data for the given key.
- *
- * @param string $key Cache key to expire.
- *
- * @return boolean Success or failure.
- */
- public function expire($key)
- {
- return false;
- }
-
-}
+++ /dev/null
-<?php
-/**
- * This class provides a session storage implementation of the Horde caching
- * 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@curecanti.org>
- * @category Horde
- * @license http://www.fsf.org/copyleft/lgpl.html LGPL
- * @package Cache
- */
-class Horde_Cache_Session extends Horde_Cache
-{
- /**
- * Pointer to the session entry.
- *
- * @var array
- */
- protected $_sess;
-
- /**
- * Constructor.
- *
- * @param array $params Optional parameters:
- * <pre>
- * 'session' - (string) Store session data in this entry.
- * DEFAULT: 'horde_cache_session'
- * </pre>
- */
- public function __construct(array $params = array())
- {
- $params = array_merge(array(
- 'sess_name' => 'horde_cache_session'
- ), $params);
-
- parent::__construct($params);
-
- if (!isset($_SESSION[$this->_params['sess_name']])) {
- $_SESSION[$this->_params['sess_name']] = array();
- }
- $this->_sess = &$_SESSION[$this->_params['sess_name']];
- }
-
- /**
- */
- protected function _get($key, $lifetime)
- {
- return $this->exists($key, $lifetime)
- ? $this->_sess[$key]['d']
- : false;
- }
-
- /**
- */
- protected function _set($key, $data, $lifetime)
- {
- $this->_sess[$key] = array(
- 'd' => $data,
- 'l' => $this->_getLifetime($lifetime)
- );
- }
-
- /**
- * Checks if a given key exists in the cache, valid for the given
- * lifetime.
- *
- * @param string $key Cache key to check.
- * @param integer $lifetime Lifetime of the key in seconds.
- *
- * @return boolean Existence.
- */
- public function exists($key, $lifetime = 1)
- {
- if (isset($this->_sess[$key])) {
- /* 0 means no expire. */
- if (($lifetime == 0) ||
- ((time() - $lifetime) <= $this->_sess[$key]['l'])) {
- return true;
- }
-
- unset($this->_sess[$key]);
- }
-
- return false;
- }
-
- /**
- * Expire any existing data for the given key.
- *
- * @param string $key Cache key to expire.
- *
- * @return boolean Success or failure.
- */
- public function expire($key)
- {
- if (isset($this->_sess[$key])) {
- unset($this->_sess[$key]);
- return true;
- }
-
- return false;
- }
-
-}
+++ /dev/null
-<?php
-/**
- * The Horde_Cache_Sql:: class provides a SQL implementation of the Horde
- * Caching system.
- *
- * The table structure for the cache is as follows:
- * <pre>
- * CREATE TABLE horde_cache (
- * cache_id VARCHAR(32) NOT NULL,
- * cache_timestamp BIGINT NOT NULL,
- * cache_data LONGBLOB,
- * (Or on PostgreSQL:)
- * cache_data TEXT,
- * (Or on some other DBMS systems:)
- * cache_data IMAGE,
- *
- * PRIMARY KEY (cache_id)
- * );
- * </pre>
- *
- * Copyright 2007-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>
- * @author Ben Klang <ben@alkaloid.net>
- * @category Horde
- * @package Cache
- */
-class Horde_Cache_Sql extends Horde_Cache
-{
- /**
- * Handle for the current database connection.
- *
- * @var Horde_Db_Adapter
- */
- protected $_db;
-
- /**
- * Constructor.
- *
- * @param array $params Parameters:
- * <pre>
- * 'db' - (Horde_Db_Adapter) [REQUIRED] The DB instance.
- * 'table' - (string) The name of the cache table.
- * DEFAULT: 'horde_cache'
- * </pre>
- *
- * @throws Horde_Cache_Exception
- */
- public function __construct($params = array())
- {
- if (!isset($params['db'])) {
- throw new Horde_Cache_Exception('Missing db parameter.');
- }
- $this->_db = $params['db'];
- unset($params['db']);
-
- $params = array_merge(array(
- 'table' => 'horde_cache',
- ), $params);
-
- parent::__construct($params);
- }
-
- /**
- * Destructor.
- */
- public function __destruct()
- {
- /* Only do garbage collection 0.1% of the time we create an object. */
- if (rand(0, 999) != 0) {
- return;
- }
-
- $query = 'DELETE FROM ' . $this->_params['table'] .
- ' WHERE cache_expiration < ? AND cache_expiration <> 0';
- $values = array(time());
-
- try {
- $this->_db->delete($query, $values);
- } catch (Horde_Db_Exception $e) {}
- }
-
- /**
- */
- protected function _get($key, $lifetime)
- {
- $okey = $key;
- $key = hash('md5', $key);
-
- $timestamp = time();
- $maxage = $timestamp - $lifetime;
-
- /* Build SQL query. */
- $query = 'SELECT cache_data FROM ' . $this->_params['table'] .
- ' WHERE cache_id = ?';
- $values = array($key);
-
- // 0 lifetime checks for objects which have no expiration
- if ($lifetime != 0) {
- $query .= ' AND cache_timestamp >= ?';
- $values[] = $maxage;
- }
-
- try {
- $result = $this->_db->selectValue($query, $values);
- } catch (Horde_Db_Exception $e) {
- return false;
- }
-
- if (is_null($result)) {
- /* No rows were found - cache miss */
- if ($this->_logger) {
- $this->_logger->log(sprintf('Cache miss: %s (Id %s newer than %d)', $okey, $key, $maxage), 'DEBUG');
- }
- return false;
- }
-
- if ($this->_logger) {
- $this->_logger->log(sprintf('Cache hit: %s (Id %s newer than %d)', $okey, $key, $maxage), 'DEBUG');
- }
-
- return $result;
- }
-
- /**
- */
- protected function _set($key, $data, $lifetime)
- {
- $okey = $key;
- $key = hash('md5', $key);
-
- $timestamp = time();
-
- // 0 lifetime indicates the object should not be GC'd.
- $expiration = ($lifetime === 0)
- ? 0
- : $this->_getLifetime($lifetime) + $timestamp;
-
- if ($this->_logger) {
- $this->_logger->log(sprintf('Cache set: %s (Id %s set at %d expires at %d)', $okey, $key, $timestamp, $expiration), 'DEBUG');
- }
-
- // Remove any old cache data and prevent duplicate keys
- $query = 'DELETE FROM ' . $this->_params['table'] . ' WHERE cache_id=?';
- $values = array($key);
- try {
- $this->_db->delete($query, $values);
- } catch (Horde_Db_Exception $e) {}
-
- /* Build SQL query. */
- $query = 'INSERT INTO ' . $this->_params['table'] .
- ' (cache_id, cache_timestamp, cache_expiration, cache_data)' .
- ' VALUES (?, ?, ?, ?)';
- $values = array($key, $timestamp, $expiration, $data);
-
- try {
- $this->_db->insert($query, $values);
- } catch (Horde_Db_Exception $e) {
- throw new Horde_Cache_Exception($e);
- }
- }
-
- /**
- * Checks if a given key exists in the cache, valid for the given
- * lifetime.
- *
- * @param string $key Cache key to check.
- * @param integer $lifetime Maximum age of the key in seconds or 0 for
- * any object.
- *
- * @return boolean Existence.
- */
- public function exists($key, $lifetime = 1)
- {
- $okey = $key;
- $key = hash('md5', $key);
-
- /* Build SQL query. */
- $query = 'SELECT 1 FROM ' . $this->_params['table'] .
- ' WHERE cache_id = ?';
- $values = array($key);
-
- // 0 lifetime checks for objects which have no expiration
- if ($lifetime != 0) {
- $query .= ' AND cache_timestamp >= ?';
- $values[] = time() - $lifetime;
- }
-
- try {
- $result = $this->_db->selectValue($query, $values);
- } catch (Horde_Db_Exception $e) {
- return false;
- }
-
- $timestamp = time();
- if (empty($result)) {
- if ($this->_logger) {
- $this->_logger->log(sprintf('Cache exists() miss: %s (Id %s newer than %d)', $okey, $key, $timestamp), 'DEBUG');
- }
- return false;
- }
-
- if ($this->_logger) {
- $this->_logger->log(sprintf('Cache exists() hit: %s (Id %s newer than %d)', $okey, $key, $timestamp), 'DEBUG');
- }
-
- return true;
- }
-
- /**
- * Expire any existing data for the given key.
- *
- * @param string $key Cache key to expire.
- *
- * @return boolean Success or failure.
- */
- public function expire($key)
- {
- $key = hash('md5', $key);
-
- $query = 'DELETE FROM ' . $this->_params['table'] .
- ' WHERE cache_id = ?';
- $values = array($key);
-
- try {
- $this->_db->delete($query, $values);
- } catch (Horde_Db_Exception $e) {
- return false;
- }
-
- return true;
- }
-
-}
+++ /dev/null
-<?php
-/**
- * Horde_Cache_Stack:: is a Cache implementation that will loop through a
- * given list of Cache drivers to search for a cached value. This driver
- * allows for use of caching backends on top of persistent backends.
- *
- * 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
- * @package Cache
- */
-class Horde_Cache_Stack extends Horde_Cache
-{
- /**
- * Stack of cache drivers.
- *
- * @var string
- */
- protected $_stack = array();
-
- /**
- * Constructor.
- *
- * @param array $params Parameters:
- * <pre>
- * 'stack' - (array) [REQUIRED] An array of Cache instances to loop
- * through, in order of priority. The last entry is considered
- * the 'master' driver, for purposes of writes.
- * </pre>
- *
- * @throws InvalidArgumentException
- */
- public function __construct(array $params = array())
- {
- if (!isset($params['stack'])) {
- throw new InvalidArgumentException('Missing stack parameter.');
- }
- $this->_stack[] = $params['stack'];
-
- unset($params['stack']);
- parent::__construct($params);
- }
-
- /**
- */
- protected function _get($key, $lifetime)
- {
- foreach ($this->_stack as $val) {
- $result = $val->get($key, $lifetime);
- if ($result !== false) {
- return $result;
- }
- }
-
- return false;
- }
-
- /**
- */
- protected function _set($key, $data, $lifetime)
- {
- /* Do writes in *reverse* order - it is OK if a write to one of the
- * non-master backends fails. */
- $master = true;
-
- foreach (array_reverse($this->_stack) as $val) {
- $result = $val->set($key, $data, $lifetime);
- if ($result === false) {
- if ($master) {
- return;
- }
-
- /* Attempt to invalidate cache if write failed. */
- $val->expire($id);
- }
- $master = false;
- }
- }
-
- /**
- * Checks if a given key exists in the cache, valid for the given
- * lifetime.
- *
- * @param string $key Cache key to check.
- * @param integer $lifetime Lifetime of the key in seconds.
- *
- * @return boolean Existence.
- */
- public function exists($key, $lifetime = 1)
- {
- foreach ($this->_stack as $val) {
- $result = $val->exists($key, $lifetime);
- if ($result === true) {
- break;
- }
- }
-
- return $result;
- }
-
- /**
- * Expire any existing data for the given key.
- *
- * @param string $key Cache key to expire.
- *
- * @return boolean Success or failure.
- */
- public function expire($key)
- {
- /* Only report success from master. */
- $master = $success = true;
-
- foreach (array_reverse($this->_stack) as $val) {
- $result = $val->expire($id);
- if ($master && ($result === false)) {
- $success = false;
- }
- $master = false;
- }
-
- return $success;
- }
-
-}
--- /dev/null
+<?php
+/**
+ * This class provides the abstract implementation of the cache storage
+ * driver.
+ *
+ * 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 Cache
+ */
+abstract class Horde_Cache_Storage
+{
+ /**
+ * Logger.
+ *
+ * @var Horde_Log_Logger
+ */
+ protected $_logger;
+
+ /**
+ * Parameters.
+ *
+ * @var array
+ */
+ protected $_params = array();
+
+ /**
+ * Constructor.
+ *
+ * @param array $params Configuration parameters.
+ */
+ public function __construct(array $params = array())
+ {
+ $this->_params = array_merge($this->_params, $params);
+ }
+
+ /**
+ * Set the logging object.
+ *
+ * @param Horde_Log_Logger $logger Log object.
+ */
+ public function setLogger($logger)
+ {
+ $this->_logger = $logger;
+ }
+
+ /**
+ * Retrieve cached data.
+ *
+ * @param string $key Object ID to query.
+ * @param integer $lifetime Lifetime of the object in seconds.
+ *
+ * @return mixed Cached data, or false if none was found.
+ */
+ abstract public function get($key, $lifetime);
+
+ /**
+ * Store an object in the cache.
+ *
+ * @param string $key Object ID used as the caching key.
+ * @param mixed $data Data to store in the cache.
+ * @param integer $lifetime Object lifetime - i.e. the time before the
+ * data becomes available for garbage
+ * collection. If 0 will not be GC'd.
+ */
+ abstract public function set($key, $data, $lifetime);
+
+ /**
+ * Checks if a given key exists in the cache, valid for the given
+ * lifetime.
+ *
+ * @param string $key Cache key to check.
+ * @param integer $lifetime Lifetime of the key in seconds.
+ *
+ * @return boolean Existence.
+ */
+ abstract public function exists($key, $lifetime);
+
+ /**
+ * Expire any existing data for the given key.
+ *
+ * @param string $key Cache key to expire.
+ *
+ * @return boolean Success or failure.
+ */
+ abstract public function expire($key);
+
+}
--- /dev/null
+<?php
+/**
+ * This class provides cache storage in the Alternative PHP Cache.
+ *
+ * Copyright 2006-2007 Duck <duck@obala.net>
+ *
+ * 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 Duck <duck@obala.net>
+ * @category Horde
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @package Cache
+ */
+class Horde_Cache_Storage_Apc extends Horde_Cache_Storage
+{
+ /**
+ */
+ public function get($key, $lifetime)
+ {
+ $key = $this->_params['prefix'] . $key;
+ $this->_setExpire($key, $lifetime);
+ return apc_fetch($key);
+ }
+
+ /**
+ */
+ public function set($key, $data, $lifetime)
+ {
+ $key = $this->_params['prefix'] . $key;
+ if (apc_store($key . '_expire', time(), $lifetime)) {
+ apc_store($key, $data, $lifetime);
+ }
+ }
+
+ /**
+ */
+ public function exists($key, $lifetime)
+ {
+ $key = $this->_params['prefix'] . $key;
+ $this->_setExpire($key, $lifetime);
+ return (apc_fetch($key) !== false);
+ }
+
+ /**
+ */
+ public function expire($key)
+ {
+ $key = $this->_params['prefix'] . $key;
+ apc_delete($key . '_expire');
+ return apc_delete($key);
+ }
+
+ /**
+ * Set expire time on each call since APC sets it on cache creation.
+ *
+ * @param string $key Cache key to expire.
+ * @param integer $lifetime Lifetime of the data in seconds.
+ */
+ protected function _setExpire($key, $lifetime)
+ {
+ $key = $this->_params['prefix'] . $key;
+ if ($lifetime == 0) {
+ // Don't expire.
+ return;
+ }
+
+ $expire = apc_fetch($key . '_expire');
+
+ // Set prune period.
+ if ($expire + $lifetime < time()) {
+ // Expired
+ apc_delete($key);
+ apc_delete($key . '_expire');
+ }
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * This class provides cache storage in eAccelerator (version 0.9.5+).
+ *
+ * Copyright 2006-2007 Duck <duck@obala.net>
+ *
+ * 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 Duck <duck@obala.net>
+ * @category Horde
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @package Cache
+ */
+class Horde_Cache_Storage_Eaccelerator extends Horde_Cache_Storage
+{
+ /**
+ * @throws Horde_Cache_Exception
+ */
+ public function __construct(array $params = array())
+ {
+ if (!function_exists('eaccelerator_gc')) {
+ throw new Horde_Cache_Exception('eAccelerator must be compiled with support for shared memory to use as caching backend.');
+ }
+
+ parent::__construct($params);
+ }
+
+ /**
+ */
+ public function get($key, $lifetime)
+ {
+ $key = $this->_params['prefix'] . $key;
+ $this->_setExpire($key, $lifetime);
+ return eaccelerator_get($key);
+ }
+
+ /**
+ */
+ public function set($key, $data, $lifetime)
+ {
+ $key = $this->_params['prefix'] . $key;
+ if (eaccelerator_put($key . '_expire', time(), $lifetime)) {
+ eaccelerator_put($key, $data, $lifetime);
+ }
+ }
+
+ /**
+ */
+ public function exists($key, $lifetime)
+ {
+ $key = $this->_params['prefix'] . $key;
+ $this->_setExpire($key, $lifetime);
+ return eaccelerator_get($key) !== false;
+ }
+
+ /**
+ */
+ public function expire($key)
+ {
+ $key = $this->_params['prefix'] . $key;
+ eaccelerator_rm($key . '_expire');
+ return eaccelerator_rm($key);
+ }
+
+ /**
+ * Set expire time on each call since eAccelerator sets it on
+ * cache creation.
+ *
+ * @param string $key Cache key to expire.
+ * @param integer $lifetime Lifetime of the data in seconds.
+ */
+ protected function _setExpire($key, $lifetime)
+ {
+ if ($lifetime == 0) {
+ // Don't expire.
+ return;
+ }
+
+ $key = $this->_params['prefix'] . $key;
+ $expire = eaccelerator_get($key . '_expire');
+
+ // Set prune period.
+ if ($expire + $lifetime < time()) {
+ // Expired
+ eaccelerator_rm($key);
+ eaccelerator_rm($key . '_expire');
+ }
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * This class provides cache storage in the filesystem.
+ *
+ * Copyright 1999-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 Anil Madhavapeddy <anil@recoil.org>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @author Michael Slusarz <slusarz@horde.org>
+ * @category Horde
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @package Cache
+ */
+class Horde_Cache_Storage_File extends Horde_Cache_Storage
+{
+ /* Location of the garbage collection data file. */
+ const GC_FILE = 'horde_cache_gc';
+
+ /**
+ * The location of the temp directory.
+ *
+ * @var string
+ */
+ protected $_dir;
+
+ /**
+ * List of key to filename mappings.
+ *
+ * @var array
+ */
+ protected $_file = array();
+
+ /**
+ * Constructor.
+ *
+ * @param array $params Optional parameters:
+ * <pre>
+ * 'dir' - (string) The base directory to store the cache files in.
+ * DEFAULT: System default
+ * 'prefix' - (string) The filename prefix to use for the cache files.
+ * DEFAULT: 'cache_'
+ * 'sub' - (integer) If non-zero, the number of subdirectories to create
+ * to store the file (i.e. PHP's session.save_path).
+ * DEFAULT: 0
+ * </pre>
+ */
+ public function __construct(array $params = array())
+ {
+ $params = array_merge(array(
+ 'prefix' => 'cache_',
+ 'sub' => 0
+ ), $params);
+
+ $this->_dir = (isset($params['dir']) && @is_dir($params['dir']))
+ ? $params['dir']
+ : Horde_Util::getTempDir();
+
+ parent::__construct($params);
+ }
+
+ /**
+ * Destructor.
+ */
+ public function __destruct()
+ {
+ /* Only do garbage collection 0.1% of the time we create an object. */
+ if (rand(0, 999) != 0) {
+ return;
+ }
+
+ $filename = $this->_dir . '/' . self::GC_FILE;
+ $excepts = array();
+
+ if (file_exists($filename)) {
+ $gc_file = file($filename, FILE_IGNORE_NEW_LINES);
+ reset($gc_file);
+ next($gc_file);
+ while (list(,$data) = each($gc_file)) {
+ $parts = explode("\t", $data, 2);
+ $excepts[$parts[0]] = $parts[1];
+ }
+ }
+
+ try {
+ $it = empty($this->_params['sub'])
+ ? new DirectoryIterator($this->_dir)
+ : new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->_dir), RecursiveIteratorIterator::CHILD_FIRST);
+ } catch (UnexpectedValueException $e) {
+ return;
+ }
+
+ $c_time = time();
+
+ foreach ($it as $key => $val) {
+ if (!$val->isDir() &&
+ (strpos($val->getFilename(), $this->_params['prefix']) === 0)) {
+ $d_time = isset($excepts[$key])
+ ? $excepts[$key]
+ : $this->_params['lifetime'];
+
+ if (!empty($d_time) &&
+ (($c_time - $d_time) > filemtime($key))) {
+ @unlink($key);
+ unset($excepts[$key]);
+ }
+ }
+ }
+
+ $fp = fopen($filename, 'w');
+ foreach ($excepts as $key => $val) {
+ fwrite($fp, $key . "\t" . $val . "\n");
+ }
+ fclose($fp);
+ }
+
+ /**
+ */
+ public function get($key, $lifetime)
+ {
+ if (!$this->exists($key, $lifetime)) {
+ /* Nothing cached, return failure. */
+ return false;
+ }
+
+ $filename = $this->_keyToFile($key);
+ $size = filesize($filename);
+
+ return $size
+ ? @file_get_contents($filename)
+ : '';
+ }
+
+ /**
+ */
+ public function set($key, $data, $lifetime)
+ {
+ $filename = $this->_keyToFile($key, true);
+ $tmp_file = Horde_Util::getTempFile('HordeCache', true, $this->_dir);
+ if (isset($this->_params['umask'])) {
+ chmod($tmp_file, 0666 & ~$this->_params['umask']);
+ }
+
+ if (file_put_contents($tmp_file, $data) === false) {
+ throw new Horde_Cache_Exception('Cannot write to cache directory ' . $this->_dir);
+ }
+
+ @rename($tmp_file, $filename);
+
+ if (($lifetime != $this->_params['lifetime']) &&
+ ($fp = @fopen($this->_dir . '/horde_cache_gc', 'a'))) {
+ // This may result in duplicate entries in horde_cache_gc, but we
+ // will take care of these whenever we do GC and this is quicker
+ // than having to check every time we access the file.
+ fwrite($fp, $filename . "\t" . (empty($lifetime) ? 0 : time() + $lifetime) . "\n");
+ fclose($fp);
+ }
+ }
+
+ /**
+ */
+ public function exists($key, $lifetime)
+ {
+ $filename = $this->_keyToFile($key);
+
+ /* Key exists in the cache */
+ if (file_exists($filename)) {
+ /* 0 means no expire.
+ * Also, If the file was been created after the supplied value,
+ * the data is valid (fresh). */
+ if (($lifetime == 0) ||
+ (time() - $lifetime <= filemtime($filename))) {
+ return true;
+ }
+
+ @unlink($filename);
+ }
+
+ return false;
+ }
+
+ /**
+ */
+ public function expire($key)
+ {
+ $filename = $this->_keyToFile($key);
+ return @unlink($filename);
+ }
+
+ /**
+ * Map a cache key to a unique filename.
+ *
+ * @param string $key Cache key.
+ * @param string $create Create path if it doesn't exist?
+ *
+ * @return string Fully qualified filename.
+ */
+ protected function _keyToFile($key, $create = false)
+ {
+ if ($create || !isset($this->_file[$key])) {
+ $dir = $this->_dir . '/';
+ $md5 = hash('md5', $key);
+ $sub = '';
+
+ if (!empty($this->_params['sub'])) {
+ $max = min($this->_params['sub'], strlen($md5));
+ for ($i = 0; $i < $max; $i++) {
+ $sub .= $md5[$i];
+ if ($create && !is_dir($dir . $sub)) {
+ if (!mkdir($dir . $sub)) {
+ $sub = '';
+ break;
+ }
+ }
+ $sub .= '/';
+ }
+ }
+
+ $this->_file[$key] = $dir . $sub . $this->_params['prefix'] . $md5;
+ }
+
+ return $this->_file[$key];
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * This class provides cache storage in a memcache installation.
+ * Horde caching system.
+ *
+ * Copyright 2006-2007 Duck <duck@obala.net>
+ * Copyright 2007-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 Duck <duck@obala.net>
+ * @author Michael Slusarz <slusarz@horde.org>
+ * @category Horde
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @package Cache
+ */
+class Horde_Cache_Storage_Memcache extends Horde_Cache_Storage implements Serializable
+{
+ /**
+ * Cache results of expire() calls (since we will get the entire object
+ * on an expire() call anyway).
+ *
+ * @var array
+ */
+ protected $_expirecache = array();
+
+ /**
+ * Memcache object.
+ *
+ * @var Horde_Memcache
+ */
+ protected $_memcache;
+
+ /**
+ * Construct a new Horde_Cache_Memcache object.
+ *
+ * @param array $params Parameter array:
+ * <pre>
+ * 'memcache' - (Horde_Memcache) A Horde_Memcache object.
+ * </pre>
+ *
+ * @throws InvalidArgumentException
+ */
+ public function __construct($params = array())
+ {
+ if (!isset($params['memcache'])) {
+ throw new InvalidArgumentException('Missing memcache object');
+ }
+
+ $this->_memcache = $params['memcache'];
+ unset($params['memcache']);
+
+ parent::__construct($params);
+ }
+
+ /**
+ */
+ public function get($key, $lifetime)
+ {
+ $key = $this->_params['prefix'] . $key;
+ if (isset($this->_expirecache[$key])) {
+ return $this->_expirecache[$key];
+ }
+
+ $key_list = array($key);
+ if (!empty($lifetime)) {
+ $key_list[] = $key . '_e';
+ }
+
+ $res = $this->_memcache->get($key_list);
+
+ if ($res === false) {
+ unset($this->_expirecache[$key]);
+ } else {
+ // If we can't find the expire time, assume we have exceeded it.
+ if (empty($lifetime) ||
+ (($res[$key . '_e'] !== false) && ($res[$key . '_e'] + $lifetime > time()))) {
+ $this->_expirecache[$key] = $res[$key];
+ } else {
+ $res[$key] = false;
+ $this->expire($key);
+ }
+ }
+
+ return $res[$key];
+ }
+
+ /**
+ */
+ public function _set($key, $data, $lifetime)
+ {
+ $key = $this->_params['prefix'] . $key;
+
+ if ($this->_memcache->set($key . '_e', time(), $lifetime) !== false) {
+ $this->_memcache->set($key, $data, $lifetime);
+ }
+ }
+
+ /**
+ */
+ public function exists($key, $lifetime)
+ {
+ $key = $this->_params['prefix'] . $key;
+
+ return ($this->get($key, $lifetime) !== false);
+ }
+
+ /**
+ */
+ public function expire($key)
+ {
+ $key = $this->_params['prefix'] . $key;
+ unset($this->_expirecache[$key]);
+ $this->_memcache->delete($key . '_e');
+
+ return $this->_memcache->delete($key);
+ }
+
+ /* Serializable methods. */
+
+ /**
+ */
+ public function serialize()
+ {
+ return serialize($this->_memcache);
+ }
+
+ /**
+ */
+ public function unserialize($data)
+ {
+ $this->_memcache = unserialize($data);
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * This class provides cache storage in PHP memory.
+ * It persists only during a script run and ignores the object lifetime
+ * because of that.
+ *
+ * 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 Gunnar Wrobel <wrobel@pardus.de>
+ * @category Horde
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link http://pear.horde.org/index.php?package=Cache
+ * @package Cache
+ */
+class Horde_Cache_Storage_Mock extends Horde_Cache_Storage
+{
+ /**
+ * The storage location for this cache.
+ *
+ * @var array
+ */
+ private $_cache = array();
+
+ /**
+ */
+ public function get($key, $lifetime)
+ {
+ return isset($this->_cache[$key])
+ ? $this->_cache[$key]
+ : false;
+ }
+
+ /**
+ */
+ public function set($key, $data, $lifetime)
+ {
+ $this->_cache[$key] = $data;
+ }
+
+ /**
+ */
+ public function exists($key, $lifetime = 1)
+ {
+ return isset($this->_cache[$key]);
+ }
+
+ /**
+ */
+ public function expire($key)
+ {
+ unset($this->_cache[$key]);
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * This class provides a null cache storage driver.
+ *
+ * Copyright 2006-2007 Duck <duck@obala.net>
+ *
+ * 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 Duck <duck@obala.net>
+ * @category Horde
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @package Cache
+ */
+class Horde_Cache_Storage_Null extends Horde_Cache_Storage
+{
+ /**
+ */
+ public function get($key, $lifetime)
+ {
+ return false;
+ }
+
+ /**
+ */
+ public function set($key, $data, $lifetime)
+ {
+ }
+
+ /**
+ */
+ public function exists($key, $lifetime)
+ {
+ return false;
+ }
+
+ /**
+ */
+ public function expire($key)
+ {
+ return false;
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * This class provides cache storage in a PHP session.
+ *
+ * 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@curecanti.org>
+ * @category Horde
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @package Cache
+ */
+class Horde_Cache_Storage_Session extends Horde_Cache_Storage
+{
+ /**
+ * Pointer to the session entry.
+ *
+ * @var array
+ */
+ protected $_sess;
+
+ /**
+ * Constructor.
+ *
+ * @param array $params Optional parameters:
+ * <pre>
+ * 'session' - (string) Store session data in this entry.
+ * DEFAULT: 'horde_cache_session'
+ * </pre>
+ */
+ public function __construct(array $params = array())
+ {
+ $params = array_merge(array(
+ 'sess_name' => 'horde_cache_session'
+ ), $params);
+
+ parent::__construct($params);
+
+ if (!isset($_SESSION[$this->_params['sess_name']])) {
+ $_SESSION[$this->_params['sess_name']] = array();
+ }
+ $this->_sess = &$_SESSION[$this->_params['sess_name']];
+ }
+
+ /**
+ */
+ public function get($key, $lifetime)
+ {
+ return $this->exists($key, $lifetime)
+ ? $this->_sess[$key]['d']
+ : false;
+ }
+
+ /**
+ */
+ public function set($key, $data, $lifetime)
+ {
+ $this->_sess[$key] = array(
+ 'd' => $data,
+ 'l' => $lifetime
+ );
+ }
+
+ /**
+ */
+ public function exists($key, $lifetime)
+ {
+ if (isset($this->_sess[$key])) {
+ /* 0 means no expire. */
+ if (($lifetime == 0) ||
+ ((time() - $lifetime) <= $this->_sess[$key]['l'])) {
+ return true;
+ }
+
+ unset($this->_sess[$key]);
+ }
+
+ return false;
+ }
+
+ /**
+ */
+ public function expire($key)
+ {
+ if (isset($this->_sess[$key])) {
+ unset($this->_sess[$key]);
+ return true;
+ }
+
+ return false;
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * This class provides cache storage in a SQL databsae.
+ *
+ * The table structure for the cache is as follows:
+ * <pre>
+ * CREATE TABLE horde_cache (
+ * cache_id VARCHAR(32) NOT NULL,
+ * cache_timestamp BIGINT NOT NULL,
+ * cache_data LONGBLOB,
+ * (Or on PostgreSQL:)
+ * cache_data TEXT,
+ * (Or on some other DBMS systems:)
+ * cache_data IMAGE,
+ *
+ * PRIMARY KEY (cache_id)
+ * );
+ * </pre>
+ *
+ * Copyright 2007-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 Ben Klang <ben@alkaloid.net>
+ * @author Michael Slusarz <slusarz@horde.org>
+ * @category Horde
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @package Cache
+ */
+class Horde_Cache_Storage_Sql extends Horde_Cache_Storage
+{
+ /**
+ * Handle for the current database connection.
+ *
+ * @var Horde_Db_Adapter
+ */
+ protected $_db;
+
+ /**
+ * Constructor.
+ *
+ * @param array $params Parameters:
+ * <pre>
+ * 'db' - (Horde_Db_Adapter) [REQUIRED] The DB instance.
+ * 'table' - (string) The name of the cache table.
+ * DEFAULT: 'horde_cache'
+ * </pre>
+ *
+ * @throws Horde_Cache_Exception
+ */
+ public function __construct($params = array())
+ {
+ if (!isset($params['db'])) {
+ throw new Horde_Cache_Exception('Missing db parameter.');
+ }
+ $this->_db = $params['db'];
+ unset($params['db']);
+
+ $params = array_merge(array(
+ 'table' => 'horde_cache',
+ ), $params);
+
+ parent::__construct($params);
+ }
+
+ /**
+ * Destructor.
+ */
+ public function __destruct()
+ {
+ /* Only do garbage collection 0.1% of the time we create an object. */
+ if (rand(0, 999) != 0) {
+ return;
+ }
+
+ $query = 'DELETE FROM ' . $this->_params['table'] .
+ ' WHERE cache_expiration < ? AND cache_expiration <> 0';
+ $values = array(time());
+
+ try {
+ $this->_db->delete($query, $values);
+ } catch (Horde_Db_Exception $e) {}
+ }
+
+ /**
+ */
+ public function get($key, $lifetime)
+ {
+ $okey = $key;
+ $key = hash('md5', $key);
+
+ $timestamp = time();
+ $maxage = $timestamp - $lifetime;
+
+ /* Build SQL query. */
+ $query = 'SELECT cache_data FROM ' . $this->_params['table'] .
+ ' WHERE cache_id = ?';
+ $values = array($key);
+
+ // 0 lifetime checks for objects which have no expiration
+ if ($lifetime != 0) {
+ $query .= ' AND cache_timestamp >= ?';
+ $values[] = $maxage;
+ }
+
+ try {
+ $result = $this->_db->selectValue($query, $values);
+ } catch (Horde_Db_Exception $e) {
+ return false;
+ }
+
+ if (is_null($result)) {
+ /* No rows were found - cache miss */
+ if ($this->_logger) {
+ $this->_logger->log(sprintf('Cache miss: %s (Id %s newer than %d)', $okey, $key, $maxage), 'DEBUG');
+ }
+ return false;
+ }
+
+ if ($this->_logger) {
+ $this->_logger->log(sprintf('Cache hit: %s (Id %s newer than %d)', $okey, $key, $maxage), 'DEBUG');
+ }
+
+ return $result;
+ }
+
+ /**
+ */
+ public function _set($key, $data, $lifetime)
+ {
+ $okey = $key;
+ $key = hash('md5', $key);
+
+ $timestamp = time();
+
+ // 0 lifetime indicates the object should not be GC'd.
+ $expiration = ($lifetime === 0)
+ ? 0
+ : ($lifetime + $timestamp);
+
+ if ($this->_logger) {
+ $this->_logger->log(sprintf('Cache set: %s (Id %s set at %d expires at %d)', $okey, $key, $timestamp, $expiration), 'DEBUG');
+ }
+
+ // Remove any old cache data and prevent duplicate keys
+ $query = 'DELETE FROM ' . $this->_params['table'] . ' WHERE cache_id=?';
+ $values = array($key);
+ try {
+ $this->_db->delete($query, $values);
+ } catch (Horde_Db_Exception $e) {}
+
+ /* Build SQL query. */
+ $query = 'INSERT INTO ' . $this->_params['table'] .
+ ' (cache_id, cache_timestamp, cache_expiration, cache_data)' .
+ ' VALUES (?, ?, ?, ?)';
+ $values = array($key, $timestamp, $expiration, $data);
+
+ try {
+ $this->_db->insert($query, $values);
+ } catch (Horde_Db_Exception $e) {
+ throw new Horde_Cache_Exception($e);
+ }
+ }
+
+ /**
+ */
+ public function exists($key, $lifetime)
+ {
+ $okey = $key;
+ $key = hash('md5', $key);
+
+ /* Build SQL query. */
+ $query = 'SELECT 1 FROM ' . $this->_params['table'] .
+ ' WHERE cache_id = ?';
+ $values = array($key);
+
+ // 0 lifetime checks for objects which have no expiration
+ if ($lifetime != 0) {
+ $query .= ' AND cache_timestamp >= ?';
+ $values[] = time() - $lifetime;
+ }
+
+ try {
+ $result = $this->_db->selectValue($query, $values);
+ } catch (Horde_Db_Exception $e) {
+ return false;
+ }
+
+ $timestamp = time();
+ if (empty($result)) {
+ if ($this->_logger) {
+ $this->_logger->log(sprintf('Cache exists() miss: %s (Id %s newer than %d)', $okey, $key, $timestamp), 'DEBUG');
+ }
+ return false;
+ }
+
+ if ($this->_logger) {
+ $this->_logger->log(sprintf('Cache exists() hit: %s (Id %s newer than %d)', $okey, $key, $timestamp), 'DEBUG');
+ }
+
+ return true;
+ }
+
+ /**
+ */
+ public function expire($key)
+ {
+ $key = hash('md5', $key);
+
+ $query = 'DELETE FROM ' . $this->_params['table'] .
+ ' WHERE cache_id = ?';
+ $values = array($key);
+
+ try {
+ $this->_db->delete($query, $values);
+ } catch (Horde_Db_Exception $e) {
+ return false;
+ }
+
+ return true;
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * This class loops through a given list of storage drivers to search for a
+ * cached value. This driver allows for use of caching backends on top of
+ * persistent backends.
+ *
+ * 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 Cache
+ */
+class Horde_Cache_Storage_Stack extends Horde_Cache_Storage
+{
+ /**
+ * Stack of cache drivers.
+ *
+ * @var string
+ */
+ protected $_stack = array();
+
+ /**
+ * Constructor.
+ *
+ * @param array $params Parameters:
+ * <pre>
+ * 'stack' - (array) [REQUIRED] An array of storage instances to loop
+ * through, in order of priority. The last entry is considered
+ * the 'master' driver, for purposes of writes.
+ * </pre>
+ *
+ * @throws InvalidArgumentException
+ */
+ public function __construct(array $params = array())
+ {
+ if (!isset($params['stack'])) {
+ throw new InvalidArgumentException('Missing stack parameter.');
+ }
+ $this->_stack[] = $params['stack'];
+ unset($params['stack']);
+
+ parent::__construct($params);
+ }
+
+ /**
+ */
+ public function get($key, $lifetime)
+ {
+ foreach ($this->_stack as $val) {
+ $result = $val->get($key, $lifetime);
+ if ($result !== false) {
+ return $result;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ */
+ public function set($key, $data, $lifetime)
+ {
+ /* Do writes in *reverse* order - it is OK if a write to one of the
+ * non-master backends fails. */
+ $master = true;
+
+ foreach (array_reverse($this->_stack) as $val) {
+ $result = $val->set($key, $data, $lifetime);
+ if ($result === false) {
+ if ($master) {
+ return;
+ }
+
+ /* Attempt to invalidate cache if write failed. */
+ $val->expire($id);
+ }
+ $master = false;
+ }
+ }
+
+ /**
+ */
+ public function exists($key, $lifetime)
+ {
+ foreach ($this->_stack as $val) {
+ $result = $val->exists($key, $lifetime);
+ if ($result === true) {
+ break;
+ }
+ }
+
+ return $result;
+ }
+
+ /**
+ */
+ public function expire($key)
+ {
+ /* Only report success from master. */
+ $master = $success = true;
+
+ foreach (array_reverse($this->_stack) as $val) {
+ $result = $val->expire($id);
+ if ($master && ($result === false)) {
+ $success = false;
+ }
+ $master = false;
+ }
+
+ return $success;
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * This class provides cache storage in Xcache.
+ *
+ * Copyright 2006-2007 Duck <duck@obala.net>
+ *
+ * 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 Duck <duck@obala.net>
+ * @category Horde
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @package Cache
+ */
+class Horde_Cache_Storage_Xcache extends Horde_Cache_Storage
+{
+ /**
+ */
+ public function get($key, $lifetime)
+ {
+ $key = $this->_params['prefix'] . $key;
+ $this->_setExpire($key, $lifetime);
+ $result = xcache_get($key);
+
+ return empty($result)
+ ? false
+ : $result;
+ }
+
+ /**
+ */
+ public function set($key, $data, $lifetime)
+ {
+ $key = $this->_params['prefix'] . $key;
+ if (xcache_set($key . '_expire', time(), $lifetime)) {
+ xcache_set($key, $data, $lifetime);
+ }
+ }
+
+ /**
+ */
+ public function exists($key, $lifetime)
+ {
+ $key = $this->_params['prefix'] . $key;
+ $this->_setExpire($key, $lifetime);
+ return xcache_isset($key);
+ }
+
+ /**
+ */
+ public function expire($key)
+ {
+ $key = $this->_params['prefix'] . $key;
+ xcache_unset($key . '_expire');
+ return xcache_unset($key);
+ }
+
+ /**
+ * Set expire time on each call since memcache sets it on cache creation.
+ *
+ * @param string $key Cache key to expire.
+ * @param integer $lifetime Lifetime of the data in seconds.
+ */
+ protected function _setExpire($key, $lifetime)
+ {
+ if ($lifetime == 0) {
+ // don't expire
+ return;
+ }
+ $key = $this->_params['prefix'] . $key;
+ $expire = xcache_get($key . '_expire');
+
+ // set prune period
+ if ($expire + $lifetime < time()) {
+ // Expired
+ xcache_unset($key . '_expire');
+ xcache_unset($key);
+ }
+ }
+
+}
+++ /dev/null
-<?php
-/**
- * The Horde_Cache_Xcache:: class provides an XCache implementation of
- * the Horde caching system.
- *
- * Copyright 2006-2007 Duck <duck@obala.net>
- *
- * 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 Duck <duck@obala.net>
- * @category Horde
- * @package Cache
- */
-class Horde_Cache_Xcache extends Horde_Cache
-{
- /**
- */
- protected function _get($key, $lifetime)
- {
- $key = $this->_params['prefix'] . $key;
- $this->_setExpire($key, $lifetime);
- $result = xcache_get($key);
-
- return empty($result)
- ? false
- : $result;
- }
-
- /**
- */
- protected function _set($key, $data, $lifetime)
- {
- $key = $this->_params['prefix'] . $key;
- $lifetime = $this->_getLifetime($lifetime);
- if (xcache_set($key . '_expire', time(), $lifetime)) {
- xcache_set($key, $data, $lifetime);
- }
- }
-
- /**
- * Checks if a given key exists in the cache, valid for the given
- * lifetime.
- *
- * @param string $key Cache key to check.
- * @param integer $lifetime Lifetime of the key in seconds.
- *
- * @return boolean Existence.
- */
- public function exists($key, $lifetime = 1)
- {
- $key = $this->_params['prefix'] . $key;
- $this->_setExpire($key, $lifetime);
- return xcache_isset($key);
- }
-
- /**
- * Expire any existing data for the given key.
- *
- * @param string $key Cache key to expire.
- *
- * @return boolean Success or failure.
- */
- public function expire($key)
- {
- $key = $this->_params['prefix'] . $key;
- xcache_unset($key . '_expire');
- return xcache_unset($key);
- }
-
- /**
- * Set expire time on each call since memcache sets it on cache creation.
- *
- * @param string $key Cache key to expire.
- * @param integer $lifetime Lifetime of the data in seconds.
- */
- protected function _setExpire($key, $lifetime)
- {
- if ($lifetime == 0) {
- // don't expire
- return;
- }
- $key = $this->_params['prefix'] . $key;
- $expire = xcache_get($key . '_expire');
-
- // set prune period
- if ($expire + $lifetime < time()) {
- // Expired
- xcache_unset($key . '_expire');
- xcache_unset($key);
- }
- }
-
-}
<api>beta</api>
</stability>
<license uri="http://www.gnu.org/copyleft/lesser.html">LGPL</license>
- <notes>* Add option to transparently compress cache data using lzf.
+ <notes>* Abstracted storage-specific code into 'Storage' drivers.
+ * Add option to transparently compress cache data using lzf.
* Added Horde_Cache_Session::.
* Horde_Cache::set() no longer returns a boolean result.
* Added Horde_Cache_Exception::.
<dir name="lib">
<dir name="Horde">
<dir name="Cache">
- <file name="Apc.php" role="php" />
- <file name="Eaccelerator.php" role="php" />
+ <dir name="Storage">
+ <file name="Apc.php" role="php" />
+ <file name="Eaccelerator.php" role="php" />
+ <file name="File.php" role="php" />
+ <file name="Memcache.php" role="php" />
+ <file name="Mock.php" role="php" />
+ <file name="Null.php" role="php" />
+ <file name="Session.php" role="php" />
+ <file name="Sql.php" role="php" />
+ <file name="Stack.php" role="php" />
+ <file name="Xcache.php" role="php" />
+ </dir> <!-- /lib/Horde/Cache/Storage -->
<file name="Exception.php" role="php" />
- <file name="File.php" role="php" />
- <file name="Memcache.php" role="php" />
- <file name="Mock.php" role="php" />
- <file name="Null.php" role="php" />
- <file name="Session.php" role="php" />
- <file name="Sql.php" role="php" />
- <file name="Stack.php" role="php" />
- <file name="Xcache.php" role="php" />
+ <file name="Storage.php" role="php" />
</dir> <!-- /lib/Horde/Cache -->
<file name="Cache.php" role="php" />
</dir> <!-- /lib/Horde -->
</dependencies>
<phprelease>
<filelist>
- <install name="lib/Horde/Cache/Apc.php" as="Horde/Cache/Apc.php" />
- <install name="lib/Horde/Cache/Eaccelerator.php" as="Horde/Cache/Eaccelerator.php" />
+ <install name="lib/Horde/Cache/Storage/Apc.php" as="Horde/Cache/Storage/Apc.php" />
+ <install name="lib/Horde/Cache/Storage/Eaccelerator.php" as="Horde/Cache/Storage/Eaccelerator.php" />
+ <install name="lib/Horde/Cache/Storage/File.php" as="Horde/Cache/Storage/File.php" />
+ <install name="lib/Horde/Cache/Storage/Memcache.php" as="Horde/Cache/Storage/Memcache.php" />
+ <install name="lib/Horde/Cache/Storage/Mock.php" as="Horde/Cache/Storage/Mock.php" />
+ <install name="lib/Horde/Cache/Storage/Null.php" as="Horde/Cache/Storage/Null.php" />
+ <install name="lib/Horde/Cache/Storage/Session.php" as="Horde/Cache/Storage/Session.php" />
+ <install name="lib/Horde/Cache/Storage/Sql.php" as="Horde/Cache/Storage/Sql.php" />
+ <install name="lib/Horde/Cache/Storage/Stack.php" as="Horde/Cache/Storage/Stack.php" />
+ <install name="lib/Horde/Cache/Storage/Xcache.php" as="Horde/Cache/Storage/Xcache.php" />
<install name="lib/Horde/Cache/Exception.php" as="Horde/Cache/Exception.php" />
- <install name="lib/Horde/Cache/File.php" as="Horde/Cache/File.php" />
- <install name="lib/Horde/Cache/Memcache.php" as="Horde/Cache/Memcache.php" />
- <install name="lib/Horde/Cache/Mock.php" as="Horde/Cache/Mock.php" />
- <install name="lib/Horde/Cache/Null.php" as="Horde/Cache/Null.php" />
- <install name="lib/Horde/Cache/Session.php" as="Horde/Cache/Session.php" />
- <install name="lib/Horde/Cache/Sql.php" as="Horde/Cache/Sql.php" />
- <install name="lib/Horde/Cache/Stack.php" as="Horde/Cache/Stack.php" />
- <install name="lib/Horde/Cache/Xcache.php" as="Horde/Cache/Xcache.php" />
+ <install name="lib/Horde/Cache/Storage.php" as="Horde/Cache/Storage.php" />
<install name="lib/Horde/Cache.php" as="Horde/Cache.php" />
</filelist>
</phprelease>
if (isset($GLOBALS['conf']['cache']['default_lifetime'])) {
$params['lifetime'] = $GLOBALS['conf']['cache']['default_lifetime'];
}
+ $params['logger'] = $injector->getInstance('Horde_Log_Logger');
- $logger = $injector->getInstance('Horde_Log_Logger');
- $params['logger'] = $logger;
-
- $base_params = $params;
-
- if (strcasecmp($driver, 'Memcache') === 0) {
+ $lc_driver = Horde_String::lower($driver);
+ switch ($lc_driver) {
+ case 'Memcache':
$params['memcache'] = $injector->getInstance('Horde_Memcache');
- } elseif (strcasecmp($driver, 'Sql') === 0) {
+ break;
+
+ case 'Sql':
$params['db'] = $injector->getInstance('Horde_Db_Adapter');
+ break;
}
+ $storage = $this->_getStorage($driver, $params);
+
if (!empty($GLOBALS['conf']['cache']['use_memorycache']) &&
- ((strcasecmp($driver, 'Sql') === 0) ||
- (strcasecmp($driver, 'File') === 0))) {
+ in_array($lc_driver, array('File', 'Sql'))) {
if (strcasecmp($GLOBALS['conf']['cache']['use_memorycache'], 'Memcache') === 0) {
- $base_params['memcache'] = $injector->getInstance('Horde_Memcache');
+ $params['memcache'] = $injector->getInstance('Horde_Memcache');
}
- $class1 = $this->_driverToClassname($GLOBALS['conf']['cache']['use_memorycache']);
- $class2 = $this->_driverToClassname($driver);
- $params = array(
+ $cname = $this->_driverToClassname($GLOBALS['conf']['cache']['use_memorycache']);
+ $storage = new Horde_Cache_Storage_Stack(array(
'stack' => array(
- new $class1($base_params),
- new $class2($params),
+ $this->_getStorage($GLOBALS['conf']['cache']['use_memorycache'], $params),
+ $storage
)
- );
- $driver = 'Stack';
+ ));
}
- $classname = $this->_driverToClassname($driver);
- return new $classname($params);
+ return new Horde_Cache($storage, $params);
}
/**
*/
- protected function _driverToClassname($driver)
+ protected function _getStorage($driver, $params)
{
$driver = ucfirst(basename($driver));
- $classname = 'Horde_Cache_' . $driver;
+ $classname = 'Horde_Cache_Storage_' . $driver;
+
if (!class_exists($classname)) {
- $classname = 'Horde_Cache_Null';
+ $classname = 'Horde_Cache_Storage_Null';
}
- return $classname;
+ return new $classname($params);
}
}