refactoring cache engines, adding tests, update configure fixes #3082

git-svn-id: https://svn.cakephp.org/repo/branches/1.2.x.x@5700 3807eeeb-6ff5-0310-8944-8be069107fe0
This commit is contained in:
gwoo 2007-09-30 07:45:34 +00:00
parent 908f4c8a39
commit 4f8f7a7045
17 changed files with 720 additions and 497 deletions

View file

@ -3,7 +3,7 @@
/**
* This is core configuration file.
*
* Use it to configure core behaviour ofCake.
* Use it to configure core behavior of Cake.
*
* PHP versions 4 and 5
*
@ -35,11 +35,9 @@
* /app/.htaccess
* /app/webroot/.htaccess
*
* And uncomment the define below:
* And uncomment the baseUrl below:
*/
// define ('BASE_URL', env('SCRIPT_NAME'));
//Configure::write('baseUrl', env('SCRIPT_NAME'));
/**
* CakePHP Debug Level:
*
@ -63,7 +61,7 @@
* controller-wide by setting var $cacheAction = true, or in each action
* using $this->cacheAction = true.
*/
define('CACHE_CHECK', false);
Configure::write('Cache.check', true);
/**
* Defines the default error type when using the log() function. Used for
* differentiating error logging and debugging. Currently PHP supports LOG_DEBUG.
@ -156,50 +154,52 @@
define('ACL_CLASSNAME', 'DB_ACL');
define('ACL_DATABASE', 'default');
/**
* How long to cache data if not defined
* 3600 = 1 hour
*/
define('CACHE_DEFAULT_DURATION', 3600);
/**
* How often to do garbage collection
* about once in every hundred page loads
*/
define('CACHE_GC_PROBABILITY', 100);
/**
* Use the file storage engine with default parameters.
* Cached data is kept in app/tmp/cache/
* Cache Engine Configuration
*
* File storage
* $cakeCache = array('File', [optional]array(
* 'dir' => '/tmp/', // use system tmp directory - remember to use absolute path
* 'prefix' => 'cakecache_', // prefix every cache file with this string
* 'lock' => true, // use file locking
* File storage engine.
* default dir is /app/tmp/cache/
* $cakeCache = array('File', array(
* [optional] 'duration'=> 3600,
* [optional] 'probability'=> 100,
* [optional] 'dir' => '/tmp', // use system tmp directory - remember to use absolute path
* [optional] 'prefix' => 'cake_', // prefix every cache file with this string
* [optional] 'lock' => false, // use file locking
* [optional] 'serialize' => true,
* ));
* $cakeCache = array('File');
*
* APC (Alternative PHP Cache)
* $cakeCache = array('APC');
* $cakeCache = array('Apc', array(
* [optional] 'duration'=> 3600,
* [optional] 'probability'=> 100
* ));
*
* Xcache (PHP opcode cacher)
* $cakeCache = array('Xcache', array(
* [optional] 'duration'=> 3600,
* [optional] 'probability'=> 100,
* 'user' => 'admin', // user from xcache.admin.user settings
* 'password' => 'your_password', // plaintext password (xcache.admin.pass)
* ));
* ));
*
* Memcache
* $cakeCache = array('Memcache', [optional]array(
* 'servers' => array(
* '127.0.0.1', // localhost, default port
* '10.0.0.1:12345', // port 12345
* ),
* 'compress' => true, // compress data in Memcache (slower, but uses less memory)
* $cakeCache = array('Memcache', array(
* [optional] 'duration'=> 3600,
* [optional] 'probability'=> 100,
* [optional] 'servers' => array(
* '127.0.0.1', // localhost, default port
* '10.0.0.1:12345', // port 12345
* ),
* [optional] 'compress' => true, // compress data in Memcache (slower, but uses less memory)
* ));
*
* Cake Model
* $cakeCache = array('Model', [optional]array(
* 'modelName' => 'DbModel',
* 'dataField' => 'value',
* 'expiryField' => 'expires'));
* $cakeCache = array('Model', array(
* [optional] 'duration'=> 3600,
* [optional] 'probability'=> 100,
* [optional] 'name' => 'Cache',
* [optional] 'fields' => array('data' => 'data', 'expires => 'expires'),
* [optional] 'serialize' => true,
* ));
*/
$cakeCache = array('File');
?>

View file

@ -1122,7 +1122,7 @@
*/
function cache($path, $data = null, $expires = '+1 day', $target = 'cache') {
if (defined('DISABLE_CACHE')) {
if (Configure::read('Cache.disable')) {
return null;
}
$now = time();

View file

@ -1,4 +1,4 @@
<?php
<?php
/* SVN FILE: $Id$ */
/**
* Basic Cake functionality.
@ -29,6 +29,9 @@
if (!defined('PHP5')) {
define ('PHP5', (phpversion() >= 5));
}
if (!defined('SERVER_IIS') && php_sapi_name() == 'isapi') {
define('SERVER_IIS', true);
}
/**
* Configuration, directory layout and standard libraries
*/
@ -40,7 +43,7 @@ if (!defined('PHP5')) {
require LIBS . 'inflector.php';
require LIBS . 'configure.php';
}
require APP_PATH . 'config' . DS . 'core.php';
require LIBS . 'cache.php';
require LIBS . 'session.php';
require LIBS . 'security.php';
@ -48,11 +51,10 @@ if (!defined('PHP5')) {
if (isset($cakeCache)) {
$cache = 'File';
$settings = array();
if (isset($cakeCache[0])) {
$cache = $cakeCache[0];
}
$settings = array();
if (isset($cakeCache[1])) {
$settings = $cakeCache[1];
}
@ -64,16 +66,6 @@ if (!defined('PHP5')) {
Configure::store(null, 'class.paths');
Configure::load('class.paths');
if (defined('DEBUG')) {
Configure::write('debug', DEBUG);
}
/**
* Check for IIS Server
*/
if (!defined('SERVER_IIS') && php_sapi_name() == 'isapi') {
define('SERVER_IIS', true);
}
$url = null;
require CAKE . 'dispatcher.php';
?>

View file

@ -31,15 +31,6 @@
if (!class_exists('object')) {
uses('object');
}
/**
* Set defines if not set in core.php
*/
if (!defined('CACHE_DEFAULT_DURATION')) {
define('CACHE_DEFAULT_DURATION', 3600);
}
if (!defined('CACHE_GC_PROBABILITY')) {
define('CACHE_GC_PROBABILITY', 100);
}
/**
* Caching for CakePHP.
*
@ -73,58 +64,57 @@ class Cache extends Object {
return $instance[0];
}
/**
* Tries to find and include a file for a cache engine
* Tries to find and include a file for a cache engine and returns object instance
*
* @param $name Name of the engine (without 'Engine')
* @return boolean
* @access protected
* @return mixed $engine object or null
* @access private
*/
function _includeEngine($name) {
if (class_exists($name.'Engine')) {
return true;
function __loadEngine($name) {
if (!class_exists($name . 'Engine')) {
$fileName = LIBS . DS . 'cache' . DS . strtolower($name) . '.php';
if (!require($fileName)) {
return false;
}
}
$fileName = strtolower($name);
if (vendor('cache_engines' . DS . $fileName)) {
return true;
}
$fileName = dirname(__FILE__) . DS . 'cache' . DS . $fileName . '.php';
if (is_readable($fileName)) {
require $fileName;
return true;
}
return false;
return true;
}
/**
* Set the cache engine to use
*
* @param string $name Name of the engine (without 'Engine')
* @param array $parmas Optional associative array of parameters passed to the engine
* @param array $settings Optional associative array of settings passed to the engine
* @return boolean True on success, false on failure
* @access public
*/
function engine($name = 'File', $params = array()) {
if (defined('DISABLE_CACHE')) {
function engine($name = 'File', $settings = array()) {
if (Configure::read('Cache.disable')) {
return false;
}
$cacheClass = $name . 'Engine';
$_this =& Cache::getInstance();
$cacheClass = $name.'Engine';
if (!Cache::_includeEngine($name) || !class_exists($cacheClass)) {
return false;
if (!isset($_this->_Engine)) {
if ($_this->__loadEngine($name) === false) {
return false;
}
}
$_this->_Engine =& new $cacheClass();
if (!isset($_this->_Engine) || (isset($_this->_Engine) && $_this->_Engine->name !== $name)) {
$_this->_Engine =& new $cacheClass($name);
}
if ($_this->_Engine->init($params)) {
if (time() % CACHE_GC_PROBABILITY == 0) {
if ($_this->_Engine->init($settings)) {
if (time() % $_this->_Engine->settings['probability'] == 0) {
$_this->_Engine->gc();
}
return true;
}
$_this->_Engine = null;
return false;
}
/**
* Write a value in the cache
* Write data for key into cache
*
* @param string $key Identifier for the data
* @param mixed $value Data to be cached - anything except a resource
@ -132,10 +122,12 @@ class Cache extends Object {
* @return boolean True if the data was succesfully cached, false on failure
* @access public
*/
function write($key, $value, $duration = CACHE_DEFAULT_DURATION) {
if (defined('DISABLE_CACHE')) {
function write($key, $value, $duration = null) {
$_this =& Cache::getInstance();
if (!$_this->isInitialized()) {
return false;
}
$key = strval($key);
if (empty($key)) {
return false;
@ -143,77 +135,64 @@ class Cache extends Object {
if (is_resource($value)) {
return false;
}
if ($duration == null) {
$duration = $_this->_Engine->settings['duration'];
}
$duration = ife(is_string($duration), strtotime($duration) - time(), intval($duration));
if ($duration < 1) {
return false;
}
$_this =& Cache::getInstance();
if (!isset($_this->_Engine)) {
return false;
}
return $_this->_Engine->write($key, $value, $duration);
}
/**
* Read a value from the cache
* Read a key from the cache
*
* @param string $key Identifier for the data
* @return mixed The cached data, or false if the data doesn't exist, has expired, or if there was an error fetching it
* @access public
*/
function read($key) {
if (defined('DISABLE_CACHE')) {
$_this =& Cache::getInstance();
if (!$_this->isInitialized()) {
return false;
}
$key = strval($key);
if (empty($key)) {
return false;
}
$_this =& Cache::getInstance();
if (!isset($_this->_Engine)) {
return false;
}
return $_this->_Engine->read($key);
}
/**
* Delete a value from the cache
* Delete a key from the cache
*
* @param string $key Identifier for the data
* @return boolean True if the value was succesfully deleted, false if it didn't exist or couldn't be removed
* @access public
*/
function delete($key) {
if (defined('DISABLE_CACHE')) {
$_this =& Cache::getInstance();
if (!$_this->isInitialized()) {
return false;
}
$key = strval($key);
if (empty($key)) {
return false;
}
$_this =& Cache::getInstance();
if (!isset($_this->_Engine)) {
return false;
}
return $_this->_Engine->delete($key);
}
/**
* Delete all values from the cache
* Delete all keys from the cache
*
* @param boolean $check if true will check expiration, otherwise delete all
* @return boolean True if the cache was succesfully cleared, false otherwise
* @access public
*/
function clear() {
if (defined('DISABLE_CACHE')) {
return false;
}
function clear($check = false) {
$_this =& Cache::getInstance();
if (!isset($_this->_Engine)) {
if (!$_this->isInitialized()) {
return false;
}
return $_this->_Engine->clear();
return $_this->_Engine->clear($check);
}
/**
* Check if Cache has initialized a working storage engine
@ -222,7 +201,7 @@ class Cache extends Object {
* @access public
*/
function isInitialized() {
if (defined('DISABLE_CACHE')) {
if (Configure::read('Cache.disable')) {
return false;
}
$_this =& Cache::getInstance();
@ -249,6 +228,29 @@ class Cache extends Object {
* @subpackage cake.cake.libs
*/
class CacheEngine extends Object {
/**
* Name of engine being used
*
* @var int
* @access public
*/
var $name;
/**
* settings of current engine instance
*
* @var int
* @access public
*/
var $settings;
/**
* Constructor
*
* @access private
*/
function __construct($name = null) {
$this->name = $name;
}
/**
* Set up the cache engine
*
@ -258,7 +260,8 @@ class CacheEngine extends Object {
* @return boolean True if the engine has been succesfully initialized, false if not
* @access public
*/
function init($params) {
function init($settings = array()) {
$this->settings = am(array('duration'=> 3600, 'probability'=> 100), $settings);
}
/**
* Garbage collection
@ -270,7 +273,7 @@ class CacheEngine extends Object {
function gc() {
}
/**
* Write a value in the cache
* Write value for a key into cache
*
* @param string $key Identifier for the data
* @param mixed $value Data to be cached
@ -278,11 +281,11 @@ class CacheEngine extends Object {
* @return boolean True if the data was succesfully cached, false on failure
* @access public
*/
function write($key, &$value, $duration = CACHE_DEFAULT_DURATION) {
function write($key, &$value, $duration) {
trigger_error(sprintf(__('Method write() not implemented in %s', true), get_class($this)), E_USER_ERROR);
}
/**
* Read a value from the cache
* Read a key from the cache
*
* @param string $key Identifier for the data
* @return mixed The cached data, or false if the data doesn't exist, has expired, or if there was an error fetching it
@ -292,7 +295,7 @@ class CacheEngine extends Object {
trigger_error(sprintf(__('Method read() not implemented in %s', true), get_class($this)), E_USER_ERROR);
}
/**
* Delete a value from the cache
* Delete a key from the cache
*
* @param string $key Identifier for the data
* @return boolean True if the value was succesfully deleted, false if it didn't exist or couldn't be removed
@ -301,21 +304,22 @@ class CacheEngine extends Object {
function delete($key) {
}
/**
* Delete all values from the cache
* Delete all keys from the cache
*
* @param boolean $check if true will check expiration, otherwise delete all
* @return boolean True if the cache was succesfully cleared, false otherwise
* @access public
*/
function clear() {
function clear($check) {
}
/**
* Delete all values from the cache
* Cache Engine settings
*
* @return boolean True if the cache was succesfully cleared, false otherwise
* @return array settings
* @access public
*/
function settings() {
trigger_error(sprintf(__('Method settings() not implemented in %s', true), get_class($this)), E_USER_ERROR);
return am($this->settings, array('name'=> $this->name));
}
}
?>

View file

@ -33,19 +33,22 @@
*/
class APCEngine extends CacheEngine {
/**
* Set up the cache engine
* Initialize the Cache Engine
*
* Called automatically by the cache frontend
* To reinitialize the settings call Cache::engine('EngineName', [optional] settings = array());
*
* @param array $params Associative array of parameters for the engine
* @return boolean True if the engine has been succesfully initialized, false if not
* @see var $__defaults
* @param array $setting array of setting for the engine
* @return boolean True if the engine has been successfully initialized, false if not
* @access public
*/
function init(&$params) {
function init($settings = array()) {
parent::init($settings);
return function_exists('apc_cache_info');
}
/**
* Write a value in the cache
* Write data for key into cache
*
* @param string $key Identifier for the data
* @param mixed $value Data to be cached
@ -53,11 +56,11 @@ class APCEngine extends CacheEngine {
* @return boolean True if the data was succesfully cached, false on failure
* @access public
*/
function write($key, &$value, $duration = CACHE_DEFAULT_DURATION) {
function write($key, &$value, $duration) {
return apc_store($key, $value, $duration);
}
/**
* Read a value from the cache
* Read a key from the cache
*
* @param string $key Identifier for the data
* @return mixed The cached data, or false if the data doesn't exist, has expired, or if there was an error fetching it
@ -67,7 +70,7 @@ class APCEngine extends CacheEngine {
return apc_fetch($key);
}
/**
* Delete a value from the cache
* Delete a key from the cache
*
* @param string $key Identifier for the data
* @return boolean True if the value was succesfully deleted, false if it didn't exist or couldn't be removed
@ -77,7 +80,7 @@ class APCEngine extends CacheEngine {
return apc_delete($key);
}
/**
* Delete all values from the cache
* Delete all keys from the cache
*
* @return boolean True if the cache was succesfully cleared, false otherwise
* @access public
@ -85,14 +88,5 @@ class APCEngine extends CacheEngine {
function clear() {
return apc_clear_cache('user');
}
/**
* Return the settings for this cache engine
*
* @return array list of settings for this engine
* @access public
*/
function settings() {
return array('class' => get_class($this));
}
}
?>

View file

@ -43,63 +43,52 @@ if (!class_exists('file')) {
* @subpackage cake.cake.libs.cache
*/
class FileEngine extends CacheEngine {
/**
* Does the cache engine handle prefixes on it's own?
*
* @var boolean
* @access private
*/
var $_usesPrefixes = true;
/**
* Cache directory
* instance of Folder class
*
* @var string
* @access private
*/
var $_dir = '';
var $__Folder = null;
/**
* Cache filename prefix
* instance of File class
*
* @var string
* @access private
*/
var $_prefix = '';
var $__File = null;
/**
* Use locking
* settings
* path = absolute path to cache directory, default => CACHE
* prefix = string prefix for filename, default => cake_
* lock = enable file locking on write, default => false
* serialize = serialize the data, default => true
*
* @var boolean
* @access private
*/
var $_lock = false;
/**
* Set up the cache engine
*
* Called automatically by the cache frontend
*
* @param array $params Associative array of parameters for the engine
* @return boolean True if the engine has been succesfully initialized, false if not
* @see var __defaults
* @var array
* @access public
*/
function init($params) {
$dir = CACHE;
$prefix = 'cake_';
$lock = false;
extract($params);
$dir = trim($dir);
$this->Folder =& new Folder();
if (!empty($dir)) {
$dir = $this->Folder->slashTerm($dir);
}
if (empty($dir) || !$this->Folder->isAbsolute($dir) || !is_writable($dir)) {
var $settings = array();
/**
* Initialize the Cache Engine
*
* Called automatically by the cache frontend
* To reinitialize the settings call Cache::engine('EngineName', [optional] settings = array());
*
* @param array $setting array of setting for the engine
* @return boolean True if the engine has been successfully initialized, false if not
* @access public
*/
function init($settings = array()) {
parent::init($settings);
$defaults = array('path' => CACHE, 'prefix'=> 'cake_', 'lock'=> false, 'serialize'=> true);
$this->settings = am($this->settings, $defaults, $settings);
$this->__Folder =& new Folder($this->settings['path']);
$this->settings['path'] = $this->__Folder->pwd();
if (!is_writable($this->settings['path'])) {
return false;
}
$this->_dir = $dir;
$this->_prefix = strval($prefix);
$this->_lock = $lock;
return true;
}
/**
@ -113,92 +102,57 @@ class FileEngine extends CacheEngine {
return $this->clear(true);
}
/**
* Write a value in the cache
* Write data for key into cache
*
* @param string $key Identifier for the data
* @param mixed $value Data to be cached
* @param mixed $data Data to be cached
* @param mixed $duration How long to cache the data, in seconds
* @return boolean True if the data was succesfully cached, false on failure
* @access public
*/
function write($key, &$data, $duration = CACHE_DEFAULT_DURATION) {
if(!$data) {
return false;
}
$data = serialize($data);
function write($key, &$data, $duration) {
if (!$data) {
return false;
}
if ($duration == null) {
$duration = $this->settings['duration'];
}
if (isset($this->settings['serialize'])) {
$data = serialize($data);
}
if (!$data) {
return false;
}
$file = $this->fullpath($key);
if ($file === false) {
return false;
}
$expires = time() + $duration;
$fileName = $this->_getFilename($key);
if ($fileName === false) {
return false;
}
return $this->_writeCache($fileName, $data, $expires);
return $this->__write($file, $data, $expires);
}
/**
* Get absolute filename for a key
*
* @param string $key The key
* @return mixed Absolute cache filename for the given key or false if erroneous
* @access private
*/
function _getFilename($key) {
$file =& new File($this->_dir);
$path = array_map(array($file , 'safe'), explode(DS, $key));
$key = array_pop($path);
$fullpath = $this->Folder->realpath($this->_dir . implode(DS, $path) . DS . $this->_prefix . $key);
if (!$this->Folder->inPath($fullpath, true)) {
return false;
}
return $fullpath;
}
/**
* write serialized data to a file
*
* @param string $filename
* @param string $value
* @param integer $expires
* @return boolean True on success, false on failure
* @access private
*/
function _writeCache(&$filename, &$data, &$expires) {
$directoryName = dirname($filename);
if (!is_writable($directoryName)) {
if (!$this->Folder->create($directoryName)) {
return false;
}
}
$contents = $expires."\n".$data."\n";
return ife(file_put_contents($filename, $contents, ife($this->_lock, LOCK_EX, 0)), true, false);
}
/**
* Read a value from the cache
* Read a key from the cache
*
* @param string $key Identifier for the data
* @return mixed The cached data, or false if the data doesn't exist, has expired, or if there was an error fetching it
* @access public
*/
function read($key) {
$filename = $this->_getFilename($key);
if ($filename === false || !is_file($filename) || !is_readable($filename)) {
$file = $this->fullpath($key);
if ($file === false || !is_file($file) || !is_readable($file)) {
return false;
}
$fp = fopen($filename, 'r');
$fp = fopen($file, 'r');
if (!$fp) {
return false;
}
if ($this->_lock && !flock($fp, LOCK_SH)) {
if ($this->settings['lock'] && !flock($fp, LOCK_SH)) {
return false;
}
$cachetime = fgets($fp, 11);
if (intval($cachetime) < time()) {
fclose($fp);
unlink($filename);
unlink($file);
return false;
}
$data = '';
@ -206,96 +160,119 @@ class FileEngine extends CacheEngine {
$data .= fgets($fp, 4096);
}
$data = trim($data);
return unserialize($data);
if (isset($this->settings['serialize'])) {
return unserialize($data);
}
return $data;
}
/**
* Get the expiry time for a cache file
* Delete a key from the cache
*
* @param string $filename
* @param string $key Identifier for the data
* @return boolean True if the value was successfully deleted, false if it didn't exist or couldn't be removed
* @access public
*/
function delete($key) {
$file = $this->fullpath($key);
if ($file === false) {
return false;
}
return unlink($file);
}
/**
* Delete all values from the cache
*
* @param boolean $check Optional - only delete expired cache items
* @return boolean True if the cache was succesfully cleared, false otherwise
* @access public
*/
function clear($check) {
$dir = dir($this->settings['path']);
if ($check) {
$now = time();
$threshold = $now - 86400;
}
while (($entry = $dir->read()) !== false) {
if (strpos($entry, $this->settings['prefix']) !== 0) {
continue;
}
$file = $this->settings['path'] . $entry;
if ($check) {
$mtime = filemtime($file);
if ($mtime === false || $mtime > $threshold) {
continue;
}
$expires = $this->__expires($file);
if ($expires > $now) {
continue;
}
}
unlink($file);
}
$dir->close();
return true;
}
/**
* Get absolute file for a given key
*
* @param string $key The key
* @return mixed Absolute cache file for the given key or false if erroneous
* @access private
*/
function fullpath($key) {
if (!isset($this->__File)) {
$this->__File =& new File($this->settings['path']);
}
$parts = array_map(array($this->__File , 'safe'), explode(DS, $key));
$key = array_pop($parts);
$dir = implode(DS, $parts) . DS;
$path = str_replace(DS . DS, DS, $this->settings['path'] . $dir);
$fullpath = $this->__Folder->realpath($path . $this->settings['prefix'] . $key);
if (!$this->__Folder->inPath($fullpath, true)) {
return false;
}
return $fullpath;
}
/**
* write data to a file
*
* @param string $file
* @param string $value
* @param integer $expires
* @return boolean True on success, false on failure
* @access private
*/
function __write(&$file, &$data, &$expires) {
$dir = dirname($file);
if (!is_writable($dir)) {
if (!$this->__Folder->create($dir)) {
return false;
}
}
$contents = $expires."\n".$data."\n";
return ife(file_put_contents($file, $contents, ife($this->settings['lock'], LOCK_EX, 0)), true, false);
}
/**
* Get the time to live for cache
*
* @param string $file
* @return mixed Expiration timestamp, or false on failure
* @access private
*/
function _getExpiry($filename) {
$fp = fopen($filename, 'r');
function __expires($file) {
$fp = fopen($file, 'r');
if (!$fp) {
return false;
}
if ($this->_lock && !flock($fp, LOCK_SH)) {
if ($this->settings['lock'] && !flock($fp, LOCK_SH)) {
return false;
}
$expires = intval(fgets($fp, 11));
fclose($fp);
return $expires;
}
/**
* Delete a value from the cache
*
* @param string $key Identifier for the data
* @return boolean True if the value was succesfully deleted, false if it didn't exist or couldn't be removed
* @access public
*/
function delete($key) {
$filename = $this->_getFilename($key);
if ($filename === false) {
return false;
}
return unlink($filename);
}
/**
* Delete all values from the cache
*
* @param boolean $checkExpiry Optional - only delete expired cache items
* @return boolean True if the cache was succesfully cleared, false otherwise
* @access public
*/
function clear($checkExpiry = false) {
$dir = dir($this->_dir);
if ($checkExpiry) {
$now = time();
$threshold = $now - 86400;
}
while (($entry = $dir->read()) !== false) {
if (strpos($entry, $this->_prefix) !== 0) {
continue;
}
$filename = $this->_dir . $entry;
if ($checkExpiry) {
$mtime = filemtime($filename);
if ($mtime === false || $mtime > $threshold) {
continue;
}
$expires = $this->_getExpiry($filename);
if ($expires > $now) {
continue;
}
}
unlink($filename);
}
$dir->close();
return true;
}
/**
* Return the settings for this cache engine
*
* @return array list of settings for this engine
* @access public
*/
function settings() {
$lock = 'false';
if ($this->_lock) {
$lock = 'true';
}
return array('class' => get_class($this),
'directory' => $this->_dir,
'prefix' => $this->_prefix,
'lock' => $lock);
}
}
?>

View file

@ -40,54 +40,57 @@ class MemcacheEngine extends CacheEngine {
*/
var $__Memcache = null;
/**
* Memcache compress status.
* settings
* servers = string or array of memcache servers, default => 127.0.0.1
* compress = boolean, default => false
*
* @var int
* @access private
*/
var $_compress = 0;
/**
* Set up the cache engine
*
* Called automatically by the cache frontend
*
* @param array $params Associative array of parameters for the engine
* @return boolean True if the engine has been succesfully initialized, false if not
* @var array
* @access public
*/
function init(&$params) {
var $settings = array();
/**
* Initialize the Cache Engine
*
* Called automatically by the cache frontend
* To reinitialize the settings call Cache::engine('EngineName', [optional] settings = array());
*
* @param array $setting array of setting for the engine
* @return boolean True if the engine has been successfully initialized, false if not
* @access public
*/
function init($settings = array()) {
if (!class_exists('Memcache')) {
return false;
}
$servers = array('127.0.0.1');
$compress = false;
extract($params);
if ($compress) {
$this->_compress = MEMCACHE_COMPRESSED;
} else {
$this->_compress = 0;
parent::init($settings);
$defaults = array('servers' => array('127.0.0.1'), 'compress'=> false);
$this->settings = am($this->settings, $defaults, $settings);
if ($this->settings['compress']) {
$this->settings['compress'] = MEMCACHE_COMPRESSED;
}
if (!is_array($this->settings['servers'])) {
$this->settings['servers'] = array($this->settings['servers']);
}
if (!is_array($servers)) {
$servers = array($servers);
}
$this->__Memcache =& new Memcache();
$connected = false;
foreach ($servers as $server) {
foreach ($this->settings['servers'] as $server) {
$parts = explode(':', $server);
$host = $parts[0];
$port = isset($parts[1]) ? $parts[1] : 11211;
$port = 11211;
if (isset($parts[1])) {
$port = $parts[1];
}
if ($this->__Memcache->addServer($host, $port)) {
$connected = true;
return true;
}
}
return $connected;
return false;
}
/**
* Write a value in the cache
* Write data for key into cache
*
* @param string $key Identifier for the data
* @param mixed $value Data to be cached
@ -95,11 +98,11 @@ class MemcacheEngine extends CacheEngine {
* @return boolean True if the data was succesfully cached, false on failure
* @access public
*/
function write($key, &$value, $duration = CACHE_DEFAULT_DURATION) {
return $this->__Memcache->set($key, $value, $this->_compress, $duration);
function write($key, &$value, $duration) {
return $this->__Memcache->set($key, $value, $this->settings['compress'], $duration);
}
/**
* Read a value from the cache
* Read a key from the cache
*
* @param string $key Identifier for the data
* @return mixed The cached data, or false if the data doesn't exist, has expired, or if there was an error fetching it
@ -109,7 +112,7 @@ class MemcacheEngine extends CacheEngine {
return $this->__Memcache->get($key);
}
/**
* Delete a value from the cache
* Delete a key from the cache
*
* @param string $key Identifier for the data
* @return boolean True if the value was succesfully deleted, false if it didn't exist or couldn't be removed
@ -119,7 +122,7 @@ class MemcacheEngine extends CacheEngine {
return $this->__Memcache->delete($key);
}
/**
* Delete all values from the cache
* Delete all keys from the cache
*
* @return boolean True if the cache was succesfully cleared, false otherwise
* @access public
@ -128,14 +131,21 @@ class MemcacheEngine extends CacheEngine {
return $this->__Memcache->flush();
}
/**
* Return the settings for this cache engine
* connects to a server in connection pool
*
* @return array list of settings for this engine
* @param string $host host ip address or name
* @param integer $port
* @return boolean True if memcache server was connected
* @access public
*/
function settings() {
return array('class' => get_class($this),
'compress' => $this->_compress);
function connect($host, $port = 11211) {
if ($this->__Memcache->getServerStatus($host, $port) === 0) {
if ($this->__Memcache->connect($host, $port)) {
return true;
}
return false;
}
return true;
}
}
?>

View file

@ -28,7 +28,6 @@
/**
* Database Storage engine for cache
*
* @todo Not Implemented
* @package cake
* @subpackage cake.cake.libs.cache
*/
@ -39,43 +38,35 @@ class ModelEngine extends CacheEngine {
* @var object
* @access private
*/
var $_Model = null;
var $__Model = null;
/**
* Fields that holds data.
* settings
* className = name of the model to use, default => Cache
* fields = database fields that hold data and ttl, default => data, expires
*
* @var string
* @access private
* @var array
* @access public
*/
var $_dataField = '';
var $settings = array();
/**
* Field that holds expiration information.
*
* @var string
* @access private
*/
var $_expiryField = '';
/**
* Set up the cache engine
* Initialize the Cache Engine
*
* Called automatically by the cache frontend
* To reinitialize the settings call Cache::engine('EngineName', [optional] settings = array());
*
* @todo does not work will return false
* @param array $params Associative array of parameters for the engine
* @param array $setting array of setting for the engine
* @return boolean True if the engine has been successfully initialized, false if not
* @return boolean True if the engine has been succesfully initialized, false if not
*/
function init($params) {
return false;
$modelName = 'DbCache';
$dataField = 'value';
$expiryField = 'expires';
extract($params);
if (!class_exists($modelName) && !loadModel($modelName)) {
return false;
function init($settings) {
parent::init($settings);
$defaults = array('className'=> 'Cache', 'fields'=> array('data', 'expires'));
$this->settings = am($this->settings, $defaults, $settings);
if (!class_exists($this->settings['className']) && !loadModel($this->settings['className'])) {
$this->__Model = new $modelName();
} else {
$this->__Model = new Model(array('name' => $this->settings['className']));
}
$this->_Model = new $modelName;
}
/**
* Garbage collection
@ -85,78 +76,72 @@ class ModelEngine extends CacheEngine {
* @access public
*/
function gc() {
return $this->_Model->deleteAll(array($this->_expiryField => '<= '.time()));
return $this->__Model->deleteAll(array($this->__fields[1] => '<= '.time()));
}
/**
* Write a value in the cache
* Write data for key into cache
*
* @param string $key Identifier for the data
* @param mixed $value Data to be cached
* @param mixed $data Data to be cached
* @param mixed $duration How long to cache the data, in seconds
* @return boolean True if the data was succesfully cached, false on failure
* @access public
*/
function write($key, &$value, $duration = CACHE_DEFAULT_DURATION) {
$serialized = serialize($value);
function write($key, &$data, $duration) {
if (isset($this->settings['serialize'])) {
$data = serialize($data);
}
if (!$serialized) {
if (!$data) {
return false;
}
$data = array($this->_Model->name => array(
$this->_dataField => $serialized,
$this->_expiryField => time() + $duration));
$oldId = $this->_Model->id;
$this->_Model->id = $key;
$res = $this->_Model->save($data);
$this->_Model->id = $oldId;
$cache = array($this->__Model->name => array(
$this->__fields[0] => $data,
$this->__fields[1] => time() + $duration));
$oldId = $this->__Model->id;
$this->__Model->id = $key;
$res = $this->__Model->save($cache);
$this->__Model->id = $oldId;
return $res;
}
/**
* Read a value from the cache
* Read a key from the cache
*
* @param string $key Identifier for the data
* @return mixed The cached data, or false if the data doesn't exist, has expired, or if there was an error fetching it
* @access public
*/
function read($key) {
$val = $this->_Model->field($this->_expiryField, array($this->_Model->primaryKey => $key, $this->_expiryField => '> '.time()));
return ife($val, unserialize($val), false);
$data = $this->__Model->field($this->__fields[0], array($this->__Model->primaryKey => $key, $this->__fields[1] => '> '.time()));
if (!$data) {
return false;
}
if (isset($this->settings['serialize'])) {
return unserialize($val);
}
return $data;
}
/**
* Delete a value from the cache
* Delete a key from the cache
*
* @param string $key Identifier for the data
* @return boolean True if the value was succesfully deleted, false if it didn't exist or couldn't be removed
* @access public
*/
function delete($key) {
return $this->_Model->del($key);
return $this->__Model->del($key);
}
/**
* Delete all values from the cache
* Delete all keys from the cache
*
* @return boolean True if the cache was succesfully cleared, false otherwise
* @access public
*/
function clear() {
return $this->_Model->deleteAll(null);
}
/**
* Return the settings for this cache engine
*
* @return array list of settings for this engine
* @access public
*/
function settings() {
$class = null;
if (is_a($this->_Model, 'Model')) {
$class = get_class($this->_Model);
}
return array('class' => get_class($this),
'modelName' => $class,
'dataField' => $this->_dataField,
'expiryField' => $this->_expiryField);
return $this->__Model->deleteAll(null);
}
}
?>

View file

@ -34,35 +34,32 @@
*/
class XcacheEngine extends CacheEngine {
/**
* Admin username (xcache.admin.user)
* settings
* PHP_AUTH_USER = xcache.admin.user, default cake
* PHP_AUTH_PW = xcache.admin.password, default cake
*
* @var string
* @access private
*/
var $_php_auth_user = '';
/**
* Plaintext password for basic auth (xcache.admin.pass)
*
* @var string
* @access private
*/
var $_php_auth_pw = '';
/**
* Set up the cache engine
*
* Called automatically by the cache frontend
*
* @param array $params Associative array of parameters for the engine
* @return boolean True if the engine has been succesfully initialized, false if not
* @var array
* @access public
*/
function init($params) {
$this->_php_auth_user = $params['user'];
$this->_php_auth_pw = $params['password'];
var $settings = array();
/**
* Initialize the Cache Engine
*
* Called automatically by the cache frontend
* To reinitialize the settings call Cache::engine('EngineName', [optional] settings = array());
*
* @param array $setting array of setting for the engine
* @return boolean True if the engine has been successfully initialized, false if not
* @access public
*/
function init($settings) {
parent::init($settings);
$defaults = array('PHP_AUTH_USER' => 'cake', 'PHP_AUTH_PW' => 'cake');
$this->settings = am($this->settings, $defaults, $settings);
return function_exists('xcache_info');
}
/**
* Write a value in the cache
* Write data for key into cache
*
* @param string $key Identifier for the data
* @param mixed $value Data to be cached
@ -70,11 +67,11 @@ class XcacheEngine extends CacheEngine {
* @return boolean True if the data was succesfully cached, false on failure
* @access public
*/
function write($key, &$value, $duration = CACHE_DEFAULT_DURATION) {
function write($key, &$value, $duration) {
return xcache_set($key, $value, $duration);
}
/**
* Read a value from the cache
* Read a key from the cache
*
* @param string $key Identifier for the data
* @return mixed The cached data, or false if the data doesn't exist, has expired, or if there was an error fetching it
@ -87,7 +84,7 @@ class XcacheEngine extends CacheEngine {
return false;
}
/**
* Delete a value from the cache
* Delete a key from the cache
*
* @param string $key Identifier for the data
* @return boolean True if the value was succesfully deleted, false if it didn't exist or couldn't be removed
@ -97,46 +94,36 @@ class XcacheEngine extends CacheEngine {
return xcache_unset($key);
}
/**
* Delete all values from the cache
* Delete all keys from the cache
*
* @return boolean True if the cache was succesfully cleared, false otherwise
* @access public
*/
function clear() {
$result = true;
$this->_phpAuth();
$this->__auth();
for ($i = 0, $max = xcache_count(XC_TYPE_VAR); $i < $max; $i++) {
if (!xcache_clear_cache(XC_TYPE_VAR, $i)) {
$result = false;
break;
}
}
$this->_phpAuth(true);
$this->__auth(true);
return $result;
}
/**
* Return the settings for this cache engine
*
* @return array list of settings for this engine
* @access public
*/
function settings() {
return array('class' => get_class($this));
}
/**
* Populates and reverses $_SERVER authentication values
* Makes necessary changes (and reverting them back) in $_SERVER
*
* This has to be done because xcache_clear_cache() needs pass Basic Auth
* This has to be done because xcache_clear_cache() needs to pass Basic Http Auth
* (see xcache.admin configuration settings)
*
* @param boolean Revert changes
* @access private
* @access protected
*/
function _phpAuth($reverse = false) {
function __auth($reverse = false) {
static $backup = array();
$keys = array('PHP_AUTH_USER', 'PHP_AUTH_PW');
foreach ($keys as $key) {
if ($reverse) {
if (isset($backup[$key])) {
@ -150,8 +137,8 @@ class XcacheEngine extends CacheEngine {
if (!empty($value)) {
$backup[$key] = $value;
}
$varName = '_' . low($key);
$_SERVER[$key] = $this->{$varName};
$varName = '__' . $key;
$_SERVER[$key] = $this->settings[$varName];
}
}
}

View file

@ -523,18 +523,6 @@ class Configure extends Object {
*/
function __loadBootstrap($boot) {
$_this =& Configure::getInstance();
$baseUrl = false;
if (defined('BASE_URL')) {
$baseUrl = BASE_URL;
}
$_this->write('App', array('base' => false, 'baseUrl' => $baseUrl, 'dir' => APP_DIR, 'webroot' => WEBROOT_DIR));
if (defined('CAKE_ADMIN')) {
$_this->write('Routing.admin', CAKE_ADMIN);
}
if (defined('WEBSERVICES')) {
$_this->write('Routing.webservices', WEBSERVICES);
}
$modelPaths = null;
$viewPaths = null;
@ -543,11 +531,16 @@ class Configure extends Object {
$componentPaths = null;
$behaviorPaths = null;
$pluginPaths = null;
if ($boot) {
if (!require_once(APP_PATH . 'config' . DS . 'core.php')) {
trigger_error(sprintf(__("Can't find application core file. Please create %score.php, and make sure it is readable by PHP.", true), CONFIGS), E_USER_ERROR);
}
if (!include(APP_PATH . 'config' . DS . 'bootstrap.php')) {
trigger_error(sprintf(__("Can't find application bootstrap file. Please create %sbootstrap.php, and make sure it is readable by PHP.", true), CONFIGS), E_USER_ERROR);
}
}
$_this->__buildModelPaths($modelPaths);
$_this->__buildViewPaths($viewPaths);
$_this->__buildControllerPaths($controllerPaths);
@ -555,6 +548,25 @@ class Configure extends Object {
$_this->__buildComponentPaths($componentPaths);
$_this->__buildBehaviorPaths($behaviorPaths);
$_this->__buildPluginPaths($pluginPaths);
$baseUrl = false;
if (defined('BASE_URL')) {
$baseUrl = BASE_URL;
}
$_this->write('App', array('base' => false, 'baseUrl' => $baseUrl, 'dir' => APP_DIR, 'webroot' => WEBROOT_DIR));
if (defined('DEBUG')) {
trigger_error('Deprecated: Use Configure::write(\'debug\', ' . DEBUG . ');', E_USER_WARNING);
$_this->write('debug', DEBUG);
}
if (defined('CAKE_ADMIN')) {
trigger_error('Deprecated: Use Configure::write(\'Routing.admin\', ' . CAKE_ADMIN . ');', E_USER_WARNING);
$_this->write('Routing.admin', CAKE_ADMIN);
}
if (defined('WEBSERVICES')) {
trigger_error('Deprecated: Use Router::parseExtensions();', E_USER_WARNING);
$_this->write('Routing.webservices', WEBSERVICES);
}
}
}
?>

View file

@ -60,7 +60,7 @@ class Folder extends Object{
* @var boolean
* @access public
*/
var $mode = 0755;
var $mode = '0755';
/**
* holds messages from last method.
*
@ -107,7 +107,7 @@ class Folder extends Object{
if (!file_exists($path) && $create == true) {
$this->create($path, $this->mode);
}
if($path{0} != '/') {
if (!$this->isAbsolute($path)) {
$path = realpath($path);
}
$this->cd($path);

View file

@ -33,14 +33,7 @@
* Database name for cake sessions.
*
*/
if (!defined('CAKE_SESSION_TABLE')) {
define('CAKE_SESSION_TABLE', 'cake_sessions');
}
if (CAKE_SESSION_SAVE === 'database') {
uses('model' . DS . 'connection_manager');
}
uses('set');
uses('set');
/**
* Session class for Cake.
*
@ -122,6 +115,14 @@ class CakeSession extends Object {
* @access public
*/
function __construct($base = null, $start = true) {
if (!defined('CAKE_SESSION_TABLE')) {
define('CAKE_SESSION_TABLE', 'cake_sessions');
}
if (CAKE_SESSION_SAVE === 'database' && !class_exists('ConnectionManager')) {
uses('model' . DS . 'connection_manager');
}
if (env('HTTP_USER_AGENT') != null) {
$this->_userAgent = md5(env('HTTP_USER_AGENT') . CAKE_SESSION_STRING);
} else {

View file

@ -36,7 +36,56 @@ uses('cache', 'cache' . DS . 'apc');
class APCEngineTest extends UnitTestCase {
function skip() {
$this->skipif (true, 'APCEngineTest not implemented');
$skip = true;
if($result = Cache::engine('Apc')) {
$skip = false;
}
$this->skipif ($skip, 'APCEngineTest not implemented');
}
function testReadAndWriteCache() {
$result = Cache::read('test');
$expecting = '';
$this->assertEqual($result, $expecting);
$data = 'this is a test of the emergency broadcasting system';
$result = Cache::write('test', $data, 1);
$this->assertTrue($result);
$result = Cache::read('test');
$expecting = $data;
$this->assertEqual($result, $expecting);
}
function testExpiry() {
sleep(2);
$result = Cache::read('test');
$this->assertFalse($result);
$data = 'this is a test of the emergency broadcasting system';
$result = Cache::write('other_test', $data, 1);
$this->assertTrue($result);
sleep(2);
$result = Cache::read('other_test');
$this->assertFalse($result);
$data = 'this is a test of the emergency broadcasting system';
$result = Cache::write('other_test', $data, "+1 second");
$this->assertTrue($result);
sleep(2);
$result = Cache::read('other_test');
$this->assertFalse($result);
}
function testDeleteCache() {
$data = 'this is a test of the emergency broadcasting system';
$result = Cache::write('delete_test', $data);
$this->assertTrue($result);
$result = Cache::delete('delete_test');
$this->assertTrue($result);
}
}
?>

View file

@ -39,6 +39,32 @@ class FileEngineTest extends UnitTestCase {
Cache::engine();
}
function testSettings() {
Cache::engine('File', array('path' => TMP . 'tests'));
$settings = Cache::settings();
$expecting = array('duration'=> 3600,
'probability' => 100,
'path'=> TMP . 'tests',
'prefix'=> 'cake_',
'lock' => false,
'serialize'=> true,
'name' => 'File'
);
$this->assertEqual($settings, $expecting);
}
function testCacheName() {
$cache =& Cache::getInstance();
$result = $cache->_Engine->fullpath('models' . DS . 'default_posts');
$expecting = CACHE . 'models' . DS .'cake_default_posts';
$this->assertEqual($result, $expecting);
$result = $cache->_Engine->fullpath('default_posts');
$expecting = CACHE . 'cake_default_posts';
$this->assertEqual($result, $expecting);
}
function testReadAndWriteCache() {
$result = Cache::read('test');
$expecting = '';
@ -84,11 +110,17 @@ class FileEngineTest extends UnitTestCase {
$this->assertTrue($result);
}
function testCacheName() {
$cache =& Cache::getInstance();
$result = $cache->_Engine->_getFilename('models' . DS . 'default_' . 'posts');
$expecting = CACHE . 'models' . DS .'cake_default_posts';
$this->assertEqual($result, $expecting);
function testSerialize() {
Cache::engine('File', array('serialize' => true));
$data = 'this is a test of the emergency broadcasting system';
$write = Cache::write('seriailze_test', $data, 1);
Cache::engine('File', array('serialize' => false));
$read = Cache::read('seriailze_test');
$result = Cache::delete('seriailze_test');
$this->assertNotIdentical($write, $read);
}
}

View file

@ -36,7 +36,78 @@ uses('cache', 'cache' . DS . 'memcache');
class MemcacheEngineTest extends UnitTestCase {
function skip() {
$this->skipif (true, 'MemcacheEngineTest not implemented');
$skip = true;
if($result = Cache::engine('Memcache')) {
$skip = false;
}
$this->skipif ($skip, 'Memcache not available');
}
function setUp() {
Cache::engine('Memcache');
}
function testSettings() {
$settings = Cache::settings();
$expecting = array('duration'=> 3600,
'probability' => 100,
'servers' => array('127.0.0.1'),
'compress' => false,
'name' => 'Memcache'
);
$this->assertEqual($settings, $expecting);
}
function testConnect() {
$Cache =& Cache::getInstance();
$result = $Cache->_Engine->connect('127.0.0.1');
$this->assertTrue($result);
}
function testReadAndWriteCache() {
$result = Cache::read('test');
$expecting = '';
$this->assertEqual($result, $expecting);
$data = 'this is a test of the emergency broadcasting system';
$result = Cache::write('test', $data, 1);
$this->assertTrue($result);
$result = Cache::read('test');
$expecting = $data;
$this->assertEqual($result, $expecting);
}
function testExpiry() {
sleep(2);
$result = Cache::read('test');
$this->assertFalse($result);
$data = 'this is a test of the emergency broadcasting system';
$result = Cache::write('other_test', $data, 1);
$this->assertTrue($result);
sleep(2);
$result = Cache::read('other_test');
$this->assertFalse($result);
$data = 'this is a test of the emergency broadcasting system';
$result = Cache::write('other_test', $data, "+1 second");
$this->assertTrue($result);
sleep(2);
$result = Cache::read('other_test');
$this->assertFalse($result);
}
function testDeleteCache() {
$data = 'this is a test of the emergency broadcasting system';
$result = Cache::write('delete_test', $data);
$this->assertTrue($result);
$result = Cache::delete('delete_test');
$this->assertTrue($result);
}
}
?>

View file

@ -38,5 +38,50 @@ class ModelEngineTest extends UnitTestCase {
function skip() {
$this->skipif (true, 'ModelEngineTest not implemented');
}
function testReadAndWriteCache() {
$result = Cache::read('test');
$expecting = '';
$this->assertEqual($result, $expecting);
$data = 'this is a test of the emergency broadcasting system';
$result = Cache::write('test', $data, 1);
$this->assertTrue($result);
$result = Cache::read('test');
$expecting = $data;
$this->assertEqual($result, $expecting);
}
function testExpiry() {
sleep(2);
$result = Cache::read('test');
$this->assertFalse($result);
$data = 'this is a test of the emergency broadcasting system';
$result = Cache::write('other_test', $data, 1);
$this->assertTrue($result);
sleep(2);
$result = Cache::read('other_test');
$this->assertFalse($result);
$data = 'this is a test of the emergency broadcasting system';
$result = Cache::write('other_test', $data, "+1 second");
$this->assertTrue($result);
sleep(2);
$result = Cache::read('other_test');
$this->assertFalse($result);
}
function testDeleteCache() {
$data = 'this is a test of the emergency broadcasting system';
$result = Cache::write('delete_test', $data);
$this->assertTrue($result);
$result = Cache::delete('delete_test');
$this->assertTrue($result);
}
}
?>

View file

@ -36,7 +36,71 @@ uses('cache', 'cache' . DS . 'xcache');
class XcacheEngineTest extends UnitTestCase {
function skip() {
$this->skipif (true, 'XcacheEngineTest not implemented');
$skip = true;
if($result = Cache::engine('Xcache')) {
$skip = false;
}
$this->skipif($skip, 'XcacheEngineTest not implemented');
}
function setUp() {
Cache::engine('Xcache');
}
function testSettings() {
$settings = Cache::settings();
$expecting = array('duration'=> 3600,
'probability' => 100,
'PHP_AUTH_USER' => 'cake',
'PHP_AUTH_PW' => '',
'name' => 'Xcache'
);
$this->assertEqual($settings, $expecting);
}
function testReadAndWriteCache() {
$result = Cache::read('test');
$expecting = '';
$this->assertEqual($result, $expecting);
$data = 'this is a test of the emergency broadcasting system';
$result = Cache::write('test', $data, 1);
$this->assertTrue($result);
$result = Cache::read('test');
$expecting = $data;
$this->assertEqual($result, $expecting);
}
function testExpiry() {
sleep(2);
$result = Cache::read('test');
$this->assertFalse($result);
$data = 'this is a test of the emergency broadcasting system';
$result = Cache::write('other_test', $data, 1);
$this->assertTrue($result);
sleep(2);
$result = Cache::read('other_test');
$this->assertFalse($result);
$data = 'this is a test of the emergency broadcasting system';
$result = Cache::write('other_test', $data, "+1 second");
$this->assertTrue($result);
sleep(2);
$result = Cache::read('other_test');
$this->assertFalse($result);
}
function testDeleteCache() {
$data = 'this is a test of the emergency broadcasting system';
$result = Cache::write('delete_test', $data);
$this->assertTrue($result);
$result = Cache::delete('delete_test');
$this->assertTrue($result);
}
}
?>