mirror of
https://github.com/yiisoft/yii2.git
synced 2025-11-02 21:41:19 +08:00
Merge branch 'master' into developeruz-15726-exist-validator-useMaster
This commit is contained in:
@ -342,7 +342,7 @@ to representative class names:
|
||||
And so on.
|
||||
|
||||
Using the object format makes it possible to create your own conditions or to change the way default ones are built.
|
||||
See [Creating Custom Conditions and Expressions](#creating-custom-conditions-and-expressions) chapter to learn more.
|
||||
See [Adding Custom Conditions and Expressions](#adding-custom-conditions-and-expressions) chapter to learn more.
|
||||
|
||||
|
||||
#### Appending Conditions <span id="appending-conditions"></span>
|
||||
|
||||
@ -142,7 +142,7 @@ to the application configuration:
|
||||
|
||||
> Info: We use an sqlite database here for simplicity. Please refer to the [Database guide](db-dao.md) for more options.
|
||||
|
||||
Next we create a [database migration](db-migrations.md) to create a posts table.
|
||||
Next we create a [database migration](db-migrations.md) to create a post table.
|
||||
Make sure you have a separate configuration file as explained above, we need it to run the console commands below.
|
||||
Running the following commands will
|
||||
create a database migration file and apply the migration to the database:
|
||||
@ -163,12 +163,12 @@ class Post extends ActiveRecord
|
||||
{
|
||||
public static function tableName()
|
||||
{
|
||||
return '{{posts}}';
|
||||
return '{{post}}';
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> Info: The model created here is an ActiveRecord class, which represents the data from the `posts` table.
|
||||
> Info: The model created here is an ActiveRecord class, which represents the data from the `post` table.
|
||||
> Please refer to the [active record guide](db-active-record.md) for more information.
|
||||
|
||||
To serve posts on our API, add the `PostController` in `controllers`:
|
||||
|
||||
@ -1,12 +1,21 @@
|
||||
Yii Framework 2 Change Log
|
||||
==========================
|
||||
|
||||
2.0.15 under development
|
||||
------------------------
|
||||
2.0.14.1 under development
|
||||
--------------------------
|
||||
|
||||
- Bug #15728, #15731: Fixed BC break in `Query::select()` method (silverfire)
|
||||
- Bug #15692: Fix ExistValidator with targetRelation ignores filter (developeruz)
|
||||
- Bug #15693: Fixed `yii\filters\auth\HttpHeaderAuth` to work correctly when pattern is set but was not matched (bboure)
|
||||
- Bug #15696: Fix magic getter for ActiveRecord (developeruz)
|
||||
- Bug #15726: Fix ExistValidator is broken for NOSQL (developeruz)
|
||||
- Enh #15716: Implemented `\Traversable` in `yii\db\ArrayExpression` (silverfire)
|
||||
- Bug #15678: Fixed `resetForm()` method in `yii.activeForm.js` which used an undefined variable (Izumi-kun)
|
||||
- Bug #15742: Updated `yii\helpers\BaseHtml::setActivePlaceholder()` to be consistent with `activeLabel()` (edwards-sj)
|
||||
- Bug #15692: Fix `yii\validators\ExistValidator` to respect filter when `targetRelation` is used (developeruz)
|
||||
- Bug #15696: Fix magic getter for `yii\db\ActiveRecord` (developeruz)
|
||||
- Bug #15707: Fixed JSON retrieving from MySQL (silverfire)
|
||||
- Bug #15724: Changed shortcut in `yii\console\controllers\BaseMigrateController` for `comment` option from `-c` to `-C` due to conflict (Izumi-kun)
|
||||
|
||||
|
||||
2.0.14 February 18, 2018
|
||||
|
||||
@ -444,7 +444,7 @@
|
||||
this.value = getValue($form, this);
|
||||
this.status = 0;
|
||||
var $container = $form.find(this.container),
|
||||
$input = findInput($form, attribute),
|
||||
$input = findInput($form, this),
|
||||
$errorElement = data.settings.validationStateOn === 'input' ? $input : $container;
|
||||
|
||||
$errorElement.removeClass(
|
||||
|
||||
@ -160,7 +160,7 @@ class MigrateController extends BaseMigrateController
|
||||
public function optionAliases()
|
||||
{
|
||||
return array_merge(parent::optionAliases(), [
|
||||
'c' => 'comment',
|
||||
'C' => 'comment',
|
||||
'f' => 'fields',
|
||||
'p' => 'migrationPath',
|
||||
't' => 'migrationTable',
|
||||
|
||||
@ -7,6 +7,9 @@
|
||||
|
||||
namespace yii\db;
|
||||
|
||||
use Traversable;
|
||||
use yii\base\InvalidConfigException;
|
||||
|
||||
/**
|
||||
* Class ArrayExpression represents an array SQL expression.
|
||||
*
|
||||
@ -22,7 +25,7 @@ namespace yii\db;
|
||||
* @author Dmytro Naumenko <d.naumenko.a@gmail.com>
|
||||
* @since 2.0.14
|
||||
*/
|
||||
class ArrayExpression implements ExpressionInterface, \ArrayAccess, \Countable
|
||||
class ArrayExpression implements ExpressionInterface, \ArrayAccess, \Countable, \IteratorAggregate
|
||||
{
|
||||
/**
|
||||
* @var null|string the type of the array elements. Defaults to `null` which means the type is
|
||||
@ -33,8 +36,8 @@ class ArrayExpression implements ExpressionInterface, \ArrayAccess, \Countable
|
||||
*/
|
||||
private $type;
|
||||
/**
|
||||
* @var array|QueryInterface|mixed the array content. Either represented as an array of values or a [[Query]] that
|
||||
* returns these values. A single value will be considered as an array containing one element.
|
||||
* @var array|QueryInterface the array's content.
|
||||
* In can be represented as an array of values or a [[Query]] that returns these values.
|
||||
*/
|
||||
private $value;
|
||||
/**
|
||||
@ -167,4 +170,21 @@ class ArrayExpression implements ExpressionInterface, \ArrayAccess, \Countable
|
||||
{
|
||||
return count($this->value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve an external iterator
|
||||
*
|
||||
* @link http://php.net/manual/en/iteratoraggregate.getiterator.php
|
||||
* @return Traversable An instance of an object implementing <b>Iterator</b> or
|
||||
* <b>Traversable</b>
|
||||
* @since 5.0.0
|
||||
*/
|
||||
public function getIterator()
|
||||
{
|
||||
if ($this->getValue() instanceof QueryInterface) {
|
||||
throw new InvalidConfigException('The ArrayExpression class can not be iterated when the value is a QueryInterface object');
|
||||
}
|
||||
|
||||
return new \ArrayIterator($this->getValue());
|
||||
}
|
||||
}
|
||||
|
||||
@ -658,22 +658,28 @@ PATTERN;
|
||||
*/
|
||||
protected function getUniqueColumns($columns)
|
||||
{
|
||||
$columns = array_unique($columns);
|
||||
$unaliasedColumns = $this->getUnaliasedColumnsFromSelect();
|
||||
|
||||
$result = [];
|
||||
foreach ($columns as $columnAlias => $columnDefinition) {
|
||||
if ($columnDefinition instanceof Query) {
|
||||
continue;
|
||||
if (!$columnDefinition instanceof Query) {
|
||||
if (is_string($columnAlias)) {
|
||||
$existsInSelect = isset($this->select[$columnAlias]) && $this->select[$columnAlias] === $columnDefinition;
|
||||
if ($existsInSelect) {
|
||||
continue;
|
||||
}
|
||||
} elseif (is_integer($columnAlias)) {
|
||||
$existsInSelect = in_array($columnDefinition, $unaliasedColumns, true);
|
||||
$existsInResultSet = in_array($columnDefinition, $result, true);
|
||||
if ($existsInSelect || $existsInResultSet) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
(is_string($columnAlias) && isset($this->select[$columnAlias]) && $this->select[$columnAlias] === $columnDefinition)
|
||||
|| (is_integer($columnAlias) && in_array($columnDefinition, $unaliasedColumns))
|
||||
) {
|
||||
unset($columns[$columnAlias]);
|
||||
}
|
||||
$result[$columnAlias] = $columnDefinition;
|
||||
}
|
||||
return $columns;
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -624,15 +624,15 @@ class QueryBuilder extends \yii\base\BaseObject
|
||||
$columnSchemas = $tableSchema !== null ? $tableSchema->columns : [];
|
||||
$sets = [];
|
||||
foreach ($columns as $name => $value) {
|
||||
|
||||
$value = isset($columnSchemas[$name]) ? $columnSchemas[$name]->dbTypecast($value) : $value;
|
||||
if ($value instanceof ExpressionInterface) {
|
||||
$sets[] = $this->db->quoteColumnName($name) . '=' . $this->buildExpression($value, $params);
|
||||
$placeholder = $this->buildExpression($value, $params);
|
||||
} else {
|
||||
$phName = $this->bindParam(
|
||||
isset($columnSchemas[$name]) ? $columnSchemas[$name]->dbTypecast($value) : $value,
|
||||
$params
|
||||
);
|
||||
$sets[] = $this->db->quoteColumnName($name) . '=' . $phName;
|
||||
$placeholder = $this->bindParam($value, $params);
|
||||
}
|
||||
|
||||
$sets[] = $this->db->quoteColumnName($name) . '=' . $placeholder;
|
||||
}
|
||||
return [$sets, $params];
|
||||
}
|
||||
|
||||
52
framework/db/mysql/ColumnSchema.php
Normal file
52
framework/db/mysql/ColumnSchema.php
Normal file
@ -0,0 +1,52 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\db\mysql;
|
||||
|
||||
use yii\db\ExpressionInterface;
|
||||
use yii\db\JsonExpression;
|
||||
|
||||
/**
|
||||
* Class ColumnSchema
|
||||
*
|
||||
* @author Dmytro Naumenko <d.naumenko.a@gmail.com>
|
||||
* @since 2.0.14.1
|
||||
*/
|
||||
class ColumnSchema extends \yii\db\ColumnSchema
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function dbTypecast($value)
|
||||
{
|
||||
if ($value instanceof ExpressionInterface) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
if ($this->dbType === Schema::TYPE_JSON) {
|
||||
return new JsonExpression($value, $this->type);
|
||||
}
|
||||
|
||||
return $this->typecast($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function phpTypecast($value)
|
||||
{
|
||||
if ($value === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($this->type === Schema::TYPE_JSON) {
|
||||
return json_decode($value, true);
|
||||
}
|
||||
|
||||
return parent::phpTypecast($value);
|
||||
}
|
||||
}
|
||||
@ -30,6 +30,11 @@ class Schema extends \yii\db\Schema implements ConstraintFinderInterface
|
||||
{
|
||||
use ConstraintFinderTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public $columnSchemaClass = 'yii\db\mysql\ColumnSchema';
|
||||
|
||||
/**
|
||||
* @var bool whether MySQL used is older than 5.1.
|
||||
*/
|
||||
|
||||
@ -51,9 +51,14 @@ class HttpHeaderAuth extends AuthMethod
|
||||
$authHeader = $request->getHeaders()->get($this->header);
|
||||
|
||||
if ($authHeader !== null) {
|
||||
if ($this->pattern !== null && preg_match($this->pattern, $authHeader, $matches)) {
|
||||
$authHeader = $matches[1];
|
||||
if ($this->pattern !== null) {
|
||||
if (preg_match($this->pattern, $authHeader, $matches)) {
|
||||
$authHeader = $matches[1];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
$identity = $user->loginByAccessToken($authHeader, get_class($this));
|
||||
if ($identity === null) {
|
||||
$this->challenge($response);
|
||||
|
||||
@ -1386,6 +1386,7 @@ class BaseHtml
|
||||
protected static function setActivePlaceholder($model, $attribute, &$options = [])
|
||||
{
|
||||
if (isset($options['placeholder']) && $options['placeholder'] === true) {
|
||||
$attribute = static::getAttributeName($attribute);
|
||||
$options['placeholder'] = $model->getAttributeLabel($attribute);
|
||||
}
|
||||
}
|
||||
|
||||
@ -35,7 +35,7 @@ return [
|
||||
'Missing required arguments: {params}' => 'Nedostaju obavezni argumenti: {params}',
|
||||
'Missing required parameters: {params}' => 'Nedostaju obavezni parametri: {params}',
|
||||
'No' => 'Ne',
|
||||
'No results found.' => 'Nema rezulatata.',
|
||||
'No results found.' => 'Nema rezultata.',
|
||||
'Only files with these MIME types are allowed: {mimeTypes}.' => 'Samo datoteke sa sljedećim MIME tipovima su dozvoljeni: {mimeTypes}.',
|
||||
'Only files with these extensions are allowed: {extensions}.' => 'Samo datoteke sa sljedećim ekstenzijama su dozvoljeni: {extensions}.',
|
||||
'Page not found.' => 'Stranica nije pronađena.',
|
||||
|
||||
@ -12,6 +12,7 @@ namespace yiiunit\data\ar;
|
||||
* @property string $title
|
||||
* @property string $content
|
||||
* @property int $version
|
||||
* @property array $properties
|
||||
*/
|
||||
class Document extends ActiveRecord
|
||||
{
|
||||
|
||||
23
tests/data/ar/Storage.php
Normal file
23
tests/data/ar/Storage.php
Normal file
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yiiunit\data\ar;
|
||||
|
||||
/**
|
||||
* Class Animal
|
||||
*
|
||||
* @author Dmytro Naumenko <d.naumenko.a@gmail.com>
|
||||
* @property int $id
|
||||
* @property array $data
|
||||
*/
|
||||
class Storage extends ActiveRecord
|
||||
{
|
||||
public static function tableName()
|
||||
{
|
||||
return 'storage';
|
||||
}
|
||||
}
|
||||
@ -23,6 +23,7 @@ DROP TABLE IF EXISTS `comment` CASCADE;
|
||||
DROP TABLE IF EXISTS `dossier`;
|
||||
DROP TABLE IF EXISTS `employee`;
|
||||
DROP TABLE IF EXISTS `department`;
|
||||
DROP TABLE IF EXISTS `storage`;
|
||||
DROP VIEW IF EXISTS `animal_view`;
|
||||
DROP TABLE IF EXISTS `T_constraints_4` CASCADE;
|
||||
DROP TABLE IF EXISTS `T_constraints_3` CASCADE;
|
||||
@ -202,6 +203,12 @@ CREATE TABLE `dossier` (
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE `storage` (
|
||||
`id` INT(11) NOT NULL AUTO_INCREMENT,
|
||||
`data` JSON NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE VIEW `animal_view` AS SELECT * FROM `animal`;
|
||||
|
||||
INSERT INTO `animal` (`type`) VALUES ('yiiunit\data\ar\Cat');
|
||||
|
||||
@ -177,7 +177,7 @@ CREATE TABLE "default_pk" (
|
||||
CREATE TABLE "document" (
|
||||
id serial primary key,
|
||||
title varchar(255) not null,
|
||||
content text not null,
|
||||
content text,
|
||||
version integer not null default 0
|
||||
);
|
||||
|
||||
@ -325,6 +325,7 @@ INSERT INTO "bit_values" (id, val) VALUES (1, '0'), (2, '1');
|
||||
|
||||
DROP TABLE IF EXISTS "array_and_json_types" CASCADE;
|
||||
CREATE TABLE "array_and_json_types" (
|
||||
id SERIAL NOT NULL PRIMARY KEY,
|
||||
intarray_col INT[],
|
||||
textarray2_col TEXT[][],
|
||||
json_col JSON,
|
||||
|
||||
@ -62,6 +62,37 @@ abstract class QueryTest extends DatabaseTestCase
|
||||
$query = new Query();
|
||||
$query->select('name, name, name as X, name as X');
|
||||
$this->assertEquals(['name', 'name as X'], array_values($query->select));
|
||||
|
||||
/** @see https://github.com/yiisoft/yii2/issues/15676 */
|
||||
$query = (new Query())->select('id');
|
||||
$this->assertSame(['id'], $query->select);
|
||||
$query->select(['id', 'brand_id']);
|
||||
$this->assertSame(['id', 'brand_id'], $query->select);
|
||||
|
||||
/** @see https://github.com/yiisoft/yii2/issues/15676 */
|
||||
$query = (new Query())->select(['prefix' => 'LEFT(name, 7)', 'prefix_key' => 'LEFT(name, 7)']);
|
||||
$this->assertSame(['prefix' => 'LEFT(name, 7)', 'prefix_key' => 'LEFT(name, 7)'], $query->select);
|
||||
$query->addSelect(['LEFT(name,7) as test']);
|
||||
$this->assertSame(['prefix' => 'LEFT(name, 7)', 'prefix_key' => 'LEFT(name, 7)', 'LEFT(name,7) as test'], $query->select);
|
||||
$query->addSelect(['LEFT(name,7) as test']);
|
||||
$this->assertSame(['prefix' => 'LEFT(name, 7)', 'prefix_key' => 'LEFT(name, 7)', 'LEFT(name,7) as test'], $query->select);
|
||||
$query->addSelect(['test' => 'LEFT(name,7)']);
|
||||
$this->assertSame(['prefix' => 'LEFT(name, 7)', 'prefix_key' => 'LEFT(name, 7)', 'LEFT(name,7) as test', 'test' => 'LEFT(name,7)'], $query->select);
|
||||
|
||||
/** @see https://github.com/yiisoft/yii2/issues/15731 */
|
||||
$selectedCols = [
|
||||
'total_sum' => 'SUM(f.amount)',
|
||||
'in_sum' => 'SUM(IF(f.type = :type_in, f.amount, 0))',
|
||||
'out_sum' => 'SUM(IF(f.type = :type_out, f.amount, 0))',
|
||||
];
|
||||
$query = (new Query())->select($selectedCols)->addParams([
|
||||
':type_in' => 'in',
|
||||
':type_out' => 'out',
|
||||
':type_partner' => 'partner',
|
||||
]);
|
||||
$this->assertSame($selectedCols, $query->select);
|
||||
$query->select($selectedCols);
|
||||
$this->assertSame($selectedCols, $query->select);
|
||||
}
|
||||
|
||||
public function testFrom()
|
||||
@ -675,18 +706,4 @@ abstract class QueryTest extends DatabaseTestCase
|
||||
$this->assertEquals('user11', $query->cache()->where(['id' => 1])->scalar($db));
|
||||
}, 10);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see https://github.com/yiisoft/yii2/issues/15676
|
||||
*/
|
||||
public function testIssue15676()
|
||||
{
|
||||
$query = (new Query())
|
||||
->select('id')
|
||||
->from('place');
|
||||
$this->assertSame(['id'], $query->select);
|
||||
|
||||
$query->select(['id', 'brand_id']);
|
||||
$this->assertSame(['id', 'brand_id'], $query->select);
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,6 +7,8 @@
|
||||
|
||||
namespace yiiunit\framework\db\mysql;
|
||||
|
||||
use yiiunit\data\ar\Storage;
|
||||
|
||||
/**
|
||||
* @group db
|
||||
* @group mysql
|
||||
@ -14,4 +16,35 @@ namespace yiiunit\framework\db\mysql;
|
||||
class ActiveRecordTest extends \yiiunit\framework\db\ActiveRecordTest
|
||||
{
|
||||
public $driverName = 'mysql';
|
||||
|
||||
public function testJsonColumn()
|
||||
{
|
||||
if (version_compare($this->getConnection()->getSchema()->getServerVersion(), '5.7', '<')) {
|
||||
$this->markTestSkipped('JSON columns are not supported in MySQL < 5.7');
|
||||
}
|
||||
if (version_compare(PHP_VERSION, '5.6', '<')) {
|
||||
$this->markTestSkipped('JSON columns are not supported in PDO for PHP < 5.6');
|
||||
}
|
||||
|
||||
$data = [
|
||||
'obj' => ['a' => ['b' => ['c' => 2.7418]]],
|
||||
'array' => [1,2,null,3],
|
||||
'null_field' => null,
|
||||
'boolean_field' => true,
|
||||
'last_update_time' => '2018-02-21',
|
||||
];
|
||||
|
||||
$storage = new Storage(['data' => $data]);
|
||||
$this->assertTrue($storage->save(), 'Storage can be saved');
|
||||
$this->assertNotNull($storage->id);
|
||||
|
||||
$retrievedStorage = Storage::findOne($storage->id);
|
||||
$this->assertSame($data, $retrievedStorage->data, 'Properties are restored from JSON to array without changes');
|
||||
|
||||
$retrievedStorage->data = ['updatedData' => $data];
|
||||
$this->assertSame(1, $retrievedStorage->update(), 'Storage can be updated');
|
||||
|
||||
$retrievedStorage->refresh();
|
||||
$this->assertSame(['updatedData' => $data], $retrievedStorage->data, 'Properties have been changed during update');
|
||||
}
|
||||
}
|
||||
|
||||
@ -195,21 +195,35 @@ class ActiveRecordTest extends \yiiunit\framework\db\ActiveRecordTest
|
||||
$value = $type->$attribute;
|
||||
|
||||
$this->assertEquals($expected, $value, 'In column ' . $attribute);
|
||||
|
||||
if ($value instanceof ArrayExpression) {
|
||||
$this->assertInstanceOf('\ArrayAccess', $value);
|
||||
$this->assertInstanceOf('\Traversable', $value);
|
||||
foreach ($type->$attribute as $key => $v) { // testing arrayaccess
|
||||
$this->assertSame($expected[$key], $value[$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Testing UPDATE
|
||||
foreach ($attributes as $attribute => $expected) {
|
||||
$type->markAttributeDirty($attribute);
|
||||
}
|
||||
$this->assertSame(1, $type->update(), 'The record got updated');
|
||||
}
|
||||
|
||||
public function arrayValuesProvider()
|
||||
{
|
||||
return [
|
||||
'simple arrays values' => [[
|
||||
'intarray_col' => [new ArrayExpression([1,-2,null,'42'], 'int4', 1)],
|
||||
'textarray2_col' => [new ArrayExpression([['text'], [null], [1]], 'text', 2)],
|
||||
'intarray_col' => [
|
||||
new ArrayExpression([1,-2,null,'42'], 'int4', 1),
|
||||
new ArrayExpression([1,-2,null,42], 'int4', 1),
|
||||
],
|
||||
'textarray2_col' => [
|
||||
new ArrayExpression([['text'], [null], [1]], 'text', 2),
|
||||
new ArrayExpression([['text'], [null], ['1']], 'text', 2),
|
||||
],
|
||||
'json_col' => [['a' => 1, 'b' => null, 'c' => [1,3,5]]],
|
||||
'jsonb_col' => [[null, 'a', 'b', '\"', '{"af"}']],
|
||||
'jsonarray_col' => [new ArrayExpression([[',', 'null', true, 'false', 'f']], 'json')],
|
||||
@ -217,11 +231,11 @@ class ActiveRecordTest extends \yiiunit\framework\db\ActiveRecordTest
|
||||
'arrays packed in classes' => [[
|
||||
'intarray_col' => [
|
||||
new ArrayExpression([1,-2,null,'42'], 'int', 1),
|
||||
new ArrayExpression([1,-2,null,'42'], 'int4', 1),
|
||||
new ArrayExpression([1,-2,null,42], 'int4', 1),
|
||||
],
|
||||
'textarray2_col' => [
|
||||
new ArrayExpression([['text'], [null], [1]], 'text', 2),
|
||||
new ArrayExpression([['text'], [null], [1]], 'text', 2),
|
||||
new ArrayExpression([['text'], [null], ['1']], 'text', 2),
|
||||
],
|
||||
'json_col' => [
|
||||
new JsonExpression(['a' => 1, 'b' => null, 'c' => [1,3,5]]),
|
||||
@ -234,7 +248,6 @@ class ActiveRecordTest extends \yiiunit\framework\db\ActiveRecordTest
|
||||
'jsonarray_col' => [
|
||||
new Expression("array['[\",\",\"null\",true,\"false\",\"f\"]'::json]::json[]"),
|
||||
new ArrayExpression([[',', 'null', true, 'false', 'f']], 'json'),
|
||||
|
||||
]
|
||||
]],
|
||||
'scalars' => [[
|
||||
@ -278,6 +291,7 @@ class UserAR extends ActiveRecord
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @property array id
|
||||
* @property array intarray_col
|
||||
* @property array textarray2_col
|
||||
* @property array json_col
|
||||
|
||||
@ -10,6 +10,7 @@ namespace yiiunit\framework\filters\auth;
|
||||
use Yii;
|
||||
use yii\filters\auth\AuthMethod;
|
||||
use yii\filters\auth\CompositeAuth;
|
||||
use yii\filters\auth\HttpBearerAuth;
|
||||
use yii\rest\Controller;
|
||||
use yiiunit\framework\web\UserIdentity;
|
||||
|
||||
@ -26,6 +27,8 @@ class TestAuth extends AuthMethod
|
||||
|
||||
class TestController extends Controller
|
||||
{
|
||||
public $authMethods = [];
|
||||
|
||||
public function actionA()
|
||||
{
|
||||
return 'success';
|
||||
@ -66,7 +69,7 @@ class TestController extends Controller
|
||||
return [
|
||||
'authenticator' => [
|
||||
'class' => CompositeAuth::className(),
|
||||
'authMethods' => [
|
||||
'authMethods' => $this->authMethods ?: [
|
||||
TestAuth::className(),
|
||||
],
|
||||
],
|
||||
@ -123,4 +126,19 @@ class CompositeAuthTest extends \yiiunit\TestCase
|
||||
$controller = Yii::$app->createController('test')[0];
|
||||
$this->assertEquals('success', $controller->run('c'));
|
||||
}
|
||||
|
||||
public function testCompositeAuth()
|
||||
{
|
||||
Yii::$app->request->headers->set('Authorization', base64_encode("foo:bar"));
|
||||
/** @var TestAuthController $controller */
|
||||
$controller = Yii::$app->createController('test')[0];
|
||||
$controller->authMethods = [
|
||||
HttpBearerAuth::className(),
|
||||
TestAuth::className(),
|
||||
];
|
||||
try {
|
||||
$this->assertEquals('success', $controller->run('b'));
|
||||
} catch (UnauthorizedHttpException $e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1698,6 +1698,16 @@ HTML;
|
||||
|
||||
$this->assertContains('placeholder="Custom placeholder"', $html);
|
||||
}
|
||||
|
||||
public function testActiveTextInput_placeholderFillFromModelTabular()
|
||||
{
|
||||
$model = new HtmlTestModel();
|
||||
|
||||
$html = Html::activeTextInput($model, '[0]name', ['placeholder' => true]);
|
||||
|
||||
$this->assertContains('placeholder="Name"', $html);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -43,4 +43,4 @@ class UserIdentity extends Component implements IdentityInterface
|
||||
{
|
||||
return $authKey === 'ABCD1234';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -80,6 +80,50 @@ describe('yii.activeForm', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describe('resetForm method', function () {
|
||||
var windowSetTimeoutStub;
|
||||
|
||||
beforeEach(function () {
|
||||
windowSetTimeoutStub = sinon.stub(window, 'setTimeout', function (callback) {
|
||||
callback();
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
windowSetTimeoutStub.restore();
|
||||
});
|
||||
|
||||
it('should remove classes from error element', function () {
|
||||
var inputId = 'name';
|
||||
var $input = $('#' + inputId);
|
||||
var options = {
|
||||
validatingCssClass: 'validating',
|
||||
errorCssClass: 'error',
|
||||
successCssClass: 'success',
|
||||
validationStateOn: 'input'
|
||||
};
|
||||
|
||||
$activeForm = $('#w0');
|
||||
$activeForm.yiiActiveForm('destroy');
|
||||
$activeForm.yiiActiveForm([
|
||||
{
|
||||
id: inputId,
|
||||
input: '#' + inputId
|
||||
}
|
||||
], options);
|
||||
|
||||
$input.addClass(options.validatingCssClass);
|
||||
$input.addClass(options.errorCssClass);
|
||||
$input.addClass(options.successCssClass);
|
||||
$input.addClass('test');
|
||||
$activeForm.yiiActiveForm('resetForm');
|
||||
assert.isFalse($input.hasClass(options.validatingCssClass));
|
||||
assert.isFalse($input.hasClass(options.errorCssClass));
|
||||
assert.isFalse($input.hasClass(options.successCssClass));
|
||||
assert.isTrue($input.hasClass('test'));
|
||||
});
|
||||
});
|
||||
|
||||
describe('events', function () {
|
||||
describe('afterValidateAttribute', function () {
|
||||
var afterValidateAttributeSpy;
|
||||
|
||||
Reference in New Issue
Block a user