diff --git a/cache/lib.php b/cache/lib.php index 001cd431439..1ee4100e7cf 100644 --- a/cache/lib.php +++ b/cache/lib.php @@ -148,4 +148,81 @@ class cache_exception extends moodle_exception { // This may appear like a useless override but you will notice that we have set a MUCH more useful default for $module. parent::__construct($errorcode, $module, $link, $a, $debuginfo); } +} + +/** + * An array of cacheable objects. + * + * This class allows a developer to create an array of cacheable objects and store that. + * The cache API doesn't check items within an array to see whether they are cacheable. Such a check would be very costly to both + * arrays using cacheable object and those that don't. + * Instead the developer must explicitly use a cacheable_object_array instance. + * + * The following is one example of how this class can be used. + * + * $data = array(); + * $data[] = new cacheable_object('one'); + * $data[] = new cacheable_object('two'); + * $data[] = new cacheable_object('three'); + * $cache->set(new cacheable_object_array($data)); + * + * Another example would be + * + * $data = new cacheable_object_array(); + * $data[] = new cacheable_object('one'); + * $data[] = new cacheable_object('two'); + * $data[] = new cacheable_object('three'); + * $cache->set($data); + * + * + * @copyright 2012 Sam Hemelryk + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class cacheable_object_array extends ArrayObject implements cacheable_object { + + /** + * Constructs a new array object instance. + * @param array $items + */ + final public function __construct(array $items = array()) { + parent::__construct($items, ArrayObject::STD_PROP_LIST); + } + + /** + * Returns the data to cache for this object. + * + * @return array An array of cache_cached_object instances. + * @throws coding_exception + */ + final public function prepare_to_cache() { + $result = array(); + foreach ($this as $key => $value) { + if ($value instanceof cacheable_object) { + $value = new cache_cached_object($value); + } else { + throw new coding_exception('Only cacheable_object instances can be added to a cacheable_array'); + } + $result[$key] = $value; + } + return $result; + } + + /** + * Returns the cacheable_object_array that was originally sent to the cache. + * + * @param array $data + * @return cacheable_object_array + * @throws coding_exception + */ + final static public function wake_from_cache($data) { + if (!is_array($data)) { + throw new coding_exception('Invalid data type when reviving cacheable_array data'); + } + $result = array(); + foreach ($data as $key => $value) { + $result[$key] = $value->restore_object(); + } + $class = __CLASS__; + return new $class($result); + } } \ No newline at end of file diff --git a/cache/tests/cache_test.php b/cache/tests/cache_test.php index edef90db99d..e7fe8369204 100644 --- a/cache/tests/cache_test.php +++ b/cache/tests/cache_test.php @@ -231,6 +231,23 @@ class cache_phpunit_tests extends advanced_testcase { $this->assertEquals('red_ptc_wfc', $result->property1); $this->assertEquals('blue_ptc_wfc', $result->property2); + // Test array of objects + $specobject = new cache_phpunit_dummy_object('red', 'blue'); + $data = new cacheable_object_array(array( + clone($specobject), + clone($specobject), + clone($specobject)) + ); + $this->assertTrue($cache->set($key, $data)); + $result = $cache->get($key); + $this->assertInstanceOf('cacheable_object_array', $result); + $this->assertCount(3, $data); + foreach ($result as $item) { + $this->assertInstanceOf('cache_phpunit_dummy_object', $item); + $this->assertEquals('red_ptc_wfc', $item->property1); + $this->assertEquals('blue_ptc_wfc', $item->property2); + } + // Test set many. $cache->set_many(array('key1' => 'data1', 'key2' => 'data2')); $this->assertEquals('data1', $cache->get('key1'));