summaryrefslogtreecommitdiff
path: root/framework/caching
diff options
context:
space:
mode:
Diffstat (limited to 'framework/caching')
-rw-r--r--framework/caching/CApcCache.php109
-rw-r--r--framework/caching/CCache.php332
-rw-r--r--framework/caching/CDbCache.php314
-rw-r--r--framework/caching/CDummyCache.php164
-rw-r--r--framework/caching/CEAcceleratorCache.php107
-rw-r--r--framework/caching/CFileCache.php222
-rw-r--r--framework/caching/CMemCache.php276
-rw-r--r--framework/caching/CWinCache.php109
-rw-r--r--framework/caching/CXCache.php103
-rw-r--r--framework/caching/CZendDataCache.php99
-rw-r--r--framework/caching/dependencies/CCacheDependency.php66
-rw-r--r--framework/caching/dependencies/CChainedCacheDependency.php98
-rw-r--r--framework/caching/dependencies/CDbCacheDependency.php112
-rw-r--r--framework/caching/dependencies/CDirectoryCacheDependency.php134
-rw-r--r--framework/caching/dependencies/CExpressionDependency.php53
-rw-r--r--framework/caching/dependencies/CFileCacheDependency.php53
-rw-r--r--framework/caching/dependencies/CGlobalStateCacheDependency.php54
17 files changed, 2405 insertions, 0 deletions
diff --git a/framework/caching/CApcCache.php b/framework/caching/CApcCache.php
new file mode 100644
index 0000000..f098356
--- /dev/null
+++ b/framework/caching/CApcCache.php
@@ -0,0 +1,109 @@
+<?php
+/**
+ * CApcCache class file
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @link http://www.yiiframework.com/
+ * @copyright Copyright &copy; 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: CApcCache.php 3515 2011-12-28 12:29:24Z mdomba $
+ * @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');
+ }
+}
diff --git a/framework/caching/CCache.php b/framework/caching/CCache.php
new file mode 100644
index 0000000..0d66d4b
--- /dev/null
+++ b/framework/caching/CCache.php
@@ -0,0 +1,332 @@
+<?php
+/**
+ * CCache class file.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @link http://www.yiiframework.com/
+ * @copyright Copyright &copy; 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 flush} (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: CCache.php 3515 2011-12-28 12:29:24Z mdomba $
+ * @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 {@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();
+ }
+
+ /**
+ * @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 md5($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=unserialize($value);
+ if(!is_array($data))
+ return false;
+ if(!($data[1] instanceof ICacheDependency) || !$data[1]->getHasChanged())
+ {
+ Yii::trace('Serving "'.$id.'" from cache','system.caching.'.get_class($this));
+ return $data[0];
+ }
+ }
+ 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=unserialize($values[$uniqueID]);
+ if(is_array($data) && (!($data[1] instanceof ICacheDependency) || !$data[1]->getHasChanged()))
+ {
+ Yii::trace('Serving "'.$id.'" from cache','system.caching.'.get_class($this));
+ $results[$id]=$data[0];
+ }
+ }
+ 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)
+ $dependency->evaluateDependency();
+ $data=array($value,$dependency);
+ return $this->setValue($this->generateUniqueKey($id),serialize($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)
+ $dependency->evaluateDependency();
+ $data=array($value,$dependency);
+ return $this->addValue($this->generateUniqueKey($id),serialize($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))));
+ }
+
+ /**
+ * 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);
+ }
+} \ No newline at end of file
diff --git a/framework/caching/CDbCache.php b/framework/caching/CDbCache.php
new file mode 100644
index 0000000..90e5009
--- /dev/null
+++ b/framework/caching/CDbCache.php
@@ -0,0 +1,314 @@
+<?php
+/**
+ * CDbCache class file
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @link http://www.yiiframework.com/
+ * @copyright Copyright &copy; 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: CDbCache.php 3515 2011-12-28 12:29:24Z mdomba $
+ * @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']]=$results[$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;
+ }
+}
diff --git a/framework/caching/CDummyCache.php b/framework/caching/CDummyCache.php
new file mode 100644
index 0000000..52bf553
--- /dev/null
+++ b/framework/caching/CDummyCache.php
@@ -0,0 +1,164 @@
+<?php
+/**
+ * CDummyCache class file.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @link http://www.yiiframework.com/
+ * @copyright Copyright &copy; 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: CDummyCache.php 3515 2011-12-28 12:29:24Z mdomba $
+ * @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)
+ {
+ }
+}
diff --git a/framework/caching/CEAcceleratorCache.php b/framework/caching/CEAcceleratorCache.php
new file mode 100644
index 0000000..d02545d
--- /dev/null
+++ b/framework/caching/CEAcceleratorCache.php
@@ -0,0 +1,107 @@
+<?php
+/**
+ * CEAcceleratorCache class file
+ *
+ * @author Steffen Dietz <steffo.dietz[at]googlemail[dot]com>
+ * @link http://www.yiiframework.com/
+ * @copyright Copyright &copy; 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: CEAcceleratorCache.php 3515 2011-12-28 12:29:24Z mdomba $
+ * @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;
+ }
+}
diff --git a/framework/caching/CFileCache.php b/framework/caching/CFileCache.php
new file mode 100644
index 0000000..a339699
--- /dev/null
+++ b/framework/caching/CFileCache.php
@@ -0,0 +1,222 @@
+<?php
+/**
+ * CFileCache class file
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @link http://www.yiiframework.com/
+ * @copyright Copyright &copy; 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: CFileCache.php 3515 2011-12-28 12:29:24Z mdomba $
+ * @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);
+ }
+}
diff --git a/framework/caching/CMemCache.php b/framework/caching/CMemCache.php
new file mode 100644
index 0000000..b18d939
--- /dev/null
+++ b/framework/caching/CMemCache.php
@@ -0,0 +1,276 @@
+<?php
+/**
+ * CMemCache class file
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @link http://www.yiiframework.com/
+ * @copyright Copyright &copy; 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: CMemCache.php 3515 2011-12-28 12:29:24Z mdomba $
+ * @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);
+ }
+
+ /**
+ * @return mixed 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
+ 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: CMemCache.php 3515 2011-12-28 12:29:24Z mdomba $
+ * @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.'));
+ }
+} \ No newline at end of file
diff --git a/framework/caching/CWinCache.php b/framework/caching/CWinCache.php
new file mode 100644
index 0000000..82b0acf
--- /dev/null
+++ b/framework/caching/CWinCache.php
@@ -0,0 +1,109 @@
+<?php
+/**
+ * CWinCache class file
+ *
+ * @author Alexander Makarov <sam@rmcreative.ru>
+ * @link http://www.yiiframework.com/
+ * @copyright Copyright &copy; 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: CWinCache.php 2799 2011-01-01 19:31:13Z qiang.xue $
+ * @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();
+ }
+} \ No newline at end of file
diff --git a/framework/caching/CXCache.php b/framework/caching/CXCache.php
new file mode 100644
index 0000000..129c8bb
--- /dev/null
+++ b/framework/caching/CXCache.php
@@ -0,0 +1,103 @@
+<?php
+/**
+ * CXCache class file
+ *
+ * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
+ * @link http://www.yiiframework.com/
+ * @copyright Copyright &copy; 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.
+ *
+ * See {@link CCache} manual for common cache operations that are supported by CXCache.
+ *
+ * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
+ * @version $Id: CXCache.php 3515 2011-12-28 12:29:24Z mdomba $
+ * @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;
+ }
+}
+
diff --git a/framework/caching/CZendDataCache.php b/framework/caching/CZendDataCache.php
new file mode 100644
index 0000000..c1a341d
--- /dev/null
+++ b/framework/caching/CZendDataCache.php
@@ -0,0 +1,99 @@
+<?php
+/**
+ * CZendDataCache class file
+ *
+ * @author Steffen Dietz <steffo.dietz[at]googlemail[dot]com>
+ * @link http://www.yiiframework.com/
+ * @copyright Copyright &copy; 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: CZendDataCache.php 3515 2011-12-28 12:29:24Z mdomba $
+ * @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();
+ }
+}
diff --git a/framework/caching/dependencies/CCacheDependency.php b/framework/caching/dependencies/CCacheDependency.php
new file mode 100644
index 0000000..ca0f318
--- /dev/null
+++ b/framework/caching/dependencies/CCacheDependency.php
@@ -0,0 +1,66 @@
+<?php
+/**
+ * CCacheDependency class file.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @link http://www.yiiframework.com/
+ * @copyright Copyright &copy; 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: CCacheDependency.php 3426 2011-10-25 00:01:09Z alexander.makarow $
+ * @package system.caching.dependencies
+ * @since 1.0
+ */
+class CCacheDependency extends CComponent implements ICacheDependency
+{
+ 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()
+ {
+ $this->_data=$this->generateDependentData();
+ }
+
+ /**
+ * @return boolean whether the dependency has changed.
+ */
+ public function getHasChanged()
+ {
+ 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;
+ }
+} \ No newline at end of file
diff --git a/framework/caching/dependencies/CChainedCacheDependency.php b/framework/caching/dependencies/CChainedCacheDependency.php
new file mode 100644
index 0000000..a7b985f
--- /dev/null
+++ b/framework/caching/dependencies/CChainedCacheDependency.php
@@ -0,0 +1,98 @@
+<?php
+/**
+ * CChainedCacheDependency class file.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @link http://www.yiiframework.com/
+ * @copyright Copyright &copy; 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: CChainedCacheDependency.php 3515 2011-12-28 12:29:24Z mdomba $
+ * @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;
+ }
+}
diff --git a/framework/caching/dependencies/CDbCacheDependency.php b/framework/caching/dependencies/CDbCacheDependency.php
new file mode 100644
index 0000000..98b8e8d
--- /dev/null
+++ b/framework/caching/dependencies/CDbCacheDependency.php
@@ -0,0 +1,112 @@
+<?php
+/**
+ * CDbCacheDependency class file.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @link http://www.yiiframework.com/
+ * @copyright Copyright &copy; 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: CDbCacheDependency.php 3204 2011-05-05 21:36:32Z alexander.makarow $
+ * @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)));
+ }
+ }
+}
diff --git a/framework/caching/dependencies/CDirectoryCacheDependency.php b/framework/caching/dependencies/CDirectoryCacheDependency.php
new file mode 100644
index 0000000..2ebab9c
--- /dev/null
+++ b/framework/caching/dependencies/CDirectoryCacheDependency.php
@@ -0,0 +1,134 @@
+<?php
+/**
+ * CDirectoryCacheDependency class file.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @link http://www.yiiframework.com/
+ * @copyright Copyright &copy; 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: CDirectoryCacheDependency.php 3500 2011-12-20 16:25:43Z mdomba $
+ * @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;
+ }
+}
diff --git a/framework/caching/dependencies/CExpressionDependency.php b/framework/caching/dependencies/CExpressionDependency.php
new file mode 100644
index 0000000..393ac96
--- /dev/null
+++ b/framework/caching/dependencies/CExpressionDependency.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * CExpressionDependency class file.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @link http://www.yiiframework.com/
+ * @copyright Copyright &copy; 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: CExpressionDependency.php 3515 2011-12-28 12:29:24Z mdomba $
+ * @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);
+ }
+}
diff --git a/framework/caching/dependencies/CFileCacheDependency.php b/framework/caching/dependencies/CFileCacheDependency.php
new file mode 100644
index 0000000..44907cd
--- /dev/null
+++ b/framework/caching/dependencies/CFileCacheDependency.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * CFileCacheDependency class file.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @link http://www.yiiframework.com/
+ * @copyright Copyright &copy; 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: CFileCacheDependency.php 2799 2011-01-01 19:31:13Z qiang.xue $
+ * @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.'));
+ }
+}
diff --git a/framework/caching/dependencies/CGlobalStateCacheDependency.php b/framework/caching/dependencies/CGlobalStateCacheDependency.php
new file mode 100644
index 0000000..4775fc6
--- /dev/null
+++ b/framework/caching/dependencies/CGlobalStateCacheDependency.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * CGlobalStateCacheDependency class file.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @link http://www.yiiframework.com/
+ * @copyright Copyright &copy; 2008-2011 Yii Software LLC
+ * @license http://www.yiiframework.com/license/
+ */
+
+/**
+ * CGlobalStateCacheDependency represents a dependency based on a global state value.
+ *
+ * CGlobalStateCacheDependency checks if a global state is changed or not.
+ * If the global state is changed, the dependency is reported as changed.
+ * To specify which global state this dependency should check with,
+ * set {@link stateName} to the name of the global state.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @version $Id: CGlobalStateCacheDependency.php 2799 2011-01-01 19:31:13Z qiang.xue $
+ * @package system.caching.dependencies
+ * @since 1.0
+ */
+class CGlobalStateCacheDependency extends CCacheDependency
+{
+ /**
+ * @var string the name of the global state whose value is to check
+ * if the dependency has changed.
+ * @see CApplication::setGlobalState
+ */
+ public $stateName;
+
+ /**
+ * Constructor.
+ * @param string $name the name of the global state
+ */
+ public function __construct($name=null)
+ {
+ $this->stateName=$name;
+ }
+
+ /**
+ * 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->stateName!==null)
+ return Yii::app()->getGlobalState($this->stateName);
+ else
+ throw new CException(Yii::t('yii','CGlobalStateCacheDependency.stateName cannot be empty.'));
+ }
+}