Refactor ViewableData::obj caching

This commit is contained in:
Damian Mooyman 2015-03-02 10:07:58 +13:00
parent e3478e96fd
commit 95efc330e4
2 changed files with 70 additions and 6 deletions

View File

@ -156,6 +156,25 @@ class ViewableDataTest extends SapphireTest {
$this->assertEquals($uncastedData, $castedData->getValue(), 'Casted and uncasted strings are not equal.');
}
public function testCaching() {
$objCached = new ViewableDataTest_Cached();
$objNotCached = new ViewableDataTest_NotCached();
$objCached->Test = 'AAA';
$objNotCached->Test = 'AAA';
$this->assertEquals('AAA', $objCached->obj('Test', null, true, true));
$this->assertEquals('AAA', $objNotCached->obj('Test', null, true, true));
$objCached->Test = 'BBB';
$objNotCached->Test = 'BBB';
// Cached data must be always the same
$this->assertEquals('AAA', $objCached->obj('Test', null, true, true));
$this->assertEquals('BBB', $objNotCached->obj('Test', null, true, true));
}
}
/**#@+
@ -253,4 +272,17 @@ class ViewableDataTest_NoCastingInformation extends ViewableData {
}
}
class ViewableDataTest_Cached extends ViewableData {
public $Test;
}
class ViewableDataTest_NotCached extends ViewableData {
public $Test;
protected function objCacheGet($key) {
// Disable caching
return null;
}
}
/**#@-*/

View File

@ -345,6 +345,38 @@ class ViewableData extends Object implements IteratorAggregate {
"ViewableData::renderWith(): unexpected $template->class object, expected an SSViewer instance"
);
}
/**
* Generate the cache name for a field
*
* @param string $fieldName Name of field
* @param array $arguments List of optional arguments given
*/
protected function objCacheName($fieldName, $arguments) {
return $arguments
? $fieldName . ":" . implode(',', $arguments)
: $fieldName;
}
/**
* Get a cached value from the field cache
*
* @param string $key Cache key
* @return mixed
*/
protected function objCacheGet($key) {
if(isset($this->objCache[$key])) return $this->objCache[$key];
}
/**
* Store a value in the field cache
*
* @param string $key Cache key
* @param mixed $value
*/
protected function objCacheSet($key, $value) {
$this->objCache[$key] = $value;
}
/**
* Get the value of a field on this object, automatically inserting the value into any available casting objects
@ -354,12 +386,14 @@ class ViewableData extends Object implements IteratorAggregate {
* @param array $arguments
* @param bool $forceReturnedObject if TRUE, the value will ALWAYS be casted to an object before being returned,
* even if there is no explicit casting information
* @param bool $cache Cache this object
* @param string $cacheName a custom cache name
*/
public function obj($fieldName, $arguments = null, $forceReturnedObject = true, $cache = false, $cacheName = null) {
if(!$cacheName) $cacheName = $arguments ? $fieldName . implode(',', $arguments) : $fieldName;
if(!isset($this->objCache[$cacheName])) {
if(!$cacheName && $cache) $cacheName = $this->objCacheName($fieldName, $arguments);
$value = $cache ? $this->objCacheGet($cacheName) : null;
if(!isset($value)) {
// HACK: Don't call the deprecated FormField::Name() method
$methodIsAllowed = true;
if($this instanceof FormField && $fieldName == 'Name') $methodIsAllowed = false;
@ -381,9 +415,7 @@ class ViewableData extends Object implements IteratorAggregate {
$value = $valueObject;
}
if($cache) $this->objCache[$cacheName] = $value;
} else {
$value = $this->objCache[$cacheName];
if($cache) $this->objCacheSet($cacheName, $value);
}
if(!is_object($value) && $forceReturnedObject) {