From 0b13c43466ae7531a08e6830b383891a241897f6 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Sun, 24 Nov 2013 20:48:40 -0500 Subject: [PATCH 1/7] refactored redis cache. --- extensions/redis/Cache.php | 71 ++++++++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 34 deletions(-) diff --git a/extensions/redis/Cache.php b/extensions/redis/Cache.php index f1a21ed..a7a535c 100644 --- a/extensions/redis/Cache.php +++ b/extensions/redis/Cache.php @@ -7,6 +7,9 @@ namespace yii\redis; +use Yii; +use yii\base\InvalidConfigException; + /** * Redis Cache implements a cache application component based on [redis](http://redis.io/) key-value store. * @@ -46,13 +49,30 @@ namespace yii\redis; class Cache extends \yii\caching\Cache { /** - * @var string the id of the application component to use as the redis connection. - * It should be configured as a [[yii\redis\Connection]]. Defaults to `redis`. + * @var Connection|string the Redis [[Connection]] object or the application component ID of the Redis [[Connection]]. + * After the Cache object is created, if you want to change this property, you should only assign it + * with a Redis [[Connection]] object. */ - public $connectionId = 'redis'; + public $redis = 'redis'; /** + * Initializes the DbCache component. + * This method will initialize the [[db]] property to make sure it refers to a valid DB connection. + * @throws InvalidConfigException if [[db]] is invalid. + */ + public function init() + { + parent::init(); + if (is_string($this->redis)) { + $this->redis = Yii::$app->getComponent($this->redis); + } + if (!$this->redis instanceof Connection) { + throw new InvalidConfigException("Cache::redis must be either a Redis connection instance or the application component ID of a Redis connection."); + } + } + + /** * Checks whether a specified key exists in the cache. * This can be faster than getting the value from the cache if the data is big. * Note that this method does not check whether the dependency associated @@ -64,9 +84,7 @@ class Cache extends \yii\caching\Cache */ public function exists($key) { - /** @var Connection $connection */ - $connection = \Yii::$app->getComponent($this->connectionId); - return (bool) $connection->executeCommand('EXISTS', [$this->buildKey($key)]); + return (bool) $this->redis->executeCommand('EXISTS', [$this->buildKey($key)]); } /** @@ -74,9 +92,7 @@ class Cache extends \yii\caching\Cache */ protected function getValue($key) { - /** @var Connection $connection */ - $connection = \Yii::$app->getComponent($this->connectionId); - return $connection->executeCommand('GET', [$key]); + return $this->redis->executeCommand('GET', [$key]); } /** @@ -84,9 +100,7 @@ class Cache extends \yii\caching\Cache */ protected function getValues($keys) { - /** @var Connection $connection */ - $connection = \Yii::$app->getComponent($this->connectionId); - $response = $connection->executeCommand('MGET', $keys); + $response = $this->redis->executeCommand('MGET', $keys); $result = []; $i = 0; foreach ($keys as $key) { @@ -100,13 +114,11 @@ class Cache extends \yii\caching\Cache */ protected function setValue($key, $value, $expire) { - /** @var Connection $connection */ - $connection = \Yii::$app->getComponent($this->connectionId); if ($expire == 0) { - return (bool) $connection->executeCommand('SET', [$key, $value]); + return (bool) $this->redis->executeCommand('SET', [$key, $value]); } else { $expire = (int) ($expire * 1000); - return (bool) $connection->executeCommand('SET', [$key, $value, 'PX', $expire]); + return (bool) $this->redis->executeCommand('SET', [$key, $value, 'PX', $expire]); } } @@ -115,9 +127,6 @@ class Cache extends \yii\caching\Cache */ protected function setValues($data, $expire) { - /** @var Connection $connection */ - $connection = \Yii::$app->getComponent($this->connectionId); - $args = []; foreach($data as $key => $value) { $args[] = $key; @@ -126,17 +135,17 @@ class Cache extends \yii\caching\Cache $failedKeys = []; if ($expire == 0) { - $connection->executeCommand('MSET', $args); + $this->redis->executeCommand('MSET', $args); } else { $expire = (int) ($expire * 1000); - $connection->executeCommand('MULTI'); - $connection->executeCommand('MSET', $args); + $this->redis->executeCommand('MULTI'); + $this->redis->executeCommand('MSET', $args); $index = []; foreach ($data as $key => $value) { - $connection->executeCommand('PEXPIRE', [$key, $expire]); + $this->redis->executeCommand('PEXPIRE', [$key, $expire]); $index[] = $key; } - $result = $connection->executeCommand('EXEC'); + $result = $this->redis->executeCommand('EXEC'); array_shift($result); foreach($result as $i => $r) { if ($r != 1) { @@ -152,13 +161,11 @@ class Cache extends \yii\caching\Cache */ protected function addValue($key, $value, $expire) { - /** @var Connection $connection */ - $connection = \Yii::$app->getComponent($this->connectionId); if ($expire == 0) { - return (bool) $connection->executeCommand('SET', [$key, $value, 'NX']); + return (bool) $this->redis->executeCommand('SET', [$key, $value, 'NX']); } else { $expire = (int) ($expire * 1000); - return (bool) $connection->executeCommand('SET', [$key, $value, 'PX', $expire, 'NX']); + return (bool) $this->redis->executeCommand('SET', [$key, $value, 'PX', $expire, 'NX']); } } @@ -167,9 +174,7 @@ class Cache extends \yii\caching\Cache */ protected function deleteValue($key) { - /** @var Connection $connection */ - $connection = \Yii::$app->getComponent($this->connectionId); - return (bool) $connection->executeCommand('DEL', [$key]); + return (bool) $this->redis->executeCommand('DEL', [$key]); } /** @@ -177,8 +182,6 @@ class Cache extends \yii\caching\Cache */ protected function flushValues() { - /** @var Connection $connection */ - $connection = \Yii::$app->getComponent($this->connectionId); - return $connection->executeCommand('FLUSHDB'); + return $this->redis->executeCommand('FLUSHDB'); } } From c6318050d99044a2714ad1a72c8021f20a725d62 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Sun, 24 Nov 2013 21:29:11 -0500 Subject: [PATCH 2/7] removed unneeded setting. --- apps/advanced/backend/config/main.php | 3 --- apps/advanced/frontend/config/main.php | 3 --- apps/basic/config/web.php | 3 --- 3 files changed, 9 deletions(-) diff --git a/apps/advanced/backend/config/main.php b/apps/advanced/backend/config/main.php index f2745e2..c745a1f 100644 --- a/apps/advanced/backend/config/main.php +++ b/apps/advanced/backend/config/main.php @@ -17,9 +17,6 @@ return [ 'modules' => [], 'extensions' => require($rootDir . '/vendor/yiisoft/extensions.php'), 'components' => [ - 'request' => [ - 'enableCsrfValidation' => true, - ], 'db' => $params['components.db'], 'cache' => $params['components.cache'], 'mail' => $params['components.mail'], diff --git a/apps/advanced/frontend/config/main.php b/apps/advanced/frontend/config/main.php index e0fd2de..6ee8ae5 100644 --- a/apps/advanced/frontend/config/main.php +++ b/apps/advanced/frontend/config/main.php @@ -18,9 +18,6 @@ return [ ], 'extensions' => require($rootDir . '/vendor/yiisoft/extensions.php'), 'components' => [ - 'request' => [ - 'enableCsrfValidation' => true, - ], 'db' => $params['components.db'], 'cache' => $params['components.cache'], 'mail' => $params['components.mail'], diff --git a/apps/basic/config/web.php b/apps/basic/config/web.php index cf921b0..6124c4f 100644 --- a/apps/basic/config/web.php +++ b/apps/basic/config/web.php @@ -5,9 +5,6 @@ $config = [ 'basePath' => dirname(__DIR__), 'extensions' => require(__DIR__ . '/../vendor/yiisoft/extensions.php'), 'components' => [ - 'request' => [ - 'enableCsrfValidation' => true, - ], 'cache' => [ 'class' => 'yii\caching\FileCache', ], From b5c73a37247a52859ec4673590042c26f7d690ee Mon Sep 17 00:00:00 2001 From: Carsten Brandt Date: Mon, 25 Nov 2013 13:21:54 +0100 Subject: [PATCH 3/7] allow redis connection to be configure directly in cache fixes #1316 --- extensions/redis/Cache.php | 39 +++++++++++++++++++++++++++++---------- extensions/redis/README.md | 20 ++++++++++++++++++++ 2 files changed, 49 insertions(+), 10 deletions(-) diff --git a/extensions/redis/Cache.php b/extensions/redis/Cache.php index a7a535c..0dcb18a 100644 --- a/extensions/redis/Cache.php +++ b/extensions/redis/Cache.php @@ -30,13 +30,25 @@ use yii\base\InvalidConfigException; * 'components' => [ * 'cache' => [ * 'class' => 'yii\redis\Cache', + * 'redis' => [ + * 'hostname' => 'localhost', + * 'port' => 6379, + * 'database' => 0, + * ] + * ], + * ], + * ] + * ~~~ + * + * Or if you have configured the redis connection as an application component, the following is sufficient: + * + * ~~~ + * [ + * 'components' => [ + * 'cache' => [ + * 'class' => 'yii\redis\Cache', + * // 'redis' => 'redis' // id of the connection application component * ], - * 'redis' => [ - * 'class' => 'yii\redis\Connection', - * 'hostname' => 'localhost', - * 'port' => 6379, - * 'database' => 0, - * ] * ], * ] * ~~~ @@ -49,7 +61,9 @@ use yii\base\InvalidConfigException; class Cache extends \yii\caching\Cache { /** - * @var Connection|string the Redis [[Connection]] object or the application component ID of the Redis [[Connection]]. + * @var Connection|string|array the Redis [[Connection]] object or the application component ID of the Redis [[Connection]]. + * This can also be an array that is used to create a redis [[Connection]] instance in case you do not want do configure + * redis connection as an application component. * After the Cache object is created, if you want to change this property, you should only assign it * with a Redis [[Connection]] object. */ @@ -57,15 +71,20 @@ class Cache extends \yii\caching\Cache /** - * Initializes the DbCache component. - * This method will initialize the [[db]] property to make sure it refers to a valid DB connection. - * @throws InvalidConfigException if [[db]] is invalid. + * Initializes the redis Cache component. + * This method will initialize the [[redis]] property to make sure it refers to a valid redis connection. + * @throws InvalidConfigException if [[redis]] is invalid. */ public function init() { parent::init(); if (is_string($this->redis)) { $this->redis = Yii::$app->getComponent($this->redis); + } else if (is_array($this->redis)) { + if (!isset($this->redis['class'])) { + $this->redis['class'] = Connection::className(); + } + $this->redis = Yii::createObject($this->redis); } if (!$this->redis instanceof Connection) { throw new InvalidConfigException("Cache::redis must be either a Redis connection instance or the application component ID of a Redis connection."); diff --git a/extensions/redis/README.md b/extensions/redis/README.md index 28cecf1..f3777e8 100644 --- a/extensions/redis/README.md +++ b/extensions/redis/README.md @@ -35,6 +35,26 @@ return [ ]; ``` +If you only use the redis cache, you can also configure the parameters of the connection within the +cache component: + +```php +return [ + //.... + 'components' => [ + // ... + 'cache' => [ + 'class' => 'yii\redis\Cache', + 'redis' => [ + 'hostname' => 'localhost', + 'port' => 6379, + 'database' => 0, + ], + ], + ] +]; +``` + Installation ------------ From 3cb366020ac35b9a512e6eb0cd2a641f87626466 Mon Sep 17 00:00:00 2001 From: Carsten Brandt Date: Mon, 25 Nov 2013 14:39:21 +0100 Subject: [PATCH 4/7] added redis Session as suggested in issue #1316 --- extensions/redis/Cache.php | 2 +- extensions/redis/README.md | 121 +++++++++++++++++++++++++------ extensions/redis/Session.php | 157 ++++++++++++++++++++++++++++++++++++++++ extensions/redis/composer.json | 4 +- framework/yii/caching/Cache.php | 2 +- 5 files changed, 258 insertions(+), 28 deletions(-) create mode 100644 extensions/redis/Session.php diff --git a/extensions/redis/Cache.php b/extensions/redis/Cache.php index 0dcb18a..2b7e9e1 100644 --- a/extensions/redis/Cache.php +++ b/extensions/redis/Cache.php @@ -40,7 +40,7 @@ use yii\base\InvalidConfigException; * ] * ~~~ * - * Or if you have configured the redis connection as an application component, the following is sufficient: + * Or if you have configured the redis [[Connection]] as an application component, the following is sufficient: * * ~~~ * [ diff --git a/extensions/redis/README.md b/extensions/redis/README.md index f3777e8..a24ca43 100644 --- a/extensions/redis/README.md +++ b/extensions/redis/README.md @@ -1,9 +1,9 @@ -Redis Cache and ActiveRecord for Yii 2 -====================================== +Redis Cache, Session and ActiveRecord for Yii 2 +=============================================== This extension provides the [redis](http://redis.io/) key-value store support for the Yii2 framework. -It includes a `Cache` class and implents the `ActiveRecord` pattern that allows you to store active -records in redis. +It includes a `Cache` and `Session` storage handler and implents the `ActiveRecord` pattern that allows +you to store active records in redis. To use this extension, you have to configure the Connection class in your application configuration: @@ -21,7 +21,31 @@ return [ ]; ``` -To use the `Cache` component, you also have to configure the `cache` component to be `yii\redis\Cache`: +Installation +------------ + +The preferred way to install this extension is through [composer](http://getcomposer.org/download/). + +Either run + +``` +php composer.phar require yiisoft/yii2-redis "*" +``` + +or add + +```json +"yiisoft/yii2-redis": "*" +``` + +to the require section of your composer.json. + + +Using the Cache component +------------------------- + +To use the `Cache` component, in addtition to configuring the connection as described above, +you also have to configure the `cache` component to be `yii\redis\Cache`: ```php return [ @@ -36,7 +60,7 @@ return [ ``` If you only use the redis cache, you can also configure the parameters of the connection within the -cache component: +cache component (no connection application component needs to be configured in this case): ```php return [ @@ -55,26 +79,44 @@ return [ ]; ``` +Using the Session component +--------------------------- -Installation ------------- - -The preferred way to install this extension is through [composer](http://getcomposer.org/download/). +To use the `Session` component, in addtition to configuring the connection as described above, +you also have to configure the `session` component to be `yii\redis\Session`: -Either run - -``` -php composer.phar require yiisoft/yii2-redis "*" +```php +return [ + //.... + 'components' => [ + // ... + 'session' => [ + 'class' => 'yii\redis\Session', + ], + ] +]; ``` -or add +If you only use the redis session, you can also configure the parameters of the connection within the +cache component (no connection application component needs to be configured in this case): -```json -"yiisoft/yii2-redis": "*" +```php +return [ + //.... + 'components' => [ + // ... + 'session' => [ + 'class' => 'yii\redis\Session', + 'redis' => [ + 'hostname' => 'localhost', + 'port' => 6379, + 'database' => 0, + ], + ], + ] +]; ``` -to the require section of your composer.json. - Using the redis ActiveRecord ---------------------------- @@ -92,10 +134,29 @@ The following is an example model called `Customer`: ```php class Customer extends \yii\redis\ActiveRecord { - public function attributes() - { - return ['id', 'name', 'address', 'registration_date']; - } + /** + * @return array the list of attributes for this record + */ + public function attributes() + { + return ['id', 'name', 'address', 'registration_date']; + } + + /** + * @return ActiveRelation defines a relation to the Order record (can be in other database, e.g. elasticsearch or sql) + */ + public function getOrders() + { + return $this->hasMany(Order::className(), ['customer_id' => 'id']); + } + + /** + * Defines a scope that modifies the `$query` to return only active(status = 1) customers + */ + public static function active($query) + { + $query->andWhere(array('status' => 1)); + } } ``` @@ -108,4 +169,16 @@ It supports the same interface and features except the following limitations: (orderBy() is not yet implemented: [#1305](https://github.com/yiisoft/yii2/issues/1305)) - `via`-relations can not be defined via a table as there are not tables in redis. You can only define relations via other records. -It is also possible to define relations from redis ActiveRecords to normal ActiveRecord classes and vice versa. \ No newline at end of file +It is also possible to define relations from redis ActiveRecords to normal ActiveRecord classes and vice versa. + +Usage example: + +```php +$customer = new Customer(); +$customer->attributes = ['name' => 'test']; +$customer->save(); +echo $customer->id; // id will automatically be incremented if not set explicitly + +$customer = Customer::find()->where(['name' => 'test'])->one(); // find by query +$customer = Customer::find()->active()->all(); // find all by query (using the `active` scope) +``` \ No newline at end of file diff --git a/extensions/redis/Session.php b/extensions/redis/Session.php new file mode 100644 index 0000000..09a0dd4 --- /dev/null +++ b/extensions/redis/Session.php @@ -0,0 +1,157 @@ + [ + * 'session' => [ + * 'class' => 'yii\redis\Session', + * 'redis' => [ + * 'hostname' => 'localhost', + * 'port' => 6379, + * 'database' => 0, + * ] + * ], + * ], + * ] + * ~~~ + * + * Or if you have configured the redis [[Connection]] as an application component, the following is sufficient: + * + * ~~~ + * [ + * 'components' => [ + * 'session' => [ + * 'class' => 'yii\redis\Session', + * // 'redis' => 'redis' // id of the connection application component + * ], + * ], + * ] + * ~~~ + * + * @property boolean $useCustomStorage Whether to use custom storage. This property is read-only. + * + * @author Carsten Brandt + * @since 2.0 + */ +class Session extends \yii\web\Session +{ + /** + * @var Connection|string|array the Redis [[Connection]] object or the application component ID of the Redis [[Connection]]. + * This can also be an array that is used to create a redis [[Connection]] instance in case you do not want do configure + * redis connection as an application component. + * After the Session object is created, if you want to change this property, you should only assign it + * with a Redis [[Connection]] object. + */ + public $redis = 'redis'; + /** + * @var string a string prefixed to every cache key so that it is unique. If not set, + * it will use a prefix generated from [[Application::id]]. You may set this property to be an empty string + * if you don't want to use key prefix. It is recommended that you explicitly set this property to some + * static value if the cached data needs to be shared among multiple applications. + * + * To ensure interoperability, only alphanumeric characters should be used. + */ + public $keyPrefix; + + + /** + * Initializes the redis Session component. + * This method will initialize the [[redis]] property to make sure it refers to a valid redis connection. + * @throws InvalidConfigException if [[redis]] is invalid. + */ + public function init() + { + parent::init(); + if (is_string($this->redis)) { + $this->redis = Yii::$app->getComponent($this->redis); + } else if (is_array($this->redis)) { + if (!isset($this->redis['class'])) { + $this->redis['class'] = Connection::className(); + } + $this->redis = Yii::createObject($this->redis); + } + if (!$this->redis instanceof Connection) { + throw new InvalidConfigException("Session::redis must be either a Redis connection instance or the application component ID of a Redis connection."); + } + if ($this->keyPrefix === null) { + $this->keyPrefix = substr(md5(Yii::$app->id), 0, 5); + } elseif (!ctype_alnum($this->keyPrefix)) { + throw new InvalidConfigException(get_class($this) . '::keyPrefix should only contain alphanumeric characters.'); + } + } + + /** + * Returns a value indicating whether to use custom session storage. + * This method overrides the parent implementation and always returns true. + * @return boolean whether to use custom storage. + */ + public function getUseCustomStorage() + { + return true; + } + + /** + * Session read handler. + * Do not call this method directly. + * @param string $id session ID + * @return string the session data + */ + public function readSession($id) + { + $data = $this->redis->executeCommand('GET', [$this->calculateKey($id)]); + return $data === false ? '' : $data; + } + + /** + * Session write handler. + * Do not call this method directly. + * @param string $id session ID + * @param string $data session data + * @return boolean whether session write is successful + */ + public function writeSession($id, $data) + { + return (bool) $this->redis->executeCommand('SET', [$this->calculateKey($id), $data, 'EX', $this->getTimeout()]); + } + + /** + * Session destroy handler. + * Do not call this method directly. + * @param string $id session ID + * @return boolean whether session is destroyed successfully + */ + public function destroySession($id) + { + return (bool) $this->redis->executeCommand('DEL', [$this->calculateKey($id)]); + } + + /** + * Generates a unique key used for storing session data in cache. + * @param string $id session variable name + * @return string a safe cache key associated with the session variable name + */ + protected function calculateKey($id) + { + return $this->keyPrefix . md5(json_encode([__CLASS__, $id])); + } +} diff --git a/extensions/redis/composer.json b/extensions/redis/composer.json index fb5065b..16807ae 100644 --- a/extensions/redis/composer.json +++ b/extensions/redis/composer.json @@ -1,7 +1,7 @@ { "name": "yiisoft/yii2-redis", - "description": "Redis Cache and ActiveRecord for the Yii framework", - "keywords": ["yii", "redis", "active-record", "cache"], + "description": "Redis Cache, Session and ActiveRecord for the Yii framework", + "keywords": ["yii", "redis", "active-record", "cache", "session"], "type": "yii2-extension", "license": "BSD-3-Clause", "support": { diff --git a/framework/yii/caching/Cache.php b/framework/yii/caching/Cache.php index 41a25b2..371f91a 100644 --- a/framework/yii/caching/Cache.php +++ b/framework/yii/caching/Cache.php @@ -58,7 +58,7 @@ abstract class Cache extends Component implements \ArrayAccess * if you don't want to use key prefix. It is recommended that you explicitly set this property to some * static value if the cached data needs to be shared among multiple applications. * - * To ensure interoperability, only use alphanumeric characters should be used. + * To ensure interoperability, only alphanumeric characters should be used. */ public $keyPrefix; /** From de1b533a0840dd5b517e6a1c7b9c882156626060 Mon Sep 17 00:00:00 2001 From: Carsten Brandt Date: Mon, 25 Nov 2013 14:52:36 +0100 Subject: [PATCH 5/7] fixed cubrid limit --- framework/yii/db/cubrid/QueryBuilder.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/yii/db/cubrid/QueryBuilder.php b/framework/yii/db/cubrid/QueryBuilder.php index 7682516..5c03ab7 100644 --- a/framework/yii/db/cubrid/QueryBuilder.php +++ b/framework/yii/db/cubrid/QueryBuilder.php @@ -83,7 +83,7 @@ class QueryBuilder extends \yii\db\QueryBuilder $sql .= ' OFFSET ' . (int)$offset; } } elseif ($offset > 0) { - $sql = 'LIMIT ' . (int)$offset . ', 18446744073709551615'; // 2^64-1 + $sql = 'LIMIT 9223372036854775807 OFFSET ' . (int)$offset; // 2^63-1 } return $sql; } From 8be4f3778afb74fdf19e60db903ce66a096999aa Mon Sep 17 00:00:00 2001 From: Carsten Brandt Date: Mon, 25 Nov 2013 15:33:59 +0100 Subject: [PATCH 6/7] updated properties of extensions --- build/build | 2 ++ build/controllers/PhpDocController.php | 45 +++++++++++++++++++++++++++------- extensions/bootstrap/Nav.php | 8 +++--- extensions/redis/Cache.php | 2 -- extensions/sphinx/ActiveRecord.php | 17 ++++++++++--- extensions/sphinx/Command.php | 7 ++++-- extensions/sphinx/Connection.php | 7 ++++-- extensions/sphinx/Query.php | 2 ++ extensions/sphinx/Schema.php | 8 +++--- extensions/swiftmailer/Mailer.php | 4 +++ extensions/swiftmailer/Message.php | 3 ++- framework/yii/db/ActiveRecord.php | 14 ++++++++--- 12 files changed, 88 insertions(+), 31 deletions(-) diff --git a/build/build b/build/build index b1d6bb2..daf5e09 100755 --- a/build/build +++ b/build/build @@ -11,6 +11,8 @@ // fcgi doesn't have STDIN defined by default defined('STDIN') or define('STDIN', fopen('php://stdin', 'r')); +define('YII_DEBUG', true); + require(__DIR__ . '/../framework/yii/Yii.php'); $application = new yii\console\Application([ diff --git a/build/controllers/PhpDocController.php b/build/controllers/PhpDocController.php index c7a2fa7..0dc0f24 100644 --- a/build/controllers/PhpDocController.php +++ b/build/controllers/PhpDocController.php @@ -7,6 +7,7 @@ namespace yii\build\controllers; +use Yii; use yii\console\Controller; use yii\helpers\Console; use yii\helpers\FileHelper; @@ -38,10 +39,30 @@ class PhpDocController extends Controller * * @param null $root the directory to parse files from. Defaults to YII_PATH. */ - public function actionProperty($root=null) + public function actionProperty($root = null) { + $except = []; if ($root === null) { - $root = YII_PATH; + $root = dirname(dirname(YII_PATH)); + Yii::setAlias('@yii/bootstrap', $root . '/extensions/bootstrap'); + Yii::setAlias('@yii/debug', $root . '/extensions/debug'); + Yii::setAlias('@yii/elasticsearch', $root . '/extensions/elasticsearch'); + Yii::setAlias('@yii/gii', $root . '/extensions/gii'); + Yii::setAlias('@yii/jui', $root . '/extensions/jui'); + Yii::setAlias('@yii/redis', $root . '/extensions/redis'); + Yii::setAlias('@yii/smarty', $root . '/extensions/smarty'); + Yii::setAlias('@yii/sphinx', $root . '/extensions/sphinx'); + Yii::setAlias('@yii/swiftmailer', $root . '/extensions/swiftmailer'); + Yii::setAlias('@yii/twig', $root . '/extensions/twig'); + + $except = [ + '/apps/', + '/build/', + '/docs/', + '/extensions/composer/', + '/tests/', + '/vendor/', + ]; } $root = FileHelper::normalizePath($root); $options = [ @@ -55,14 +76,13 @@ class PhpDocController extends Controller return null; }, 'only' => ['.php'], - 'except' => [ + 'except' => array_merge($except, [ 'BaseYii.php', 'Yii.php', - '/debug/views/', + '/views/', '/requirements/', - '/gii/views/', '/gii/generators/', - ], + ]), ]; $files = FileHelper::findFiles($root, $options); $nFilesTotal = 0; @@ -216,20 +236,27 @@ class PhpDocController extends Controller $ns = $this->match('#\nnamespace (?[\w\\\\]+);\n#', $file); $namespace = reset($ns); $namespace = $namespace['name']; - $classes = $this->match('#\n(?:abstract )?class (?\w+)( |\n)(extends )?.+\{(?.*)\n\}(\n|$)#', $file); + $classes = $this->match('#\n(?:abstract )?class (?\w+)( extends .+)?( implements .+)?\n\{(?.*)\n\}(\n|$)#', $file); if (count($classes) > 1) { $this->stderr("[ERR] There should be only one class in a file: $fileName\n", Console::FG_RED); return false; } if (count($classes) < 1) { - $interfaces = $this->match('#\ninterface (?\w+)\n\{(?.+)\n\}(\n|$)#', $file); + $interfaces = $this->match('#\ninterface (?\w+)( extends .+)?\n\{(?.+)\n\}(\n|$)#', $file); if (count($interfaces) == 1) { return false; } elseif (count($interfaces) > 1) { $this->stderr("[ERR] There should be only one interface in a file: $fileName\n", Console::FG_RED); } else { - $this->stderr("[ERR] No class in file: $fileName\n", Console::FG_RED); + $traits = $this->match('#\ntrait (?\w+)\n\{(?.+)\n\}(\n|$)#', $file); + if (count($traits) == 1) { + return false; + } elseif (count($traits) > 1) { + $this->stderr("[ERR] There should be only one class/trait/interface in a file: $fileName\n", Console::FG_RED); + } else { + $this->stderr("[ERR] No class in file: $fileName\n", Console::FG_RED); + } } return false; } diff --git a/extensions/bootstrap/Nav.php b/extensions/bootstrap/Nav.php index 8f0a98d..ef45f09 100644 --- a/extensions/bootstrap/Nav.php +++ b/extensions/bootstrap/Nav.php @@ -14,7 +14,7 @@ use yii\helpers\Html; /** * Nav renders a nav HTML component. - * + * * For example: * * ```php @@ -37,12 +37,12 @@ use yii\helpers\Html; * ], * ]); * ``` - * + * * Note: Multilevel dropdowns beyond Level 1 are not supported in Bootstrap 3. - * + * * @see http://getbootstrap.com/components.html#dropdowns * @see http://getbootstrap.com/components/#nav - * + * * @author Antonio Ramirez * @since 2.0 */ diff --git a/extensions/redis/Cache.php b/extensions/redis/Cache.php index 2b7e9e1..733df26 100644 --- a/extensions/redis/Cache.php +++ b/extensions/redis/Cache.php @@ -53,8 +53,6 @@ use yii\base\InvalidConfigException; * ] * ~~~ * - * @property Connection $connection The redis connection object. This property is read-only. - * * @author Carsten Brandt * @since 2.0 */ diff --git a/extensions/sphinx/ActiveRecord.php b/extensions/sphinx/ActiveRecord.php index d83db62..2cadc69 100644 --- a/extensions/sphinx/ActiveRecord.php +++ b/extensions/sphinx/ActiveRecord.php @@ -26,11 +26,16 @@ use Yii; * read-only. * @property boolean $isNewRecord Whether the record is new and should be inserted when calling [[save()]]. * @property array $oldAttributes The old attribute values (name-value pairs). - * @property integer $oldPrimaryKey The old primary key value. This property is read-only. + * @property mixed $oldPrimaryKey The old primary key value. An array (column name => column value) is + * returned if the primary key is composite. A string is returned otherwise (null will be returned if the key + * value is null). This property is read-only. * @property array $populatedRelations An array of relation data indexed by relation names. This property is * read-only. - * @property integer $primaryKey The primary key value. This property is read-only. - * @property string $snippet current snippet value for this Active Record instance.. + * @property mixed $primaryKey The primary key value. An array (column name => column value) is returned if + * the primary key is composite. A string is returned otherwise (null will be returned if the key value is null). + * This property is read-only. + * @property string $snippet Snippet value. + * @property string $snippetSource Snippet source string. This property is read-only. * * @author Paul Klimov * @since 2.0 @@ -1237,6 +1242,9 @@ abstract class ActiveRecord extends Model * Returns the primary key value. * @param boolean $asArray whether to return the primary key value as an array. If true, * the return value will be an array with column names as keys and column values as values. + * @property mixed The primary key value. An array (column name => column value) is returned if + * the primary key is composite. A string is returned otherwise (null will be returned if + * the key value is null). * @return mixed the primary key value. An array (column name => column value) is returned * if `$asArray` is true. A string is returned otherwise (null will be returned if * the key value is null). @@ -1263,6 +1271,9 @@ abstract class ActiveRecord extends Model * @param boolean $asArray whether to return the primary key value as an array. If true, * the return value will be an array with column name as key and column value as value. * If this is false (default), a scalar value will be returned. + * @property mixed The old primary key value. An array (column name => column value) is + * returned if the primary key is composite. A string is returned otherwise (null will be + * returned if the key value is null). * @return mixed the old primary key value. An array (column name => column value) is returned if * `$asArray` is true. A string is returned otherwise (null will be returned if * the key value is null). diff --git a/extensions/sphinx/Command.php b/extensions/sphinx/Command.php index 93c02f8..400b3ed 100644 --- a/extensions/sphinx/Command.php +++ b/extensions/sphinx/Command.php @@ -39,14 +39,17 @@ use yii\base\NotSupportedException; * * To build SELECT SQL statements, please use [[Query]] and [[QueryBuilder]] instead. * - * @property \yii\sphinx\Connection $db the Sphinx connection that this command is associated with. - * * @author Paul Klimov * @since 2.0 */ class Command extends \yii\db\Command { /** + * @var \yii\sphinx\Connection the Sphinx connection that this command is associated with. + */ + public $db; + + /** * Creates a batch INSERT command. * For example, * diff --git a/extensions/sphinx/Connection.php b/extensions/sphinx/Connection.php index a43b0c2..6f3a18a 100644 --- a/extensions/sphinx/Connection.php +++ b/extensions/sphinx/Connection.php @@ -47,11 +47,14 @@ use yii\base\NotSupportedException; * * Note: while this class extends "yii\db\Connection" some of its methods are not supported. * + * @method \yii\sphinx\Schema getSchema() The schema information for this Sphinx connection + * @method \yii\sphinx\QueryBuilder getQueryBuilder() the query builder for this Sphinx connection + * + * @property string $lastInsertID The row ID of the last row inserted, or the last value retrieved from the + * sequence object. This property is read-only. * @property Schema $schema The schema information for this Sphinx connection. This property is read-only. * @property \yii\sphinx\QueryBuilder $queryBuilder The query builder for this Sphinx connection. This property is * read-only. - * @method \yii\sphinx\Schema getSchema() The schema information for this Sphinx connection - * @method \yii\sphinx\QueryBuilder getQueryBuilder() the query builder for this Sphinx connection * * @author Paul Klimov * @since 2.0 diff --git a/extensions/sphinx/Query.php b/extensions/sphinx/Query.php index ff0dcba..dd13363 100644 --- a/extensions/sphinx/Query.php +++ b/extensions/sphinx/Query.php @@ -41,6 +41,8 @@ use yii\db\QueryTrait; * * Warning: even if you do not set any query limit, implicit LIMIT 0,20 is present by default! * + * @property Connection $connection Sphinx connection instance. + * * @author Paul Klimov * @since 2.0 */ diff --git a/extensions/sphinx/Schema.php b/extensions/sphinx/Schema.php index 6c9571c..5515865 100644 --- a/extensions/sphinx/Schema.php +++ b/extensions/sphinx/Schema.php @@ -15,12 +15,12 @@ use yii\caching\GroupDependency; /** * Schema represents the Sphinx schema information. * - * @property QueryBuilder $queryBuilder The query builder for this connection. This property is read-only. * @property string[] $indexNames All index names in the Sphinx. This property is read-only. - * @property string[] $indexTypes ALL index types in the Sphinx (index name => index type). - * This property is read-only. - * @property IndexSchema[] $tableSchemas The metadata for all indexes in the Sphinx. Each array element is an + * @property IndexSchema[] $indexSchemas The metadata for all indexes in the Sphinx. Each array element is an * instance of [[IndexSchema]] or its child class. This property is read-only. + * @property array $indexTypes All index types in the Sphinx in format: index name => index type. This + * property is read-only. + * @property QueryBuilder $queryBuilder The query builder for this connection. This property is read-only. * * @author Paul Klimov * @since 2.0 diff --git a/extensions/swiftmailer/Mailer.php b/extensions/swiftmailer/Mailer.php index d19e013..891f2b5 100644 --- a/extensions/swiftmailer/Mailer.php +++ b/extensions/swiftmailer/Mailer.php @@ -66,6 +66,10 @@ use yii\mail\BaseMailer; * * @see http://swiftmailer.org * + * @property array|\Swift_Mailer $swiftMailer Swift mailer instance or array configuration. This property is + * read-only. + * @property array|\Swift_Transport $transport This property is read-only. + * * @author Paul Klimov * @since 2.0 */ diff --git a/extensions/swiftmailer/Message.php b/extensions/swiftmailer/Message.php index b0ebd63..9558d58 100644 --- a/extensions/swiftmailer/Message.php +++ b/extensions/swiftmailer/Message.php @@ -16,7 +16,8 @@ use yii\mail\BaseMessage; * @see Mailer * * @method Mailer getMailer() returns mailer instance. - * @property \Swift_Message $swiftMessage vendor message instance. + * + * @property \Swift_Message $swiftMessage Swift message instance. This property is read-only. * * @author Paul Klimov * @since 2.0 diff --git a/framework/yii/db/ActiveRecord.php b/framework/yii/db/ActiveRecord.php index ffae3d8..8d6c7ee 100644 --- a/framework/yii/db/ActiveRecord.php +++ b/framework/yii/db/ActiveRecord.php @@ -27,13 +27,13 @@ use yii\helpers\Inflector; * @property boolean $isNewRecord Whether the record is new and should be inserted when calling [[save()]]. * @property array $oldAttributes The old attribute values (name-value pairs). * @property mixed $oldPrimaryKey The old primary key value. An array (column name => column value) is - * returned if the primary key is composite or `$asArray` is true. A string is returned otherwise (null will be - * returned if the key value is null). This property is read-only. + * returned if the primary key is composite. A string is returned otherwise (null will be returned if the key + * value is null). This property is read-only. * @property array $populatedRelations An array of relation data indexed by relation names. This property is * read-only. * @property mixed $primaryKey The primary key value. An array (column name => column value) is returned if - * the primary key is composite or `$asArray` is true. A string is returned otherwise (null will be returned if - * the key value is null). This property is read-only. + * the primary key is composite. A string is returned otherwise (null will be returned if the key value is null). + * This property is read-only. * * @author Qiang Xue * @author Carsten Brandt @@ -1192,6 +1192,9 @@ class ActiveRecord extends Model * @param boolean $asArray whether to return the primary key value as an array. If true, * the return value will be an array with column names as keys and column values as values. * Note that for composite primary keys, an array will always be returned regardless of this parameter value. + * @property mixed The primary key value. An array (column name => column value) is returned if + * the primary key is composite. A string is returned otherwise (null will be returned if + * the key value is null). * @return mixed the primary key value. An array (column name => column value) is returned if the primary key * is composite or `$asArray` is true. A string is returned otherwise (null will be returned if * the key value is null). @@ -1218,6 +1221,9 @@ class ActiveRecord extends Model * @param boolean $asArray whether to return the primary key value as an array. If true, * the return value will be an array with column name as key and column value as value. * If this is false (default), a scalar value will be returned for non-composite primary key. + * @property mixed The old primary key value. An array (column name => column value) is + * returned if the primary key is composite. A string is returned otherwise (null will be + * returned if the key value is null). * @return mixed the old primary key value. An array (column name => column value) is returned if the primary key * is composite or `$asArray` is true. A string is returned otherwise (null will be returned if * the key value is null). From e2ff98ab53eee5d0449e8088c2ca3f9892b4adb8 Mon Sep 17 00:00:00 2001 From: Carsten Brandt Date: Mon, 25 Nov 2013 15:34:26 +0100 Subject: [PATCH 7/7] fixed broken sphinx AR::attributes() declaration Model::attributes() has been made static --- extensions/sphinx/ActiveRecord.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extensions/sphinx/ActiveRecord.php b/extensions/sphinx/ActiveRecord.php index 2cadc69..0291bdf 100644 --- a/extensions/sphinx/ActiveRecord.php +++ b/extensions/sphinx/ActiveRecord.php @@ -638,9 +638,9 @@ abstract class ActiveRecord extends Model * The default implementation will return all column names of the table associated with this AR class. * @return array list of attribute names. */ - public function attributes() + public static function attributes() { - return array_keys($this->getIndexSchema()->columns); + return array_keys(static::getIndexSchema()->columns); } /**