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