Commit 5c6966c3 by Qiang Xue

Merge branch 'master' of git.yiisoft.com:yii2

parents 80dbaaca 2f3cc8f1
......@@ -11,17 +11,27 @@ namespace yii\base;
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class Filter extends Behavior
class ActionFilter extends Behavior
{
/**
* @var array list of action IDs that this filter should apply to. If this property is not set,
* then the filter applies to all actions, unless they are listed in [[except]].
*/
public $only;
/**
* @var array list of action IDs that this filter should not apply to.
*/
public $except = array();
/**
* Declares event handlers for the [[owner]]'s events.
* @return array events (array keys) and the corresponding event handler methods (array values).
*/
public function events()
{
return array(
'beforeAction' => 'beforeAction',
'afterAction' => 'afterAction',
'beforeAction' => 'beforeFilter',
'afterAction' => 'afterFilter',
);
}
......@@ -29,8 +39,11 @@ class Filter extends Behavior
* @param ActionEvent $event
* @return boolean
*/
public function beforeAction($event)
public function beforeFilter($event)
{
if ($this->isActive($event->action)) {
$event->isValid = $this->beforeAction($event->action);
}
return $event->isValid;
}
......@@ -38,8 +51,40 @@ class Filter extends Behavior
* @param ActionEvent $event
* @return boolean
*/
public function afterAction($event)
public function afterFilter($event)
{
if ($this->isActive($event->action)) {
$this->afterAction($event->action);
}
}
/**
* This method is invoked right before an action is to be executed (after all possible filters.)
* You may override this method to do last-minute preparation for the action.
* @param Action $action the action to be executed.
* @return boolean whether the action should continue to be executed.
*/
public function beforeAction($action)
{
return true;
}
/**
* This method is invoked right after an action is executed.
* You may override this method to do some postprocessing for the action.
* @param Action $action the action just executed.
*/
public function afterAction($action)
{
}
/**
* Returns a value indicating whether the filer is active for the given action.
* @param Action $action the action being filtered
* @return boolean whether the filer is active for the given action.
*/
protected function isActive($action)
{
return !in_array($action->id, $this->except, true) && (empty($this->only) || in_array($action->id, $this->only, true));
}
}
\ No newline at end of file
......@@ -337,15 +337,16 @@ class View extends Component
* ~~~
*
* @param string $id a unique ID identifying the fragment to be cached.
* @param array $properties initial property values for [[\yii\widgets\OutputCache]]
* @param array $properties initial property values for [[\yii\widgets\FragmentCache]]
* @return boolean whether you should generate the content for caching.
* False if the cached version is available.
*/
public function beginCache($id, $properties = array())
{
$properties['id'] = $id;
/** @var $cache \yii\widgets\FragmentCache */
$cache = $this->beginWidget('yii\widgets\OutputCache', $properties);
if ($cache->getIsContentCached()) {
if ($cache->getCachedContent() !== false) {
$this->endCache();
return false;
} else {
......
......@@ -8,6 +8,7 @@
namespace yii\caching;
use yii\base\Component;
use yii\helpers\StringHelper;
/**
* Cache is the base class for cache classes supporting different cache storage implementation.
......@@ -70,13 +71,13 @@ abstract class Cache extends Component implements \ArrayAccess
/**
* Builds a normalized cache key from one or multiple parameters.
* Builds a normalized cache key from a given key.
*
* The generated key contains letters and digits only, and its length is no more than 32.
*
* If only one parameter is given and it is already a normalized key, then
* it will be returned back without change. Otherwise, a normalized key
* is generated by serializing all given parameters and applying MD5 hashing.
* If the given key is a string containing alphanumeric characters only and no more than 32 characters,
* then the key will be returned back without change. Otherwise, a normalized key
* is generated by serializing the given key and applying MD5 hashing.
*
* The following example builds a cache key using three parameters:
*
......@@ -84,16 +85,15 @@ abstract class Cache extends Component implements \ArrayAccess
* $key = $cache->buildKey($className, $method, $id);
* ~~~
*
* @param string $key the first parameter
* @param array|string $key the key to be normalized
* @return string the generated cache key
*/
public function buildKey($key)
{
if (func_num_args() === 1 && ctype_alnum($key) && strlen($key) <= 32) {
return (string)$key;
if (is_string($key)) {
return ctype_alnum($key) && StringHelper::strlen($key) <= 32 ? $key : md5($key);
} else {
$params = func_get_args();
return md5(json_encode($params));
return md5(json_encode($key));
}
}
......
......@@ -7,15 +7,15 @@
namespace yii\caching;
use Yii;
use yii\base\InvalidConfigException;
use yii\db\Connection;
use yii\db\Query;
/**
* DbDependency represents a dependency based on the query result of a SQL statement.
*
* If the query result changes, the dependency is considered as changed.
* The query is specified via the [[query]] property.
* The query is specified via the [[sql]] property.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
......@@ -27,23 +27,25 @@ class DbDependency extends Dependency
*/
public $connectionID = 'db';
/**
* @var Query the SQL query whose result is used to determine if the dependency has been changed.
* @var string the SQL query whose result is used to determine if the dependency has been changed.
* Only the first row of the query result will be used.
*/
public $query;
public $sql;
/**
* @var Connection the DB connection instance
* @var array the parameters (name=>value) to be bound to the SQL statement specified by [[sql]].
*/
private $_db;
public $params;
/**
* Constructor.
* @param Query $query the SQL query whose result is used to determine if the dependency has been changed.
* @param string $sql the SQL query whose result is used to determine if the dependency has been changed.
* @param array $params the parameters (name=>value) to be bound to the SQL statement specified by [[sql]].
* @param array $config name-value pairs that will be used to initialize the object properties
*/
public function __construct($query = null, $config = array())
public function __construct($sql, $params = array(), $config = array())
{
$this->query = $query;
$this->sql = $sql;
$this->params = $params;
parent::__construct($config);
}
......@@ -66,22 +68,23 @@ class DbDependency extends Dependency
protected function generateDependencyData()
{
$db = $this->getDb();
/**
* @var \yii\db\Command $command
*/
$command = $this->query->createCommand($db);
if ($db->enableQueryCache) {
// temporarily disable and re-enable query caching
$db->enableQueryCache = false;
$result = $command->queryRow();
$result = $db->createCommand($this->sql, $this->params)->queryRow();
$db->enableQueryCache = true;
} else {
$result = $command->queryRow();
$result = $db->createCommand($this->sql, $this->params)->queryRow();
}
return $result;
}
/**
* @var Connection the DB connection instance
*/
private $_db;
/**
* Returns the DB connection instance used for caching purpose.
* @return Connection the DB connection instance
* @throws InvalidConfigException if [[connectionID]] does not point to a valid application component.
......@@ -89,11 +92,11 @@ class DbDependency extends Dependency
public function getDb()
{
if ($this->_db === null) {
$db = \Yii::$app->getComponent($this->connectionID);
$db = Yii::$app->getComponent($this->connectionID);
if ($db instanceof Connection) {
$this->_db = $db;
} else {
throw new InvalidConfigException("DbCache::connectionID must refer to the ID of a DB application component.");
throw new InvalidConfigException("DbCacheDependency::connectionID must refer to the ID of a DB application component.");
}
}
return $this->_db;
......
......@@ -389,7 +389,13 @@ class Command extends \yii\base\Component
}
if (isset($cache)) {
$cacheKey = $cache->buildKey(__CLASS__, $db->dsn, $db->username, $sql, $paramLog);
$cacheKey = $cache->buildKey(array(
__CLASS__,
$db->dsn,
$db->username,
$sql,
$paramLog,
));
if (($result = $cache->get($cacheKey)) !== false) {
\Yii::trace('Query result found in cache', __CLASS__);
return $result;
......
......@@ -109,7 +109,12 @@ abstract class Schema extends \yii\base\Object
*/
public function getCacheKey($cache, $name)
{
return $cache->buildKey(__CLASS__, $this->db->dsn, $this->db->username, $name);
return $cache->buildKey(array(
__CLASS__,
$this->db->dsn,
$this->db->username,
$name,
));
}
/**
......
......@@ -7,15 +7,7 @@
namespace yii\helpers;
// todo define how subclassing will work
// todo add a run() or render() method
// todo test this on all kinds of terminals, especially windows (check out lib ncurses)
// todo not sure if all methods should be static
// todo subclass DetailView
// todo subclass GridView
// todo more subclasses
/**
* Console View is the base class for console view components
......
......@@ -45,6 +45,7 @@ class CacheSession extends Session
{
return true;
}
/**
* Returns the cache instance used for storing session data.
* @return Cache the cache instance
......@@ -114,6 +115,6 @@ class CacheSession extends Session
*/
protected function calculateKey($id)
{
return $this->getCache()->buildKey(__CLASS__, $id);
return $this->getCache()->buildKey(array(__CLASS__, $id));
}
}
- console
* If console is executed using Windows, do not use colors. If not, use colors. Allow to override via console application settings.
- db
* pgsql, sql server, oracle, db2 drivers
* unit tests on different DB drivers
* document-based (should allow storage-specific methods additionally to generic ones)
* mongodb (put it under framework/db/mongodb)
* key-value-based (should allow storage-specific methods additionally to generic ones)
* redis (put it under framework/db/redis or perhaps framework/caching?)
- base
* TwigViewRenderer (Alex)
* SmartyViewRenderer (Alex)
- logging
* WebTarget (TBD after web is in place): should consider using javascript and make it into a toolbar
* ProfileTarget (TBD after web is in place): should consider using javascript and make it into a toolbar
* unit tests
- caching
* backend-specific unit tests
* dependency unit tests
- validators
* Refactor validators to add validateValue() for every validator, if possible. Check if value is an array.
......
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