src/PodiumCache.php
<?php
namespace bizley\podium;
use bizley\podium\models\User;
use yii\base\InvalidConfigException;
use yii\base\Object;
use yii\base\View;
use yii\caching\Cache;
use yii\di\Instance;
use yii\widgets\FragmentCache;
/**
* Podium Cache helper
*
* Handles the cache component. If cache component is not set in configuration
* \yii\caching\DummyCache is used instead.
* Every Podium cache element is prefixed with 'podium.' automatically.
* This helper also allows to operate on single array key of cached elements and views content.
*
* List of keys:
* config => Podium configuration
* forum.lastactive => number of last active users
* forum.latestposts => 5 latest forum posts
* forum.memberscount => number of activated and banned users
* forum.moderators => moderators for each forum
* forum.threadscount => number of forum threads
* forum.postscount => number of forum posts
* members.fieldlist => list of active users w/pages
* user.friends => list of users friends
* user.newmessages => list of users new messages count
* user.postscount => list of users posts count
* user.subscriptions => list of users subscribed threads with new posts count
* user.threadscount => list of users threads count
* user.votes.ID => user's votes per hour
*
* @author Paweł Bizley Brzozowski <pawel@positive.codes>
* @since 0.5
*
* @property Cache $engine
*/
class PodiumCache extends Object
{
/**
* @var string Podium cache element prefix.
* This prefix is automatically added to every element.
*/
protected $_cachePrefix = 'podium.';
/**
* Returns cache engine.
* @return Cache
* @throws InvalidConfigException
* @since 0.2
*/
public function getEngine()
{
return Instance::ensure(Podium::getInstance()->cache, Cache::className());
}
/**
* Begins FragmentCache widget.
* Usage:
* if (Podium::getInstance()->cache->beginCache('key', $this)) {
* $this->endCache();
* }
* @param string $key the key identifying the content to be cached.
* @param View $view view object
* @param int $duration number of seconds that the data can remain valid in cache.
* Use 0 to indicate that the cached data will never expire.
* @return bool
* @since 0.2
*/
public function begin($key, $view, $duration = 60)
{
$properties['id'] = $this->_cachePrefix . $key;
$properties['view'] = $view;
$properties['duration'] = $duration;
$cache = FragmentCache::begin($properties);
if ($cache->getCachedContent() !== false) {
$this->end();
return false;
}
return true;
}
/**
* Clears several elements at once.
* @param string $what action identifier
* @since 0.2
*/
public static function clearAfter($what)
{
$cache = new static;
switch ($what) {
case 'userDelete':
$cache->delete('forum.latestposts');
// no break
case 'activate':
$cache->delete('members.fieldlist');
$cache->delete('forum.memberscount');
break;
case 'categoryDelete':
case 'forumDelete':
case 'threadDelete':
case 'postDelete':
$cache->delete('forum.threadscount');
$cache->delete('forum.postscount');
$cache->delete('user.threadscount');
$cache->delete('user.postscount');
$cache->delete('forum.latestposts');
break;
case 'threadMove':
case 'postMove':
$cache->delete('forum.threadscount');
$cache->delete('forum.postscount');
$cache->delete('forum.latestposts');
break;
case 'newThread':
$cache->delete('forum.threadscount');
$cache->deleteElement('user.threadscount', User::loggedId());
// no break
case 'newPost':
$cache->delete('forum.postscount');
$cache->delete('forum.latestposts');
$cache->deleteElement('user.postscount', User::loggedId());
break;
}
}
/**
* Deletes the value with the specified key from cache
* @param string $key the key identifying the value to be deleted from cache.
* @return bool
*/
public function delete($key)
{
return $this->engine->delete($this->_cachePrefix . $key);
}
/**
* Deletes the value of element with the specified key from cache array.
* @param string $key a key identifying the value to be deleted from cache.
* @param string $element a key of the element.
* @return bool
*/
public function deleteElement($key, $element)
{
$cache = $this->get($key);
if ($cache !== false && isset($cache[$element])) {
unset($cache[$element]);
return $this->set($key, $cache);
}
return true;
}
/**
* Ends FragmentCache widget.
*/
public function end()
{
return FragmentCache::end();
}
/**
* Flushes all cache.
*/
public function flush()
{
return $this->engine->flush();
}
/**
* Retrieves the value from cache with the specified key.
* @param string $key the key identifying the cached value.
* @return mixed the value stored in cache, false if the value is not in the cache, expired,
* or the dependency associated with the cached data has changed.
*/
public function get($key)
{
return $this->engine->get($this->_cachePrefix . $key);
}
/**
* Retrieves the value of element from array cache with the specified key.
* @param string $key the key identifying the cached value.
* @param string $element the key of the element.
* @return mixed the value of element stored in cache array, false if the value is not in the cache, expired,
* array key does not exist or the dependency associated with the cached data has changed.
*/
public function getElement($key, $element)
{
$cache = $this->get($key);
if ($cache !== false && isset($cache[$element])) {
return $cache[$element];
}
return false;
}
/**
* Stores the value identified by the key into cache.
* @param string $key the key identifying the value to be cached.
* @param mixed $value the value to be cached
* @param int $duration the number of seconds in which the cached value will expire. 0 means never expire.
* @return bool
*/
public function set($key, $value, $duration = 0)
{
return $this->engine->set($this->_cachePrefix . $key, $value, $duration);
}
/**
* Stores the value for the element into cache array identified by the key.
* @param string $key the key identifying the value to be cached.
* @param string $element the key of the element.
* @param mixed $value the value to be cached
* @param int $duration the number of seconds in which the cached value will expire. 0 means never expire.
* @return bool
*/
public function setElement($key, $element, $value, $duration = 0)
{
$cache = $this->get($key);
if ($cache === false) {
$cache = [];
}
$cache[$element] = $value;
return $this->set($key, $cache, $duration);
}
}