Commit 084f6666 by Carsten Brandt

Merge branch 'master' into elasticsearch

* master: fixed broken sphinx AR::attributes() declaration updated properties of extensions fixed cubrid limit added redis Session allow redis connection to be configure directly in cache removed unneeded setting. refactored redis cache. Conflicts: extensions/redis/README.md
parents 2691299b e2ff98ab
...@@ -17,9 +17,6 @@ return [ ...@@ -17,9 +17,6 @@ return [
'modules' => [], 'modules' => [],
'extensions' => require($rootDir . '/vendor/yiisoft/extensions.php'), 'extensions' => require($rootDir . '/vendor/yiisoft/extensions.php'),
'components' => [ 'components' => [
'request' => [
'enableCsrfValidation' => true,
],
'db' => $params['components.db'], 'db' => $params['components.db'],
'cache' => $params['components.cache'], 'cache' => $params['components.cache'],
'mail' => $params['components.mail'], 'mail' => $params['components.mail'],
......
...@@ -18,9 +18,6 @@ return [ ...@@ -18,9 +18,6 @@ return [
], ],
'extensions' => require($rootDir . '/vendor/yiisoft/extensions.php'), 'extensions' => require($rootDir . '/vendor/yiisoft/extensions.php'),
'components' => [ 'components' => [
'request' => [
'enableCsrfValidation' => true,
],
'db' => $params['components.db'], 'db' => $params['components.db'],
'cache' => $params['components.cache'], 'cache' => $params['components.cache'],
'mail' => $params['components.mail'], 'mail' => $params['components.mail'],
......
...@@ -5,9 +5,6 @@ $config = [ ...@@ -5,9 +5,6 @@ $config = [
'basePath' => dirname(__DIR__), 'basePath' => dirname(__DIR__),
'extensions' => require(__DIR__ . '/../vendor/yiisoft/extensions.php'), 'extensions' => require(__DIR__ . '/../vendor/yiisoft/extensions.php'),
'components' => [ 'components' => [
'request' => [
'enableCsrfValidation' => true,
],
'cache' => [ 'cache' => [
'class' => 'yii\caching\FileCache', 'class' => 'yii\caching\FileCache',
], ],
......
...@@ -11,6 +11,8 @@ ...@@ -11,6 +11,8 @@
// fcgi doesn't have STDIN defined by default // fcgi doesn't have STDIN defined by default
defined('STDIN') or define('STDIN', fopen('php://stdin', 'r')); defined('STDIN') or define('STDIN', fopen('php://stdin', 'r'));
define('YII_DEBUG', true);
require(__DIR__ . '/../framework/yii/Yii.php'); require(__DIR__ . '/../framework/yii/Yii.php');
$application = new yii\console\Application([ $application = new yii\console\Application([
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
namespace yii\build\controllers; namespace yii\build\controllers;
use Yii;
use yii\console\Controller; use yii\console\Controller;
use yii\helpers\Console; use yii\helpers\Console;
use yii\helpers\FileHelper; use yii\helpers\FileHelper;
...@@ -38,10 +39,30 @@ class PhpDocController extends Controller ...@@ -38,10 +39,30 @@ class PhpDocController extends Controller
* *
* @param null $root the directory to parse files from. Defaults to YII_PATH. * @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) { 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); $root = FileHelper::normalizePath($root);
$options = [ $options = [
...@@ -55,14 +76,13 @@ class PhpDocController extends Controller ...@@ -55,14 +76,13 @@ class PhpDocController extends Controller
return null; return null;
}, },
'only' => ['.php'], 'only' => ['.php'],
'except' => [ 'except' => array_merge($except, [
'BaseYii.php', 'BaseYii.php',
'Yii.php', 'Yii.php',
'/debug/views/', '/views/',
'/requirements/', '/requirements/',
'/gii/views/',
'/gii/generators/', '/gii/generators/',
], ]),
]; ];
$files = FileHelper::findFiles($root, $options); $files = FileHelper::findFiles($root, $options);
$nFilesTotal = 0; $nFilesTotal = 0;
...@@ -216,20 +236,27 @@ class PhpDocController extends Controller ...@@ -216,20 +236,27 @@ class PhpDocController extends Controller
$ns = $this->match('#\nnamespace (?<name>[\w\\\\]+);\n#', $file); $ns = $this->match('#\nnamespace (?<name>[\w\\\\]+);\n#', $file);
$namespace = reset($ns); $namespace = reset($ns);
$namespace = $namespace['name']; $namespace = $namespace['name'];
$classes = $this->match('#\n(?:abstract )?class (?<name>\w+)( |\n)(extends )?.+\{(?<content>.*)\n\}(\n|$)#', $file); $classes = $this->match('#\n(?:abstract )?class (?<name>\w+)( extends .+)?( implements .+)?\n\{(?<content>.*)\n\}(\n|$)#', $file);
if (count($classes) > 1) { if (count($classes) > 1) {
$this->stderr("[ERR] There should be only one class in a file: $fileName\n", Console::FG_RED); $this->stderr("[ERR] There should be only one class in a file: $fileName\n", Console::FG_RED);
return false; return false;
} }
if (count($classes) < 1) { if (count($classes) < 1) {
$interfaces = $this->match('#\ninterface (?<name>\w+)\n\{(?<content>.+)\n\}(\n|$)#', $file); $interfaces = $this->match('#\ninterface (?<name>\w+)( extends .+)?\n\{(?<content>.+)\n\}(\n|$)#', $file);
if (count($interfaces) == 1) { if (count($interfaces) == 1) {
return false; return false;
} elseif (count($interfaces) > 1) { } elseif (count($interfaces) > 1) {
$this->stderr("[ERR] There should be only one interface in a file: $fileName\n", Console::FG_RED); $this->stderr("[ERR] There should be only one interface in a file: $fileName\n", Console::FG_RED);
} else { } else {
$this->stderr("[ERR] No class in file: $fileName\n", Console::FG_RED); $traits = $this->match('#\ntrait (?<name>\w+)\n\{(?<content>.+)\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; return false;
} }
......
...@@ -14,7 +14,7 @@ use yii\helpers\Html; ...@@ -14,7 +14,7 @@ use yii\helpers\Html;
/** /**
* Nav renders a nav HTML component. * Nav renders a nav HTML component.
* *
* For example: * For example:
* *
* ```php * ```php
...@@ -37,12 +37,12 @@ use yii\helpers\Html; ...@@ -37,12 +37,12 @@ use yii\helpers\Html;
* ], * ],
* ]); * ]);
* ``` * ```
* *
* Note: Multilevel dropdowns beyond Level 1 are not supported in Bootstrap 3. * Note: Multilevel dropdowns beyond Level 1 are not supported in Bootstrap 3.
* *
* @see http://getbootstrap.com/components.html#dropdowns * @see http://getbootstrap.com/components.html#dropdowns
* @see http://getbootstrap.com/components/#nav * @see http://getbootstrap.com/components/#nav
* *
* @author Antonio Ramirez <amigo.cobos@gmail.com> * @author Antonio Ramirez <amigo.cobos@gmail.com>
* @since 2.0 * @since 2.0
*/ */
......
...@@ -7,6 +7,9 @@ ...@@ -7,6 +7,9 @@
namespace yii\redis; 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. * Redis Cache implements a cache application component based on [redis](http://redis.io/) key-value store.
* *
...@@ -27,18 +30,28 @@ namespace yii\redis; ...@@ -27,18 +30,28 @@ namespace yii\redis;
* 'components' => [ * 'components' => [
* 'cache' => [ * 'cache' => [
* 'class' => 'yii\redis\Cache', * 'class' => 'yii\redis\Cache',
* 'redis' => [
* 'hostname' => 'localhost',
* 'port' => 6379,
* 'database' => 0,
* ]
* ], * ],
* 'redis' => [
* 'class' => 'yii\redis\Connection',
* 'hostname' => 'localhost',
* 'port' => 6379,
* 'database' => 0,
* ]
* ], * ],
* ] * ]
* ~~~ * ~~~
* *
* @property Connection $connection The redis connection object. This property is read-only. * 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
* ],
* ],
* ]
* ~~~
* *
* @author Carsten Brandt <mail@cebe.cc> * @author Carsten Brandt <mail@cebe.cc>
* @since 2.0 * @since 2.0
...@@ -46,11 +59,35 @@ namespace yii\redis; ...@@ -46,11 +59,35 @@ namespace yii\redis;
class Cache extends \yii\caching\Cache class Cache extends \yii\caching\Cache
{ {
/** /**
* @var string the id of the application component to use as the redis connection. * @var Connection|string|array the Redis [[Connection]] object or the application component ID of the Redis [[Connection]].
* It should be configured as a [[yii\redis\Connection]]. Defaults to `redis`. * 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.
*/ */
public $connectionId = 'redis'; public $redis = 'redis';
/**
* 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.");
}
}
/** /**
* Checks whether a specified key exists in the cache. * Checks whether a specified key exists in the cache.
...@@ -64,9 +101,7 @@ class Cache extends \yii\caching\Cache ...@@ -64,9 +101,7 @@ class Cache extends \yii\caching\Cache
*/ */
public function exists($key) public function exists($key)
{ {
/** @var Connection $connection */ return (bool) $this->redis->executeCommand('EXISTS', [$this->buildKey($key)]);
$connection = \Yii::$app->getComponent($this->connectionId);
return (bool) $connection->executeCommand('EXISTS', [$this->buildKey($key)]);
} }
/** /**
...@@ -74,9 +109,7 @@ class Cache extends \yii\caching\Cache ...@@ -74,9 +109,7 @@ class Cache extends \yii\caching\Cache
*/ */
protected function getValue($key) protected function getValue($key)
{ {
/** @var Connection $connection */ return $this->redis->executeCommand('GET', [$key]);
$connection = \Yii::$app->getComponent($this->connectionId);
return $connection->executeCommand('GET', [$key]);
} }
/** /**
...@@ -84,9 +117,7 @@ class Cache extends \yii\caching\Cache ...@@ -84,9 +117,7 @@ class Cache extends \yii\caching\Cache
*/ */
protected function getValues($keys) protected function getValues($keys)
{ {
/** @var Connection $connection */ $response = $this->redis->executeCommand('MGET', $keys);
$connection = \Yii::$app->getComponent($this->connectionId);
$response = $connection->executeCommand('MGET', $keys);
$result = []; $result = [];
$i = 0; $i = 0;
foreach ($keys as $key) { foreach ($keys as $key) {
...@@ -100,13 +131,11 @@ class Cache extends \yii\caching\Cache ...@@ -100,13 +131,11 @@ class Cache extends \yii\caching\Cache
*/ */
protected function setValue($key, $value, $expire) protected function setValue($key, $value, $expire)
{ {
/** @var Connection $connection */
$connection = \Yii::$app->getComponent($this->connectionId);
if ($expire == 0) { if ($expire == 0) {
return (bool) $connection->executeCommand('SET', [$key, $value]); return (bool) $this->redis->executeCommand('SET', [$key, $value]);
} else { } else {
$expire = (int) ($expire * 1000); $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 +144,6 @@ class Cache extends \yii\caching\Cache ...@@ -115,9 +144,6 @@ class Cache extends \yii\caching\Cache
*/ */
protected function setValues($data, $expire) protected function setValues($data, $expire)
{ {
/** @var Connection $connection */
$connection = \Yii::$app->getComponent($this->connectionId);
$args = []; $args = [];
foreach($data as $key => $value) { foreach($data as $key => $value) {
$args[] = $key; $args[] = $key;
...@@ -126,17 +152,17 @@ class Cache extends \yii\caching\Cache ...@@ -126,17 +152,17 @@ class Cache extends \yii\caching\Cache
$failedKeys = []; $failedKeys = [];
if ($expire == 0) { if ($expire == 0) {
$connection->executeCommand('MSET', $args); $this->redis->executeCommand('MSET', $args);
} else { } else {
$expire = (int) ($expire * 1000); $expire = (int) ($expire * 1000);
$connection->executeCommand('MULTI'); $this->redis->executeCommand('MULTI');
$connection->executeCommand('MSET', $args); $this->redis->executeCommand('MSET', $args);
$index = []; $index = [];
foreach ($data as $key => $value) { foreach ($data as $key => $value) {
$connection->executeCommand('PEXPIRE', [$key, $expire]); $this->redis->executeCommand('PEXPIRE', [$key, $expire]);
$index[] = $key; $index[] = $key;
} }
$result = $connection->executeCommand('EXEC'); $result = $this->redis->executeCommand('EXEC');
array_shift($result); array_shift($result);
foreach($result as $i => $r) { foreach($result as $i => $r) {
if ($r != 1) { if ($r != 1) {
...@@ -152,13 +178,11 @@ class Cache extends \yii\caching\Cache ...@@ -152,13 +178,11 @@ class Cache extends \yii\caching\Cache
*/ */
protected function addValue($key, $value, $expire) protected function addValue($key, $value, $expire)
{ {
/** @var Connection $connection */
$connection = \Yii::$app->getComponent($this->connectionId);
if ($expire == 0) { if ($expire == 0) {
return (bool) $connection->executeCommand('SET', [$key, $value, 'NX']); return (bool) $this->redis->executeCommand('SET', [$key, $value, 'NX']);
} else { } else {
$expire = (int) ($expire * 1000); $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 +191,7 @@ class Cache extends \yii\caching\Cache ...@@ -167,9 +191,7 @@ class Cache extends \yii\caching\Cache
*/ */
protected function deleteValue($key) protected function deleteValue($key)
{ {
/** @var Connection $connection */ return (bool) $this->redis->executeCommand('DEL', [$key]);
$connection = \Yii::$app->getComponent($this->connectionId);
return (bool) $connection->executeCommand('DEL', [$key]);
} }
/** /**
...@@ -177,8 +199,6 @@ class Cache extends \yii\caching\Cache ...@@ -177,8 +199,6 @@ class Cache extends \yii\caching\Cache
*/ */
protected function flushValues() protected function flushValues()
{ {
/** @var Connection $connection */ return $this->redis->executeCommand('FLUSHDB');
$connection = \Yii::$app->getComponent($this->connectionId);
return $connection->executeCommand('FLUSHDB');
} }
} }
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. This extension provides the [redis](http://redis.io/) key-value store support for the Yii2 framework.
It includes a `Cache` class and implements the `ActiveRecord` pattern that allows you to store active It includes a `Cache` and `Session` storage handler and implents the `ActiveRecord` pattern that allows
records in redis. you to store active records in redis.
To use this extension, you have to configure the Connection class in your application configuration: To use this extension, you have to configure the Connection class in your application configuration:
...@@ -21,7 +21,31 @@ return [ ...@@ -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 ```php
return [ return [
...@@ -35,26 +59,64 @@ return [ ...@@ -35,26 +59,64 @@ return [
]; ];
``` ```
If you only use the redis cache, you can also configure the parameters of the connection within the
cache component (no connection application component needs to be configured in this case):
Installation ```php
------------ return [
//....
'components' => [
// ...
'cache' => [
'class' => 'yii\redis\Cache',
'redis' => [
'hostname' => 'localhost',
'port' => 6379,
'database' => 0,
],
],
]
];
```
The preferred way to install this extension is through [composer](http://getcomposer.org/download/). Using the Session component
---------------------------
Either run 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`:
``` ```php
php composer.phar require yiisoft/yii2-redis "*" 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 ```php
"yiisoft/yii2-redis": "*" 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 Using the redis ActiveRecord
---------------------------- ----------------------------
...@@ -72,10 +134,29 @@ The following is an example model called `Customer`: ...@@ -72,10 +134,29 @@ The following is an example model called `Customer`:
```php ```php
class Customer extends \yii\redis\ActiveRecord class Customer extends \yii\redis\ActiveRecord
{ {
public function attributes() /**
{ * @return array the list of attributes for this record
return ['id', 'name', 'address', 'registration_date']; */
} 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));
}
} }
``` ```
...@@ -88,4 +169,16 @@ It supports the same interface and features except the following limitations: ...@@ -88,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)) (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. - `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. It is also possible to define relations from redis ActiveRecords to normal ActiveRecord classes and vice versa.
\ No newline at end of file
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)
```
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\redis;
use Yii;
use yii\base\InvalidConfigException;
/**
* Redis Session implements a session component using [redis](http://redis.io/) as the storage medium.
*
* Redis Session requires redis version 2.6.12 or higher to work properly.
*
* It needs to be configured with a redis [[Connection]] that is also configured as an application component.
* By default it will use the `redis` application component.
*
* To use redis Session as the session application component, configure the application as follows,
*
* ~~~
* [
* 'components' => [
* '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 <mail@cebe.cc>
* @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]));
}
}
{ {
"name": "yiisoft/yii2-redis", "name": "yiisoft/yii2-redis",
"description": "Redis Cache and ActiveRecord for the Yii framework", "description": "Redis Cache, Session and ActiveRecord for the Yii framework",
"keywords": ["yii", "redis", "active-record", "cache"], "keywords": ["yii", "redis", "active-record", "cache", "session"],
"type": "yii2-extension", "type": "yii2-extension",
"license": "BSD-3-Clause", "license": "BSD-3-Clause",
"support": { "support": {
......
...@@ -26,11 +26,16 @@ use Yii; ...@@ -26,11 +26,16 @@ use Yii;
* read-only. * read-only.
* @property boolean $isNewRecord Whether the record is new and should be inserted when calling [[save()]]. * @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 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 * @property array $populatedRelations An array of relation data indexed by relation names. This property is
* read-only. * read-only.
* @property integer $primaryKey The primary key value. This property is read-only. * @property mixed $primaryKey The primary key value. An array (column name => column value) is returned if
* @property string $snippet current snippet value for this Active Record instance.. * 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 <klimov.paul@gmail.com> * @author Paul Klimov <klimov.paul@gmail.com>
* @since 2.0 * @since 2.0
...@@ -633,9 +638,9 @@ abstract class ActiveRecord extends Model ...@@ -633,9 +638,9 @@ abstract class ActiveRecord extends Model
* The default implementation will return all column names of the table associated with this AR class. * The default implementation will return all column names of the table associated with this AR class.
* @return array list of attribute names. * @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);
} }
/** /**
...@@ -1237,6 +1242,9 @@ abstract class ActiveRecord extends Model ...@@ -1237,6 +1242,9 @@ abstract class ActiveRecord extends Model
* Returns the primary key value. * Returns the primary key value.
* @param boolean $asArray whether to return the primary key value as an array. If true, * @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. * 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 * @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 * if `$asArray` is true. A string is returned otherwise (null will be returned if
* the key value is null). * the key value is null).
...@@ -1263,6 +1271,9 @@ abstract class ActiveRecord extends Model ...@@ -1263,6 +1271,9 @@ abstract class ActiveRecord extends Model
* @param boolean $asArray whether to return the primary key value as an array. If true, * @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. * 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. * 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 * @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 * `$asArray` is true. A string is returned otherwise (null will be returned if
* the key value is null). * the key value is null).
......
...@@ -39,14 +39,17 @@ use yii\base\NotSupportedException; ...@@ -39,14 +39,17 @@ use yii\base\NotSupportedException;
* *
* To build SELECT SQL statements, please use [[Query]] and [[QueryBuilder]] instead. * 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 <klimov.paul@gmail.com> * @author Paul Klimov <klimov.paul@gmail.com>
* @since 2.0 * @since 2.0
*/ */
class Command extends \yii\db\Command 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. * Creates a batch INSERT command.
* For example, * For example,
* *
......
...@@ -47,11 +47,14 @@ use yii\base\NotSupportedException; ...@@ -47,11 +47,14 @@ use yii\base\NotSupportedException;
* *
* Note: while this class extends "yii\db\Connection" some of its methods are not supported. * 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 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 * @property \yii\sphinx\QueryBuilder $queryBuilder The query builder for this Sphinx connection. This property is
* read-only. * 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 <klimov.paul@gmail.com> * @author Paul Klimov <klimov.paul@gmail.com>
* @since 2.0 * @since 2.0
......
...@@ -41,6 +41,8 @@ use yii\db\QueryTrait; ...@@ -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! * 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 <klimov.paul@gmail.com> * @author Paul Klimov <klimov.paul@gmail.com>
* @since 2.0 * @since 2.0
*/ */
......
...@@ -15,12 +15,12 @@ use yii\caching\GroupDependency; ...@@ -15,12 +15,12 @@ use yii\caching\GroupDependency;
/** /**
* Schema represents the Sphinx schema information. * 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[] $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). * @property IndexSchema[] $indexSchemas The metadata for all indexes in the Sphinx. Each array element is an
* This property is read-only.
* @property IndexSchema[] $tableSchemas 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. * 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 <klimov.paul@gmail.com> * @author Paul Klimov <klimov.paul@gmail.com>
* @since 2.0 * @since 2.0
......
...@@ -66,6 +66,10 @@ use yii\mail\BaseMailer; ...@@ -66,6 +66,10 @@ use yii\mail\BaseMailer;
* *
* @see http://swiftmailer.org * @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 <klimov.paul@gmail.com> * @author Paul Klimov <klimov.paul@gmail.com>
* @since 2.0 * @since 2.0
*/ */
......
...@@ -16,7 +16,8 @@ use yii\mail\BaseMessage; ...@@ -16,7 +16,8 @@ use yii\mail\BaseMessage;
* @see Mailer * @see Mailer
* *
* @method Mailer getMailer() returns mailer instance. * @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 <klimov.paul@gmail.com> * @author Paul Klimov <klimov.paul@gmail.com>
* @since 2.0 * @since 2.0
......
...@@ -58,7 +58,7 @@ abstract class Cache extends Component implements \ArrayAccess ...@@ -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 * 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. * 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; public $keyPrefix;
/** /**
......
...@@ -27,13 +27,13 @@ use yii\helpers\Inflector; ...@@ -27,13 +27,13 @@ use yii\helpers\Inflector;
* @property boolean $isNewRecord Whether the record is new and should be inserted when calling [[save()]]. * @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 array $oldAttributes The old attribute values (name-value pairs).
* @property mixed $oldPrimaryKey The old primary key value. An array (column name => column value) is * @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 primary key is composite. A string is returned otherwise (null will be returned if the key
* returned if the key value is null). This property is read-only. * value is null). This property is read-only.
* @property array $populatedRelations An array of relation data indexed by relation names. This property is * @property array $populatedRelations An array of relation data indexed by relation names. This property is
* read-only. * read-only.
* @property mixed $primaryKey The primary key value. An array (column name => column value) is returned if * @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 primary key is composite. A string is returned otherwise (null will be returned if the key value is null).
* the key value is null). This property is read-only. * This property is read-only.
* *
* @author Qiang Xue <qiang.xue@gmail.com> * @author Qiang Xue <qiang.xue@gmail.com>
* @author Carsten Brandt <mail@cebe.cc> * @author Carsten Brandt <mail@cebe.cc>
...@@ -1196,6 +1196,9 @@ class ActiveRecord extends Model ...@@ -1196,6 +1196,9 @@ class ActiveRecord extends Model
* @param boolean $asArray whether to return the primary key value as an array. If true, * @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. * 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. * 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 * @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 * is composite or `$asArray` is true. A string is returned otherwise (null will be returned if
* the key value is null). * the key value is null).
...@@ -1222,6 +1225,9 @@ class ActiveRecord extends Model ...@@ -1222,6 +1225,9 @@ class ActiveRecord extends Model
* @param boolean $asArray whether to return the primary key value as an array. If true, * @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. * 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. * 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 * @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 * is composite or `$asArray` is true. A string is returned otherwise (null will be returned if
* the key value is null). * the key value is null).
......
...@@ -83,7 +83,7 @@ class QueryBuilder extends \yii\db\QueryBuilder ...@@ -83,7 +83,7 @@ class QueryBuilder extends \yii\db\QueryBuilder
$sql .= ' OFFSET ' . (int)$offset; $sql .= ' OFFSET ' . (int)$offset;
} }
} elseif ($offset > 0) { } elseif ($offset > 0) {
$sql = 'LIMIT ' . (int)$offset . ', 18446744073709551615'; // 2^64-1 $sql = 'LIMIT 9223372036854775807 OFFSET ' . (int)$offset; // 2^63-1
} }
return $sql; return $sql;
} }
......
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