Commit 41650dd6 by Qiang Xue

...

parent bb92623f
...@@ -9,8 +9,6 @@ ...@@ -9,8 +9,6 @@
namespace yii\base; namespace yii\base;
use yii\util\ArrayHelper;
/** /**
* ActionFilter is the base class for all action filters. * ActionFilter is the base class for all action filters.
* *
...@@ -36,7 +34,7 @@ class ActionFilter extends Behavior ...@@ -36,7 +34,7 @@ class ActionFilter extends Behavior
*/ */
public $owner; public $owner;
/** /**
* @var array IDs (case-insensitive) of actions that this filter applies to. * @var array IDs of actions that this filter applies to.
* If this property is empty or not set, it means this filter applies to all actions. * If this property is empty or not set, it means this filter applies to all actions.
* Note that if an action appears in [[except]], the filter will not apply to this action, even * Note that if an action appears in [[except]], the filter will not apply to this action, even
* if the action also appears in [[only]]. * if the action also appears in [[only]].
...@@ -44,7 +42,7 @@ class ActionFilter extends Behavior ...@@ -44,7 +42,7 @@ class ActionFilter extends Behavior
*/ */
public $only; public $only;
/** /**
* @var array IDs (case-insensitive) of actions that this filter does NOT apply to. * @var array IDs of actions that this filter does NOT apply to.
*/ */
public $except; public $except;
...@@ -86,7 +84,7 @@ class ActionFilter extends Behavior ...@@ -86,7 +84,7 @@ class ActionFilter extends Behavior
public function applyTo(Action $action) public function applyTo(Action $action)
{ {
return (empty($this->only) || ArrayHelper::search($action->id, $this->only, false) !== false) return (empty($this->only) || in_array($action->id, $this->only, false) !== false)
&& (empty($this->except) || ArrayHelper::search($action->id, $this->except, false) === false); && (empty($this->except) || in_array($action->id, $this->except, false) === false);
} }
} }
\ No newline at end of file
...@@ -55,6 +55,10 @@ class View extends Component ...@@ -55,6 +55,10 @@ class View extends Component
* @var mixed custom parameters that are available in the view template * @var mixed custom parameters that are available in the view template
*/ */
public $params; public $params;
/**
* @var Widget[] the widgets that are currently not ended
*/
protected $widgetStack = array();
/** /**
* Constructor. * Constructor.
...@@ -128,19 +132,22 @@ class View extends Component ...@@ -128,19 +132,22 @@ class View extends Component
return \Yii::createObject($properties, $this->context); return \Yii::createObject($properties, $this->context);
} }
public function widget($class, $properties = array()) public function widget($class, $properties = array(), $captureOutput = false)
{ {
$widget = $this->createWidget($class, $properties); if ($captureOutput) {
echo $widget->run(); ob_start();
return $widget; ob_implicit_flush(false);
$widget = $this->createWidget($class, $properties);
$widget->run();
return ob_get_clean();
} else {
$widget = $this->createWidget($class, $properties);
$widget->run();
return $widget;
}
} }
/** /**
* @var Widget[] the widgets that are currently not ended
*/
private $_widgetStack = array();
/**
* Begins a widget. * Begins a widget.
* @param string $class the widget class * @param string $class the widget class
* @param array $properties the initial property values of the widget * @param array $properties the initial property values of the widget
...@@ -149,7 +156,7 @@ class View extends Component ...@@ -149,7 +156,7 @@ class View extends Component
public function beginWidget($class, $properties = array()) public function beginWidget($class, $properties = array())
{ {
$widget = $this->createWidget($class, $properties); $widget = $this->createWidget($class, $properties);
$this->_widgetStack[] = $widget; $this->widgetStack[] = $widget;
return $widget; return $widget;
} }
...@@ -163,8 +170,8 @@ class View extends Component ...@@ -163,8 +170,8 @@ class View extends Component
*/ */
public function endWidget() public function endWidget()
{ {
if (($widget = array_pop($this->_widgetStack)) !== null) { if (($widget = array_pop($this->widgetStack)) !== null) {
echo $widget->run(); $widget->run();
return $widget; return $widget;
} else { } else {
throw new Exception("Unmatched beginWidget() and endWidget() calls."); throw new Exception("Unmatched beginWidget() and endWidget() calls.");
......
...@@ -70,7 +70,6 @@ class Widget extends Component implements Initable ...@@ -70,7 +70,6 @@ class Widget extends Component implements Initable
/** /**
* Executes the widget. * Executes the widget.
* @return string the rendering result of the widget
*/ */
public function run() public function run()
{ {
......
<?php <?php
/** /**
* CChainedCacheDependency class file. * ChainedDependency class file.
* *
* @link http://www.yiiframework.com/ * @link http://www.yiiframework.com/
* @copyright Copyright &copy; 2008-2012 Yii Software LLC * @copyright Copyright &copy; 2008-2012 Yii Software LLC
...@@ -10,12 +10,12 @@ ...@@ -10,12 +10,12 @@
namespace yii\caching; namespace yii\caching;
/** /**
* CChainedCacheDependency represents a list of cache dependencies. * ChainedDependency represents a list of cache dependencies.
* *
* If any of the dependencies reports a dependency change, CChainedCacheDependency * If any of the dependencies reports a dependency change, ChainedDependency
* will return true for the checking. * will return true for the checking.
* *
* To add dependencies to CChainedCacheDependency, use {@link getDependencies Dependencies} * To add dependencies to ChainedDependency, use {@link getDependencies Dependencies}
* which gives a {@link CTypedList} instance and can be used like an array * which gives a {@link CTypedList} instance and can be used like an array
* (see {@link CList} for more details}). * (see {@link CList} for more details}).
* *
...@@ -25,7 +25,7 @@ namespace yii\caching; ...@@ -25,7 +25,7 @@ namespace yii\caching;
* @author Qiang Xue <qiang.xue@gmail.com> * @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0 * @since 2.0
*/ */
class CChainedCacheDependency extends CComponent implements ICacheDependency class ChainedDependency extends Dependency
{ {
private $_dependencies=null; private $_dependencies=null;
......
<?php <?php
/** /**
* CDbCacheDependency class file. * DbDependency class file.
* *
* @link http://www.yiiframework.com/ * @link http://www.yiiframework.com/
* @copyright Copyright &copy; 2008-2012 Yii Software LLC * @copyright Copyright &copy; 2008-2012 Yii Software LLC
...@@ -11,7 +11,7 @@ namespace yii\caching; ...@@ -11,7 +11,7 @@ namespace yii\caching;
/** /**
* CDbCacheDependency represents a dependency based on the query result of a SQL statement. * DbDependency 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. * If the query result (a scalar) changes, the dependency is considered as changed.
* To specify the SQL statement, set {@link sql} property. * To specify the SQL statement, set {@link sql} property.
...@@ -21,12 +21,12 @@ namespace yii\caching; ...@@ -21,12 +21,12 @@ namespace yii\caching;
* @author Qiang Xue <qiang.xue@gmail.com> * @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0 * @since 2.0
*/ */
class CDbCacheDependency extends CCacheDependency class DbDependency extends CacheDependency
{ {
/** /**
* @var string the ID of a {@link CDbConnection} application component. Defaults to 'db'. * @var string the ID of a {@link CDbConnection} application component. Defaults to 'db'.
*/ */
public $connectionID='db'; public $connectionID = 'db';
/** /**
* @var string the SQL statement whose result is used to determine if the dependency has been changed. * @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. * Note, the SQL statement should return back a single value.
...@@ -44,9 +44,9 @@ class CDbCacheDependency extends CCacheDependency ...@@ -44,9 +44,9 @@ class CDbCacheDependency extends CCacheDependency
* Constructor. * Constructor.
* @param string $sql the SQL statement whose result is used to determine if the dependency has been changed. * @param string $sql the SQL statement whose result is used to determine if the dependency has been changed.
*/ */
public function __construct($sql=null) public function __construct($sql = null)
{ {
$this->sql=$sql; $this->sql = $sql;
} }
/** /**
...@@ -56,7 +56,7 @@ class CDbCacheDependency extends CCacheDependency ...@@ -56,7 +56,7 @@ class CDbCacheDependency extends CCacheDependency
*/ */
public function __sleep() public function __sleep()
{ {
$this->_db=null; $this->_db = null;
return array_keys((array)$this); return array_keys((array)$this);
} }
...@@ -65,31 +65,29 @@ class CDbCacheDependency extends CCacheDependency ...@@ -65,31 +65,29 @@ class CDbCacheDependency extends CCacheDependency
* This method returns the value of the global state. * This method returns the value of the global state.
* @return mixed the data needed to determine if dependency has been changed. * @return mixed the data needed to determine if dependency has been changed.
*/ */
protected function generateDependentData() protected function generateDependencyData()
{ {
if($this->sql!==null) if ($this->sql !== null) {
{ $db = $this->getDbConnection();
$db=$this->getDbConnection(); $command = $db->createCommand($this->sql);
$command=$db->createCommand($this->sql); if (is_array($this->params)) {
if(is_array($this->params)) foreach ($this->params as $name => $value) {
{ $command->bindValue($name, $value);
foreach($this->params as $name=>$value) }
$command->bindValue($name,$value);
} }
if($db->queryCachingDuration>0) if ($db->queryCachingDuration > 0) {
{
// temporarily disable and re-enable query caching // temporarily disable and re-enable query caching
$duration=$db->queryCachingDuration; $duration = $db->queryCachingDuration;
$db->queryCachingDuration=0; $db->queryCachingDuration = 0;
$result=$command->queryRow(); $result = $command->queryRow();
$db->queryCachingDuration=$duration; $db->queryCachingDuration = $duration;
} else {
$result = $command->queryRow();
} }
else
$result=$command->queryRow();
return $result; return $result;
} else {
throw new CException(Yii::t('yii', 'DbDependency.sql cannot be empty.'));
} }
else
throw new CException(Yii::t('yii','CDbCacheDependency.sql cannot be empty.'));
} }
/** /**
...@@ -98,15 +96,15 @@ class CDbCacheDependency extends CCacheDependency ...@@ -98,15 +96,15 @@ class CDbCacheDependency extends CCacheDependency
*/ */
protected function getDbConnection() protected function getDbConnection()
{ {
if($this->_db!==null) if ($this->_db !== null) {
return $this->_db; return $this->_db;
else } else {
{ if (($this->_db = \Yii::$application->getComponent($this->connectionID)) instanceof CDbConnection) {
if(($this->_db=\Yii::$application->getComponent($this->connectionID)) instanceof CDbConnection)
return $this->_db; return $this->_db;
else } 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.', throw new CException(Yii::t('yii', 'DbDependency.connectionID "{id}" is invalid. Please make sure it refers to the ID of a CDbConnection application component.',
array('{id}'=>$this->connectionID))); array('{id}' => $this->connectionID)));
}
} }
} }
} }
...@@ -12,37 +12,21 @@ namespace yii\caching; ...@@ -12,37 +12,21 @@ namespace yii\caching;
/** /**
* Dependency is the base class for cache dependency classes. * Dependency is the base class for cache dependency classes.
* *
* Dependency implements the {@link ICacheDependency} interface. * Child classes should override its [[generateDependencyData()]] for generating
* Child classes should override its {@link generateDependentData} for * the actual dependency data.
* actual dependency checking.
* *
* @property boolean $hasChanged Whether the dependency has changed. * @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> * @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0 * @since 2.0
*/ */
class Dependency extends \yii\base\Object abstract class Dependency extends \yii\base\Object
{ {
/** /**
* @var boolean Whether this dependency is reusable or not. * @var mixed the dependency data that is saved in cache and later is compared with the
* If set to true, dependent data for this cache dependency will only be generated once per request. * latest dependency data.
* 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; public $data;
/**
* @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. * Evaluates the dependency by generating and saving the data related with dependency.
...@@ -50,15 +34,7 @@ class Dependency extends \yii\base\Object ...@@ -50,15 +34,7 @@ class Dependency extends \yii\base\Object
*/ */
public function evaluateDependency() public function evaluateDependency()
{ {
if ($this->reuseDependentData) $this->data = $this->generateDependencyData();
{
$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();
} }
/** /**
...@@ -66,47 +42,13 @@ class Dependency extends \yii\base\Object ...@@ -66,47 +42,13 @@ class Dependency extends \yii\base\Object
*/ */
public function getHasChanged() public function getHasChanged()
{ {
if ($this->reuseDependentData) return $this->generateDependencyData() != $this->data;
{
$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. * Generates the data needed to determine if dependency has been changed.
* Derived classes should override this method to generate actual dependent data. * Derived classes should override this method to generate the actual dependency data.
* @return mixed the data needed to determine if dependency has been changed. * @return mixed the data needed to determine if dependency has been changed.
*/ */
protected function generateDependentData() abstract protected function generateDependencyData();
{
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;
}
} }
\ No newline at end of file
<?php <?php
/** /**
* CDirectoryCacheDependency class file. * DirectoryDependency class file.
* *
* @link http://www.yiiframework.com/ * @link http://www.yiiframework.com/
* @copyright Copyright &copy; 2008-2012 Yii Software LLC * @copyright Copyright &copy; 2008-2012 Yii Software LLC
...@@ -11,9 +11,9 @@ namespace yii\caching; ...@@ -11,9 +11,9 @@ namespace yii\caching;
/** /**
* CDirectoryCacheDependency represents a dependency based on change of a directory. * DirectoryDependency represents a dependency based on change of a directory.
* *
* CDirectoryCacheDependency performs dependency checking based on the * DirectoryDependency performs dependency checking based on the
* modification time of the files contained in the specified directory. * modification time of the files contained in the specified directory.
* The directory being checked is specified via {@link directory}. * The directory being checked is specified via {@link directory}.
* *
...@@ -29,7 +29,7 @@ namespace yii\caching; ...@@ -29,7 +29,7 @@ namespace yii\caching;
* @author Qiang Xue <qiang.xue@gmail.com> * @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0 * @since 2.0
*/ */
class CDirectoryCacheDependency extends CCacheDependency class DirectoryDependency extends Dependency
{ {
/** /**
* @var string the directory whose change is used to determine if the dependency has been changed. * @var string the directory whose change is used to determine if the dependency has been changed.
...@@ -41,7 +41,7 @@ class CDirectoryCacheDependency extends CCacheDependency ...@@ -41,7 +41,7 @@ class CDirectoryCacheDependency extends CCacheDependency
* If the value is less than 0, it means unlimited depth. * 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. * If the value is 0, it means checking the files directly under the specified directory.
*/ */
public $recursiveLevel=-1; public $recursiveLevel = -1;
/** /**
* @var string the regular expression matching valid file/directory names. * @var string the regular expression matching valid file/directory names.
* Only the matching files or directories will be checked for changes. * Only the matching files or directories will be checked for changes.
...@@ -53,9 +53,9 @@ class CDirectoryCacheDependency extends CCacheDependency ...@@ -53,9 +53,9 @@ class CDirectoryCacheDependency extends CCacheDependency
* Constructor. * Constructor.
* @param string $directory the directory to be checked * @param string $directory the directory to be checked
*/ */
public function __construct($directory=null) public function __construct($directory = null)
{ {
$this->directory=$directory; $this->directory = $directory;
} }
/** /**
...@@ -63,12 +63,13 @@ class CDirectoryCacheDependency extends CCacheDependency ...@@ -63,12 +63,13 @@ class CDirectoryCacheDependency extends CCacheDependency
* This method returns the modification timestamps for files under the directory. * This method returns the modification timestamps for files under the directory.
* @return mixed the data needed to determine if dependency has been changed. * @return mixed the data needed to determine if dependency has been changed.
*/ */
protected function generateDependentData() protected function generateDependencyData()
{ {
if($this->directory!==null) if ($this->directory !== null) {
return $this->generateTimestamps($this->directory); return $this->generateTimestamps($this->directory);
else } else {
throw new CException(Yii::t('yii','CDirectoryCacheDependency.directory cannot be empty.')); throw new CException(Yii::t('yii', 'DirectoryDependency.directory cannot be empty.'));
}
} }
/** /**
...@@ -78,28 +79,29 @@ class CDirectoryCacheDependency extends CCacheDependency ...@@ -78,28 +79,29 @@ class CDirectoryCacheDependency extends CCacheDependency
* @param integer $level level of the recursion * @param integer $level level of the recursion
* @return array list of file modification time indexed by the file path * @return array list of file modification time indexed by the file path
*/ */
protected function generateTimestamps($directory,$level=0) protected function generateTimestamps($directory, $level = 0)
{ {
if(($dir=@opendir($directory))===false) if (($dir = @opendir($directory)) === false) {
throw new CException(Yii::t('yii','"{path}" is not a valid directory.', throw new CException(Yii::t('yii', '"{path}" is not a valid directory.',
array('{path}'=>$directory))); array('{path}' => $directory)));
$timestamps=array(); }
while(($file=readdir($dir))!==false) $timestamps = array();
{ while (($file = readdir($dir)) !== false) {
$path=$directory.DIRECTORY_SEPARATOR.$file; $path = $directory . DIRECTORY_SEPARATOR . $file;
if($file==='.' || $file==='..') if ($file === '.' || $file === '..') {
continue; continue;
if($this->namePattern!==null && !preg_match($this->namePattern,$file)) }
if ($this->namePattern !== null && !preg_match($this->namePattern, $file)) {
continue; continue;
if(is_file($path))
{
if($this->validateFile($path))
$timestamps[$path]=filemtime($path);
} }
else if (is_file($path)) {
{ if ($this->validateFile($path)) {
if(($this->recursiveLevel<0 || $level<$this->recursiveLevel) && $this->validateDirectory($path)) $timestamps[$path] = filemtime($path);
$timestamps=array_merge($timestamps, $this->generateTimestamps($path,$level+1)); }
} else {
if (($this->recursiveLevel < 0 || $level < $this->recursiveLevel) && $this->validateDirectory($path)) {
$timestamps = array_merge($timestamps, $this->generateTimestamps($path, $level + 1));
}
} }
} }
closedir($dir); closedir($dir);
......
...@@ -45,7 +45,7 @@ class CExpressionDependency extends CCacheDependency ...@@ -45,7 +45,7 @@ class CExpressionDependency extends CCacheDependency
* This method returns the result of the PHP expression. * This method returns the result of the PHP expression.
* @return mixed the data needed to determine if dependency has been changed. * @return mixed the data needed to determine if dependency has been changed.
*/ */
protected function generateDependentData() protected function generateDependencyData()
{ {
return $this->evaluateExpression($this->expression); return $this->evaluateExpression($this->expression);
} }
......
<?php <?php
/** /**
* CFileCacheDependency class file. * FileDependency class file.
* *
* @link http://www.yiiframework.com/ * @link http://www.yiiframework.com/
* @copyright Copyright &copy; 2008-2012 Yii Software LLC * @copyright Copyright &copy; 2008-2012 Yii Software LLC
...@@ -9,19 +9,16 @@ ...@@ -9,19 +9,16 @@
namespace yii\caching; namespace yii\caching;
/** /**
* CFileCacheDependency represents a dependency based on a file's last modification time. * FileDependency represents a dependency based on a file's last modification time.
* *
* CFileCacheDependency performs dependency checking based on the * If th last modification time of the file specified via [[fileName]] is changed,
* last modification time of the file specified via {@link fileName}. * the dependency is considered as changed.
* 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> * @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0 * @since 2.0
*/ */
class CFileCacheDependency extends CCacheDependency class FileDependency extends Dependency
{ {
/** /**
* @var string the name of the file whose last modification time is used to * @var string the name of the file whose last modification time is used to
...@@ -33,9 +30,9 @@ class CFileCacheDependency extends CCacheDependency ...@@ -33,9 +30,9 @@ class CFileCacheDependency extends CCacheDependency
* Constructor. * Constructor.
* @param string $fileName name of the file whose change is to be checked. * @param string $fileName name of the file whose change is to be checked.
*/ */
public function __construct($fileName=null) public function __construct($fileName = null)
{ {
$this->fileName=$fileName; $this->fileName = $fileName;
} }
/** /**
...@@ -43,11 +40,8 @@ class CFileCacheDependency extends CCacheDependency ...@@ -43,11 +40,8 @@ class CFileCacheDependency extends CCacheDependency
* This method returns the file's last modification time. * This method returns the file's last modification time.
* @return mixed the data needed to determine if dependency has been changed. * @return mixed the data needed to determine if dependency has been changed.
*/ */
protected function generateDependentData() protected function generateDependencyData()
{ {
if($this->fileName!==null) return $this->fileName !== null ? @filemtime($this->fileName) : 0;
return @filemtime($this->fileName);
else
throw new CException(Yii::t('yii','CFileCacheDependency.fileName cannot be empty.'));
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment