From 6c8b87f3e2fce07ef9e79012f8347bb1189f0afd Mon Sep 17 00:00:00 2001 From: Dmitry Naumenko Date: Fri, 23 Feb 2018 22:50:06 +0200 Subject: [PATCH] Implemented \Traversable in ArrayExpression (#15733) * Implemented \Traversable in ArrayExpression * Fix punctuation [skip ci] --- framework/CHANGELOG.md | 1 + framework/db/ArrayExpression.php | 26 +++++++++++++++++++++++--- tests/framework/db/pgsql/ActiveRecordTest.php | 16 +++++++++++----- 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md index 60e1b98..007c2a5 100644 --- a/framework/CHANGELOG.md +++ b/framework/CHANGELOG.md @@ -4,6 +4,7 @@ Yii Framework 2 Change Log 2.0.14.1 under development -------------------------- +- 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 setActivePlaceholder to be consistent with activeLabel (edwards-sj) - Bug #15692: Fix ExistValidator with targetRelation ignores filter (developeruz) diff --git a/framework/db/ArrayExpression.php b/framework/db/ArrayExpression.php index a4d4d7c..6ef7a3d 100644 --- a/framework/db/ArrayExpression.php +++ b/framework/db/ArrayExpression.php @@ -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 * @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 Iterator or + * Traversable + * @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()); + } } diff --git a/tests/framework/db/pgsql/ActiveRecordTest.php b/tests/framework/db/pgsql/ActiveRecordTest.php index aa0bc9c..8519880 100644 --- a/tests/framework/db/pgsql/ActiveRecordTest.php +++ b/tests/framework/db/pgsql/ActiveRecordTest.php @@ -197,6 +197,7 @@ class ActiveRecordTest extends \yiiunit\framework\db\ActiveRecordTest $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]); } @@ -208,8 +209,14 @@ class ActiveRecordTest extends \yiiunit\framework\db\ActiveRecordTest { 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 +224,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 +241,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' => [[