Commit cfb3e98b by Klimov Paul

Merge branch 'master' of github.com:yiisoft/yii2 into sphinx

parents d6ddfd7b a2fe1284
...@@ -14,6 +14,8 @@ class LoginForm extends Model ...@@ -14,6 +14,8 @@ class LoginForm extends Model
public $password; public $password;
public $rememberMe = true; public $rememberMe = true;
private $_user = false;
/** /**
* @return array the validation rules. * @return array the validation rules.
*/ */
...@@ -35,7 +37,7 @@ class LoginForm extends Model ...@@ -35,7 +37,7 @@ class LoginForm extends Model
*/ */
public function validatePassword() public function validatePassword()
{ {
$user = User::findByUsername($this->username); $user = $this->getUser();
if (!$user || !$user->validatePassword($this->password)) { if (!$user || !$user->validatePassword($this->password)) {
$this->addError('password', 'Incorrect username or password.'); $this->addError('password', 'Incorrect username or password.');
} }
...@@ -48,11 +50,22 @@ class LoginForm extends Model ...@@ -48,11 +50,22 @@ class LoginForm extends Model
public function login() public function login()
{ {
if ($this->validate()) { if ($this->validate()) {
$user = User::findByUsername($this->username); return Yii::$app->user->login($this->getUser(), $this->rememberMe ? 3600*24*30 : 0);
Yii::$app->user->login($user, $this->rememberMe ? 3600*24*30 : 0);
return true;
} else { } else {
return false; return false;
} }
} }
/**
* Finds user by [[username]]
*
* @return User|null
*/
private function getUser()
{
if ($this->_user === false) {
$this->_user = User::findByUsername($this->username);
}
return $this->_user;
}
} }
...@@ -14,6 +14,8 @@ class LoginForm extends Model ...@@ -14,6 +14,8 @@ class LoginForm extends Model
public $password; public $password;
public $rememberMe = true; public $rememberMe = true;
private $_user = false;
/** /**
* @return array the validation rules. * @return array the validation rules.
*/ */
...@@ -35,7 +37,7 @@ class LoginForm extends Model ...@@ -35,7 +37,7 @@ class LoginForm extends Model
*/ */
public function validatePassword() public function validatePassword()
{ {
$user = User::findByUsername($this->username); $user = $this->getUser();
if (!$user || !$user->validatePassword($this->password)) { if (!$user || !$user->validatePassword($this->password)) {
$this->addError('password', 'Incorrect username or password.'); $this->addError('password', 'Incorrect username or password.');
} }
...@@ -48,11 +50,22 @@ class LoginForm extends Model ...@@ -48,11 +50,22 @@ class LoginForm extends Model
public function login() public function login()
{ {
if ($this->validate()) { if ($this->validate()) {
$user = User::findByUsername($this->username); return Yii::$app->user->login($this->getUser(), $this->rememberMe ? 3600*24*30 : 0);
Yii::$app->user->login($user, $this->rememberMe ? 3600*24*30 : 0);
return true;
} else { } else {
return false; return false;
} }
} }
/**
* Finds user by [[username]]
*
* @return User|null
*/
private function getUser()
{
if ($this->_user === false) {
$this->_user = User::findByUsername($this->username);
}
return $this->_user;
}
} }
...@@ -46,10 +46,7 @@ class ClassmapController extends Controller ...@@ -46,10 +46,7 @@ class ClassmapController extends Controller
'except' => [ 'except' => [
'Yii.php', 'Yii.php',
'BaseYii.php', 'BaseYii.php',
'/debug/',
'/console/', '/console/',
'/test/',
'/gii/',
], ],
]; ];
$files = FileHelper::findFiles($root, $options); $files = FileHelper::findFiles($root, $options);
......
...@@ -48,7 +48,7 @@ use yii\helpers\Html; ...@@ -48,7 +48,7 @@ use yii\helpers\Html;
* 'bars' => [ * 'bars' => [
* ['percent' => 30, 'options' => ['class' => 'bar-danger']], * ['percent' => 30, 'options' => ['class' => 'bar-danger']],
* ['percent' => 30, 'label' => 'test', 'options' => ['class' => 'bar-success']], * ['percent' => 30, 'label' => 'test', 'options' => ['class' => 'bar-success']],
* ['percent' => 35, 'options' => array['class' => 'bar-warning']], * ['percent' => 35, 'options' => ['class' => 'bar-warning']],
* ] * ]
* ]); * ]);
* ``` * ```
......
...@@ -115,11 +115,16 @@ class Generator extends \yii\gii\Generator ...@@ -115,11 +115,16 @@ class Generator extends \yii\gii\Generator
*/ */
public function autoCompleteData() public function autoCompleteData()
{ {
return [ $db = $this->getDbConnection();
'tableName' => function () { if ($db !== null) {
return $this->getDbConnection()->getSchema()->getTableNames(); return [
}, 'tableName' => function () use ($db) {
]; return $db->getSchema()->getTableNames();
},
];
} else {
return [];
}
} }
/** /**
......
...@@ -6,7 +6,17 @@ and makes using JQuery UI widgets in Yii applications extremely easy. For exampl ...@@ -6,7 +6,17 @@ and makes using JQuery UI widgets in Yii applications extremely easy. For exampl
single line of code in a view file would render a JQuery UI DatePicker widget: single line of code in a view file would render a JQuery UI DatePicker widget:
```php ```php
<?= yii\jui\DatePicker::widget(['name' => 'start']) ?> <?= yii\jui\DatePicker::widget(['name' => 'attributeName']) ?>
```
Configuring the Jquery UI options should be done using the clientOptions attribute:
```php
<?= yii\jui\DatePicker::widget(['name' => 'attributeName', 'clientOptions' => ['dateFormat' => 'yy-mm-dd']]) ?>
```
If you want to use the JUI widget in an ActiveRecord form, it can be done like this:
```php
<?= $form->field($model,'attributeName')->widget(DatePicker::className(),['clientOptions' => ['dateFormat' => 'yy-mm-dd']]) ?>
``` ```
......
...@@ -17,9 +17,9 @@ use yii\mail\BaseMailer; ...@@ -17,9 +17,9 @@ use yii\mail\BaseMailer;
* To use Mailer, you should configure it in the application configuration like the following, * To use Mailer, you should configure it in the application configuration like the following,
* *
* ~~~ * ~~~
* 'components' => array( * 'components' => [
* ... * ...
* 'email' => array( * 'email' => [
* 'class' => 'yii\swiftmailer\Mailer', * 'class' => 'yii\swiftmailer\Mailer',
* 'transport' => [ * 'transport' => [
* 'class' => 'Swift_SmtpTransport', * 'class' => 'Swift_SmtpTransport',
...@@ -29,9 +29,9 @@ use yii\mail\BaseMailer; ...@@ -29,9 +29,9 @@ use yii\mail\BaseMailer;
* 'port' => '587', * 'port' => '587',
* 'encryption' => 'tls', * 'encryption' => 'tls',
* ], * ],
* ), * ],
* ... * ...
* ), * ],
* ~~~ * ~~~
* *
* You may also skip the configuration of the [[transport]] property. In that case, the default * You may also skip the configuration of the [[transport]] property. In that case, the default
......
...@@ -31,7 +31,8 @@ use yii\web\HttpException; ...@@ -31,7 +31,8 @@ use yii\web\HttpException;
* @property \yii\web\UrlManager $urlManager The URL manager for this application. This property is read-only. * @property \yii\web\UrlManager $urlManager The URL manager for this application. This property is read-only.
* @property string $vendorPath The directory that stores vendor files. Defaults to "vendor" directory under * @property string $vendorPath The directory that stores vendor files. Defaults to "vendor" directory under
* [[basePath]]. * [[basePath]].
* @property View $view The view object that is used to render various view files. This property is read-only. * @property View|\yii\web\View $view The view object that is used to render various view files. This property
* is read-only.
* *
* @author Qiang Xue <qiang.xue@gmail.com> * @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0 * @since 2.0
......
...@@ -452,7 +452,7 @@ class Component extends Object ...@@ -452,7 +452,7 @@ class Component extends Object
$event->data = $handler[1]; $event->data = $handler[1];
call_user_func($handler[0], $event); call_user_func($handler[0], $event);
// stop further handling if the event is handled // stop further handling if the event is handled
if ($event instanceof Event && $event->handled) { if ($event->handled) {
return; return;
} }
} }
......
...@@ -72,6 +72,17 @@ class ApcCache extends Cache ...@@ -72,6 +72,17 @@ class ApcCache extends Cache
} }
/** /**
* Stores multiple key-value pairs in cache.
* @param array $data array where key corresponds to cache key while value
* @param integer $expire the number of seconds in which the cached values will expire. 0 means never expire.
* @return array array of failed keys
*/
protected function setValues($data, $expire)
{
return array_keys(apc_store($data, null, $expire));
}
/**
* Stores a value identified by a key into cache if the cache does not contain this key. * Stores a value identified by a key into cache if the cache does not contain this key.
* This is the implementation of the method declared in the parent class. * This is the implementation of the method declared in the parent class.
* @param string $key the key identifying the value to be cached * @param string $key the key identifying the value to be cached
...@@ -85,6 +96,17 @@ class ApcCache extends Cache ...@@ -85,6 +96,17 @@ class ApcCache extends Cache
} }
/** /**
* Adds multiple key-value pairs to cache.
* @param array $data array where key corresponds to cache key while value is the value stored
* @param integer $expire the number of seconds in which the cached values will expire. 0 means never expire.
* @return array array of failed keys
*/
protected function addValues($data, $expire)
{
return array_keys(apc_add($data, null, $expire));
}
/**
* Deletes a value with the specified key from cache * Deletes a value with the specified key from cache
* This is the implementation of the method declared in the parent class. * This is the implementation of the method declared in the parent class.
* @param string $key the key of the value to be deleted * @param string $key the key of the value to be deleted
......
...@@ -93,7 +93,7 @@ abstract class Cache extends Component implements \ArrayAccess ...@@ -93,7 +93,7 @@ abstract class Cache extends Component implements \ArrayAccess
* If the given key is a string containing alphanumeric characters only and no more than 32 characters, * If the given key is a string containing alphanumeric characters only and no more than 32 characters,
* then the key will be returned back prefixed with [[keyPrefix]]. Otherwise, a normalized key * then the key will be returned back prefixed with [[keyPrefix]]. Otherwise, a normalized key
* is generated by serializing the given key, applying MD5 hashing, and prefixing with [[keyPrefix]]. * is generated by serializing the given key, applying MD5 hashing, and prefixing with [[keyPrefix]].
* *
* @param mixed $key the key to be normalized * @param mixed $key the key to be normalized
* @return string the generated cache key * @return string the generated cache key
*/ */
...@@ -216,6 +216,69 @@ abstract class Cache extends Component implements \ArrayAccess ...@@ -216,6 +216,69 @@ abstract class Cache extends Component implements \ArrayAccess
} }
/** /**
* Stores multiple items in cache. Each item contains a value identified by a key.
* If the cache already contains such a key, the existing value and
* expiration time will be replaced with the new ones, respectively.
*
* @param array $items the items to be cached, as key-value pairs.
* @param integer $expire default number of seconds in which the cached values will expire. 0 means never expire.
* @param Dependency $dependency dependency of the cached items. If the dependency changes,
* the corresponding values in the cache will be invalidated when it is fetched via [[get()]].
* This parameter is ignored if [[serializer]] is false.
* @return boolean whether the items are successfully stored into cache
*/
public function mset($items, $expire = 0, $dependency = null)
{
if ($dependency !== null && $this->serializer !== false) {
$dependency->evaluateDependency($this);
}
$data = [];
foreach ($items as $key => $value) {
$itemKey = $this->buildKey($key);
if ($this->serializer === null) {
$itemValue = serialize([$value, $dependency]);
} elseif ($this->serializer !== false) {
$itemValue = call_user_func($this->serializer[0], [$value, $dependency]);
}
$data[$itemKey] = $itemValue;
}
return $this->setValues($data, $expire);
}
/**
* Stores multiple items in cache. Each item contains a value identified by a key.
* If the cache already contains such a key, the existing value and expiration time will be preserved.
*
* @param array $items the items to be cached, as key-value pairs.
* @param integer $expire default number of seconds in which the cached values will expire. 0 means never expire.
* @param Dependency $dependency dependency of the cached items. If the dependency changes,
* the corresponding values in the cache will be invalidated when it is fetched via [[get()]].
* This parameter is ignored if [[serializer]] is false.
* @return boolean whether the items are successfully stored into cache
*/
public function madd($items, $expire = 0, $dependency = null)
{
if ($dependency !== null && $this->serializer !== false) {
$dependency->evaluateDependency($this);
}
$data = [];
foreach ($items as $key => $value) {
$itemKey = $this->buildKey($key);
if ($this->serializer === null) {
$itemValue = serialize([$value, $dependency]);
} elseif ($this->serializer !== false) {
$itemValue = call_user_func($this->serializer[0], [$value, $dependency]);
}
$data[$itemKey] = $itemValue;
}
return $this->addValues($data, $expire);
}
/**
* Stores a value identified by a key into cache if the cache does not contain this key. * Stores a value identified by a key into cache if the cache does not contain this key.
* Nothing will be done if the cache already contains the key. * Nothing will be done if the cache already contains the key.
* @param mixed $key a key identifying the value to be cached. This can be a simple string or * @param mixed $key a key identifying the value to be cached. This can be a simple string or
...@@ -327,6 +390,46 @@ abstract class Cache extends Component implements \ArrayAccess ...@@ -327,6 +390,46 @@ abstract class Cache extends Component implements \ArrayAccess
} }
/** /**
* Stores multiple key-value pairs in cache.
* The default implementation calls [[setValue()]] multiple times store values one by one. If the underlying cache
* storage supports multiset, this method should be overridden to exploit that feature.
* @param array $data array where key corresponds to cache key while value is the value stored
* @param integer $expire the number of seconds in which the cached values will expire. 0 means never expire.
* @return array array of failed keys
*/
protected function setValues($data, $expire)
{
$failedKeys = [];
foreach ($data as $key => $value)
{
if ($this->setValue($key, $value, $expire) === false) {
$failedKeys[] = $key;
}
}
return $failedKeys;
}
/**
* Adds multiple key-value pairs to cache.
* The default implementation calls [[addValue()]] multiple times add values one by one. If the underlying cache
* storage supports multiadd, this method should be overridden to exploit that feature.
* @param array $data array where key corresponds to cache key while value is the value stored
* @param integer $expire the number of seconds in which the cached values will expire. 0 means never expire.
* @return array array of failed keys
*/
protected function addValues($data, $expire)
{
$failedKeys = [];
foreach ($data as $key => $value)
{
if ($this->addValue($key, $value, $expire) === false) {
$failedKeys[] = $key;
}
}
return $failedKeys;
}
/**
* Returns whether there is a cache entry with a specified key. * Returns whether there is a cache entry with a specified key.
* This method is required by the interface ArrayAccess. * This method is required by the interface ArrayAccess.
* @param string $key a key identifying the cached value * @param string $key a key identifying the cached value
......
...@@ -202,6 +202,27 @@ class MemCache extends Cache ...@@ -202,6 +202,27 @@ class MemCache extends Cache
} }
/** /**
* Stores multiple key-value pairs in cache.
* @param array $data array where key corresponds to cache key while value is the value stored
* @param integer $expire the number of seconds in which the cached values will expire. 0 means never expire.
* @return array array of failed keys. Always empty in case of using memcached.
*/
protected function setValues($data, $expire)
{
if ($this->useMemcached) {
if ($expire > 0) {
$expire += time();
} else {
$expire = 0;
}
$this->_cache->setMulti($data, $expire);
return [];
} else {
return parent::setValues($data, $expire);
}
}
/**
* Stores a value identified by a key into cache if the cache does not contain this key. * Stores a value identified by a key into cache if the cache does not contain this key.
* This is the implementation of the method declared in the parent class. * This is the implementation of the method declared in the parent class.
* *
......
...@@ -72,6 +72,17 @@ class WinCache extends Cache ...@@ -72,6 +72,17 @@ class WinCache extends Cache
} }
/** /**
* Stores multiple key-value pairs in cache.
* @param array $data array where key corresponds to cache key while value is the value stored
* @param integer $expire the number of seconds in which the cached values will expire. 0 means never expire.
* @return array array of failed keys
*/
protected function setValues($data, $expire)
{
return wincache_ucache_set($data, null, $expire);
}
/**
* Stores a value identified by a key into cache if the cache does not contain this key. * Stores a value identified by a key into cache if the cache does not contain this key.
* This is the implementation of the method declared in the parent class. * This is the implementation of the method declared in the parent class.
* *
...@@ -86,6 +97,19 @@ class WinCache extends Cache ...@@ -86,6 +97,19 @@ class WinCache extends Cache
} }
/** /**
* Adds multiple key-value pairs to cache.
* The default implementation calls [[addValue()]] multiple times add values one by one. If the underlying cache
* storage supports multiadd, this method should be overridden to exploit that feature.
* @param array $data array where key corresponds to cache key while value is the value stored
* @param integer $expire the number of seconds in which the cached values will expire. 0 means never expire.
* @return array array of failed keys
*/
protected function addValues($data, $expire)
{
return wincache_ucache_add($data, null, $expire);
}
/**
* Deletes a value with the specified key from cache * Deletes a value with the specified key from cache
* This is the implementation of the method declared in the parent class. * This is the implementation of the method declared in the parent class.
* @param string $key the key of the value to be deleted * @param string $key the key of the value to be deleted
......
...@@ -76,8 +76,12 @@ return [ ...@@ -76,8 +76,12 @@ return [
'yii\data\Pagination' => YII_PATH . '/data/Pagination.php', 'yii\data\Pagination' => YII_PATH . '/data/Pagination.php',
'yii\data\Sort' => YII_PATH . '/data/Sort.php', 'yii\data\Sort' => YII_PATH . '/data/Sort.php',
'yii\db\ActiveQuery' => YII_PATH . '/db/ActiveQuery.php', 'yii\db\ActiveQuery' => YII_PATH . '/db/ActiveQuery.php',
'yii\db\ActiveQueryInterface' => YII_PATH . '/db/ActiveQueryInterface.php',
'yii\db\ActiveQueryTrait' => YII_PATH . '/db/ActiveQueryTrait.php',
'yii\db\ActiveRecord' => YII_PATH . '/db/ActiveRecord.php', 'yii\db\ActiveRecord' => YII_PATH . '/db/ActiveRecord.php',
'yii\db\ActiveRelation' => YII_PATH . '/db/ActiveRelation.php', 'yii\db\ActiveRelation' => YII_PATH . '/db/ActiveRelation.php',
'yii\db\ActiveRelationInterface' => YII_PATH . '/db/ActiveRelationInterface.php',
'yii\db\ActiveRelationTrait' => YII_PATH . '/db/ActiveRelationTrait.php',
'yii\db\ColumnSchema' => YII_PATH . '/db/ColumnSchema.php', 'yii\db\ColumnSchema' => YII_PATH . '/db/ColumnSchema.php',
'yii\db\Command' => YII_PATH . '/db/Command.php', 'yii\db\Command' => YII_PATH . '/db/Command.php',
'yii\db\Connection' => YII_PATH . '/db/Connection.php', 'yii\db\Connection' => YII_PATH . '/db/Connection.php',
...@@ -87,6 +91,8 @@ return [ ...@@ -87,6 +91,8 @@ return [
'yii\db\Migration' => YII_PATH . '/db/Migration.php', 'yii\db\Migration' => YII_PATH . '/db/Migration.php',
'yii\db\Query' => YII_PATH . '/db/Query.php', 'yii\db\Query' => YII_PATH . '/db/Query.php',
'yii\db\QueryBuilder' => YII_PATH . '/db/QueryBuilder.php', 'yii\db\QueryBuilder' => YII_PATH . '/db/QueryBuilder.php',
'yii\db\QueryInterface' => YII_PATH . '/db/QueryInterface.php',
'yii\db\QueryTrait' => YII_PATH . '/db/QueryTrait.php',
'yii\db\Schema' => YII_PATH . '/db/Schema.php', 'yii\db\Schema' => YII_PATH . '/db/Schema.php',
'yii\db\StaleObjectException' => YII_PATH . '/db/StaleObjectException.php', 'yii\db\StaleObjectException' => YII_PATH . '/db/StaleObjectException.php',
'yii\db\TableSchema' => YII_PATH . '/db/TableSchema.php', 'yii\db\TableSchema' => YII_PATH . '/db/TableSchema.php',
...@@ -149,6 +155,10 @@ return [ ...@@ -149,6 +155,10 @@ return [
'yii\log\FileTarget' => YII_PATH . '/log/FileTarget.php', 'yii\log\FileTarget' => YII_PATH . '/log/FileTarget.php',
'yii\log\Logger' => YII_PATH . '/log/Logger.php', 'yii\log\Logger' => YII_PATH . '/log/Logger.php',
'yii\log\Target' => YII_PATH . '/log/Target.php', 'yii\log\Target' => YII_PATH . '/log/Target.php',
'yii\mail\BaseMailer' => YII_PATH . '/mail/BaseMailer.php',
'yii\mail\BaseMessage' => YII_PATH . '/mail/BaseMessage.php',
'yii\mail\MailerInterface' => YII_PATH . '/mail/MailerInterface.php',
'yii\mail\MessageInterface' => YII_PATH . '/mail/MessageInterface.php',
'yii\mutex\DbMutex' => YII_PATH . '/mutex/DbMutex.php', 'yii\mutex\DbMutex' => YII_PATH . '/mutex/DbMutex.php',
'yii\mutex\FileMutex' => YII_PATH . '/mutex/FileMutex.php', 'yii\mutex\FileMutex' => YII_PATH . '/mutex/FileMutex.php',
'yii\mutex\Mutex' => YII_PATH . '/mutex/Mutex.php', 'yii\mutex\Mutex' => YII_PATH . '/mutex/Mutex.php',
...@@ -161,6 +171,8 @@ return [ ...@@ -161,6 +171,8 @@ return [
'yii\redis\Connection' => YII_PATH . '/redis/Connection.php', 'yii\redis\Connection' => YII_PATH . '/redis/Connection.php',
'yii\redis\Transaction' => YII_PATH . '/redis/Transaction.php', 'yii\redis\Transaction' => YII_PATH . '/redis/Transaction.php',
'yii\requirements\YiiRequirementChecker' => YII_PATH . '/requirements/YiiRequirementChecker.php', 'yii\requirements\YiiRequirementChecker' => YII_PATH . '/requirements/YiiRequirementChecker.php',
'yii\test\DbFixtureManager' => YII_PATH . '/test/DbFixtureManager.php',
'yii\test\DbTestTrait' => YII_PATH . '/test/DbTestTrait.php',
'yii\validators\BooleanValidator' => YII_PATH . '/validators/BooleanValidator.php', 'yii\validators\BooleanValidator' => YII_PATH . '/validators/BooleanValidator.php',
'yii\validators\CompareValidator' => YII_PATH . '/validators/CompareValidator.php', 'yii\validators\CompareValidator' => YII_PATH . '/validators/CompareValidator.php',
'yii\validators\DateValidator' => YII_PATH . '/validators/DateValidator.php', 'yii\validators\DateValidator' => YII_PATH . '/validators/DateValidator.php',
...@@ -169,6 +181,7 @@ return [ ...@@ -169,6 +181,7 @@ return [
'yii\validators\ExistValidator' => YII_PATH . '/validators/ExistValidator.php', 'yii\validators\ExistValidator' => YII_PATH . '/validators/ExistValidator.php',
'yii\validators\FileValidator' => YII_PATH . '/validators/FileValidator.php', 'yii\validators\FileValidator' => YII_PATH . '/validators/FileValidator.php',
'yii\validators\FilterValidator' => YII_PATH . '/validators/FilterValidator.php', 'yii\validators\FilterValidator' => YII_PATH . '/validators/FilterValidator.php',
'yii\validators\ImageValidator' => YII_PATH . '/validators/ImageValidator.php',
'yii\validators\InlineValidator' => YII_PATH . '/validators/InlineValidator.php', 'yii\validators\InlineValidator' => YII_PATH . '/validators/InlineValidator.php',
'yii\validators\NumberValidator' => YII_PATH . '/validators/NumberValidator.php', 'yii\validators\NumberValidator' => YII_PATH . '/validators/NumberValidator.php',
'yii\validators\PunycodeAsset' => YII_PATH . '/validators/PunycodeAsset.php', 'yii\validators\PunycodeAsset' => YII_PATH . '/validators/PunycodeAsset.php',
......
...@@ -594,7 +594,7 @@ class MigrateController extends Controller ...@@ -594,7 +594,7 @@ class MigrateController extends Controller
{ {
echo 'Creating migration history table "' . $this->migrationTable . '"...'; echo 'Creating migration history table "' . $this->migrationTable . '"...';
$this->db->createCommand()->createTable($this->migrationTable, [ $this->db->createCommand()->createTable($this->migrationTable, [
'version' => 'varchar(255) NOT NULL PRIMARY KEY', 'version' => 'varchar(180) NOT NULL PRIMARY KEY',
'apply_time' => 'integer', 'apply_time' => 'integer',
])->execute(); ])->execute();
$this->db->createCommand()->insert($this->migrationTable, [ $this->db->createCommand()->insert($this->migrationTable, [
......
...@@ -9,6 +9,7 @@ namespace yii\data; ...@@ -9,6 +9,7 @@ namespace yii\data;
use Yii; use Yii;
use yii\base\Object; use yii\base\Object;
use yii\web\Request;
/** /**
* Pagination represents information relevant to pagination of data items. * Pagination represents information relevant to pagination of data items.
...@@ -83,7 +84,7 @@ class Pagination extends Object ...@@ -83,7 +84,7 @@ class Pagination extends Object
public $route; public $route;
/** /**
* @var array parameters (name => value) that should be used to obtain the current page number * @var array parameters (name => value) that should be used to obtain the current page number
* and to create new pagination URLs. If not set, $_GET will be used instead. * and to create new pagination URLs. If not set, all parameters from $_GET will be used instead.
* *
* The array element indexed by [[pageVar]] is considered to be the current page number. * The array element indexed by [[pageVar]] is considered to be the current page number.
* If the element does not exist, the current page number is considered 0. * If the element does not exist, the current page number is considered 0.
...@@ -131,7 +132,10 @@ class Pagination extends Object ...@@ -131,7 +132,10 @@ class Pagination extends Object
public function getPage($recalculate = false) public function getPage($recalculate = false)
{ {
if ($this->_page === null || $recalculate) { if ($this->_page === null || $recalculate) {
$params = $this->params === null ? $_GET : $this->params; if (($params = $this->params) === null) {
$request = Yii::$app->getRequest();
$params = $request instanceof Request ? $request->get() : [];
}
if (isset($params[$this->pageVar]) && is_scalar($params[$this->pageVar])) { if (isset($params[$this->pageVar]) && is_scalar($params[$this->pageVar])) {
$this->_page = (int)$params[$this->pageVar] - 1; $this->_page = (int)$params[$this->pageVar] - 1;
if ($this->validatePage) { if ($this->validatePage) {
...@@ -169,7 +173,10 @@ class Pagination extends Object ...@@ -169,7 +173,10 @@ class Pagination extends Object
*/ */
public function createUrl($page) public function createUrl($page)
{ {
$params = $this->params === null ? $_GET : $this->params; if (($params = $this->params) === null) {
$request = Yii::$app->getRequest();
$params = $request instanceof Request ? $request->get() : [];
}
if ($page > 0 || $page >= 0 && $this->forcePageVar) { if ($page > 0 || $page >= 0 && $this->forcePageVar) {
$params[$this->pageVar] = $page + 1; $params[$this->pageVar] = $page + 1;
} else { } else {
......
...@@ -68,7 +68,7 @@ class ActiveQuery extends Query implements ActiveQueryInterface ...@@ -68,7 +68,7 @@ class ActiveQuery extends Query implements ActiveQueryInterface
if (!empty($rows)) { if (!empty($rows)) {
$models = $this->createModels($rows); $models = $this->createModels($rows);
if (!empty($this->with)) { if (!empty($this->with)) {
$this->populateRelations($models, $this->with); $this->findWith($this->with, $models);
} }
return $models; return $models;
} else { } else {
...@@ -98,7 +98,7 @@ class ActiveQuery extends Query implements ActiveQueryInterface ...@@ -98,7 +98,7 @@ class ActiveQuery extends Query implements ActiveQueryInterface
} }
if (!empty($this->with)) { if (!empty($this->with)) {
$models = [$model]; $models = [$model];
$this->populateRelations($models, $this->with); $this->findWith($this->with, $models);
$model = $models[0]; $model = $models[0];
} }
return $model; return $model;
......
...@@ -21,7 +21,7 @@ trait ActiveQueryTrait ...@@ -21,7 +21,7 @@ trait ActiveQueryTrait
*/ */
public $modelClass; public $modelClass;
/** /**
* @var array list of relations that this query should be performed with * @var array a list of relations that this query should be performed with
*/ */
public $with; public $with;
/** /**
...@@ -143,10 +143,12 @@ trait ActiveQueryTrait ...@@ -143,10 +143,12 @@ trait ActiveQueryTrait
} }
/** /**
* @param ActiveRecord[] $models * Finds records corresponding to one or multiple relations and populates them into the primary models.
* @param array $with * @param array $with a list of relations that this query should be performed with. Please
* refer to [[with()]] for details about specifying this parameter.
* @param ActiveRecord[] $models the primary models
*/ */
private function populateRelations(&$models, $with) public function findWith($with, &$models)
{ {
$primaryModel = new $this->modelClass; $primaryModel = new $this->modelClass;
$relations = $this->normalizeRelations($primaryModel, $with); $relations = $this->normalizeRelations($primaryModel, $with);
...@@ -155,7 +157,7 @@ trait ActiveQueryTrait ...@@ -155,7 +157,7 @@ trait ActiveQueryTrait
// inherit asArray from primary query // inherit asArray from primary query
$relation->asArray = $this->asArray; $relation->asArray = $this->asArray;
} }
$relation->findWith($name, $models); $relation->populateRelation($name, $models);
} }
} }
......
...@@ -1485,18 +1485,19 @@ class ActiveRecord extends Model ...@@ -1485,18 +1485,19 @@ class ActiveRecord extends Model
} }
/** /**
* @param array $keys * Returns a value indicating whether the given set of attributes represents the primary key for this model
* @return boolean * @param array $keys the set of attributes to check
* @return boolean whether the given set of attributes represents the primary key for this model
*/ */
private function isPrimaryKey($keys) public static function isPrimaryKey($keys)
{ {
$pks = $this->primaryKey(); $pks = static::primaryKey();
foreach ($keys as $key) { foreach ($keys as $key) {
if (!in_array($key, $pks, true)) { if (!in_array($key, $pks, true)) {
return false; return false;
} }
} }
return true; return count($keys) === count($pks);
} }
/** /**
......
...@@ -20,9 +20,6 @@ namespace yii\db; ...@@ -20,9 +20,6 @@ namespace yii\db;
* *
* If a relation involves a pivot table, it may be specified by [[via()]] or [[viaTable()]] method. * If a relation involves a pivot table, it may be specified by [[via()]] or [[viaTable()]] method.
* *
* @property array|ActiveRelation $via the query associated with the pivot table. Please call [[via()]]
* or [[viaTable()]] to set this property instead of directly setting it.
*
* @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>
* @since 2.0 * @since 2.0
......
...@@ -73,13 +73,12 @@ trait ActiveRelationTrait ...@@ -73,13 +73,12 @@ trait ActiveRelationTrait
/** /**
* Finds the related records and populates them into the primary models. * Finds the related records and populates them into the primary models.
* This method is internally used by [[ActiveQuery]]. Do not call it directly.
* @param string $name the relation name * @param string $name the relation name
* @param array $primaryModels primary models * @param array $primaryModels primary models
* @return array the related models * @return array the related models
* @throws InvalidConfigException * @throws InvalidConfigException if [[link]] is invalid
*/ */
public function findWith($name, &$primaryModels) public function populateRelation($name, &$primaryModels)
{ {
if (!is_array($this->link)) { if (!is_array($this->link)) {
throw new InvalidConfigException('Invalid link: it must be an array of key-value pairs.'); throw new InvalidConfigException('Invalid link: it must be an array of key-value pairs.');
...@@ -96,7 +95,7 @@ trait ActiveRelationTrait ...@@ -96,7 +95,7 @@ trait ActiveRelationTrait
/** @var ActiveRelationTrait $viaQuery */ /** @var ActiveRelationTrait $viaQuery */
list($viaName, $viaQuery) = $this->via; list($viaName, $viaQuery) = $this->via;
$viaQuery->primaryModel = null; $viaQuery->primaryModel = null;
$viaModels = $viaQuery->findWith($viaName, $primaryModels); $viaModels = $viaQuery->populateRelation($viaName, $primaryModels);
$this->filterByModels($viaModels); $this->filterByModels($viaModels);
} else { } else {
$this->filterByModels($primaryModels); $this->filterByModels($primaryModels);
......
...@@ -138,11 +138,15 @@ class Schema extends \yii\db\Schema ...@@ -138,11 +138,15 @@ class Schema extends \yii\db\Schema
foreach ($columns as $info) { foreach ($columns as $info) {
$column = $this->loadColumnSchema($info); $column = $this->loadColumnSchema($info);
$table->columns[$column->name] = $column; $table->columns[$column->name] = $column;
if ($column->isPrimaryKey) { }
$table->primaryKey[] = $column->name;
if ($column->autoIncrement) { $primaryKeys = $this->db->pdo->cubrid_schema(\PDO::CUBRID_SCH_PRIMARY_KEY, $table->name);
$table->sequenceName = ''; foreach ($primaryKeys as $key) {
} $column = $table->columns[$key['ATTR_NAME']];
$column->isPrimaryKey = true;
$table->primaryKey[] = $column->name;
if ($column->autoIncrement) {
$table->sequenceName = '';
} }
} }
......
...@@ -653,6 +653,9 @@ class BaseHtml ...@@ -653,6 +653,9 @@ class BaseHtml
*/ */
public static function dropDownList($name, $selection = null, $items = [], $options = []) public static function dropDownList($name, $selection = null, $items = [], $options = [])
{ {
if (!empty($options['multiple'])) {
return static::listBox($name, $selection, $items, $options);
}
$options['name'] = $name; $options['name'] = $name;
$selectOptions = static::renderSelectOptions($selection, $items, $options); $selectOptions = static::renderSelectOptions($selection, $items, $options);
return static::tag('select', "\n" . $selectOptions . "\n", $options); return static::tag('select', "\n" . $selectOptions . "\n", $options);
......
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\test;
use Yii;
use yii\base\Component;
use yii\base\InvalidConfigException;
use yii\db\ActiveRecord;
use yii\db\Connection;
/**
* DbFixtureManager manages database fixtures during tests.
*
* A fixture represents a list of rows for a specific table. For a test method,
* using a fixture means that at the beginning of the method, the table has and only
* has the rows that are given in the fixture. Therefore, the table's state is
* predictable.
*
* A fixture is represented as a PHP script whose name (without suffix) is the
* same as the table name (if schema name is needed, it should be prefixed to
* the table name). The PHP script returns an array representing a list of table
* rows. Each row is an associative array of column values indexed by column names.
*
* Fixtures must be stored under the [[basePath]] directory. The directory
* may contain a file named `init.php` which will be executed before any fixture is loaded.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class DbFixtureManager extends Component
{
/**
* @var string the init script file that should be executed before running each test.
* This should be a path relative to [[basePath]].
*/
public $initScript = 'init.php';
/**
* @var string the base path containing all fixtures. This can be either a directory path or path alias.
*/
public $basePath = '@app/tests/fixtures';
/**
* @var Connection|string the DB connection object or the application component ID of the DB connection.
* After the DbFixtureManager object is created, if you want to change this property, you should only assign it
* with a DB connection object.
*/
public $db = 'db';
/**
* @var array list of database schemas that the test tables may reside in. Defaults to
* array(''), meaning using the default schema (an empty string refers to the
* default schema). This property is mainly used when turning on and off integrity checks
* so that fixture data can be populated into the database without causing problem.
*/
public $schemas = [''];
private $_rows; // fixture name, row alias => row
private $_models; // fixture name, row alias => record (or class name)
private $_modelClasses;
/**
* Loads the specified fixtures.
*
* This method does the following things to load the fixtures:
*
* - Run [[initScript]] if any.
* - Clean up data and models loaded in memory previously.
* - Load each specified fixture by calling [[loadFixture()]].
*
* @param array $fixtures a list of fixtures (fixture name => table name or AR class name) to be loaded.
* Each array element can be either a table name (with schema prefix if needed), or a fully-qualified
* ActiveRecord class name (e.g. `app\models\Post`). An element can be associated with a key
* which will be treated as the fixture name.
* @return array the loaded fixture data (fixture name => table rows)
* @throws InvalidConfigException if a model class specifying a fixture is not an ActiveRecord class.
*/
public function load(array $fixtures = [])
{
$this->basePath = Yii::getAlias($this->basePath);
if (is_string($this->db)) {
$this->db = Yii::$app->getComponent($this->db);
}
if (!$this->db instanceof Connection) {
throw new InvalidConfigException("The 'db' property must be either a DB connection instance or the application component ID of a DB connection.");
}
foreach ($fixtures as $name => $fixture) {
if (strpos($fixture, '\\') !== false) {
$model = new $fixture;
if ($model instanceof ActiveRecord) {
$this->_modelClasses[$name] = $fixture;
$fixtures[$name] = $model->getTableSchema()->name;
} else {
throw new InvalidConfigException("Fixture '$fixture' must be an ActiveRecord class.");
}
}
}
$this->_modelClasses = $this->_rows = $this->_models = [];
$this->checkIntegrity(false);
if (!empty($this->initScript)) {
$initFile = $this->basePath . '/' . $this->initScript;
if (is_file($initFile)) {
require($initFile);
}
}
foreach ($fixtures as $name => $tableName) {
$rows = $this->loadFixture($tableName);
if (is_array($rows)) {
$this->_rows[$name] = $rows;
}
}
$this->checkIntegrity(true);
return $this->_rows;
}
/**
* Loads the fixture for the specified table.
*
* This method does the following tasks to load the fixture for a table:
*
* - Remove existing rows in the table.
* - If there is any auto-incremental column, the corresponding sequence will be reset to 0.
* - If a fixture file is found, it will be executed, and its return value will be treated
* as rows which will then be inserted into the table.
*
* @param string $tableName table name
* @return array|boolean the loaded fixture rows indexed by row aliases (if any).
* False is returned if the table does not have a fixture.
* @throws InvalidConfigException if the specified table does not exist
*/
public function loadFixture($tableName)
{
$table = $this->db->getSchema()->getTableSchema($tableName);
if ($table === null) {
throw new InvalidConfigException("Table does not exist: $tableName");
}
$this->db->createCommand()->truncateTable($tableName);
$fileName = $this->basePath . '/' . $tableName . '.php';
if (!is_file($fileName)) {
return false;
}
$rows = [];
foreach (require($fileName) as $alias => $row) {
$this->db->createCommand()->insert($tableName, $row)->execute();
if ($table->sequenceName !== null) {
foreach ($table->primaryKey as $pk) {
if (!isset($row[$pk])) {
$row[$pk] = $this->db->getLastInsertID($table->sequenceName);
break;
}
}
}
$rows[$alias] = $row;
}
return $rows;
}
/**
* Returns the fixture data rows.
* The rows will have updated primary key values if the primary key is auto-incremental.
* @param string $fixtureName the fixture name
* @return array the fixture data rows. False is returned if there is no such fixture data.
*/
public function getRows($fixtureName)
{
return isset($this->_rows[$fixtureName]) ? $this->_rows[$fixtureName] : false;
}
/**
* Returns the specified ActiveRecord instance in the fixture data.
* @param string $fixtureName the fixture name
* @param string $modelName the alias for the fixture data row
* @return \yii\db\ActiveRecord the ActiveRecord instance. Null is returned if there is no such fixture row.
*/
public function getModel($fixtureName, $modelName)
{
if (!isset($this->_modelClasses[$fixtureName]) || !isset($this->_rows[$fixtureName][$modelName])) {
return null;
}
if (isset($this->_models[$fixtureName][$modelName])) {
return $this->_models[$fixtureName][$modelName];
}
$row = $this->_rows[$fixtureName][$modelName];
/** @var \yii\db\ActiveRecord $modelClass */
$modelClass = $this->_models[$fixtureName];
/** @var \yii\db\ActiveRecord $model */
$model = new $modelClass;
$keys = [];
foreach ($model->primaryKey() as $key) {
$keys[$key] = isset($row[$key]) ? $row[$key] : null;
}
return $this->_models[$fixtureName][$modelName] = $modelClass::find($keys);
}
/**
* Enables or disables database integrity check.
* This method may be used to temporarily turn off foreign constraints check.
* @param boolean $check whether to enable database integrity check
*/
public function checkIntegrity($check)
{
foreach ($this->schemas as $schema) {
$this->db->createCommand()->checkIntegrity($check, $schema);
}
}
}
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\test;
use Yii;
/**
* DbTestTrait implements the commonly used methods for setting up and accessing fixture data.
*
* To use DbTestTrait, call the [[loadFixtures()]] method in the setup method in a test case class.
* The specified fixtures will be loaded and accessible through [[getFixtureData()]] and [[getFixtureModel()]].
*
* For example,
*
* ~~~
* use yii\test\DbTestTrait;
* use app\models\Post;
* use app\models\User;
*
* class PostTestCase extends \PHPUnit_Framework_TestCase
* {
* use DbTestTrait;
*
* public function setUp()
* {
* $this->loadFixtures([
* 'posts' => Post::className(),
* 'users' => User::className(),
* ]);
* }
* }
* ~~~
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
trait DbTestTrait
{
/**
* Loads the specified fixtures.
*
* This method should typically be called in the setup method of test cases so that
* the fixtures are loaded before running each test method.
*
* This method does the following things:
*
* - Run [[DbFixtureManager::initScript]] if it is found under [[DbFixtureManager::basePath]].
* - Clean up data and models loaded in memory previously.
* - Load each specified fixture:
* * Truncate the corresponding table.
* * If a fixture file named `TableName.php` is found under [[DbFixtureManager::basePath]],
* the file will be executed, and the return value will be treated as rows which will
* then be inserted into the table.
*
* @param array $fixtures a list of fixtures (fixture name => table name or AR class name) to be loaded.
* Each array element can be either a table name (with schema prefix if needed), or a fully-qualified
* ActiveRecord class name (e.g. `app\models\Post`). An element can be optionally associated with a key
* which will be treated as the fixture name. For example,
*
* ~~~
* [
* 'tbl_comment',
* 'users' => 'tbl_user', // 'users' is the fixture name, 'tbl_user' is a table name
* 'posts' => 'app\models\Post, // 'app\models\Post' is a model class name
* ]
* ~~~
*
* @return array the loaded fixture data (fixture name => table rows)
*/
public function loadFixtures(array $fixtures = [])
{
return $this->getFixtureManager()->load($fixtures);
}
/**
* Returns the DB fixture manager.
* @return DbFixtureManager the DB fixture manager
*/
public function getFixtureManager()
{
return Yii::$app->getComponent('fixture');
}
/**
* Returns the table rows of the named fixture.
* @param string $fixtureName the fixture name.
* @return array the named fixture table rows. False is returned if there is no such fixture data.
*/
public function getFixtureRows($fixtureName)
{
return $this->getFixtureManager()->getRows($fixtureName);
}
/**
* Returns the named AR instance corresponding to the named fixture.
* @param string $fixtureName the fixture name.
* @param string $modelName the name of the fixture data row
* @return \yii\db\ActiveRecord the named AR instance corresponding to the named fixture.
* Null is returned if there is no such fixture or the record cannot be found.
*/
public function getFixtureModel($fixtureName, $modelName)
{
return $this->getFixtureManager()->getModel($fixtureName, $modelName);
}
}
<?php
/**
* TestCase class.
*
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\test;
require_once('PHPUnit/Runner/Version.php');
spl_autoload_unregister(['Yii', 'autoload']);
require_once('PHPUnit/Autoload.php');
spl_autoload_register(['Yii', 'autoload']); // put yii's autoloader at the end
/**
* TestCase is the base class for all test case classes.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
abstract class TestCase extends \PHPUnit_Framework_TestCase
{
}
<?php
/**
* WebTestCase class.
*
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\test;
require_once('PHPUnit/Runner/Version.php');
spl_autoload_unregister(['Yii','autoload']);
require_once('PHPUnit/Autoload.php');
spl_autoload_register(['Yii','autoload']); // put yii's autoloader at the end
/**
* WebTestCase is the base class for all test case classes.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
abstract class WebTestCase extends \PHPUnit_Extensions_SeleniumTestCase
{
}
...@@ -74,11 +74,11 @@ class AssetConverter extends Component implements AssetConverterInterface ...@@ -74,11 +74,11 @@ class AssetConverter extends Component implements AssetConverterInterface
'{from}' => escapeshellarg("$basePath/$asset"), '{from}' => escapeshellarg("$basePath/$asset"),
'{to}' => escapeshellarg("$basePath/$result"), '{to}' => escapeshellarg("$basePath/$result"),
]); ]);
$descriptor = array( $descriptor = [
1 => array('pipe', 'w'), 1 => ['pipe', 'w'],
2 => array('pipe', 'w'), 2 => ['pipe', 'w'],
); ];
$pipes = array(); $pipes = [];
$proc = proc_open($command, $descriptor, $pipes, $basePath); $proc = proc_open($command, $descriptor, $pipes, $basePath);
$stdout = stream_get_contents($pipes[1]); $stdout = stream_get_contents($pipes[1]);
$stderr = stream_get_contents($pipes[2]); $stderr = stream_get_contents($pipes[2]);
......
...@@ -35,7 +35,6 @@ use yii\helpers\Security; ...@@ -35,7 +35,6 @@ use yii\helpers\Security;
* @property string $csrfTokenFromHeader The CSRF token sent via [[CSRF_HEADER]] by browser. Null is returned * @property string $csrfTokenFromHeader The CSRF token sent via [[CSRF_HEADER]] by browser. Null is returned
* if no such header is sent. This property is read-only. * if no such header is sent. This property is read-only.
* @property array $delete The DELETE request parameter values. This property is read-only. * @property array $delete The DELETE request parameter values. This property is read-only.
* @property array $get The GET request parameter values. This property is read-only.
* @property string $hostInfo Schema and hostname part (with port number if needed) of the request URL (e.g. * @property string $hostInfo Schema and hostname part (with port number if needed) of the request URL (e.g.
* `http://www.yiiframework.com`). * `http://www.yiiframework.com`).
* @property boolean $isAjax Whether this is an AJAX (XMLHttpRequest) request. This property is read-only. * @property boolean $isAjax Whether this is an AJAX (XMLHttpRequest) request. This property is read-only.
...@@ -312,15 +311,6 @@ class Request extends \yii\base\Request ...@@ -312,15 +311,6 @@ class Request extends \yii\base\Request
} }
/** /**
* Returns the GET request parameter values.
* @return array the GET request parameter values
*/
public function getGet()
{
return $_GET;
}
/**
* Returns the named POST parameter value. * Returns the named POST parameter value.
* If the POST parameter does not exist, the second parameter to this method will be returned. * If the POST parameter does not exist, the second parameter to this method will be returned.
* @param string $name the POST parameter name. If not specified, whole $_POST is returned. * @param string $name the POST parameter name. If not specified, whole $_POST is returned.
......
...@@ -46,7 +46,7 @@ use yii\base\InvalidParamException; ...@@ -46,7 +46,7 @@ use yii\base\InvalidParamException;
* call methods such as [[setFlash()]], [[getFlash()]]. * call methods such as [[setFlash()]], [[getFlash()]].
* *
* @property array $allFlashes Flash messages (key => message). This property is read-only. * @property array $allFlashes Flash messages (key => message). This property is read-only.
* @property array $cookieParams The session cookie parameters. * @property array $cookieParams The session cookie parameters. This property is read-only.
* @property integer $count The number of session variables. This property is read-only. * @property integer $count The number of session variables. This property is read-only.
* @property string $flash The key identifying the flash message. Note that flash messages and normal session * @property string $flash The key identifying the flash message. Note that flash messages and normal session
* variables share the same name space. If you have a normal session variable using the same name, its value will * variables share the same name space. If you have a normal session variable using the same name, its value will
......
...@@ -2,10 +2,15 @@ ...@@ -2,10 +2,15 @@
namespace yiiunit; namespace yiiunit;
require_once('PHPUnit/Runner/Version.php');
spl_autoload_unregister(['Yii', 'autoload']);
require_once('PHPUnit/Autoload.php');
spl_autoload_register(['Yii', 'autoload']); // put yii's autoloader at the end
/** /**
* This is the base class for all yii framework unit tests. * This is the base class for all yii framework unit tests.
*/ */
abstract class TestCase extends \yii\test\TestCase abstract class TestCase extends \PHPUnit_Framework_TestCase
{ {
public static $params; public static $params;
......
<?php <?php
namespace yiiunit\framework\base; namespace yiiunit\framework\base;
use yii\test\TestCase; use yiiunit\TestCase;
use yii\base\UserException; use yii\base\UserException;
use yii\base\InvalidCallException; use yii\base\InvalidCallException;
......
...@@ -91,6 +91,26 @@ abstract class CacheTestCase extends TestCase ...@@ -91,6 +91,26 @@ abstract class CacheTestCase extends TestCase
$this->assertEquals('array_test', $array['array_test']); $this->assertEquals('array_test', $array['array_test']);
} }
public function testMset()
{
$cache = $this->getCacheInstance();
$cache->flush();
$cache->mset([
'string_test' => 'string_test',
'number_test' => 42,
'array_test' => ['array_test' => 'array_test'],
]);
$this->assertEquals('string_test', $cache->get('string_test'));
$this->assertEquals(42, $cache->get('number_test'));
$array = $cache->get('array_test');
$this->assertArrayHasKey('array_test', $array);
$this->assertEquals('array_test', $array['array_test']);
}
public function testExists() public function testExists()
{ {
$cache = $this->prepare(); $cache = $this->prepare();
...@@ -164,6 +184,21 @@ abstract class CacheTestCase extends TestCase ...@@ -164,6 +184,21 @@ abstract class CacheTestCase extends TestCase
$this->assertEquals(13, $cache->get('add_test')); $this->assertEquals(13, $cache->get('add_test'));
} }
public function testMadd()
{
$cache = $this->prepare();
$this->assertFalse($cache->get('add_test'));
$cache->madd([
'number_test' => 13,
'add_test' => 13,
]);
$this->assertEquals(42, $cache->get('number_test'));
$this->assertEquals(13, $cache->get('add_test'));
}
public function testDelete() public function testDelete()
{ {
$cache = $this->prepare(); $cache = $this->prepare();
......
...@@ -489,4 +489,21 @@ class ActiveRecordTest extends DatabaseTestCase ...@@ -489,4 +489,21 @@ class ActiveRecordTest extends DatabaseTestCase
$customers = Customer::find()->where(['status' => false])->all(); $customers = Customer::find()->where(['status' => false])->all();
$this->assertEquals(1, count($customers)); $this->assertEquals(1, count($customers));
} }
public function testIsPrimaryKey()
{
$this->assertFalse(Customer::isPrimaryKey([]));
$this->assertTrue(Customer::isPrimaryKey(['id']));
$this->assertFalse(Customer::isPrimaryKey(['id', 'name']));
$this->assertFalse(Customer::isPrimaryKey(['name']));
$this->assertFalse(Customer::isPrimaryKey(['name', 'email']));
$this->assertFalse(OrderItem::isPrimaryKey([]));
$this->assertFalse(OrderItem::isPrimaryKey(['order_id']));
$this->assertFalse(OrderItem::isPrimaryKey(['item_id']));
$this->assertFalse(OrderItem::isPrimaryKey(['quantity']));
$this->assertFalse(OrderItem::isPrimaryKey(['quantity', 'subtotal']));
$this->assertTrue(OrderItem::isPrimaryKey(['order_id', 'item_id']));
$this->assertFalse(OrderItem::isPrimaryKey(['order_id', 'item_id', 'quantity']));
}
} }
...@@ -4,7 +4,7 @@ namespace yiiunit\framework\helpers; ...@@ -4,7 +4,7 @@ namespace yiiunit\framework\helpers;
use yii\base\Object; use yii\base\Object;
use yii\helpers\ArrayHelper; use yii\helpers\ArrayHelper;
use yii\test\TestCase; use yiiunit\TestCase;
use yii\data\Sort; use yii\data\Sort;
class Post1 class Post1
......
<?php <?php
use yii\helpers\FileHelper; use yii\helpers\FileHelper;
use yii\test\TestCase; use yiiunit\TestCase;
/** /**
* Unit test for [[yii\helpers\FileHelper]] * Unit test for [[yii\helpers\FileHelper]]
...@@ -126,10 +126,10 @@ class FileHelperTest extends TestCase ...@@ -126,10 +126,10 @@ class FileHelperTest extends TestCase
FileHelper::copyDirectory($srcDirName, $dstDirName); FileHelper::copyDirectory($srcDirName, $dstDirName);
$this->assertTrue(file_exists($dstDirName), 'Destination directory does not exist!'); $this->assertFileExists($dstDirName, 'Destination directory does not exist!');
foreach ($files as $name => $content) { foreach ($files as $name => $content) {
$fileName = $dstDirName . DIRECTORY_SEPARATOR . $name; $fileName = $dstDirName . DIRECTORY_SEPARATOR . $name;
$this->assertTrue(file_exists($fileName), 'Directory file is missing!'); $this->assertFileExists($fileName);
$this->assertEquals($content, file_get_contents($fileName), 'Incorrect file content!'); $this->assertEquals($content, file_get_contents($fileName), 'Incorrect file content!');
} }
} }
...@@ -189,7 +189,7 @@ class FileHelperTest extends TestCase ...@@ -189,7 +189,7 @@ class FileHelperTest extends TestCase
FileHelper::removeDirectory($dirName); FileHelper::removeDirectory($dirName);
$this->assertFalse(file_exists($dirName), 'Unable to remove directory!'); $this->assertFileNotExists($dirName, 'Unable to remove directory!');
// should be silent about non-existing directories // should be silent about non-existing directories
FileHelper::removeDirectory($basePath . DIRECTORY_SEPARATOR . 'nonExisting'); FileHelper::removeDirectory($basePath . DIRECTORY_SEPARATOR . 'nonExisting');
...@@ -277,7 +277,7 @@ class FileHelperTest extends TestCase ...@@ -277,7 +277,7 @@ class FileHelperTest extends TestCase
$basePath = $this->testFilePath; $basePath = $this->testFilePath;
$dirName = $basePath . DIRECTORY_SEPARATOR . 'test_dir_level_1' . DIRECTORY_SEPARATOR . 'test_dir_level_2'; $dirName = $basePath . DIRECTORY_SEPARATOR . 'test_dir_level_1' . DIRECTORY_SEPARATOR . 'test_dir_level_2';
$this->assertTrue(FileHelper::createDirectory($dirName), 'FileHelper::createDirectory should return true if directory was created!'); $this->assertTrue(FileHelper::createDirectory($dirName), 'FileHelper::createDirectory should return true if directory was created!');
$this->assertTrue(file_exists($dirName), 'Unable to create directory recursively!'); $this->assertFileExists($dirName, 'Unable to create directory recursively!');
$this->assertTrue(FileHelper::createDirectory($dirName), 'FileHelper::createDirectory should return true for already existing directories!'); $this->assertTrue(FileHelper::createDirectory($dirName), 'FileHelper::createDirectory should return true for already existing directories!');
} }
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
namespace yiiunit\framework\helpers; namespace yiiunit\framework\helpers;
use yii\helpers\Json; use yii\helpers\Json;
use yii\test\TestCase; use yiiunit\TestCase;
use yii\web\JsExpression; use yii\web\JsExpression;
/** /**
......
<?php <?php
namespace yiiunit\framework\helpers; namespace yiiunit\framework\helpers;
use \yii\helpers\StringHelper as StringHelper; use yii\helpers\StringHelper;
use yii\test\TestCase; use yiiunit\TestCase;
/** /**
* StringHelperTest * StringHelperTest
......
<?php <?php
namespace yiiunit\framework\helpers; namespace yiiunit\framework\helpers;
use \yii\helpers\VarDumper; use yii\helpers\VarDumper;
use yii\test\TestCase; use yiiunit\TestCase;
/** /**
* @group helpers * @group helpers
......
...@@ -69,7 +69,7 @@ class BaseMessageTest extends TestCase ...@@ -69,7 +69,7 @@ class BaseMessageTest extends TestCase
class TestMailer extends BaseMailer class TestMailer extends BaseMailer
{ {
public $messageClass = 'yiiunit\framework\mail\TestMessage'; public $messageClass = 'yiiunit\framework\mail\TestMessage';
public $sentMessages = array(); public $sentMessages = [];
protected function sendMessage($message) protected function sendMessage($message)
{ {
......
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