Hi,
I’m fairly new to yii, really enjoying the framework!
I’ve been figuring out a way to automatically update fragment caches when a model saves or deletes and I’d like to run it by more experienced yii developers.
Model
My idea is to have a new class CActiveRecordCached that inherits from CActiveRecord. In this new class I override afterSave() and afterDelete() which will create a list of related models and update global state variables for each model e.g. for Post model, a global state variable called Cache.post will be updated with the timestamp. In addition, because Author is a related model, Cache.author will also be updated.
Any models which should trigger a fragment cache refresh should inherit from CActiveRecordCached.
class CActiveRecordCached extends CActiveRecord
{
protected function afterSave()
{
parent::afterSave();
$this->updateCacheDependencies();
}
protected function afterDelete()
{
parent::afterDelete();
$this->updateCacheDependencies();
}
protected function updateCacheDependencies()
{
//Update timestamps on related models so that view caches get updated
$cacheUpdates = array();
$cacheUpdates[] = 'Cache.'.$this->tablename();
$relations = $this->relations();
foreach($relations as $relation)
$cacheUpdates[] = 'Cache.'.strtolower($relation[1]);
foreach($cacheUpdates as $cacheUpdate)
{
Yii::app()->setGlobalState($cacheUpdate, time());
Yii::app()->saveGlobalState();
}
}
}
View
Use fragment caches as usual, using CGlobalStateCacheDependency and using the appropriate global state variable e.g. Cache.post
<?php
if($this->beginCache('postindex', array('dependency'=>array(
'class'=>'system.caching.dependencies.CGlobalStateCacheDependency',
'stateName'=>'Cache.post')))) { ?>
//e.g. output post+author info
Therefore in the above example, if a post or author is updated/deleted, global states Cache.post and Cache.author are updated, causing any fragment caches with a dependency on either of these global states to refresh.
How does this sound?
Thanks,
Peter