first commit
This commit is contained in:
Vendored
+93
@@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file classes/cache/APCCache.php
|
||||
*
|
||||
* Copyright (c) 2014-2021 Simon Fraser University
|
||||
* Copyright (c) 2000-2021 John Willinsky
|
||||
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
|
||||
*
|
||||
* @class apc_false
|
||||
*
|
||||
* @ingroup cache
|
||||
*
|
||||
* @see GenericCache
|
||||
*
|
||||
* @brief Provides caching based on APC's variable store.
|
||||
*/
|
||||
|
||||
namespace PKP\cache;
|
||||
|
||||
class apc_false
|
||||
{
|
||||
};
|
||||
|
||||
class APCCache extends GenericCache
|
||||
{
|
||||
/**
|
||||
* Flush the cache.
|
||||
*/
|
||||
public function flush()
|
||||
{
|
||||
$prefix = INDEX_FILE_LOCATION . ':' . $this->getContext() . ':' . $this->getCacheId();
|
||||
$info = apc_cache_info('user');
|
||||
foreach ($info['cache_list'] as $entry) {
|
||||
if (substr($entry['info'], 0, strlen($prefix)) == $prefix) {
|
||||
apc_delete($entry['info']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an object from the cache.
|
||||
*
|
||||
*/
|
||||
public function getCache($id)
|
||||
{
|
||||
$key = INDEX_FILE_LOCATION . ':' . $this->getContext() . ':' . $this->getCacheId() . ':' . $id;
|
||||
$returner = unserialize(apc_fetch($key));
|
||||
if ($returner === false) {
|
||||
return $this->cacheMiss;
|
||||
}
|
||||
if ($returner instanceof apc_false) {
|
||||
$returner = false;
|
||||
}
|
||||
return $returner;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an object in the cache. This function should be overridden
|
||||
* by subclasses.
|
||||
*
|
||||
*/
|
||||
public function setCache($id, $value)
|
||||
{
|
||||
$key = INDEX_FILE_LOCATION . ':' . $this->getContext() . ':' . $this->getCacheId() . ':' . $id;
|
||||
if ($value === false) {
|
||||
$value = new apc_false();
|
||||
}
|
||||
apc_store($key, serialize($value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the time at which the data was cached.
|
||||
* Not implemented in this type of cache.
|
||||
*/
|
||||
public function getCacheTime()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the entire contents of the cache.
|
||||
* WARNING: THIS DOES NOT FLUSH THE CACHE FIRST!
|
||||
*
|
||||
* @param array $contents Complete cache contents.
|
||||
*/
|
||||
public function setEntireCache($contents)
|
||||
{
|
||||
foreach ($contents as $id => $value) {
|
||||
$this->setCache($id, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
+171
@@ -0,0 +1,171 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file classes/cache/CacheManager.php
|
||||
*
|
||||
* Copyright (c) 2014-2021 Simon Fraser University
|
||||
* Copyright (c) 2000-2021 John Willinsky
|
||||
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
|
||||
*
|
||||
* @ingroup cache
|
||||
*
|
||||
* @see GenericCache
|
||||
*
|
||||
* @brief Provides cache management functions.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace PKP\cache;
|
||||
|
||||
use PKP\config\Config;
|
||||
use PKP\core\Core;
|
||||
use PKP\core\Registry;
|
||||
|
||||
define('CACHE_TYPE_FILE', 1);
|
||||
define('CACHE_TYPE_OBJECT', 2);
|
||||
|
||||
class CacheManager
|
||||
{
|
||||
/**
|
||||
* Get the static instance of the cache manager.
|
||||
*
|
||||
* @return CacheManager
|
||||
*/
|
||||
public static function getManager()
|
||||
{
|
||||
$manager = & Registry::get('cacheManager', true, null);
|
||||
if ($manager === null) {
|
||||
$manager = new CacheManager();
|
||||
}
|
||||
return $manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a file cache.
|
||||
*
|
||||
* @param string $context
|
||||
* @param string $cacheId
|
||||
* @param callable $fallback
|
||||
*
|
||||
* @return FileCache
|
||||
*/
|
||||
public function getFileCache($context, $cacheId, $fallback)
|
||||
{
|
||||
return new FileCache(
|
||||
$context,
|
||||
$cacheId,
|
||||
$fallback,
|
||||
$this->getFileCachePath()
|
||||
);
|
||||
}
|
||||
|
||||
public function getObjectCache($context, $cacheId, $fallback)
|
||||
{
|
||||
return $this->getCache($context, $cacheId, $fallback, CACHE_TYPE_OBJECT);
|
||||
}
|
||||
|
||||
public function getCacheImplementation($type)
|
||||
{
|
||||
switch ($type) {
|
||||
case CACHE_TYPE_FILE: return 'file';
|
||||
case CACHE_TYPE_OBJECT: return Config::getVar('cache', 'object_cache');
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a cache.
|
||||
*
|
||||
* @param string $context
|
||||
* @param string $cacheId
|
||||
* @param ?callable $fallback
|
||||
* @param string $type Type of cache: CACHE_TYPE_...
|
||||
*
|
||||
* @return GenericCache
|
||||
*/
|
||||
public function getCache($context, $cacheId, $fallback, $type = CACHE_TYPE_FILE)
|
||||
{
|
||||
switch ($this->getCacheImplementation($type)) {
|
||||
case 'xcache':
|
||||
$cache = new \PKP\cache\XCacheCache(
|
||||
$context,
|
||||
$cacheId,
|
||||
$fallback
|
||||
);
|
||||
break;
|
||||
case 'apc':
|
||||
$cache = new \PKP\cache\APCCache(
|
||||
$context,
|
||||
$cacheId,
|
||||
$fallback
|
||||
);
|
||||
break;
|
||||
case 'memcache':
|
||||
$cache = new \PKP\cache\MemcacheCache(
|
||||
$context,
|
||||
$cacheId,
|
||||
$fallback,
|
||||
Config::getVar('cache', 'memcache_hostname'),
|
||||
Config::getVar('cache', 'memcache_port')
|
||||
);
|
||||
break;
|
||||
case '': // Provide a default if not specified
|
||||
case 'file':
|
||||
$cache = $this->getFileCache($context, $cacheId, $fallback);
|
||||
break;
|
||||
case 'none':
|
||||
$cache = new \PKP\cache\GenericCache(
|
||||
$context,
|
||||
$cacheId,
|
||||
$fallback
|
||||
);
|
||||
break;
|
||||
default:
|
||||
exit("Unknown cache type \"{$type}\"!\n");
|
||||
}
|
||||
return $cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the path in which file caches will be stored.
|
||||
*
|
||||
* @return string The full path to the file cache directory
|
||||
*/
|
||||
public static function getFileCachePath()
|
||||
{
|
||||
return Core::getBaseDir() . '/cache';
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush an entire context, if specified, or
|
||||
* the whole cache.
|
||||
*
|
||||
* @param string $context The context to flush, if only one is to be flushed
|
||||
* @param string $type The type of cache to flush
|
||||
*/
|
||||
public function flush($context = null, $type = CACHE_TYPE_FILE)
|
||||
{
|
||||
$cacheImplementation = $this->getCacheImplementation($type);
|
||||
switch ($cacheImplementation) {
|
||||
case 'xcache':
|
||||
case 'apc':
|
||||
case 'memcache':
|
||||
$junkCache = $this->getCache($context, null, null);
|
||||
$junkCache->flush();
|
||||
break;
|
||||
case 'file':
|
||||
$filePath = $this->getFileCachePath();
|
||||
$files = glob("{$filePath}/fc-" . (isset($context) ? $context . '-' : '') . '*.php');
|
||||
foreach ($files as $file) {
|
||||
@unlink($file);
|
||||
}
|
||||
break;
|
||||
case '':
|
||||
case 'none':
|
||||
// Nothing necessary.
|
||||
break;
|
||||
default:
|
||||
exit("Unknown cache type \"{$type}\"!\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
Vendored
+150
@@ -0,0 +1,150 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @defgroup cache Cache
|
||||
* Implements various forms of caching, i.e. object caches, file caches, etc.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file classes/cache/FileCache.php
|
||||
*
|
||||
* Copyright (c) 2014-2021 Simon Fraser University
|
||||
* Copyright (c) 2000-2021 John Willinsky
|
||||
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
|
||||
*
|
||||
* @class FileCache
|
||||
*
|
||||
* @ingroup cache
|
||||
*
|
||||
* @brief Provides caching based on machine-generated PHP code on the filesystem.
|
||||
*/
|
||||
|
||||
namespace PKP\cache;
|
||||
|
||||
use Exception;
|
||||
use PKP\config\Config;
|
||||
use PKP\file\FileManager;
|
||||
|
||||
class FileCache extends GenericCache
|
||||
{
|
||||
/**
|
||||
* Connection to use for caching.
|
||||
*/
|
||||
public $filename;
|
||||
|
||||
/**
|
||||
* @var ?array The cached data
|
||||
*/
|
||||
public $cache;
|
||||
|
||||
/**
|
||||
* Instantiate a cache.
|
||||
*/
|
||||
public function __construct($context, $cacheId, $fallback, $path)
|
||||
{
|
||||
parent::__construct($context, $cacheId, $fallback);
|
||||
|
||||
$this->filename = "{$path}/fc-{$context}-" . str_replace('/', '.', $cacheId) . '.php';
|
||||
|
||||
// If the file couldn't be opened or if a lock couldn't be acquired, quit
|
||||
if (!($fp = @fopen($this->filename, 'r')) || !flock($fp, LOCK_SH)) {
|
||||
$this->cache = null;
|
||||
return;
|
||||
}
|
||||
|
||||
// Reasoning: When the include below fails, it returns "false" and we have no way to determine if it's an error or a valid cache value
|
||||
set_error_handler(static fn () => throw new Exception('Failed to include file'));
|
||||
try {
|
||||
$this->cache = include $this->filename;
|
||||
} catch (Exception) {
|
||||
$this->cache = null;
|
||||
} finally {
|
||||
restore_error_handler();
|
||||
flock($fp, LOCK_UN);
|
||||
fclose($fp);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush the cache
|
||||
*/
|
||||
public function flush()
|
||||
{
|
||||
unset($this->cache);
|
||||
$this->cache = null;
|
||||
if (function_exists('opcache_invalidate')) {
|
||||
opcache_invalidate($this->filename, true);
|
||||
}
|
||||
@unlink($this->filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an object from the cache.
|
||||
*
|
||||
* @param string $id
|
||||
*/
|
||||
public function getCache($id)
|
||||
{
|
||||
if (!isset($this->cache)) {
|
||||
return $this->cacheMiss;
|
||||
}
|
||||
return ($this->cache[$id] ?? null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an object in the cache. This function should be overridden
|
||||
* by subclasses.
|
||||
*
|
||||
* @param string $id
|
||||
*/
|
||||
public function setCache($id, $value)
|
||||
{
|
||||
// Flush the cache; it will be regenerated on demand.
|
||||
$this->flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the entire contents of the cache.
|
||||
*/
|
||||
public function setEntireCache($contents)
|
||||
{
|
||||
if (@file_put_contents(
|
||||
$this->filename,
|
||||
'<?php return ' . var_export($contents, true) . ';',
|
||||
LOCK_EX
|
||||
) !== false) {
|
||||
$umask = Config::getVar('files', 'umask');
|
||||
if ($umask) {
|
||||
@chmod($this->filename, FileManager::FILE_MODE_MASK & ~$umask);
|
||||
}
|
||||
}
|
||||
$this->cache = $contents;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the time at which the data was cached.
|
||||
* If the file does not exist or an error occurs, null is returned.
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
public function getCacheTime()
|
||||
{
|
||||
$result = @filemtime($this->filename);
|
||||
if ($result === false) {
|
||||
return null;
|
||||
}
|
||||
return ((int) $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the entire contents of the cache in an associative array.
|
||||
*/
|
||||
public function &getContents()
|
||||
{
|
||||
if (!isset($this->cache)) {
|
||||
// Trigger a cache miss to load the cache.
|
||||
$this->get(null);
|
||||
}
|
||||
return $this->cache;
|
||||
}
|
||||
}
|
||||
+154
@@ -0,0 +1,154 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file classes/cache/GenericCache.php
|
||||
*
|
||||
* Copyright (c) 2014-2021 Simon Fraser University
|
||||
* Copyright (c) 2000-2021 John Willinsky
|
||||
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
|
||||
*
|
||||
* @class generic_cache_miss
|
||||
*
|
||||
* @ingroup cache
|
||||
*
|
||||
* @brief Provides implementation-independent caching. Although this class is intended
|
||||
* to be overridden with a more specific implementation, it can be used as the
|
||||
* null cache.
|
||||
*/
|
||||
|
||||
namespace PKP\cache;
|
||||
|
||||
// Pseudotype to represent a cache miss
|
||||
class generic_cache_miss
|
||||
{
|
||||
}
|
||||
|
||||
class GenericCache
|
||||
{
|
||||
/**
|
||||
* The unique string identifying the context of this cache.
|
||||
* Must be suitable for a filename.
|
||||
*/
|
||||
public $context;
|
||||
|
||||
/**
|
||||
* The ID of this particular cache within the context
|
||||
*/
|
||||
public $cacheId;
|
||||
|
||||
public $cacheMiss;
|
||||
|
||||
/**
|
||||
* The getter fallback callback (for a cache miss)
|
||||
* This function is called with two parameters:
|
||||
* 1. The cache object that is suffering a miss
|
||||
* 2. The id of the value to fetch
|
||||
* The function is responsible for loading data into the
|
||||
* cache, using setEntireCache or setCache.
|
||||
*/
|
||||
public $fallback;
|
||||
|
||||
/**
|
||||
* Instantiate a cache.
|
||||
*/
|
||||
public function __construct($context, $cacheId, $fallback)
|
||||
{
|
||||
$this->context = $context;
|
||||
$this->cacheId = $cacheId;
|
||||
$this->fallback = $fallback;
|
||||
$this->cacheMiss = new generic_cache_miss();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an object from cache, using the fallback if necessary.
|
||||
*/
|
||||
public function get($id)
|
||||
{
|
||||
$result = $this->getCache($id);
|
||||
if (is_object($result) && $result instanceof generic_cache_miss) {
|
||||
$result = call_user_func_array($this->fallback, [$this, $id]);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an object in the cache. This function should be overridden
|
||||
* by subclasses.
|
||||
*/
|
||||
public function set($id, $value)
|
||||
{
|
||||
return $this->setCache($id, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush the cache.
|
||||
*/
|
||||
public function flush()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the entire contents of the cache. May (should) be overridden
|
||||
* by subclasses.
|
||||
*/
|
||||
public function setEntireCache($contents)
|
||||
{
|
||||
$this->flush();
|
||||
foreach ($contents as $id => $value) {
|
||||
$this->setCache($id, $value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an object from the cache. This function should be overridden
|
||||
* by subclasses.
|
||||
*
|
||||
* @param string $id
|
||||
*/
|
||||
public function getCache($id)
|
||||
{
|
||||
return $this->cacheMiss;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an object in the cache. This function should be overridden
|
||||
* by subclasses.
|
||||
*
|
||||
* @param string $id
|
||||
*/
|
||||
public function setCache($id, $value)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the cache. (Optionally overridden by subclasses.)
|
||||
*/
|
||||
public function close()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the context.
|
||||
*/
|
||||
public function getContext()
|
||||
{
|
||||
return $this->context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the cache ID within its context
|
||||
*/
|
||||
public function getCacheId()
|
||||
{
|
||||
return $this->cacheId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the time at which the data was cached.
|
||||
*/
|
||||
public function getCacheTime()
|
||||
{
|
||||
// Since it's not really cached, we'll consider it to have been cached just now.
|
||||
return time();
|
||||
}
|
||||
}
|
||||
+166
@@ -0,0 +1,166 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file classes/cache/MemcacheCache.php
|
||||
*
|
||||
* Copyright (c) 2014-2021 Simon Fraser University
|
||||
* Copyright (c) 2000-2021 John Willinsky
|
||||
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
|
||||
*
|
||||
* @class memcache_null
|
||||
*
|
||||
* @ingroup cache
|
||||
*
|
||||
* @see GenericCache
|
||||
*
|
||||
* @brief Provides caching based on Memcache.
|
||||
*/
|
||||
|
||||
namespace PKP\cache;
|
||||
|
||||
use Memcached;
|
||||
|
||||
// WARNING: This cache MUST be loaded in batch, or else many cache
|
||||
// misses will result.
|
||||
|
||||
// Pseudotypes used to represent false and null values in the cache
|
||||
class memcache_false
|
||||
{
|
||||
}
|
||||
class memcache_null
|
||||
{
|
||||
}
|
||||
|
||||
class MemcacheCache extends GenericCache
|
||||
{
|
||||
/**
|
||||
* Connection to use for caching.
|
||||
*/
|
||||
public $connection;
|
||||
|
||||
/**
|
||||
* Flag (used by Memcache::set)
|
||||
*/
|
||||
public $flag;
|
||||
|
||||
/**
|
||||
* Expiry (used by Memcache::set)
|
||||
*/
|
||||
public $expire;
|
||||
|
||||
/**
|
||||
* Instantiate a cache.
|
||||
*/
|
||||
public function __construct($context, $cacheId, $fallback, $hostname, $port)
|
||||
{
|
||||
parent::__construct($context, $cacheId, $fallback);
|
||||
$this->connection = new Memcached();
|
||||
|
||||
// FIXME This should use connection pooling
|
||||
// XXX check whether memcached server is usable
|
||||
if (!$this->connection->addServer($hostname, $port)) {
|
||||
$this->connection = null;
|
||||
}
|
||||
|
||||
$this->flag = null;
|
||||
$this->expire = 3600; // 1 hour default expiry
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the flag (used in Memcache::set)
|
||||
*/
|
||||
public function setFlag($flag)
|
||||
{
|
||||
$this->flag = $flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the expiry time (used in Memcache::set)
|
||||
*/
|
||||
public function setExpiry($expiry)
|
||||
{
|
||||
$this->expire = $expiry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush the cache.
|
||||
*/
|
||||
public function flush()
|
||||
{
|
||||
$this->connection->flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an object from the cache.
|
||||
*
|
||||
* @param string $id
|
||||
*/
|
||||
public function getCache($id)
|
||||
{
|
||||
$result = $this->connection->get($this->getContext() . ':' . $this->getCacheId() . ':' . $id);
|
||||
if ($this->connection->getResultCode() == Memcached::RES_NOTFOUND) {
|
||||
return $this->cacheMiss;
|
||||
}
|
||||
if ($result instanceof memcache_false) {
|
||||
$result = false;
|
||||
}
|
||||
if ($result instanceof memcache_null) {
|
||||
$result = null;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an object in the cache. This function should be overridden
|
||||
* by subclasses.
|
||||
*
|
||||
* @param string $id
|
||||
*/
|
||||
public function setCache($id, $value)
|
||||
{
|
||||
if ($value === false) {
|
||||
$value = new memcache_false();
|
||||
} elseif ($value === null) {
|
||||
$value = new memcache_null();
|
||||
}
|
||||
return ($this->connection->set($this->getContext() . ':' . $this->getCacheId() . ':' . $id, $value, $this->expire));
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the cache and free resources.
|
||||
*/
|
||||
public function close()
|
||||
{
|
||||
$this->connection->quit();
|
||||
unset($this->connection);
|
||||
$this->contextChecked = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the time at which the data was cached.
|
||||
* Note that keys expire in memcache, which means
|
||||
* that it's possible that the date will disappear
|
||||
* before the data -- in this case we'll have to
|
||||
* assume the data is still good.
|
||||
*/
|
||||
public function getCacheTime()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the entire contents of the cache.
|
||||
* WARNING: THIS DOES NOT FLUSH THE CACHE FIRST!
|
||||
* This is because there is no "scope restriction"
|
||||
* for flushing within memcache and therefore
|
||||
* a flush here would flush the entire cache,
|
||||
* resulting in more subsequent calls to this function,
|
||||
* resulting in more flushes, etc.
|
||||
*/
|
||||
public function setEntireCache($contents)
|
||||
{
|
||||
foreach ($contents as $id => $value) {
|
||||
$this->setCache($id, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file classes/cache/XCacheCache.php
|
||||
*
|
||||
* Copyright (c) 2014-2021 Simon Fraser University
|
||||
* Copyright (c) 2000-2021 John Willinsky
|
||||
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
|
||||
*
|
||||
* @class XCacheCache
|
||||
*
|
||||
* @ingroup cache
|
||||
*
|
||||
* @see GenericCache
|
||||
*
|
||||
* @brief Provides caching based on XCache's variable store.
|
||||
*/
|
||||
|
||||
namespace PKP\cache;
|
||||
|
||||
class XCacheCache extends GenericCache
|
||||
{
|
||||
/**
|
||||
* Flush the cache.
|
||||
*/
|
||||
public function flush()
|
||||
{
|
||||
$prefix = INDEX_FILE_LOCATION . ':' . $this->getContext() . ':' . $this->getCacheId();
|
||||
if (function_exists('xcache_unset_by_prefix')) {
|
||||
// If possible, just flush the context
|
||||
xcache_unset_by_prefix(prefix);
|
||||
} else {
|
||||
// Otherwise, we need to do this manually
|
||||
for ($i = 0; $i < xcache_count(XC_TYPE_VAR); $i++) {
|
||||
$cache = xcache_list(XC_TYPE_VAR, $i);
|
||||
foreach ($cache['cache_list'] as $entry) {
|
||||
if (substr($entry['name'], 0, strlen($prefix)) == $prefix) {
|
||||
xcache_unset($entry['name']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an object from the cache.
|
||||
*
|
||||
* @param string $id
|
||||
*/
|
||||
public function getCache($id)
|
||||
{
|
||||
$key = INDEX_FILE_LOCATION . ':' . $this->getContext() . ':' . $this->getCacheId() . ':' . $id;
|
||||
if (!xcache_isset($key)) {
|
||||
return $this->cacheMiss;
|
||||
}
|
||||
$returner = unserialize(xcache_get($key));
|
||||
return $returner;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an object in the cache. This function should be overridden
|
||||
* by subclasses.
|
||||
*
|
||||
* @param string $id
|
||||
*/
|
||||
public function setCache($id, $value)
|
||||
{
|
||||
return (xcache_set(INDEX_FILE_LOCATION . ':' . $this->getContext() . ':' . $this->getCacheId() . ':' . $id, serialize($value)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the time at which the data was cached.
|
||||
* Not implemented in this type of cache.
|
||||
*/
|
||||
public function getCacheTime()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the entire contents of the cache.
|
||||
* WARNING: THIS DOES NOT FLUSH THE CACHE FIRST!
|
||||
*/
|
||||
public function setEntireCache($contents)
|
||||
{
|
||||
foreach ($contents as $id => $value) {
|
||||
$this->setCache($id, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user