Qiang Xue
13 years ago
25 changed files with 2603 additions and 154 deletions
@ -0,0 +1,39 @@ |
|||||||
|
<?php |
||||||
|
/** |
||||||
|
* RenderEvent class file. |
||||||
|
* |
||||||
|
* @link http://www.yiiframework.com/ |
||||||
|
* @copyright Copyright © 2008-2012 Yii Software LLC |
||||||
|
* @license http://www.yiiframework.com/license/ |
||||||
|
*/ |
||||||
|
|
||||||
|
namespace yii\base; |
||||||
|
|
||||||
|
/** |
||||||
|
* RenderEvent represents the event parameter used for when calling [[Controller::render()]]. |
||||||
|
* |
||||||
|
* By setting the [[isValid]] property, one may control whether to continue the rendering. |
||||||
|
* |
||||||
|
* @author Qiang Xue <qiang.xue@gmail.com> |
||||||
|
* @since 2.0 |
||||||
|
*/ |
||||||
|
class RenderEvent extends Event |
||||||
|
{ |
||||||
|
/** |
||||||
|
* @var Action the action currently being executed |
||||||
|
*/ |
||||||
|
public $action; |
||||||
|
/** |
||||||
|
* @var boolean whether the action is in valid state and its life cycle should proceed. |
||||||
|
*/ |
||||||
|
public $isValid = true; |
||||||
|
|
||||||
|
/** |
||||||
|
* Constructor. |
||||||
|
* @param Action $action the action associated with this action event. |
||||||
|
*/ |
||||||
|
public function __construct(Action $action) |
||||||
|
{ |
||||||
|
$this->action = $action; |
||||||
|
} |
||||||
|
} |
@ -1,94 +0,0 @@ |
|||||||
<?php |
|
||||||
/** |
|
||||||
* ThemeManager class file. |
|
||||||
* |
|
||||||
* @link http://www.yiiframework.com/ |
|
||||||
* @copyright Copyright © 2008-2012 Yii Software LLC |
|
||||||
* @license http://www.yiiframework.com/license/ |
|
||||||
*/ |
|
||||||
|
|
||||||
namespace yii\base; |
|
||||||
|
|
||||||
/** |
|
||||||
* ThemeManager manages the themes for the Web application. |
|
||||||
* |
|
||||||
* A theme is a collection of view/layout files and resource files |
|
||||||
* (e.g. css, image, js files). When a theme is active, {@link CController} |
|
||||||
* will look for the specified view/layout under the theme folder first. |
|
||||||
* The corresponding view/layout files will be used if the theme provides them. |
|
||||||
* Otherwise, the default view/layout files will be used. |
|
||||||
* |
|
||||||
* By default, each theme is organized as a directory whose name is the theme name. |
|
||||||
* All themes are located under the "WebRootPath/themes" directory. |
|
||||||
* |
|
||||||
* To activate a theme, set the {@link CWebApplication::setTheme theme} property |
|
||||||
* to be the name of that theme. |
|
||||||
* |
|
||||||
* Since a self-contained theme often contains resource files that are made |
|
||||||
* Web accessible, please make sure the view/layout files are protected from Web access. |
|
||||||
* |
|
||||||
* @property array $themeNames List of available theme names. |
|
||||||
* @property string $basePath The base path for all themes. Defaults to "WebRootPath/themes". |
|
||||||
* @property string $baseUrl The base URL for all themes. Defaults to "/WebRoot/themes". |
|
||||||
* |
|
||||||
* @author Qiang Xue <qiang.xue@gmail.com> |
|
||||||
* @since 2.0 |
|
||||||
*/ |
|
||||||
class ThemeManager extends ApplicationComponent |
|
||||||
{ |
|
||||||
/** |
|
||||||
* default themes base path |
|
||||||
*/ |
|
||||||
const DEFAULT_BASEPATH = 'themes'; |
|
||||||
|
|
||||||
/** |
|
||||||
* @var string the name of the theme class for representing a theme. |
|
||||||
* Defaults to {@link Theme}. This can also be a class name in dot syntax. |
|
||||||
*/ |
|
||||||
public $themeClass = 'Theme'; |
|
||||||
/** |
|
||||||
* @var string the base path containing all themes. Defaults to '@entry/themes'. |
|
||||||
*/ |
|
||||||
public $basePath = '@entry/themes'; |
|
||||||
/** |
|
||||||
* @var string the base URL for all themes. Defaults to "@www/themes". |
|
||||||
*/ |
|
||||||
public $baseUrl = '@www/themes'; |
|
||||||
|
|
||||||
|
|
||||||
/** |
|
||||||
* @param string $name name of the theme to be retrieved |
|
||||||
* @return Theme the theme retrieved. Null if the theme does not exist. |
|
||||||
*/ |
|
||||||
public function getTheme($name) |
|
||||||
{ |
|
||||||
$themePath = $this->getBasePath() . DIRECTORY_SEPARATOR . $name; |
|
||||||
if (is_dir($themePath)) { |
|
||||||
$class = Yii::import($this->themeClass, true); |
|
||||||
return new $class($name, $themePath, $this->getBaseUrl() . '/' . $name); |
|
||||||
} else { |
|
||||||
return null; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* @return array list of available theme names |
|
||||||
*/ |
|
||||||
public function getThemeNames() |
|
||||||
{ |
|
||||||
static $themes; |
|
||||||
if ($themes === null) { |
|
||||||
$themes = array(); |
|
||||||
$basePath = $this->getBasePath(); |
|
||||||
$folder = @opendir($basePath); |
|
||||||
while (($file = @readdir($folder)) !== false) { |
|
||||||
if ($file !== '.' && $file !== '..' && $file !== '.svn' && $file !== '.gitignore' && is_dir($basePath . DIRECTORY_SEPARATOR . $file)) { |
|
||||||
$themes[] = $file; |
|
||||||
} |
|
||||||
} |
|
||||||
closedir($folder); |
|
||||||
sort($themes); |
|
||||||
} |
|
||||||
return $themes; |
|
||||||
} |
|
||||||
} |
|
@ -0,0 +1,109 @@ |
|||||||
|
<?php |
||||||
|
/** |
||||||
|
* CApcCache class file |
||||||
|
* |
||||||
|
* @author Qiang Xue <qiang.xue@gmail.com> |
||||||
|
* @link http://www.yiiframework.com/ |
||||||
|
* @copyright Copyright © 2008-2011 Yii Software LLC |
||||||
|
* @license http://www.yiiframework.com/license/ |
||||||
|
*/ |
||||||
|
|
||||||
|
/** |
||||||
|
* CApcCache provides APC caching in terms of an application component. |
||||||
|
* |
||||||
|
* The caching is based on {@link http://www.php.net/apc APC}. |
||||||
|
* To use this application component, the APC PHP extension must be loaded. |
||||||
|
* |
||||||
|
* See {@link CCache} manual for common cache operations that are supported by CApcCache. |
||||||
|
* |
||||||
|
* @author Qiang Xue <qiang.xue@gmail.com> |
||||||
|
* @version $Id$ |
||||||
|
* @package system.caching |
||||||
|
* @since 1.0 |
||||||
|
*/ |
||||||
|
class CApcCache extends CCache |
||||||
|
{ |
||||||
|
/** |
||||||
|
* Initializes this application component. |
||||||
|
* This method is required by the {@link IApplicationComponent} interface. |
||||||
|
* It checks the availability of memcache. |
||||||
|
* @throws CException if APC cache extension is not loaded or is disabled. |
||||||
|
*/ |
||||||
|
public function init() |
||||||
|
{ |
||||||
|
parent::init(); |
||||||
|
if(!extension_loaded('apc')) |
||||||
|
throw new CException(Yii::t('yii','CApcCache requires PHP apc extension to be loaded.')); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Retrieves a value from cache with a specified key. |
||||||
|
* This is the implementation of the method declared in the parent class. |
||||||
|
* @param string $key a unique key identifying the cached value |
||||||
|
* @return string the value stored in cache, false if the value is not in the cache or expired. |
||||||
|
*/ |
||||||
|
protected function getValue($key) |
||||||
|
{ |
||||||
|
return apc_fetch($key); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Retrieves multiple values from cache with the specified keys. |
||||||
|
* @param array $keys a list of keys identifying the cached values |
||||||
|
* @return array a list of cached values indexed by the keys |
||||||
|
*/ |
||||||
|
protected function getValues($keys) |
||||||
|
{ |
||||||
|
return apc_fetch($keys); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Stores a value identified by a key in cache. |
||||||
|
* This is the implementation of the method declared in the parent class. |
||||||
|
* |
||||||
|
* @param string $key the key identifying the value to be cached |
||||||
|
* @param string $value the value to be cached |
||||||
|
* @param integer $expire the number of seconds in which the cached value will expire. 0 means never expire. |
||||||
|
* @return boolean true if the value is successfully stored into cache, false otherwise |
||||||
|
*/ |
||||||
|
protected function setValue($key,$value,$expire) |
||||||
|
{ |
||||||
|
return apc_store($key,$value,$expire); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Stores a value identified by a key into cache if the cache does not contain this key. |
||||||
|
* This is the implementation of the method declared in the parent class. |
||||||
|
* |
||||||
|
* @param string $key the key identifying the value to be cached |
||||||
|
* @param string $value the value to be cached |
||||||
|
* @param integer $expire the number of seconds in which the cached value will expire. 0 means never expire. |
||||||
|
* @return boolean true if the value is successfully stored into cache, false otherwise |
||||||
|
*/ |
||||||
|
protected function addValue($key,$value,$expire) |
||||||
|
{ |
||||||
|
return apc_add($key,$value,$expire); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Deletes a value with the specified key from cache |
||||||
|
* This is the implementation of the method declared in the parent class. |
||||||
|
* @param string $key the key of the value to be deleted |
||||||
|
* @return boolean if no error happens during deletion |
||||||
|
*/ |
||||||
|
protected function deleteValue($key) |
||||||
|
{ |
||||||
|
return apc_delete($key); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Deletes all values from cache. |
||||||
|
* This is the implementation of the method declared in the parent class. |
||||||
|
* @return boolean whether the flush operation was successful. |
||||||
|
* @since 1.1.5 |
||||||
|
*/ |
||||||
|
protected function flushValues() |
||||||
|
{ |
||||||
|
return apc_clear_cache('user'); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,399 @@ |
|||||||
|
<?php |
||||||
|
/** |
||||||
|
* CCache class file. |
||||||
|
* |
||||||
|
* @author Qiang Xue <qiang.xue@gmail.com> |
||||||
|
* @link http://www.yiiframework.com/ |
||||||
|
* @copyright Copyright © 2008-2011 Yii Software LLC |
||||||
|
* @license http://www.yiiframework.com/license/ |
||||||
|
*/ |
||||||
|
|
||||||
|
/** |
||||||
|
* CCache is the base class for cache classes with different cache storage implementation. |
||||||
|
* |
||||||
|
* A data item can be stored in cache by calling {@link set} and be retrieved back |
||||||
|
* later by {@link get}. In both operations, a key identifying the data item is required. |
||||||
|
* An expiration time and/or a dependency can also be specified when calling {@link set}. |
||||||
|
* If the data item expires or the dependency changes, calling {@link get} will not |
||||||
|
* return back the data item. |
||||||
|
* |
||||||
|
* Note, by definition, cache does not ensure the existence of a value |
||||||
|
* even if it does not expire. Cache is not meant to be a persistent storage. |
||||||
|
* |
||||||
|
* CCache implements the interface {@link ICache} with the following methods: |
||||||
|
* <ul> |
||||||
|
* <li>{@link get} : retrieve the value with a key (if any) from cache</li> |
||||||
|
* <li>{@link set} : store the value with a key into cache</li> |
||||||
|
* <li>{@link add} : store the value only if cache does not have this key</li> |
||||||
|
* <li>{@link delete} : delete the value with the specified key from cache</li> |
||||||
|
* <li>{@link flush} : delete all values from cache</li> |
||||||
|
* </ul> |
||||||
|
* |
||||||
|
* Child classes must implement the following methods: |
||||||
|
* <ul> |
||||||
|
* <li>{@link getValue}</li> |
||||||
|
* <li>{@link setValue}</li> |
||||||
|
* <li>{@link addValue}</li> |
||||||
|
* <li>{@link deleteValue}</li> |
||||||
|
* <li>{@link flushValues} (optional)</li> |
||||||
|
* <li>{@link serializeValue} (optional)</li> |
||||||
|
* <li>{@link unserializeValue} (optional)</li> |
||||||
|
* </ul> |
||||||
|
* |
||||||
|
* CCache also implements ArrayAccess so that it can be used like an array. |
||||||
|
* |
||||||
|
* @author Qiang Xue <qiang.xue@gmail.com> |
||||||
|
* @version $Id$ |
||||||
|
* @package system.caching |
||||||
|
* @since 1.0 |
||||||
|
*/ |
||||||
|
abstract class CCache extends CApplicationComponent implements ICache, ArrayAccess |
||||||
|
{ |
||||||
|
/** |
||||||
|
* @var string a string prefixed to every cache key so that it is unique. Defaults to null which means |
||||||
|
* to use the {@link CApplication::getId() application ID}. If different applications need to access the same |
||||||
|
* pool of cached data, the same prefix should be set for each of the applications explicitly. |
||||||
|
*/ |
||||||
|
public $keyPrefix; |
||||||
|
|
||||||
|
/** |
||||||
|
* @var boolean whether to md5-hash the cache key for normalization purposes. Defaults to true. Setting this property to false makes sure the cache |
||||||
|
* key will not be tampered when calling the relevant methods {@link get()}, {@link set()}, {@link add()} and {@link delete()}. This is useful if a Yii |
||||||
|
* application as well as an external application need to access the same cache pool (also see description of {@link keyPrefix} regarding this use case). |
||||||
|
* However, without normalization you should make sure the affected cache backend does support the structure (charset, length, etc.) of all the provided |
||||||
|
* cache keys, otherwise there might be unexpected behavior. |
||||||
|
* @since 1.1.11 |
||||||
|
**/ |
||||||
|
public $hashKey=true; |
||||||
|
|
||||||
|
/** |
||||||
|
* @var boolean whether to automatically serialize/unserialize the cache values. Defaults to true. Setting this property to false makes sure the cache |
||||||
|
* value will not be tampered when calling the methods {@link set()} and {@link add()}. This is useful in case you want to store data which simply |
||||||
|
* does not require serialization (e.g. integers, strings or raw binary data). Thus there might be a small increase in performance and a smaller overall |
||||||
|
* cache size. Take in mind that you will be unable to store PHP structures like arrays or objects, you would have to serialize and unserialize them manually. |
||||||
|
* Another negative side effect is that providing a dependency via {@link set()} or {@link add()} will have no effect since dependencies rely on serialization. |
||||||
|
* Since all the relevant core application components rely on dependency support, you should be very careful disabling this feature. Usually you want to |
||||||
|
* configure a dedicated cache component for the sole purpose of storing raw unserialized data, the main cache component should always support serialization. |
||||||
|
* @since 1.1.11 |
||||||
|
**/ |
||||||
|
public $autoSerialize=true; |
||||||
|
|
||||||
|
/** |
||||||
|
* @var boolean wether to make use of the {@link http://pecl.php.net/package/igbinary igbinary} serializer for cache entry serialization. Defaults to false. |
||||||
|
* <strong>NOTE:</strong> If this is set to true while the igbinary extension has not been loaded, cache serialization will silently fall back to PHP's default |
||||||
|
* serializer. Since the two serialization formats are incompatible, caches should be purged before switching this on to prevent errors. |
||||||
|
* @since 1.1.11 |
||||||
|
*/ |
||||||
|
public $useIgbinarySerializer=false; |
||||||
|
|
||||||
|
/** |
||||||
|
* Initializes the application component. |
||||||
|
* This method overrides the parent implementation by setting default cache key prefix. |
||||||
|
*/ |
||||||
|
public function init() |
||||||
|
{ |
||||||
|
parent::init(); |
||||||
|
if($this->keyPrefix===null) |
||||||
|
$this->keyPrefix=Yii::app()->getId(); |
||||||
|
$this->useIgbinarySerializer=$this->useIgbinarySerializer&&extension_loaded('igbinary'); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param string $key a key identifying a value to be cached |
||||||
|
* @return sring a key generated from the provided key which ensures the uniqueness across applications |
||||||
|
*/ |
||||||
|
protected function generateUniqueKey($key) |
||||||
|
{ |
||||||
|
return $this->hashKey ? md5($this->keyPrefix.$key) : $this->keyPrefix.$key; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Retrieves a value from cache with a specified key. |
||||||
|
* @param string $id a 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 has changed. |
||||||
|
*/ |
||||||
|
public function get($id) |
||||||
|
{ |
||||||
|
if(($value=$this->getValue($this->generateUniqueKey($id)))!==false) |
||||||
|
{ |
||||||
|
$data=$this->autoSerialize ? $this->unserializeValue($value) : $value; |
||||||
|
if(!$this->autoSerialize || (is_array($data) && (!($data[1] instanceof ICacheDependency) || !$data[1]->getHasChanged()))) |
||||||
|
{ |
||||||
|
Yii::trace('Serving "'.$id.'" from cache','system.caching.'.get_class($this)); |
||||||
|
return $this->autoSerialize ? $data[0] : $data; |
||||||
|
} |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Retrieves multiple values from cache with the specified keys. |
||||||
|
* Some caches (such as memcache, apc) allow retrieving multiple cached values at one time, |
||||||
|
* which may improve the performance since it reduces the communication cost. |
||||||
|
* In case a cache doesn't support this feature natively, it will be simulated by this method. |
||||||
|
* @param array $ids list of keys identifying the cached values |
||||||
|
* @return array list of cached values corresponding to the specified keys. The array |
||||||
|
* is returned in terms of (key,value) pairs. |
||||||
|
* If a value is not cached or expired, the corresponding array value will be false. |
||||||
|
*/ |
||||||
|
public function mget($ids) |
||||||
|
{ |
||||||
|
$uniqueIDs=array(); |
||||||
|
$results=array(); |
||||||
|
foreach($ids as $id) |
||||||
|
{ |
||||||
|
$uniqueIDs[$id]=$this->generateUniqueKey($id); |
||||||
|
$results[$id]=false; |
||||||
|
} |
||||||
|
$values=$this->getValues($uniqueIDs); |
||||||
|
foreach($uniqueIDs as $id=>$uniqueID) |
||||||
|
{ |
||||||
|
if(!isset($values[$uniqueID])) |
||||||
|
continue; |
||||||
|
$data=$this->autoSerialize ? $this->unserializeValue($values[$uniqueID]) : $values[$uniqueID]; |
||||||
|
if(!$this->autoSerialize || (is_array($data) && (!($data[1] instanceof ICacheDependency) || !$data[1]->getHasChanged()))) |
||||||
|
{ |
||||||
|
Yii::trace('Serving "'.$id.'" from cache','system.caching.'.get_class($this)); |
||||||
|
$results[$id]=$this->autoSerialize ? $data[0] : $data; |
||||||
|
} |
||||||
|
} |
||||||
|
return $results; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Stores a value identified by a key into cache. |
||||||
|
* If the cache already contains such a key, the existing value and |
||||||
|
* expiration time will be replaced with the new ones. |
||||||
|
* |
||||||
|
* @param string $id the key identifying the value to be cached |
||||||
|
* @param mixed $value the value to be cached |
||||||
|
* @param integer $expire the number of seconds in which the cached value will expire. 0 means never expire. |
||||||
|
* @param ICacheDependency $dependency dependency of the cached item. If the dependency changes, the item is labeled invalid. |
||||||
|
* @return boolean true if the value is successfully stored into cache, false otherwise |
||||||
|
*/ |
||||||
|
public function set($id,$value,$expire=0,$dependency=null) |
||||||
|
{ |
||||||
|
Yii::trace('Saving "'.$id.'" to cache','system.caching.'.get_class($this)); |
||||||
|
if($dependency!==null && $this->autoSerialize) |
||||||
|
$dependency->evaluateDependency(); |
||||||
|
$data=$this->autoSerialize ? $this->serializeValue(array($value,$dependency)) : $value; |
||||||
|
return $this->setValue($this->generateUniqueKey($id),$data,$expire); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Stores a value identified by a key into cache if the cache does not contain this key. |
||||||
|
* Nothing will be done if the cache already contains the key. |
||||||
|
* @param string $id the key identifying the value to be cached |
||||||
|
* @param mixed $value the value to be cached |
||||||
|
* @param integer $expire the number of seconds in which the cached value will expire. 0 means never expire. |
||||||
|
* @param ICacheDependency $dependency dependency of the cached item. If the dependency changes, the item is labeled invalid. |
||||||
|
* @return boolean true if the value is successfully stored into cache, false otherwise |
||||||
|
*/ |
||||||
|
public function add($id,$value,$expire=0,$dependency=null) |
||||||
|
{ |
||||||
|
Yii::trace('Adding "'.$id.'" to cache','system.caching.'.get_class($this)); |
||||||
|
if($dependency!==null && $this->autoSerialize) |
||||||
|
$dependency->evaluateDependency(); |
||||||
|
$data=$this->autoSerialize ? $this->serializeValue(array($value,$dependency)) : $value; |
||||||
|
return $this->addValue($this->generateUniqueKey($id),$data,$expire); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Deletes a value with the specified key from cache |
||||||
|
* @param string $id the key of the value to be deleted |
||||||
|
* @return boolean if no error happens during deletion |
||||||
|
*/ |
||||||
|
public function delete($id) |
||||||
|
{ |
||||||
|
Yii::trace('Deleting "'.$id.'" from cache','system.caching.'.get_class($this)); |
||||||
|
return $this->deleteValue($this->generateUniqueKey($id)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Deletes all values from cache. |
||||||
|
* Be careful of performing this operation if the cache is shared by multiple applications. |
||||||
|
* @return boolean whether the flush operation was successful. |
||||||
|
*/ |
||||||
|
public function flush() |
||||||
|
{ |
||||||
|
Yii::trace('Flushing cache','system.caching.'.get_class($this)); |
||||||
|
return $this->flushValues(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Retrieves a value from cache with a specified key. |
||||||
|
* This method should be implemented by child classes to retrieve the data |
||||||
|
* from specific cache storage. The uniqueness and dependency are handled |
||||||
|
* in {@link get()} already. So only the implementation of data retrieval |
||||||
|
* is needed. |
||||||
|
* @param string $key a unique key identifying the cached value |
||||||
|
* @return string the value stored in cache, false if the value is not in the cache or expired. |
||||||
|
* @throws CException if this method is not overridden by child classes |
||||||
|
*/ |
||||||
|
protected function getValue($key) |
||||||
|
{ |
||||||
|
throw new CException(Yii::t('yii','{className} does not support get() functionality.', |
||||||
|
array('{className}'=>get_class($this)))); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Retrieves multiple values from cache with the specified keys. |
||||||
|
* The default implementation simply calls {@link getValue} multiple |
||||||
|
* times to retrieve the cached values one by one. |
||||||
|
* If the underlying cache storage supports multiget, this method should |
||||||
|
* be overridden to exploit that feature. |
||||||
|
* @param array $keys a list of keys identifying the cached values |
||||||
|
* @return array a list of cached values indexed by the keys |
||||||
|
*/ |
||||||
|
protected function getValues($keys) |
||||||
|
{ |
||||||
|
$results=array(); |
||||||
|
foreach($keys as $key) |
||||||
|
$results[$key]=$this->getValue($key); |
||||||
|
return $results; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Stores a value identified by a key in cache. |
||||||
|
* This method should be implemented by child classes to store the data |
||||||
|
* in specific cache storage. The uniqueness and dependency are handled |
||||||
|
* in {@link set()} already. So only the implementation of data storage |
||||||
|
* is needed. |
||||||
|
* |
||||||
|
* @param string $key the key identifying the value to be cached |
||||||
|
* @param string $value the value to be cached |
||||||
|
* @param integer $expire the number of seconds in which the cached value will expire. 0 means never expire. |
||||||
|
* @return boolean true if the value is successfully stored into cache, false otherwise |
||||||
|
* @throws CException if this method is not overridden by child classes |
||||||
|
*/ |
||||||
|
protected function setValue($key,$value,$expire) |
||||||
|
{ |
||||||
|
throw new CException(Yii::t('yii','{className} does not support set() functionality.', |
||||||
|
array('{className}'=>get_class($this)))); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Stores a value identified by a key into cache if the cache does not contain this key. |
||||||
|
* This method should be implemented by child classes to store the data |
||||||
|
* in specific cache storage. The uniqueness and dependency are handled |
||||||
|
* in {@link add()} already. So only the implementation of data storage |
||||||
|
* is needed. |
||||||
|
* |
||||||
|
* @param string $key the key identifying the value to be cached |
||||||
|
* @param string $value the value to be cached |
||||||
|
* @param integer $expire the number of seconds in which the cached value will expire. 0 means never expire. |
||||||
|
* @return boolean true if the value is successfully stored into cache, false otherwise |
||||||
|
* @throws CException if this method is not overridden by child classes |
||||||
|
*/ |
||||||
|
protected function addValue($key,$value,$expire) |
||||||
|
{ |
||||||
|
throw new CException(Yii::t('yii','{className} does not support add() functionality.', |
||||||
|
array('{className}'=>get_class($this)))); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Deletes a value with the specified key from cache |
||||||
|
* This method should be implemented by child classes to delete the data from actual cache storage. |
||||||
|
* @param string $key the key of the value to be deleted |
||||||
|
* @return boolean if no error happens during deletion |
||||||
|
* @throws CException if this method is not overridden by child classes |
||||||
|
*/ |
||||||
|
protected function deleteValue($key) |
||||||
|
{ |
||||||
|
throw new CException(Yii::t('yii','{className} does not support delete() functionality.', |
||||||
|
array('{className}'=>get_class($this)))); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Deletes all values from cache. |
||||||
|
* Child classes may implement this method to realize the flush operation. |
||||||
|
* @return boolean whether the flush operation was successful. |
||||||
|
* @throws CException if this method is not overridden by child classes |
||||||
|
* @since 1.1.5 |
||||||
|
*/ |
||||||
|
protected function flushValues() |
||||||
|
{ |
||||||
|
throw new CException(Yii::t('yii','{className} does not support flushValues() functionality.', |
||||||
|
array('{className}'=>get_class($this)))); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Serializes the value before it will be stored in the actual cache backend. |
||||||
|
* This method will be called if {@link autoSerialize} is set to true. Child classes may override this method to change |
||||||
|
* the way the value is being serialized. The default implementation simply makes use of the PHP serialize() function |
||||||
|
* unless {@link useIgbinarySerializer} is set to true and the igbinary extension is installed. |
||||||
|
* Make sure to override {@link unserializeValue()} as well if you want to change the serialization process. |
||||||
|
* @param mixed $value the unserialized representation of the value |
||||||
|
* @return string the serialized representation of the value |
||||||
|
* @since 1.1.11 |
||||||
|
**/ |
||||||
|
protected function serializeValue($value) |
||||||
|
{ |
||||||
|
if($this->useIgbinarySerializer) |
||||||
|
return igbinary_serialize($value); |
||||||
|
return serialize($value); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Unserializes the value after it was retrieved from the actual cache backend. |
||||||
|
* This method will be called if {@link autoSerialize} is set to true. Child classes may override this method to change |
||||||
|
* the way the value is being unserialized. The default implementation simply makes use of the PHP unserialize() function |
||||||
|
* unless {@link useIgbinarySerializer} is set to true and the igbinary extension is installed. |
||||||
|
* Make sure to override {@link serializeValue()} as well if you want to change the serialization process. |
||||||
|
* @param string $value the serialized representation of the value |
||||||
|
* @return mixed the unserialized representation of the value |
||||||
|
* @since 1.1.11 |
||||||
|
**/ |
||||||
|
protected function unserializeValue($value) |
||||||
|
{ |
||||||
|
if($this->useIgbinarySerializer) |
||||||
|
return igbinary_unserialize($value); |
||||||
|
return unserialize($value); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns whether there is a cache entry with a specified key. |
||||||
|
* This method is required by the interface ArrayAccess. |
||||||
|
* @param string $id a key identifying the cached value |
||||||
|
* @return boolean |
||||||
|
*/ |
||||||
|
public function offsetExists($id) |
||||||
|
{ |
||||||
|
return $this->get($id)!==false; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Retrieves the value from cache with a specified key. |
||||||
|
* This method is required by the interface ArrayAccess. |
||||||
|
* @param string $id a key identifying the cached value |
||||||
|
* @return mixed the value stored in cache, false if the value is not in the cache or expired. |
||||||
|
*/ |
||||||
|
public function offsetGet($id) |
||||||
|
{ |
||||||
|
return $this->get($id); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Stores the value identified by a key into cache. |
||||||
|
* If the cache already contains such a key, the existing value will be |
||||||
|
* replaced with the new ones. To add expiration and dependencies, use the set() method. |
||||||
|
* This method is required by the interface ArrayAccess. |
||||||
|
* @param string $id the key identifying the value to be cached |
||||||
|
* @param mixed $value the value to be cached |
||||||
|
*/ |
||||||
|
public function offsetSet($id, $value) |
||||||
|
{ |
||||||
|
$this->set($id, $value); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Deletes the value with the specified key from cache |
||||||
|
* This method is required by the interface ArrayAccess. |
||||||
|
* @param string $id the key of the value to be deleted |
||||||
|
* @return boolean if no error happens during deletion |
||||||
|
*/ |
||||||
|
public function offsetUnset($id) |
||||||
|
{ |
||||||
|
$this->delete($id); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,98 @@ |
|||||||
|
<?php |
||||||
|
/** |
||||||
|
* CChainedCacheDependency class file. |
||||||
|
* |
||||||
|
* @author Qiang Xue <qiang.xue@gmail.com> |
||||||
|
* @link http://www.yiiframework.com/ |
||||||
|
* @copyright Copyright © 2008-2011 Yii Software LLC |
||||||
|
* @license http://www.yiiframework.com/license/ |
||||||
|
*/ |
||||||
|
|
||||||
|
/** |
||||||
|
* CChainedCacheDependency represents a list of cache dependencies. |
||||||
|
* |
||||||
|
* If any of the dependencies reports a dependency change, CChainedCacheDependency |
||||||
|
* will return true for the checking. |
||||||
|
* |
||||||
|
* To add dependencies to CChainedCacheDependency, use {@link getDependencies Dependencies} |
||||||
|
* which gives a {@link CTypedList} instance and can be used like an array |
||||||
|
* (see {@link CList} for more details}). |
||||||
|
* |
||||||
|
* @property CTypedList $dependencies List of dependency objects. |
||||||
|
* @property boolean $hasChanged Whether the dependency is changed or not. |
||||||
|
* |
||||||
|
* @author Qiang Xue <qiang.xue@gmail.com> |
||||||
|
* @version $Id$ |
||||||
|
* @package system.caching.dependencies |
||||||
|
* @since 1.0 |
||||||
|
*/ |
||||||
|
class CChainedCacheDependency extends CComponent implements ICacheDependency |
||||||
|
{ |
||||||
|
private $_dependencies=null; |
||||||
|
|
||||||
|
/** |
||||||
|
* Constructor. |
||||||
|
* @param array $dependencies the dependencies to be added to this chain. |
||||||
|
* @since 1.1.4 |
||||||
|
*/ |
||||||
|
public function __construct($dependencies=array()) |
||||||
|
{ |
||||||
|
if(!empty($dependencies)) |
||||||
|
$this->setDependencies($dependencies); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @return CTypedList list of dependency objects |
||||||
|
*/ |
||||||
|
public function getDependencies() |
||||||
|
{ |
||||||
|
if($this->_dependencies===null) |
||||||
|
$this->_dependencies=new CTypedList('ICacheDependency'); |
||||||
|
return $this->_dependencies; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param array $values list of dependency objects or configurations to be added to this chain. |
||||||
|
* If a depedency is specified as a configuration, it must be an array that can be recognized |
||||||
|
* by {@link YiiBase::createComponent}. |
||||||
|
*/ |
||||||
|
public function setDependencies($values) |
||||||
|
{ |
||||||
|
$dependencies=$this->getDependencies(); |
||||||
|
foreach($values as $value) |
||||||
|
{ |
||||||
|
if(is_array($value)) |
||||||
|
$value=Yii::createComponent($value); |
||||||
|
$dependencies->add($value); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Evaluates the dependency by generating and saving the data related with dependency. |
||||||
|
*/ |
||||||
|
public function evaluateDependency() |
||||||
|
{ |
||||||
|
if($this->_dependencies!==null) |
||||||
|
{ |
||||||
|
foreach($this->_dependencies as $dependency) |
||||||
|
$dependency->evaluateDependency(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Performs the actual dependency checking. |
||||||
|
* This method returns true if any of the dependency objects |
||||||
|
* reports a dependency change. |
||||||
|
* @return boolean whether the dependency is changed or not. |
||||||
|
*/ |
||||||
|
public function getHasChanged() |
||||||
|
{ |
||||||
|
if($this->_dependencies!==null) |
||||||
|
{ |
||||||
|
foreach($this->_dependencies as $dependency) |
||||||
|
if($dependency->getHasChanged()) |
||||||
|
return true; |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,314 @@ |
|||||||
|
<?php |
||||||
|
/** |
||||||
|
* CDbCache class file |
||||||
|
* |
||||||
|
* @author Qiang Xue <qiang.xue@gmail.com> |
||||||
|
* @link http://www.yiiframework.com/ |
||||||
|
* @copyright Copyright © 2008-2011 Yii Software LLC |
||||||
|
* @license http://www.yiiframework.com/license/ |
||||||
|
*/ |
||||||
|
|
||||||
|
/** |
||||||
|
* CDbCache implements a cache application component by storing cached data in a database. |
||||||
|
* |
||||||
|
* CDbCache stores cache data in a DB table named {@link cacheTableName}. |
||||||
|
* If the table does not exist, it will be automatically created. |
||||||
|
* By setting {@link autoCreateCacheTable} to false, you can also manually create the DB table. |
||||||
|
* |
||||||
|
* CDbCache relies on {@link http://www.php.net/manual/en/ref.pdo.php PDO} to access database. |
||||||
|
* By default, it will use a SQLite3 database under the application runtime directory. |
||||||
|
* You can also specify {@link connectionID} so that it makes use of |
||||||
|
* a DB application component to access database. |
||||||
|
* |
||||||
|
* See {@link CCache} manual for common cache operations that are supported by CDbCache. |
||||||
|
* |
||||||
|
* @property integer $gCProbability The probability (parts per million) that garbage collection (GC) should be performed |
||||||
|
* when storing a piece of data in the cache. Defaults to 100, meaning 0.01% chance. |
||||||
|
* @property CDbConnection $dbConnection The DB connection instance. |
||||||
|
* |
||||||
|
* @author Qiang Xue <qiang.xue@gmail.com> |
||||||
|
* @version $Id$ |
||||||
|
* @package system.caching |
||||||
|
* @since 1.0 |
||||||
|
*/ |
||||||
|
class CDbCache extends CCache |
||||||
|
{ |
||||||
|
/** |
||||||
|
* @var string the ID of the {@link CDbConnection} application component. If not set, |
||||||
|
* a SQLite3 database will be automatically created and used. The SQLite database file |
||||||
|
* is <code>protected/runtime/cache-YiiVersion.db</code>. |
||||||
|
*/ |
||||||
|
public $connectionID; |
||||||
|
/** |
||||||
|
* @var string name of the DB table to store cache content. Defaults to 'YiiCache'. |
||||||
|
* Note, if {@link autoCreateCacheTable} is false and you want to create the DB table |
||||||
|
* manually by yourself, you need to make sure the DB table is of the following structure: |
||||||
|
* <pre> |
||||||
|
* (id CHAR(128) PRIMARY KEY, expire INTEGER, value BLOB) |
||||||
|
* </pre> |
||||||
|
* Note, some DBMS might not support BLOB type. In this case, replace 'BLOB' with a suitable |
||||||
|
* binary data type (e.g. LONGBLOB in MySQL, BYTEA in PostgreSQL.) |
||||||
|
* @see autoCreateCacheTable |
||||||
|
*/ |
||||||
|
public $cacheTableName='YiiCache'; |
||||||
|
/** |
||||||
|
* @var boolean whether the cache DB table should be created automatically if it does not exist. Defaults to true. |
||||||
|
* If you already have the table created, it is recommended you set this property to be false to improve performance. |
||||||
|
* @see cacheTableName |
||||||
|
*/ |
||||||
|
public $autoCreateCacheTable=true; |
||||||
|
/** |
||||||
|
* @var CDbConnection the DB connection instance |
||||||
|
*/ |
||||||
|
private $_db; |
||||||
|
private $_gcProbability=100; |
||||||
|
private $_gced=false; |
||||||
|
|
||||||
|
/** |
||||||
|
* Initializes this application component. |
||||||
|
* |
||||||
|
* This method is required by the {@link IApplicationComponent} interface. |
||||||
|
* It ensures the existence of the cache DB table. |
||||||
|
* It also removes expired data items from the cache. |
||||||
|
*/ |
||||||
|
public function init() |
||||||
|
{ |
||||||
|
parent::init(); |
||||||
|
|
||||||
|
$db=$this->getDbConnection(); |
||||||
|
$db->setActive(true); |
||||||
|
if($this->autoCreateCacheTable) |
||||||
|
{ |
||||||
|
$sql="DELETE FROM {$this->cacheTableName} WHERE expire>0 AND expire<".time(); |
||||||
|
try |
||||||
|
{ |
||||||
|
$db->createCommand($sql)->execute(); |
||||||
|
} |
||||||
|
catch(Exception $e) |
||||||
|
{ |
||||||
|
$this->createCacheTable($db,$this->cacheTableName); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @return integer the probability (parts per million) that garbage collection (GC) should be performed |
||||||
|
* when storing a piece of data in the cache. Defaults to 100, meaning 0.01% chance. |
||||||
|
*/ |
||||||
|
public function getGCProbability() |
||||||
|
{ |
||||||
|
return $this->_gcProbability; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param integer $value the probability (parts per million) that garbage collection (GC) should be performed |
||||||
|
* when storing a piece of data in the cache. Defaults to 100, meaning 0.01% chance. |
||||||
|
* This number should be between 0 and 1000000. A value 0 meaning no GC will be performed at all. |
||||||
|
*/ |
||||||
|
public function setGCProbability($value) |
||||||
|
{ |
||||||
|
$value=(int)$value; |
||||||
|
if($value<0) |
||||||
|
$value=0; |
||||||
|
if($value>1000000) |
||||||
|
$value=1000000; |
||||||
|
$this->_gcProbability=$value; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates the cache DB table. |
||||||
|
* @param CDbConnection $db the database connection |
||||||
|
* @param string $tableName the name of the table to be created |
||||||
|
*/ |
||||||
|
protected function createCacheTable($db,$tableName) |
||||||
|
{ |
||||||
|
$driver=$db->getDriverName(); |
||||||
|
if($driver==='mysql') |
||||||
|
$blob='LONGBLOB'; |
||||||
|
else if($driver==='pgsql') |
||||||
|
$blob='BYTEA'; |
||||||
|
else |
||||||
|
$blob='BLOB'; |
||||||
|
$sql=<<<EOD |
||||||
|
CREATE TABLE $tableName |
||||||
|
( |
||||||
|
id CHAR(128) PRIMARY KEY, |
||||||
|
expire INTEGER, |
||||||
|
value $blob |
||||||
|
) |
||||||
|
EOD; |
||||||
|
$db->createCommand($sql)->execute(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @return CDbConnection the DB connection instance |
||||||
|
* @throws CException if {@link connectionID} does not point to a valid application component. |
||||||
|
*/ |
||||||
|
public function getDbConnection() |
||||||
|
{ |
||||||
|
if($this->_db!==null) |
||||||
|
return $this->_db; |
||||||
|
else if(($id=$this->connectionID)!==null) |
||||||
|
{ |
||||||
|
if(($this->_db=Yii::app()->getComponent($id)) instanceof CDbConnection) |
||||||
|
return $this->_db; |
||||||
|
else |
||||||
|
throw new CException(Yii::t('yii','CDbCache.connectionID "{id}" is invalid. Please make sure it refers to the ID of a CDbConnection application component.', |
||||||
|
array('{id}'=>$id))); |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
$dbFile=Yii::app()->getRuntimePath().DIRECTORY_SEPARATOR.'cache-'.Yii::getVersion().'.db'; |
||||||
|
return $this->_db=new CDbConnection('sqlite:'.$dbFile); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Sets the DB connection used by the cache component. |
||||||
|
* @param CDbConnection $value the DB connection instance |
||||||
|
* @since 1.1.5 |
||||||
|
*/ |
||||||
|
public function setDbConnection($value) |
||||||
|
{ |
||||||
|
$this->_db=$value; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Retrieves a value from cache with a specified key. |
||||||
|
* This is the implementation of the method declared in the parent class. |
||||||
|
* @param string $key a unique key identifying the cached value |
||||||
|
* @return string the value stored in cache, false if the value is not in the cache or expired. |
||||||
|
*/ |
||||||
|
protected function getValue($key) |
||||||
|
{ |
||||||
|
$time=time(); |
||||||
|
$sql="SELECT value FROM {$this->cacheTableName} WHERE id='$key' AND (expire=0 OR expire>$time)"; |
||||||
|
$db=$this->getDbConnection(); |
||||||
|
if($db->queryCachingDuration>0) |
||||||
|
{ |
||||||
|
$duration=$db->queryCachingDuration; |
||||||
|
$db->queryCachingDuration=0; |
||||||
|
$result=$db->createCommand($sql)->queryScalar(); |
||||||
|
$db->queryCachingDuration=$duration; |
||||||
|
return $result; |
||||||
|
} |
||||||
|
else |
||||||
|
return $db->createCommand($sql)->queryScalar(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Retrieves multiple values from cache with the specified keys. |
||||||
|
* @param array $keys a list of keys identifying the cached values |
||||||
|
* @return array a list of cached values indexed by the keys |
||||||
|
*/ |
||||||
|
protected function getValues($keys) |
||||||
|
{ |
||||||
|
if(empty($keys)) |
||||||
|
return array(); |
||||||
|
|
||||||
|
$ids=implode("','",$keys); |
||||||
|
$time=time(); |
||||||
|
$sql="SELECT id, value FROM {$this->cacheTableName} WHERE id IN ('$ids') AND (expire=0 OR expire>$time)"; |
||||||
|
|
||||||
|
$db=$this->getDbConnection(); |
||||||
|
if($db->queryCachingDuration>0) |
||||||
|
{ |
||||||
|
$duration=$db->queryCachingDuration; |
||||||
|
$db->queryCachingDuration=0; |
||||||
|
$rows=$db->createCommand($sql)->queryAll(); |
||||||
|
$db->queryCachingDuration=$duration; |
||||||
|
} |
||||||
|
else |
||||||
|
$rows=$db->createCommand($sql)->queryAll(); |
||||||
|
|
||||||
|
$results=array(); |
||||||
|
foreach($keys as $key) |
||||||
|
$results[$key]=false; |
||||||
|
foreach($rows as $row) |
||||||
|
$results[$row['id']]=$row['value']; |
||||||
|
return $results; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Stores a value identified by a key in cache. |
||||||
|
* This is the implementation of the method declared in the parent class. |
||||||
|
* |
||||||
|
* @param string $key the key identifying the value to be cached |
||||||
|
* @param string $value the value to be cached |
||||||
|
* @param integer $expire the number of seconds in which the cached value will expire. 0 means never expire. |
||||||
|
* @return boolean true if the value is successfully stored into cache, false otherwise |
||||||
|
*/ |
||||||
|
protected function setValue($key,$value,$expire) |
||||||
|
{ |
||||||
|
$this->deleteValue($key); |
||||||
|
return $this->addValue($key,$value,$expire); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Stores a value identified by a key into cache if the cache does not contain this key. |
||||||
|
* This is the implementation of the method declared in the parent class. |
||||||
|
* |
||||||
|
* @param string $key the key identifying the value to be cached |
||||||
|
* @param string $value the value to be cached |
||||||
|
* @param integer $expire the number of seconds in which the cached value will expire. 0 means never expire. |
||||||
|
* @return boolean true if the value is successfully stored into cache, false otherwise |
||||||
|
*/ |
||||||
|
protected function addValue($key,$value,$expire) |
||||||
|
{ |
||||||
|
if(!$this->_gced && mt_rand(0,1000000)<$this->_gcProbability) |
||||||
|
{ |
||||||
|
$this->gc(); |
||||||
|
$this->_gced=true; |
||||||
|
} |
||||||
|
|
||||||
|
if($expire>0) |
||||||
|
$expire+=time(); |
||||||
|
else |
||||||
|
$expire=0; |
||||||
|
$sql="INSERT INTO {$this->cacheTableName} (id,expire,value) VALUES ('$key',$expire,:value)"; |
||||||
|
try |
||||||
|
{ |
||||||
|
$command=$this->getDbConnection()->createCommand($sql); |
||||||
|
$command->bindValue(':value',$value,PDO::PARAM_LOB); |
||||||
|
$command->execute(); |
||||||
|
return true; |
||||||
|
} |
||||||
|
catch(Exception $e) |
||||||
|
{ |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Deletes a value with the specified key from cache |
||||||
|
* This is the implementation of the method declared in the parent class. |
||||||
|
* @param string $key the key of the value to be deleted |
||||||
|
* @return boolean if no error happens during deletion |
||||||
|
*/ |
||||||
|
protected function deleteValue($key) |
||||||
|
{ |
||||||
|
$sql="DELETE FROM {$this->cacheTableName} WHERE id='$key'"; |
||||||
|
$this->getDbConnection()->createCommand($sql)->execute(); |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Removes the expired data values. |
||||||
|
*/ |
||||||
|
protected function gc() |
||||||
|
{ |
||||||
|
$this->getDbConnection()->createCommand("DELETE FROM {$this->cacheTableName} WHERE expire>0 AND expire<".time())->execute(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Deletes all values from cache. |
||||||
|
* This is the implementation of the method declared in the parent class. |
||||||
|
* @return boolean whether the flush operation was successful. |
||||||
|
* @since 1.1.5 |
||||||
|
*/ |
||||||
|
protected function flushValues() |
||||||
|
{ |
||||||
|
$this->getDbConnection()->createCommand("DELETE FROM {$this->cacheTableName}")->execute(); |
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,112 @@ |
|||||||
|
<?php |
||||||
|
/** |
||||||
|
* CDbCacheDependency class file. |
||||||
|
* |
||||||
|
* @author Qiang Xue <qiang.xue@gmail.com> |
||||||
|
* @link http://www.yiiframework.com/ |
||||||
|
* @copyright Copyright © 2008-2011 Yii Software LLC |
||||||
|
* @license http://www.yiiframework.com/license/ |
||||||
|
*/ |
||||||
|
|
||||||
|
/** |
||||||
|
* CDbCacheDependency represents a dependency based on the query result of a SQL statement. |
||||||
|
* |
||||||
|
* If the query result (a scalar) changes, the dependency is considered as changed. |
||||||
|
* To specify the SQL statement, set {@link sql} property. |
||||||
|
* The {@link connectionID} property specifies the ID of a {@link CDbConnection} application |
||||||
|
* component. It is this DB connection that is used to perform the query. |
||||||
|
* |
||||||
|
* @author Qiang Xue <qiang.xue@gmail.com> |
||||||
|
* @version $Id$ |
||||||
|
* @package system.caching.dependencies |
||||||
|
* @since 1.0 |
||||||
|
*/ |
||||||
|
class CDbCacheDependency extends CCacheDependency |
||||||
|
{ |
||||||
|
/** |
||||||
|
* @var string the ID of a {@link CDbConnection} application component. Defaults to 'db'. |
||||||
|
*/ |
||||||
|
public $connectionID='db'; |
||||||
|
/** |
||||||
|
* @var string the SQL statement whose result is used to determine if the dependency has been changed. |
||||||
|
* Note, the SQL statement should return back a single value. |
||||||
|
*/ |
||||||
|
public $sql; |
||||||
|
/** |
||||||
|
* @var array parameters (name=>value) to be bound to the SQL statement specified by {@link sql}. |
||||||
|
* @since 1.1.4 |
||||||
|
*/ |
||||||
|
public $params; |
||||||
|
|
||||||
|
private $_db; |
||||||
|
|
||||||
|
/** |
||||||
|
* Constructor. |
||||||
|
* @param string $sql the SQL statement whose result is used to determine if the dependency has been changed. |
||||||
|
*/ |
||||||
|
public function __construct($sql=null) |
||||||
|
{ |
||||||
|
$this->sql=$sql; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* PHP sleep magic method. |
||||||
|
* This method ensures that the database instance is set null because it contains resource handles. |
||||||
|
* @return array |
||||||
|
*/ |
||||||
|
public function __sleep() |
||||||
|
{ |
||||||
|
$this->_db=null; |
||||||
|
return array_keys((array)$this); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Generates the data needed to determine if dependency has been changed. |
||||||
|
* This method returns the value of the global state. |
||||||
|
* @return mixed the data needed to determine if dependency has been changed. |
||||||
|
*/ |
||||||
|
protected function generateDependentData() |
||||||
|
{ |
||||||
|
if($this->sql!==null) |
||||||
|
{ |
||||||
|
$db=$this->getDbConnection(); |
||||||
|
$command=$db->createCommand($this->sql); |
||||||
|
if(is_array($this->params)) |
||||||
|
{ |
||||||
|
foreach($this->params as $name=>$value) |
||||||
|
$command->bindValue($name,$value); |
||||||
|
} |
||||||
|
if($db->queryCachingDuration>0) |
||||||
|
{ |
||||||
|
// temporarily disable and re-enable query caching |
||||||
|
$duration=$db->queryCachingDuration; |
||||||
|
$db->queryCachingDuration=0; |
||||||
|
$result=$command->queryRow(); |
||||||
|
$db->queryCachingDuration=$duration; |
||||||
|
} |
||||||
|
else |
||||||
|
$result=$command->queryRow(); |
||||||
|
return $result; |
||||||
|
} |
||||||
|
else |
||||||
|
throw new CException(Yii::t('yii','CDbCacheDependency.sql cannot be empty.')); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @return CDbConnection the DB connection instance |
||||||
|
* @throws CException if {@link connectionID} does not point to a valid application component. |
||||||
|
*/ |
||||||
|
protected function getDbConnection() |
||||||
|
{ |
||||||
|
if($this->_db!==null) |
||||||
|
return $this->_db; |
||||||
|
else |
||||||
|
{ |
||||||
|
if(($this->_db=Yii::app()->getComponent($this->connectionID)) instanceof CDbConnection) |
||||||
|
return $this->_db; |
||||||
|
else |
||||||
|
throw new CException(Yii::t('yii','CDbCacheDependency.connectionID "{id}" is invalid. Please make sure it refers to the ID of a CDbConnection application component.', |
||||||
|
array('{id}'=>$this->connectionID))); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,113 @@ |
|||||||
|
<?php |
||||||
|
/** |
||||||
|
* CCacheDependency class file. |
||||||
|
* |
||||||
|
* @author Qiang Xue <qiang.xue@gmail.com> |
||||||
|
* @link http://www.yiiframework.com/ |
||||||
|
* @copyright Copyright © 2008-2011 Yii Software LLC |
||||||
|
* @license http://www.yiiframework.com/license/ |
||||||
|
*/ |
||||||
|
|
||||||
|
/** |
||||||
|
* CCacheDependency is the base class for cache dependency classes. |
||||||
|
* |
||||||
|
* CCacheDependency implements the {@link ICacheDependency} interface. |
||||||
|
* Child classes should override its {@link generateDependentData} for |
||||||
|
* actual dependency checking. |
||||||
|
* |
||||||
|
* @property boolean $hasChanged Whether the dependency has changed. |
||||||
|
* @property mixed $dependentData The data used to determine if dependency has been changed. |
||||||
|
* This data is available after {@link evaluateDependency} is called. |
||||||
|
* |
||||||
|
* @author Qiang Xue <qiang.xue@gmail.com> |
||||||
|
* @version $Id$ |
||||||
|
* @package system.caching.dependencies |
||||||
|
* @since 1.0 |
||||||
|
*/ |
||||||
|
class CCacheDependency extends CComponent implements ICacheDependency |
||||||
|
{ |
||||||
|
/** |
||||||
|
* @var boolean Whether this dependency is reusable or not. |
||||||
|
* If set to true, dependent data for this cache dependency will only be generated once per request. |
||||||
|
* You can then use the same cache dependency for multiple separate cache calls on the same page |
||||||
|
* without the overhead of re-evaluating the dependency each time. |
||||||
|
* Defaults to false; |
||||||
|
* @since 1.1.11 |
||||||
|
*/ |
||||||
|
public $reuseDependentData=false; |
||||||
|
|
||||||
|
/** |
||||||
|
* @var array cached data for reusable dependencies. |
||||||
|
* @since 1.1.11 |
||||||
|
*/ |
||||||
|
private static $_reusableData=array(); |
||||||
|
|
||||||
|
private $_hash; |
||||||
|
private $_data; |
||||||
|
|
||||||
|
/** |
||||||
|
* Evaluates the dependency by generating and saving the data related with dependency. |
||||||
|
* This method is invoked by cache before writing data into it. |
||||||
|
*/ |
||||||
|
public function evaluateDependency() |
||||||
|
{ |
||||||
|
if ($this->reuseDependentData) |
||||||
|
{ |
||||||
|
$hash=$this->getHash(); |
||||||
|
if (!isset(self::$_reusableData[$hash]['dependentData'])) |
||||||
|
self::$_reusableData[$hash]['dependentData']=$this->generateDependentData(); |
||||||
|
$this->_data=self::$_reusableData[$hash]['dependentData']; |
||||||
|
} |
||||||
|
else |
||||||
|
$this->_data=$this->generateDependentData(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @return boolean whether the dependency has changed. |
||||||
|
*/ |
||||||
|
public function getHasChanged() |
||||||
|
{ |
||||||
|
if ($this->reuseDependentData) |
||||||
|
{ |
||||||
|
$hash=$this->getHash(); |
||||||
|
if (!isset(self::$_reusableData[$hash]['hasChanged'])) |
||||||
|
{ |
||||||
|
if (!isset(self::$_reusableData[$hash]['dependentData'])) |
||||||
|
self::$_reusableData[$hash]['dependentData']=$this->generateDependentData(); |
||||||
|
self::$_reusableData[$hash]['hasChanged']=self::$_reusableData[$hash]['dependentData']!=$this->_data; |
||||||
|
} |
||||||
|
return self::$_reusableData[$hash]['hasChanged']; |
||||||
|
} |
||||||
|
else |
||||||
|
return $this->generateDependentData()!=$this->_data; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @return mixed the data used to determine if dependency has been changed. |
||||||
|
* This data is available after {@link evaluateDependency} is called. |
||||||
|
*/ |
||||||
|
public function getDependentData() |
||||||
|
{ |
||||||
|
return $this->_data; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Generates the data needed to determine if dependency has been changed. |
||||||
|
* Derived classes should override this method to generate actual dependent data. |
||||||
|
* @return mixed the data needed to determine if dependency has been changed. |
||||||
|
*/ |
||||||
|
protected function generateDependentData() |
||||||
|
{ |
||||||
|
return null; |
||||||
|
} |
||||||
|
/** |
||||||
|
* Generates a unique hash that identifies this cache dependency. |
||||||
|
* @return string the hash for this cache dependency |
||||||
|
*/ |
||||||
|
private function getHash() |
||||||
|
{ |
||||||
|
if($this->_hash===null) |
||||||
|
$this->_hash=sha1(serialize($this)); |
||||||
|
return $this->_hash; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,134 @@ |
|||||||
|
<?php |
||||||
|
/** |
||||||
|
* CDirectoryCacheDependency class file. |
||||||
|
* |
||||||
|
* @author Qiang Xue <qiang.xue@gmail.com> |
||||||
|
* @link http://www.yiiframework.com/ |
||||||
|
* @copyright Copyright © 2008-2011 Yii Software LLC |
||||||
|
* @license http://www.yiiframework.com/license/ |
||||||
|
*/ |
||||||
|
|
||||||
|
/** |
||||||
|
* CDirectoryCacheDependency represents a dependency based on change of a directory. |
||||||
|
* |
||||||
|
* CDirectoryCacheDependency performs dependency checking based on the |
||||||
|
* modification time of the files contained in the specified directory. |
||||||
|
* The directory being checked is specified via {@link directory}. |
||||||
|
* |
||||||
|
* By default, all files under the specified directory and subdirectories |
||||||
|
* will be checked. If the last modification time of any of them is changed |
||||||
|
* or if different number of files are contained in a directory, the dependency |
||||||
|
* is reported as changed. By specifying {@link recursiveLevel}, |
||||||
|
* one can limit the checking to a certain depth of the directory. |
||||||
|
* |
||||||
|
* Note, dependency checking for a directory is expensive because it involves |
||||||
|
* accessing modification time of multiple files under the directory. |
||||||
|
* |
||||||
|
* @author Qiang Xue <qiang.xue@gmail.com> |
||||||
|
* @version $Id$ |
||||||
|
* @package system.caching.dependencies |
||||||
|
* @since 1.0 |
||||||
|
*/ |
||||||
|
class CDirectoryCacheDependency extends CCacheDependency |
||||||
|
{ |
||||||
|
/** |
||||||
|
* @var string the directory whose change is used to determine if the dependency has been changed. |
||||||
|
* If any of the files under the directory is changed, the dependency is considered as changed. |
||||||
|
*/ |
||||||
|
public $directory; |
||||||
|
/** |
||||||
|
* @var integer the depth of the subdirectories to be recursively checked. |
||||||
|
* If the value is less than 0, it means unlimited depth. |
||||||
|
* If the value is 0, it means checking the files directly under the specified directory. |
||||||
|
*/ |
||||||
|
public $recursiveLevel=-1; |
||||||
|
/** |
||||||
|
* @var string the regular expression matching valid file/directory names. |
||||||
|
* Only the matching files or directories will be checked for changes. |
||||||
|
* Defaults to null, meaning all files/directories will qualify. |
||||||
|
*/ |
||||||
|
public $namePattern; |
||||||
|
|
||||||
|
/** |
||||||
|
* Constructor. |
||||||
|
* @param string $directory the directory to be checked |
||||||
|
*/ |
||||||
|
public function __construct($directory=null) |
||||||
|
{ |
||||||
|
$this->directory=$directory; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Generates the data needed to determine if dependency has been changed. |
||||||
|
* This method returns the modification timestamps for files under the directory. |
||||||
|
* @return mixed the data needed to determine if dependency has been changed. |
||||||
|
*/ |
||||||
|
protected function generateDependentData() |
||||||
|
{ |
||||||
|
if($this->directory!==null) |
||||||
|
return $this->generateTimestamps($this->directory); |
||||||
|
else |
||||||
|
throw new CException(Yii::t('yii','CDirectoryCacheDependency.directory cannot be empty.')); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Determines the last modification time for files under the directory. |
||||||
|
* This method may go recursively into subdirectories if {@link recursiveLevel} is not 0. |
||||||
|
* @param string $directory the directory name |
||||||
|
* @param integer $level level of the recursion |
||||||
|
* @return array list of file modification time indexed by the file path |
||||||
|
*/ |
||||||
|
protected function generateTimestamps($directory,$level=0) |
||||||
|
{ |
||||||
|
if(($dir=@opendir($directory))===false) |
||||||
|
throw new CException(Yii::t('yii','"{path}" is not a valid directory.', |
||||||
|
array('{path}'=>$directory))); |
||||||
|
$timestamps=array(); |
||||||
|
while(($file=readdir($dir))!==false) |
||||||
|
{ |
||||||
|
$path=$directory.DIRECTORY_SEPARATOR.$file; |
||||||
|
if($file==='.' || $file==='..') |
||||||
|
continue; |
||||||
|
if($this->namePattern!==null && !preg_match($this->namePattern,$file)) |
||||||
|
continue; |
||||||
|
if(is_file($path)) |
||||||
|
{ |
||||||
|
if($this->validateFile($path)) |
||||||
|
$timestamps[$path]=filemtime($path); |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
if(($this->recursiveLevel<0 || $level<$this->recursiveLevel) && $this->validateDirectory($path)) |
||||||
|
$timestamps=array_merge($timestamps, $this->generateTimestamps($path,$level+1)); |
||||||
|
} |
||||||
|
} |
||||||
|
closedir($dir); |
||||||
|
return $timestamps; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Checks to see if the file should be checked for dependency. |
||||||
|
* This method is invoked when dependency of the whole directory is being checked. |
||||||
|
* By default, it always returns true, meaning the file should be checked. |
||||||
|
* You may override this method to check only certain files. |
||||||
|
* @param string $fileName the name of the file that may be checked for dependency. |
||||||
|
* @return boolean whether this file should be checked. |
||||||
|
*/ |
||||||
|
protected function validateFile($fileName) |
||||||
|
{ |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Checks to see if the specified subdirectory should be checked for dependency. |
||||||
|
* This method is invoked when dependency of the whole directory is being checked. |
||||||
|
* By default, it always returns true, meaning the subdirectory should be checked. |
||||||
|
* You may override this method to check only certain subdirectories. |
||||||
|
* @param string $directory the name of the subdirectory that may be checked for dependency. |
||||||
|
* @return boolean whether this subdirectory should be checked. |
||||||
|
*/ |
||||||
|
protected function validateDirectory($directory) |
||||||
|
{ |
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,164 @@ |
|||||||
|
<?php |
||||||
|
/** |
||||||
|
* CDummyCache class file. |
||||||
|
* |
||||||
|
* @author Qiang Xue <qiang.xue@gmail.com> |
||||||
|
* @link http://www.yiiframework.com/ |
||||||
|
* @copyright Copyright © 2008-2011 Yii Software LLC |
||||||
|
* @license http://www.yiiframework.com/license/ |
||||||
|
*/ |
||||||
|
|
||||||
|
/** |
||||||
|
* CDummyCache is a placeholder cache component. |
||||||
|
* |
||||||
|
* CDummyCache does not cache anything. It is provided so that one can always configure |
||||||
|
* a 'cache' application component and he does not need to check if Yii::app()->cache is null or not. |
||||||
|
* By replacing CDummyCache with some other cache component, one can quickly switch from |
||||||
|
* non-caching mode to caching mode. |
||||||
|
* |
||||||
|
* @author Qiang Xue <qiang.xue@gmail.com> |
||||||
|
* @version $Id$ |
||||||
|
* @package system.caching |
||||||
|
* @since 1.0 |
||||||
|
*/ |
||||||
|
class CDummyCache extends CApplicationComponent implements ICache, ArrayAccess |
||||||
|
{ |
||||||
|
/** |
||||||
|
* @var string a string prefixed to every cache key so that it is unique. Defaults to {@link CApplication::getId() application ID}. |
||||||
|
*/ |
||||||
|
public $keyPrefix; |
||||||
|
|
||||||
|
/** |
||||||
|
* Initializes the application component. |
||||||
|
* This method overrides the parent implementation by setting default cache key prefix. |
||||||
|
*/ |
||||||
|
public function init() |
||||||
|
{ |
||||||
|
parent::init(); |
||||||
|
if($this->keyPrefix===null) |
||||||
|
$this->keyPrefix=Yii::app()->getId(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Retrieves a value from cache with a specified key. |
||||||
|
* @param string $id a 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 has changed. |
||||||
|
*/ |
||||||
|
public function get($id) |
||||||
|
{ |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Retrieves multiple values from cache with the specified keys. |
||||||
|
* Some caches (such as memcache, apc) allow retrieving multiple cached values at one time, |
||||||
|
* which may improve the performance since it reduces the communication cost. |
||||||
|
* In case a cache doesn't support this feature natively, it will be simulated by this method. |
||||||
|
* @param array $ids list of keys identifying the cached values |
||||||
|
* @return array list of cached values corresponding to the specified keys. The array |
||||||
|
* is returned in terms of (key,value) pairs. |
||||||
|
* If a value is not cached or expired, the corresponding array value will be false. |
||||||
|
*/ |
||||||
|
public function mget($ids) |
||||||
|
{ |
||||||
|
$results=array(); |
||||||
|
foreach($ids as $id) |
||||||
|
$results[$id]=false; |
||||||
|
return $results; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Stores a value identified by a key into cache. |
||||||
|
* If the cache already contains such a key, the existing value and |
||||||
|
* expiration time will be replaced with the new ones. |
||||||
|
* |
||||||
|
* @param string $id the key identifying the value to be cached |
||||||
|
* @param mixed $value the value to be cached |
||||||
|
* @param integer $expire the number of seconds in which the cached value will expire. 0 means never expire. |
||||||
|
* @param ICacheDependency $dependency dependency of the cached item. If the dependency changes, the item is labeled invalid. |
||||||
|
* @return boolean true if the value is successfully stored into cache, false otherwise |
||||||
|
*/ |
||||||
|
public function set($id,$value,$expire=0,$dependency=null) |
||||||
|
{ |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Stores a value identified by a key into cache if the cache does not contain this key. |
||||||
|
* Nothing will be done if the cache already contains the key. |
||||||
|
* @param string $id the key identifying the value to be cached |
||||||
|
* @param mixed $value the value to be cached |
||||||
|
* @param integer $expire the number of seconds in which the cached value will expire. 0 means never expire. |
||||||
|
* @param ICacheDependency $dependency dependency of the cached item. If the dependency changes, the item is labeled invalid. |
||||||
|
* @return boolean true if the value is successfully stored into cache, false otherwise |
||||||
|
*/ |
||||||
|
public function add($id,$value,$expire=0,$dependency=null) |
||||||
|
{ |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Deletes a value with the specified key from cache |
||||||
|
* @param string $id the key of the value to be deleted |
||||||
|
* @return boolean if no error happens during deletion |
||||||
|
*/ |
||||||
|
public function delete($id) |
||||||
|
{ |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Deletes all values from cache. |
||||||
|
* Be careful of performing this operation if the cache is shared by multiple applications. |
||||||
|
* @return boolean whether the flush operation was successful. |
||||||
|
* @throws CException if this method is not overridden by child classes |
||||||
|
*/ |
||||||
|
public function flush() |
||||||
|
{ |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns whether there is a cache entry with a specified key. |
||||||
|
* This method is required by the interface ArrayAccess. |
||||||
|
* @param string $id a key identifying the cached value |
||||||
|
* @return boolean |
||||||
|
*/ |
||||||
|
public function offsetExists($id) |
||||||
|
{ |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Retrieves the value from cache with a specified key. |
||||||
|
* This method is required by the interface ArrayAccess. |
||||||
|
* @param string $id a key identifying the cached value |
||||||
|
* @return mixed the value stored in cache, false if the value is not in the cache or expired. |
||||||
|
*/ |
||||||
|
public function offsetGet($id) |
||||||
|
{ |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Stores the value identified by a key into cache. |
||||||
|
* If the cache already contains such a key, the existing value will be |
||||||
|
* replaced with the new ones. To add expiration and dependencies, use the set() method. |
||||||
|
* This method is required by the interface ArrayAccess. |
||||||
|
* @param string $id the key identifying the value to be cached |
||||||
|
* @param mixed $value the value to be cached |
||||||
|
*/ |
||||||
|
public function offsetSet($id, $value) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Deletes the value with the specified key from cache |
||||||
|
* This method is required by the interface ArrayAccess. |
||||||
|
* @param string $id the key of the value to be deleted |
||||||
|
* @return boolean if no error happens during deletion |
||||||
|
*/ |
||||||
|
public function offsetUnset($id) |
||||||
|
{ |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,107 @@ |
|||||||
|
<?php |
||||||
|
/** |
||||||
|
* CEAcceleratorCache class file |
||||||
|
* |
||||||
|
* @author Steffen Dietz <steffo.dietz[at]googlemail[dot]com> |
||||||
|
* @link http://www.yiiframework.com/ |
||||||
|
* @copyright Copyright © 2008-2011 Yii Software LLC |
||||||
|
* @license http://www.yiiframework.com/license/ |
||||||
|
*/ |
||||||
|
|
||||||
|
/** |
||||||
|
* CEAcceleratorCache implements a cache application module based on {@link http://eaccelerator.net/ eaccelerator}. |
||||||
|
* |
||||||
|
* To use this application component, the eAccelerator PHP extension must be loaded. |
||||||
|
* |
||||||
|
* See {@link CCache} manual for common cache operations that are supported by CEAccelerator. |
||||||
|
* |
||||||
|
* Please note that as of v0.9.6, eAccelerator no longer supports data caching. |
||||||
|
* This means if you still want to use this component, your eAccelerator should be of 0.9.5.x or lower version. |
||||||
|
* |
||||||
|
* @author Steffen Dietz <steffo.dietz[at]googlemail[dot]com> |
||||||
|
* @version $Id$ |
||||||
|
* @package system.caching |
||||||
|
*/ |
||||||
|
class CEAcceleratorCache extends CCache |
||||||
|
{ |
||||||
|
/** |
||||||
|
* Initializes this application component. |
||||||
|
* This method is required by the {@link IApplicationComponent} interface. |
||||||
|
* It checks the availability of eAccelerator. |
||||||
|
* @throws CException if eAccelerator extension is not loaded, is disabled or the cache functions are not compiled in. |
||||||
|
*/ |
||||||
|
public function init() |
||||||
|
{ |
||||||
|
parent::init(); |
||||||
|
if(!function_exists('eaccelerator_get')) |
||||||
|
throw new CException(Yii::t('yii','CEAcceleratorCache requires PHP eAccelerator extension to be loaded, enabled or compiled with the "--with-eaccelerator-shared-memory" option.')); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Retrieves a value from cache with a specified key. |
||||||
|
* This is the implementation of the method declared in the parent class. |
||||||
|
* @param string $key a unique key identifying the cached value |
||||||
|
* @return string the value stored in cache, false if the value is not in the cache or expired. |
||||||
|
*/ |
||||||
|
protected function getValue($key) |
||||||
|
{ |
||||||
|
$result = eaccelerator_get($key); |
||||||
|
return $result !== NULL ? $result : false; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Stores a value identified by a key in cache. |
||||||
|
* This is the implementation of the method declared in the parent class. |
||||||
|
* |
||||||
|
* @param string $key the key identifying the value to be cached |
||||||
|
* @param string $value the value to be cached |
||||||
|
* @param integer $expire the number of seconds in which the cached value will expire. 0 means never expire. |
||||||
|
* @return boolean true if the value is successfully stored into cache, false otherwise |
||||||
|
*/ |
||||||
|
protected function setValue($key,$value,$expire) |
||||||
|
{ |
||||||
|
return eaccelerator_put($key,$value,$expire); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Stores a value identified by a key into cache if the cache does not contain this key. |
||||||
|
* This is the implementation of the method declared in the parent class. |
||||||
|
* |
||||||
|
* @param string $key the key identifying the value to be cached |
||||||
|
* @param string $value the value to be cached |
||||||
|
* @param integer $expire the number of seconds in which the cached value will expire. 0 means never expire. |
||||||
|
* @return boolean true if the value is successfully stored into cache, false otherwise |
||||||
|
*/ |
||||||
|
protected function addValue($key,$value,$expire) |
||||||
|
{ |
||||||
|
return (NULL === eaccelerator_get($key)) ? $this->setValue($key,$value,$expire) : false; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Deletes a value with the specified key from cache |
||||||
|
* This is the implementation of the method declared in the parent class. |
||||||
|
* @param string $key the key of the value to be deleted |
||||||
|
* @return boolean if no error happens during deletion |
||||||
|
*/ |
||||||
|
protected function deleteValue($key) |
||||||
|
{ |
||||||
|
return eaccelerator_rm($key); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Deletes all values from cache. |
||||||
|
* This is the implementation of the method declared in the parent class. |
||||||
|
* @return boolean whether the flush operation was successful. |
||||||
|
* @since 1.1.5 |
||||||
|
*/ |
||||||
|
protected function flushValues() |
||||||
|
{ |
||||||
|
// first, remove expired content from cache |
||||||
|
eaccelerator_gc(); |
||||||
|
// now, remove leftover cache-keys |
||||||
|
$keys = eaccelerator_list_keys(); |
||||||
|
foreach($keys as $key) |
||||||
|
$this->deleteValue(substr($key['name'], 1)); |
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,53 @@ |
|||||||
|
<?php |
||||||
|
/** |
||||||
|
* CExpressionDependency class file. |
||||||
|
* |
||||||
|
* @author Qiang Xue <qiang.xue@gmail.com> |
||||||
|
* @link http://www.yiiframework.com/ |
||||||
|
* @copyright Copyright © 2008-2011 Yii Software LLC |
||||||
|
* @license http://www.yiiframework.com/license/ |
||||||
|
*/ |
||||||
|
|
||||||
|
/** |
||||||
|
* CExpressionDependency represents a dependency based on the result of a PHP expression. |
||||||
|
* |
||||||
|
* CExpressionDependency performs dependency checking based on the |
||||||
|
* result of a PHP {@link expression}. |
||||||
|
* The dependency is reported as unchanged if and only if the result is |
||||||
|
* the same as the one evaluated when storing the data to cache. |
||||||
|
* |
||||||
|
* @author Qiang Xue <qiang.xue@gmail.com> |
||||||
|
* @version $Id$ |
||||||
|
* @package system.caching.dependencies |
||||||
|
* @since 1.0 |
||||||
|
*/ |
||||||
|
class CExpressionDependency extends CCacheDependency |
||||||
|
{ |
||||||
|
/** |
||||||
|
* @var string the PHP expression whose result is used to determine the dependency. |
||||||
|
* The expression can also be a valid PHP callback, |
||||||
|
* including class method name (array(ClassName/Object, MethodName)), |
||||||
|
* or anonymous function (PHP 5.3.0+). The function/method will be passed with a |
||||||
|
* parameter which is the dependency object itself. |
||||||
|
*/ |
||||||
|
public $expression; |
||||||
|
|
||||||
|
/** |
||||||
|
* Constructor. |
||||||
|
* @param string $expression the PHP expression whose result is used to determine the dependency. |
||||||
|
*/ |
||||||
|
public function __construct($expression='true') |
||||||
|
{ |
||||||
|
$this->expression=$expression; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Generates the data needed to determine if dependency has been changed. |
||||||
|
* This method returns the result of the PHP expression. |
||||||
|
* @return mixed the data needed to determine if dependency has been changed. |
||||||
|
*/ |
||||||
|
protected function generateDependentData() |
||||||
|
{ |
||||||
|
return $this->evaluateExpression($this->expression); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,222 @@ |
|||||||
|
<?php |
||||||
|
/** |
||||||
|
* CFileCache class file |
||||||
|
* |
||||||
|
* @author Qiang Xue <qiang.xue@gmail.com> |
||||||
|
* @link http://www.yiiframework.com/ |
||||||
|
* @copyright Copyright © 2008-2011 Yii Software LLC |
||||||
|
* @license http://www.yiiframework.com/license/ |
||||||
|
*/ |
||||||
|
|
||||||
|
/** |
||||||
|
* CFileCache provides a file-based caching mechanism. |
||||||
|
* |
||||||
|
* For each data value being cached, CFileCache will use store it in a separate file |
||||||
|
* under {@link cachePath} which defaults to 'protected/runtime/cache'. |
||||||
|
* CFileCache will perform garbage collection automatically to remove expired cache files. |
||||||
|
* |
||||||
|
* See {@link CCache} manual for common cache operations that are supported by CFileCache. |
||||||
|
* |
||||||
|
* @property integer $gCProbability The probability (parts per million) that garbage collection (GC) should be performed |
||||||
|
* when storing a piece of data in the cache. Defaults to 100, meaning 0.01% chance. |
||||||
|
* |
||||||
|
* @author Qiang Xue <qiang.xue@gmail.com> |
||||||
|
* @version $Id$ |
||||||
|
* @package system.caching |
||||||
|
*/ |
||||||
|
class CFileCache extends CCache |
||||||
|
{ |
||||||
|
/** |
||||||
|
* @var string the directory to store cache files. Defaults to null, meaning |
||||||
|
* using 'protected/runtime/cache' as the directory. |
||||||
|
*/ |
||||||
|
public $cachePath; |
||||||
|
/** |
||||||
|
* @var string cache file suffix. Defaults to '.bin'. |
||||||
|
*/ |
||||||
|
public $cacheFileSuffix='.bin'; |
||||||
|
/** |
||||||
|
* @var integer the level of sub-directories to store cache files. Defaults to 0, |
||||||
|
* meaning no sub-directories. If the system has huge number of cache files (e.g. 10K+), |
||||||
|
* you may want to set this value to be 1 or 2 so that the file system is not over burdened. |
||||||
|
* The value of this property should not exceed 16 (less than 3 is recommended). |
||||||
|
*/ |
||||||
|
public $directoryLevel=0; |
||||||
|
|
||||||
|
private $_gcProbability=100; |
||||||
|
private $_gced=false; |
||||||
|
|
||||||
|
/** |
||||||
|
* Initializes this application component. |
||||||
|
* This method is required by the {@link IApplicationComponent} interface. |
||||||
|
* It checks the availability of memcache. |
||||||
|
* @throws CException if APC cache extension is not loaded or is disabled. |
||||||
|
*/ |
||||||
|
public function init() |
||||||
|
{ |
||||||
|
parent::init(); |
||||||
|
if($this->cachePath===null) |
||||||
|
$this->cachePath=Yii::app()->getRuntimePath().DIRECTORY_SEPARATOR.'cache'; |
||||||
|
if(!is_dir($this->cachePath)) |
||||||
|
mkdir($this->cachePath,0777,true); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @return integer the probability (parts per million) that garbage collection (GC) should be performed |
||||||
|
* when storing a piece of data in the cache. Defaults to 100, meaning 0.01% chance. |
||||||
|
*/ |
||||||
|
public function getGCProbability() |
||||||
|
{ |
||||||
|
return $this->_gcProbability; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param integer $value the probability (parts per million) that garbage collection (GC) should be performed |
||||||
|
* when storing a piece of data in the cache. Defaults to 100, meaning 0.01% chance. |
||||||
|
* This number should be between 0 and 1000000. A value 0 meaning no GC will be performed at all. |
||||||
|
*/ |
||||||
|
public function setGCProbability($value) |
||||||
|
{ |
||||||
|
$value=(int)$value; |
||||||
|
if($value<0) |
||||||
|
$value=0; |
||||||
|
if($value>1000000) |
||||||
|
$value=1000000; |
||||||
|
$this->_gcProbability=$value; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Deletes all values from cache. |
||||||
|
* This is the implementation of the method declared in the parent class. |
||||||
|
* @return boolean whether the flush operation was successful. |
||||||
|
* @since 1.1.5 |
||||||
|
*/ |
||||||
|
protected function flushValues() |
||||||
|
{ |
||||||
|
$this->gc(false); |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Retrieves a value from cache with a specified key. |
||||||
|
* This is the implementation of the method declared in the parent class. |
||||||
|
* @param string $key a unique key identifying the cached value |
||||||
|
* @return string the value stored in cache, false if the value is not in the cache or expired. |
||||||
|
*/ |
||||||
|
protected function getValue($key) |
||||||
|
{ |
||||||
|
$cacheFile=$this->getCacheFile($key); |
||||||
|
if(($time=@filemtime($cacheFile))>time()) |
||||||
|
return @file_get_contents($cacheFile); |
||||||
|
else if($time>0) |
||||||
|
@unlink($cacheFile); |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Stores a value identified by a key in cache. |
||||||
|
* This is the implementation of the method declared in the parent class. |
||||||
|
* |
||||||
|
* @param string $key the key identifying the value to be cached |
||||||
|
* @param string $value the value to be cached |
||||||
|
* @param integer $expire the number of seconds in which the cached value will expire. 0 means never expire. |
||||||
|
* @return boolean true if the value is successfully stored into cache, false otherwise |
||||||
|
*/ |
||||||
|
protected function setValue($key,$value,$expire) |
||||||
|
{ |
||||||
|
if(!$this->_gced && mt_rand(0,1000000)<$this->_gcProbability) |
||||||
|
{ |
||||||
|
$this->gc(); |
||||||
|
$this->_gced=true; |
||||||
|
} |
||||||
|
|
||||||
|
if($expire<=0) |
||||||
|
$expire=31536000; // 1 year |
||||||
|
$expire+=time(); |
||||||
|
|
||||||
|
$cacheFile=$this->getCacheFile($key); |
||||||
|
if($this->directoryLevel>0) |
||||||
|
@mkdir(dirname($cacheFile),0777,true); |
||||||
|
if(@file_put_contents($cacheFile,$value,LOCK_EX)!==false) |
||||||
|
{ |
||||||
|
@chmod($cacheFile,0777); |
||||||
|
return @touch($cacheFile,$expire); |
||||||
|
} |
||||||
|
else |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Stores a value identified by a key into cache if the cache does not contain this key. |
||||||
|
* This is the implementation of the method declared in the parent class. |
||||||
|
* |
||||||
|
* @param string $key the key identifying the value to be cached |
||||||
|
* @param string $value the value to be cached |
||||||
|
* @param integer $expire the number of seconds in which the cached value will expire. 0 means never expire. |
||||||
|
* @return boolean true if the value is successfully stored into cache, false otherwise |
||||||
|
*/ |
||||||
|
protected function addValue($key,$value,$expire) |
||||||
|
{ |
||||||
|
$cacheFile=$this->getCacheFile($key); |
||||||
|
if(@filemtime($cacheFile)>time()) |
||||||
|
return false; |
||||||
|
return $this->setValue($key,$value,$expire); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Deletes a value with the specified key from cache |
||||||
|
* This is the implementation of the method declared in the parent class. |
||||||
|
* @param string $key the key of the value to be deleted |
||||||
|
* @return boolean if no error happens during deletion |
||||||
|
*/ |
||||||
|
protected function deleteValue($key) |
||||||
|
{ |
||||||
|
$cacheFile=$this->getCacheFile($key); |
||||||
|
return @unlink($cacheFile); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns the cache file path given the cache key. |
||||||
|
* @param string $key cache key |
||||||
|
* @return string the cache file path |
||||||
|
*/ |
||||||
|
protected function getCacheFile($key) |
||||||
|
{ |
||||||
|
if($this->directoryLevel>0) |
||||||
|
{ |
||||||
|
$base=$this->cachePath; |
||||||
|
for($i=0;$i<$this->directoryLevel;++$i) |
||||||
|
{ |
||||||
|
if(($prefix=substr($key,$i+$i,2))!==false) |
||||||
|
$base.=DIRECTORY_SEPARATOR.$prefix; |
||||||
|
} |
||||||
|
return $base.DIRECTORY_SEPARATOR.$key.$this->cacheFileSuffix; |
||||||
|
} |
||||||
|
else |
||||||
|
return $this->cachePath.DIRECTORY_SEPARATOR.$key.$this->cacheFileSuffix; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Removes expired cache files. |
||||||
|
* @param boolean $expiredOnly whether to removed expired cache files only. If true, all cache files under {@link cachePath} will be removed. |
||||||
|
* @param string $path the path to clean with. If null, it will be {@link cachePath}. |
||||||
|
*/ |
||||||
|
public function gc($expiredOnly=true,$path=null) |
||||||
|
{ |
||||||
|
if($path===null) |
||||||
|
$path=$this->cachePath; |
||||||
|
if(($handle=opendir($path))===false) |
||||||
|
return; |
||||||
|
while(($file=readdir($handle))!==false) |
||||||
|
{ |
||||||
|
if($file[0]==='.') |
||||||
|
continue; |
||||||
|
$fullPath=$path.DIRECTORY_SEPARATOR.$file; |
||||||
|
if(is_dir($fullPath)) |
||||||
|
$this->gc($expiredOnly,$fullPath); |
||||||
|
else if($expiredOnly && @filemtime($fullPath)<time() || !$expiredOnly) |
||||||
|
@unlink($fullPath); |
||||||
|
} |
||||||
|
closedir($handle); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,53 @@ |
|||||||
|
<?php |
||||||
|
/** |
||||||
|
* CFileCacheDependency class file. |
||||||
|
* |
||||||
|
* @author Qiang Xue <qiang.xue@gmail.com> |
||||||
|
* @link http://www.yiiframework.com/ |
||||||
|
* @copyright Copyright © 2008-2011 Yii Software LLC |
||||||
|
* @license http://www.yiiframework.com/license/ |
||||||
|
*/ |
||||||
|
|
||||||
|
/** |
||||||
|
* CFileCacheDependency represents a dependency based on a file's last modification time. |
||||||
|
* |
||||||
|
* CFileCacheDependency performs dependency checking based on the |
||||||
|
* last modification time of the file specified via {@link fileName}. |
||||||
|
* The dependency is reported as unchanged if and only if the file's |
||||||
|
* last modification time remains unchanged. |
||||||
|
* |
||||||
|
* @author Qiang Xue <qiang.xue@gmail.com> |
||||||
|
* @version $Id$ |
||||||
|
* @package system.caching.dependencies |
||||||
|
* @since 1.0 |
||||||
|
*/ |
||||||
|
class CFileCacheDependency extends CCacheDependency |
||||||
|
{ |
||||||
|
/** |
||||||
|
* @var string the name of the file whose last modification time is used to |
||||||
|
* check if the dependency has been changed. |
||||||
|
*/ |
||||||
|
public $fileName; |
||||||
|
|
||||||
|
/** |
||||||
|
* Constructor. |
||||||
|
* @param string $fileName name of the file whose change is to be checked. |
||||||
|
*/ |
||||||
|
public function __construct($fileName=null) |
||||||
|
{ |
||||||
|
$this->fileName=$fileName; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Generates the data needed to determine if dependency has been changed. |
||||||
|
* This method returns the file's last modification time. |
||||||
|
* @return mixed the data needed to determine if dependency has been changed. |
||||||
|
*/ |
||||||
|
protected function generateDependentData() |
||||||
|
{ |
||||||
|
if($this->fileName!==null) |
||||||
|
return @filemtime($this->fileName); |
||||||
|
else |
||||||
|
throw new CException(Yii::t('yii','CFileCacheDependency.fileName cannot be empty.')); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,282 @@ |
|||||||
|
<?php |
||||||
|
/** |
||||||
|
* CMemCache class file |
||||||
|
* |
||||||
|
* @author Qiang Xue <qiang.xue@gmail.com> |
||||||
|
* @link http://www.yiiframework.com/ |
||||||
|
* @copyright Copyright © 2008-2011 Yii Software LLC |
||||||
|
* @license http://www.yiiframework.com/license/ |
||||||
|
*/ |
||||||
|
|
||||||
|
/** |
||||||
|
* CMemCache implements a cache application component based on {@link http://memcached.org/ memcached}. |
||||||
|
* |
||||||
|
* CMemCache can be configured with a list of memcache servers by settings |
||||||
|
* its {@link setServers servers} property. By default, CMemCache assumes |
||||||
|
* there is a memcache server running on localhost at port 11211. |
||||||
|
* |
||||||
|
* See {@link CCache} manual for common cache operations that are supported by CMemCache. |
||||||
|
* |
||||||
|
* Note, there is no security measure to protected data in memcache. |
||||||
|
* All data in memcache can be accessed by any process running in the system. |
||||||
|
* |
||||||
|
* To use CMemCache as the cache application component, configure the application as follows, |
||||||
|
* <pre> |
||||||
|
* array( |
||||||
|
* 'components'=>array( |
||||||
|
* 'cache'=>array( |
||||||
|
* 'class'=>'CMemCache', |
||||||
|
* 'servers'=>array( |
||||||
|
* array( |
||||||
|
* 'host'=>'server1', |
||||||
|
* 'port'=>11211, |
||||||
|
* 'weight'=>60, |
||||||
|
* ), |
||||||
|
* array( |
||||||
|
* 'host'=>'server2', |
||||||
|
* 'port'=>11211, |
||||||
|
* 'weight'=>40, |
||||||
|
* ), |
||||||
|
* ), |
||||||
|
* ), |
||||||
|
* ), |
||||||
|
* ) |
||||||
|
* </pre> |
||||||
|
* In the above, two memcache servers are used: server1 and server2. |
||||||
|
* You can configure more properties of every server, including: |
||||||
|
* host, port, persistent, weight, timeout, retryInterval, status. |
||||||
|
* See {@link http://www.php.net/manual/en/function.memcache-addserver.php} |
||||||
|
* for more details. |
||||||
|
* |
||||||
|
* CMemCache can also be used with {@link http://pecl.php.net/package/memcached memcached}. |
||||||
|
* To do so, set {@link useMemcached} to be true. |
||||||
|
* |
||||||
|
* @property mixed $memCache The memcache instance (or memcached if {@link useMemcached} is true) used by this component. |
||||||
|
* @property array $servers List of memcache server configurations. Each element is a {@link CMemCacheServerConfiguration}. |
||||||
|
* |
||||||
|
* @author Qiang Xue <qiang.xue@gmail.com> |
||||||
|
* @version $Id$ |
||||||
|
* @package system.caching |
||||||
|
* @since 1.0 |
||||||
|
*/ |
||||||
|
class CMemCache extends CCache |
||||||
|
{ |
||||||
|
/** |
||||||
|
* @var boolean whether to use memcached or memcache as the underlying caching extension. |
||||||
|
* If true {@link http://pecl.php.net/package/memcached memcached} will be used. |
||||||
|
* If false {@link http://pecl.php.net/package/memcache memcache}. will be used. |
||||||
|
* Defaults to false. |
||||||
|
*/ |
||||||
|
public $useMemcached=false; |
||||||
|
/** |
||||||
|
* @var Memcache the Memcache instance |
||||||
|
*/ |
||||||
|
private $_cache=null; |
||||||
|
/** |
||||||
|
* @var array list of memcache server configurations |
||||||
|
*/ |
||||||
|
private $_servers=array(); |
||||||
|
|
||||||
|
/** |
||||||
|
* Initializes this application component. |
||||||
|
* This method is required by the {@link IApplicationComponent} interface. |
||||||
|
* It creates the memcache instance and adds memcache servers. |
||||||
|
* @throws CException if memcache extension is not loaded |
||||||
|
*/ |
||||||
|
public function init() |
||||||
|
{ |
||||||
|
parent::init(); |
||||||
|
$servers=$this->getServers(); |
||||||
|
$cache=$this->getMemCache(); |
||||||
|
if(count($servers)) |
||||||
|
{ |
||||||
|
foreach($servers as $server) |
||||||
|
{ |
||||||
|
if($this->useMemcached) |
||||||
|
$cache->addServer($server->host,$server->port,$server->weight); |
||||||
|
else |
||||||
|
$cache->addServer($server->host,$server->port,$server->persistent,$server->weight,$server->timeout,$server->status); |
||||||
|
} |
||||||
|
} |
||||||
|
else |
||||||
|
$cache->addServer('localhost',11211); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @throws CException if extension isn't loaded |
||||||
|
* @return Memcache|Memcached the memcache instance (or memcached if {@link useMemcached} is true) used by this component. |
||||||
|
*/ |
||||||
|
public function getMemCache() |
||||||
|
{ |
||||||
|
if($this->_cache!==null) |
||||||
|
return $this->_cache; |
||||||
|
else |
||||||
|
{ |
||||||
|
$extension=$this->useMemcached ? 'memcached' : 'memcache'; |
||||||
|
if(!extension_loaded($extension)) |
||||||
|
throw new CException(Yii::t('yii',"CMemCache requires PHP $extension extension to be loaded.")); |
||||||
|
return $this->_cache=$this->useMemcached ? new Memcached : new Memcache; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @return array list of memcache server configurations. Each element is a {@link CMemCacheServerConfiguration}. |
||||||
|
*/ |
||||||
|
public function getServers() |
||||||
|
{ |
||||||
|
return $this->_servers; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param array $config list of memcache server configurations. Each element must be an array |
||||||
|
* with the following keys: host, port, persistent, weight, timeout, retryInterval, status. |
||||||
|
* @see http://www.php.net/manual/en/function.Memcache-addServer.php |
||||||
|
*/ |
||||||
|
public function setServers($config) |
||||||
|
{ |
||||||
|
foreach($config as $c) |
||||||
|
$this->_servers[]=new CMemCacheServerConfiguration($c); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Retrieves a value from cache with a specified key. |
||||||
|
* This is the implementation of the method declared in the parent class. |
||||||
|
* @param string $key a unique key identifying the cached value |
||||||
|
* @return string the value stored in cache, false if the value is not in the cache or expired. |
||||||
|
*/ |
||||||
|
protected function getValue($key) |
||||||
|
{ |
||||||
|
return $this->_cache->get($key); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Retrieves multiple values from cache with the specified keys. |
||||||
|
* @param array $keys a list of keys identifying the cached values |
||||||
|
* @return array a list of cached values indexed by the keys |
||||||
|
*/ |
||||||
|
protected function getValues($keys) |
||||||
|
{ |
||||||
|
return $this->useMemcached ? $this->_cache->getMulti($keys) : $this->_cache->get($keys); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Stores a value identified by a key in cache. |
||||||
|
* This is the implementation of the method declared in the parent class. |
||||||
|
* |
||||||
|
* @param string $key the key identifying the value to be cached |
||||||
|
* @param string $value the value to be cached |
||||||
|
* @param integer $expire the number of seconds in which the cached value will expire. 0 means never expire. |
||||||
|
* @return boolean true if the value is successfully stored into cache, false otherwise |
||||||
|
*/ |
||||||
|
protected function setValue($key,$value,$expire) |
||||||
|
{ |
||||||
|
if($expire>0) |
||||||
|
$expire+=time(); |
||||||
|
else |
||||||
|
$expire=0; |
||||||
|
|
||||||
|
return $this->useMemcached ? $this->_cache->set($key,$value,$expire) : $this->_cache->set($key,$value,0,$expire); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Stores a value identified by a key into cache if the cache does not contain this key. |
||||||
|
* This is the implementation of the method declared in the parent class. |
||||||
|
* |
||||||
|
* @param string $key the key identifying the value to be cached |
||||||
|
* @param string $value the value to be cached |
||||||
|
* @param integer $expire the number of seconds in which the cached value will expire. 0 means never expire. |
||||||
|
* @return boolean true if the value is successfully stored into cache, false otherwise |
||||||
|
*/ |
||||||
|
protected function addValue($key,$value,$expire) |
||||||
|
{ |
||||||
|
if($expire>0) |
||||||
|
$expire+=time(); |
||||||
|
else |
||||||
|
$expire=0; |
||||||
|
|
||||||
|
return $this->useMemcached ? $this->_cache->add($key,$value,$expire) : $this->_cache->add($key,$value,0,$expire); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Deletes a value with the specified key from cache |
||||||
|
* This is the implementation of the method declared in the parent class. |
||||||
|
* @param string $key the key of the value to be deleted |
||||||
|
* @return boolean if no error happens during deletion |
||||||
|
*/ |
||||||
|
protected function deleteValue($key) |
||||||
|
{ |
||||||
|
return $this->_cache->delete($key, 0); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Deletes all values from cache. |
||||||
|
* This is the implementation of the method declared in the parent class. |
||||||
|
* @return boolean whether the flush operation was successful. |
||||||
|
* @since 1.1.5 |
||||||
|
*/ |
||||||
|
protected function flushValues() |
||||||
|
{ |
||||||
|
return $this->_cache->flush(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* CMemCacheServerConfiguration represents the configuration data for a single memcache server. |
||||||
|
* |
||||||
|
* See {@link http://www.php.net/manual/en/function.Memcache-addServer.php} |
||||||
|
* for detailed explanation of each configuration property. |
||||||
|
* |
||||||
|
* @author Qiang Xue <qiang.xue@gmail.com> |
||||||
|
* @version $Id$ |
||||||
|
* @package system.caching |
||||||
|
* @since 1.0 |
||||||
|
*/ |
||||||
|
class CMemCacheServerConfiguration extends CComponent |
||||||
|
{ |
||||||
|
/** |
||||||
|
* @var string memcache server hostname or IP address |
||||||
|
*/ |
||||||
|
public $host; |
||||||
|
/** |
||||||
|
* @var integer memcache server port |
||||||
|
*/ |
||||||
|
public $port=11211; |
||||||
|
/** |
||||||
|
* @var boolean whether to use a persistent connection |
||||||
|
*/ |
||||||
|
public $persistent=true; |
||||||
|
/** |
||||||
|
* @var integer probability of using this server among all servers. |
||||||
|
*/ |
||||||
|
public $weight=1; |
||||||
|
/** |
||||||
|
* @var integer value in seconds which will be used for connecting to the server |
||||||
|
*/ |
||||||
|
public $timeout=15; |
||||||
|
/** |
||||||
|
* @var integer how often a failed server will be retried (in seconds) |
||||||
|
*/ |
||||||
|
public $retryInterval=15; |
||||||
|
/** |
||||||
|
* @var boolean if the server should be flagged as online upon a failure |
||||||
|
*/ |
||||||
|
public $status=true; |
||||||
|
|
||||||
|
/** |
||||||
|
* Constructor. |
||||||
|
* @param array $config list of memcache server configurations. |
||||||
|
* @throws CException if the configuration is not an array |
||||||
|
*/ |
||||||
|
public function __construct($config) |
||||||
|
{ |
||||||
|
if(is_array($config)) |
||||||
|
{ |
||||||
|
foreach($config as $key=>$value) |
||||||
|
$this->$key=$value; |
||||||
|
if($this->host===null) |
||||||
|
throw new CException(Yii::t('yii','CMemCache server configuration must have "host" value.')); |
||||||
|
} |
||||||
|
else |
||||||
|
throw new CException(Yii::t('yii','CMemCache server configuration must be an array.')); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,109 @@ |
|||||||
|
<?php |
||||||
|
/** |
||||||
|
* CWinCache class file |
||||||
|
* |
||||||
|
* @author Alexander Makarov <sam@rmcreative.ru> |
||||||
|
* @link http://www.yiiframework.com/ |
||||||
|
* @copyright Copyright © 2008-2011 Yii Software LLC |
||||||
|
* @license http://www.yiiframework.com/license/ |
||||||
|
*/ |
||||||
|
|
||||||
|
/** |
||||||
|
* CWinCache implements a cache application component based on {@link http://www.iis.net/expand/wincacheforphp WinCache}. |
||||||
|
* |
||||||
|
* To use this application component, the WinCache PHP extension must be loaded. |
||||||
|
* |
||||||
|
* See {@link CCache} manual for common cache operations that are supported by CWinCache. |
||||||
|
* |
||||||
|
* @author Alexander Makarov <sam@rmcreative.ru> |
||||||
|
* @version $Id$ |
||||||
|
* @package system.caching |
||||||
|
* @since 1.1.2 |
||||||
|
*/ |
||||||
|
class CWinCache extends CCache { |
||||||
|
/** |
||||||
|
* Initializes this application component. |
||||||
|
* This method is required by the {@link IApplicationComponent} interface. |
||||||
|
* It checks the availability of WinCache extension and WinCache user cache. |
||||||
|
* @throws CException if WinCache extension is not loaded or user cache is disabled |
||||||
|
*/ |
||||||
|
public function init() |
||||||
|
{ |
||||||
|
parent::init(); |
||||||
|
if(!extension_loaded('wincache')) |
||||||
|
throw new CException(Yii::t('yii', 'CWinCache requires PHP wincache extension to be loaded.')); |
||||||
|
if(!ini_get('wincache.ucenabled')) |
||||||
|
throw new CException(Yii::t('yii', 'CWinCache user cache is disabled. Please set wincache.ucenabled to On in your php.ini.')); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Retrieves a value from cache with a specified key. |
||||||
|
* This is the implementation of the method declared in the parent class. |
||||||
|
* @param string $key a unique key identifying the cached value |
||||||
|
* @return string the value stored in cache, false if the value is not in the cache or expired. |
||||||
|
*/ |
||||||
|
protected function getValue($key) |
||||||
|
{ |
||||||
|
return wincache_ucache_get($key); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Retrieves multiple values from cache with the specified keys. |
||||||
|
* @param array $keys a list of keys identifying the cached values |
||||||
|
* @return array a list of cached values indexed by the keys |
||||||
|
*/ |
||||||
|
protected function getValues($keys) |
||||||
|
{ |
||||||
|
return wincache_ucache_get($keys); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Stores a value identified by a key in cache. |
||||||
|
* This is the implementation of the method declared in the parent class. |
||||||
|
* |
||||||
|
* @param string $key the key identifying the value to be cached |
||||||
|
* @param string $value the value to be cached |
||||||
|
* @param integer $expire the number of seconds in which the cached value will expire. 0 means never expire. |
||||||
|
* @return boolean true if the value is successfully stored into cache, false otherwise |
||||||
|
*/ |
||||||
|
protected function setValue($key,$value,$expire) |
||||||
|
{ |
||||||
|
return wincache_ucache_set($key,$value,$expire); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Stores a value identified by a key into cache if the cache does not contain this key. |
||||||
|
* This is the implementation of the method declared in the parent class. |
||||||
|
* |
||||||
|
* @param string $key the key identifying the value to be cached |
||||||
|
* @param string $value the value to be cached |
||||||
|
* @param integer $expire the number of seconds in which the cached value will expire. 0 means never expire. |
||||||
|
* @return boolean true if the value is successfully stored into cache, false otherwise |
||||||
|
*/ |
||||||
|
protected function addValue($key,$value,$expire) |
||||||
|
{ |
||||||
|
return wincache_ucache_add($key,$value,$expire); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Deletes a value with the specified key from cache |
||||||
|
* This is the implementation of the method declared in the parent class. |
||||||
|
* @param string $key the key of the value to be deleted |
||||||
|
* @return boolean if no error happens during deletion |
||||||
|
*/ |
||||||
|
protected function deleteValue($key) |
||||||
|
{ |
||||||
|
return wincache_ucache_delete($key); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Deletes all values from cache. |
||||||
|
* This is the implementation of the method declared in the parent class. |
||||||
|
* @return boolean whether the flush operation was successful. |
||||||
|
* @since 1.1.5 |
||||||
|
*/ |
||||||
|
protected function flushValues() |
||||||
|
{ |
||||||
|
return wincache_ucache_clear(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,104 @@ |
|||||||
|
<?php |
||||||
|
/** |
||||||
|
* CXCache class file |
||||||
|
* |
||||||
|
* @author Wei Zhuo <weizhuo[at]gmail[dot]com> |
||||||
|
* @link http://www.yiiframework.com/ |
||||||
|
* @copyright Copyright © 2008-2011 Yii Software LLC |
||||||
|
* @license http://www.yiiframework.com/license/ |
||||||
|
*/ |
||||||
|
|
||||||
|
/** |
||||||
|
* CXCache implements a cache application module based on {@link http://xcache.lighttpd.net/ xcache}. |
||||||
|
* |
||||||
|
* To use this application component, the XCache PHP extension must be loaded. |
||||||
|
* Flush functionality will only work correctly if "xcache.admin.enable_auth" is set to "Off" in php.ini. |
||||||
|
* |
||||||
|
* See {@link CCache} manual for common cache operations that are supported by CXCache. |
||||||
|
* |
||||||
|
* @author Wei Zhuo <weizhuo[at]gmail[dot]com> |
||||||
|
* @version $Id$ |
||||||
|
* @package system.caching |
||||||
|
*/ |
||||||
|
class CXCache extends CCache |
||||||
|
{ |
||||||
|
/** |
||||||
|
* Initializes this application component. |
||||||
|
* This method is required by the {@link IApplicationComponent} interface. |
||||||
|
* It checks the availability of memcache. |
||||||
|
* @throws CException if memcache extension is not loaded or is disabled. |
||||||
|
*/ |
||||||
|
public function init() |
||||||
|
{ |
||||||
|
parent::init(); |
||||||
|
if(!function_exists('xcache_isset')) |
||||||
|
throw new CException(Yii::t('yii','CXCache requires PHP XCache extension to be loaded.')); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Retrieves a value from cache with a specified key. |
||||||
|
* This is the implementation of the method declared in the parent class. |
||||||
|
* @param string $key a unique key identifying the cached value |
||||||
|
* @return string the value stored in cache, false if the value is not in the cache or expired. |
||||||
|
*/ |
||||||
|
protected function getValue($key) |
||||||
|
{ |
||||||
|
return xcache_isset($key) ? xcache_get($key) : false; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Stores a value identified by a key in cache. |
||||||
|
* This is the implementation of the method declared in the parent class. |
||||||
|
* |
||||||
|
* @param string $key the key identifying the value to be cached |
||||||
|
* @param string $value the value to be cached |
||||||
|
* @param integer $expire the number of seconds in which the cached value will expire. 0 means never expire. |
||||||
|
* @return boolean true if the value is successfully stored into cache, false otherwise |
||||||
|
*/ |
||||||
|
protected function setValue($key,$value,$expire) |
||||||
|
{ |
||||||
|
return xcache_set($key,$value,$expire); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Stores a value identified by a key into cache if the cache does not contain this key. |
||||||
|
* This is the implementation of the method declared in the parent class. |
||||||
|
* |
||||||
|
* @param string $key the key identifying the value to be cached |
||||||
|
* @param string $value the value to be cached |
||||||
|
* @param integer $expire the number of seconds in which the cached value will expire. 0 means never expire. |
||||||
|
* @return boolean true if the value is successfully stored into cache, false otherwise |
||||||
|
*/ |
||||||
|
protected function addValue($key,$value,$expire) |
||||||
|
{ |
||||||
|
return !xcache_isset($key) ? $this->setValue($key,$value,$expire) : false; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Deletes a value with the specified key from cache |
||||||
|
* This is the implementation of the method declared in the parent class. |
||||||
|
* @param string $key the key of the value to be deleted |
||||||
|
* @return boolean if no error happens during deletion |
||||||
|
*/ |
||||||
|
protected function deleteValue($key) |
||||||
|
{ |
||||||
|
return xcache_unset($key); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Deletes all values from cache. |
||||||
|
* This is the implementation of the method declared in the parent class. |
||||||
|
* @return boolean whether the flush operation was successful. |
||||||
|
* @since 1.1.5 |
||||||
|
*/ |
||||||
|
protected function flushValues() |
||||||
|
{ |
||||||
|
for($i=0, $max=xcache_count(XC_TYPE_VAR); $i<$max; $i++) |
||||||
|
{ |
||||||
|
if(xcache_clear_cache(XC_TYPE_VAR, $i)===false) |
||||||
|
return false; |
||||||
|
} |
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
|
|
@ -0,0 +1,99 @@ |
|||||||
|
<?php |
||||||
|
/** |
||||||
|
* CZendDataCache class file |
||||||
|
* |
||||||
|
* @author Steffen Dietz <steffo.dietz[at]googlemail[dot]com> |
||||||
|
* @link http://www.yiiframework.com/ |
||||||
|
* @copyright Copyright © 2008-2011 Yii Software LLC |
||||||
|
* @license http://www.yiiframework.com/license/ |
||||||
|
*/ |
||||||
|
|
||||||
|
/** |
||||||
|
* CZendDataCache implements a cache application module based on the Zend Data Cache |
||||||
|
* delivered with {@link http://www.zend.com/en/products/server/ ZendServer}. |
||||||
|
* |
||||||
|
* To use this application component, the Zend Data Cache PHP extension must be loaded. |
||||||
|
* |
||||||
|
* See {@link CCache} manual for common cache operations that are supported by CZendDataCache. |
||||||
|
* |
||||||
|
* @author Steffen Dietz <steffo.dietz[at]googlemail[dot]com> |
||||||
|
* @version $Id$ |
||||||
|
* @package system.caching |
||||||
|
*/ |
||||||
|
class CZendDataCache extends CCache |
||||||
|
{ |
||||||
|
/** |
||||||
|
* Initializes this application component. |
||||||
|
* This method is required by the {@link IApplicationComponent} interface. |
||||||
|
* It checks the availability of Zend Data Cache. |
||||||
|
* @throws CException if Zend Data Cache extension is not loaded. |
||||||
|
*/ |
||||||
|
public function init() |
||||||
|
{ |
||||||
|
parent::init(); |
||||||
|
if(!function_exists('zend_shm_cache_store')) |
||||||
|
throw new CException(Yii::t('yii','CZendDataCache requires PHP Zend Data Cache extension to be loaded.')); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Retrieves a value from cache with a specified key. |
||||||
|
* This is the implementation of the method declared in the parent class. |
||||||
|
* @param string $key a unique key identifying the cached value |
||||||
|
* @return string the value stored in cache, false if the value is not in the cache or expired. |
||||||
|
*/ |
||||||
|
protected function getValue($key) |
||||||
|
{ |
||||||
|
$result = zend_shm_cache_fetch($key); |
||||||
|
return $result !== NULL ? $result : false; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Stores a value identified by a key in cache. |
||||||
|
* This is the implementation of the method declared in the parent class. |
||||||
|
* |
||||||
|
* @param string $key the key identifying the value to be cached |
||||||
|
* @param string $value the value to be cached |
||||||
|
* @param integer $expire the number of seconds in which the cached value will expire. 0 means never expire. |
||||||
|
* @return boolean true if the value is successfully stored into cache, false otherwise |
||||||
|
*/ |
||||||
|
protected function setValue($key,$value,$expire) |
||||||
|
{ |
||||||
|
return zend_shm_cache_store($key,$value,$expire); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Stores a value identified by a key into cache if the cache does not contain this key. |
||||||
|
* This is the implementation of the method declared in the parent class. |
||||||
|
* |
||||||
|
* @param string $key the key identifying the value to be cached |
||||||
|
* @param string $value the value to be cached |
||||||
|
* @param integer $expire the number of seconds in which the cached value will expire. 0 means never expire. |
||||||
|
* @return boolean true if the value is successfully stored into cache, false otherwise |
||||||
|
*/ |
||||||
|
protected function addValue($key,$value,$expire) |
||||||
|
{ |
||||||
|
return (NULL === zend_shm_cache_fetch($key)) ? $this->setValue($key,$value,$expire) : false; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Deletes a value with the specified key from cache |
||||||
|
* This is the implementation of the method declared in the parent class. |
||||||
|
* @param string $key the key of the value to be deleted |
||||||
|
* @return boolean if no error happens during deletion |
||||||
|
*/ |
||||||
|
protected function deleteValue($key) |
||||||
|
{ |
||||||
|
return zend_shm_cache_delete($key); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Deletes all values from cache. |
||||||
|
* This is the implementation of the method declared in the parent class. |
||||||
|
* @return boolean whether the flush operation was successful. |
||||||
|
* @since 1.1.5 |
||||||
|
*/ |
||||||
|
protected function flushValues() |
||||||
|
{ |
||||||
|
return zend_shm_cache_clear(); |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue