mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 12:05:37 +00:00
simon_w: #1954 - Added object caching methods
git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@49175 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
parent
8f4ed9d16b
commit
9a68af98cd
118
core/Object.php
118
core/Object.php
@ -429,6 +429,123 @@ class Object {
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CACHE METHODS (added by simon_w (simon -at- simon -dot- geek -dot- nz))
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/**
|
||||
* Loads a current cache from the filesystem, if it can.
|
||||
*
|
||||
* @param string $cachename The name of the cache to load
|
||||
* @param int $expire The lifetime of the cache in seconds
|
||||
* @return mixed The data from the cache, or false if the cache wasn't loaded
|
||||
*/
|
||||
protected function loadCache($cachename, $expire = 3600) {
|
||||
$cache_dir = TEMP_FOLDER;
|
||||
$cache_path = $cache_dir . "/" . $this->sanitiseCachename($cachename);
|
||||
if((!isset($_GET['flush']) || $_GET['flush']!=1) && (@file_exists($cache_path) && ((@filemtime($cache_path) + $expire) > (time())))) {
|
||||
return @unserialize(file_get_contents($cache_path));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves a cache to the file system
|
||||
*
|
||||
* @param string $cachename The name of the cache to save
|
||||
* @param mixed $data The data to cache
|
||||
*/
|
||||
protected function saveCache($cachename, $data) {
|
||||
$cache_dir = TEMP_FOLDER;
|
||||
$cache_path = $cache_dir . "/" . $this->sanitiseCachename($cachename);
|
||||
$fp = @fopen($cache_path, "w+");
|
||||
if(!$fp) {
|
||||
return; // Throw an error?
|
||||
}
|
||||
@fwrite($fp, @serialize($data));
|
||||
@fclose($fp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a cache name safe to use in a file system
|
||||
*
|
||||
* @param string $cachename The cache name to sanitise
|
||||
* @return string the sanitised cache name
|
||||
*/
|
||||
protected function sanitiseCachename($cachename) {
|
||||
// Replace illegal characters with underscores
|
||||
$cachename = str_replace(array('~', '.', '/', '!', ' ', "\n", "\r", "\t", '\\', ':', '"', '\'', ';'), '_', $cachename);
|
||||
return $cachename;
|
||||
}
|
||||
|
||||
/**
|
||||
* Caches the return value of a method.
|
||||
*
|
||||
* @param callback $callback The method to cache
|
||||
* @param int $expire The lifetime of the cache
|
||||
* @param string|int $id An id for the cache
|
||||
* @return mixed The cached return of the method
|
||||
*/
|
||||
public function cacheToFile($callback, $expire = 3600, $id = false) {
|
||||
if(!$this->class) {
|
||||
$this->class = get_class($this);
|
||||
}
|
||||
if(!method_exists($this->class, $callback)) {
|
||||
user_error("Class {$this->class} doesn't have the method $callback.", E_USER_ERROR);
|
||||
}
|
||||
$cachename = $this->class . "_" . $callback;
|
||||
if($id) {
|
||||
$cachename .= "_" . (string)$id;
|
||||
}
|
||||
if(($data = $this->loadCache($cachename, $expire)) !== false) {
|
||||
return $data;
|
||||
}
|
||||
// No cache to use
|
||||
$data = $this->$callback();
|
||||
if($data === false) {
|
||||
// Some problem with function. Didn't give anything to cache. So don't cache it.
|
||||
return false;
|
||||
}
|
||||
$this->saveCache($cachename, $data);
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Caches the return value of a method. Passes args to the method as well.
|
||||
*
|
||||
* @param callback $callback The method to cache
|
||||
* @param array $args The arguments to pass to the method
|
||||
* @param int $expire The lifetime of the cache
|
||||
* @param string|int $id An id for the cache
|
||||
* @return mixed The cached return of the method
|
||||
*/
|
||||
// I know this is almost exactly the same as cacheToFile, but call_user_func_array() is slow.
|
||||
// Which is why there's two separate functions
|
||||
public function cacheToFileWithArgs($callback, $args = array(), $expire = 3600, $id = false) {
|
||||
if(!$this->class) {
|
||||
$this->class = get_class($this);
|
||||
}
|
||||
if(!method_exists($this->class, $callback)) {
|
||||
user_error("Class {$this->class} doesn't have the method $callback.", E_USER_ERROR);
|
||||
}
|
||||
$cachename = $this->class . "_" . $callback;
|
||||
if($id) {
|
||||
$cachename .= "_" . (string)$id;
|
||||
}
|
||||
if(($data = $this->loadCache($cachename, $expire)) !== false) {
|
||||
return $data;
|
||||
}
|
||||
// No cache to use
|
||||
$data = call_user_func_array(array($this, $callback), $args);
|
||||
if($data === false) {
|
||||
// Some problem with function. Didn't give anything to cache. So don't cache it.
|
||||
return false;
|
||||
}
|
||||
$this->saveCache($cachename, $data);
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -437,4 +554,3 @@ class Object {
|
||||
* // ENFORCE STRONG_CREATE
|
||||
*/
|
||||
Object::useCustomClass('Datetime','SSDatetime',true);
|
||||
?>
|
||||
|
Loading…
x
Reference in New Issue
Block a user