Skip to content

Commit

Permalink
Fix #19872: Fixed the definition of dirty attributes in AR properties…
Browse files Browse the repository at this point in the history
… for a non-associative array in case of changing the order of elements
  • Loading branch information
eegusakov committed Jul 26, 2023
1 parent c8c0ea9 commit 323f15d
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 1 deletion.
1 change: 1 addition & 0 deletions framework/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Yii Framework 2 Change Log
2.0.49 under development
------------------------

- Bug #19872: Fixed the definition of dirty attributes in AR properties for a non-associative array in case of changing the order of elements (eegusakov)
- Bug #19899: Fixed `GridView` in some cases calling `Model::generateAttributeLabel()` to generate label values that are never used (PowerGamer1)
- Bug #9899: Fix caching a MSSQL query with BLOB data type (terabytesoftw)
- Bug #16208: Fix `yii\log\FileTarget` to not export empty messages (terabytesoftw)
Expand Down
2 changes: 1 addition & 1 deletion framework/db/BaseActiveRecord.php
Original file line number Diff line number Diff line change
Expand Up @@ -1774,7 +1774,7 @@ private function setRelationDependencies($name, $relation, $viaRelationName = nu
*/
private function isValueDifferent($newValue, $oldValue)
{
if (is_array($newValue) && is_array($oldValue) && !ArrayHelper::isAssociative($oldValue)) {
if (is_array($newValue) && is_array($oldValue) && ArrayHelper::isAssociative($oldValue)) {
$newValue = ArrayHelper::recursiveSort($newValue);
$oldValue = ArrayHelper::recursiveSort($oldValue);
}
Expand Down
42 changes: 42 additions & 0 deletions tests/framework/db/BaseActiveRecordTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

namespace yiiunit\framework\db;

use yiiunit\data\ar\ActiveRecord;

abstract class BaseActiveRecordTest extends DatabaseTestCase
{
protected function setUp()
{
parent::setUp();
ActiveRecord::$db = $this->getConnection();
}

public function provideArrayValueWithChange()
{
return [
'not an associative array with data change' => [
[1, 2, 3],
[1, 3, 2],
],

'associative array with data change case 1' => [
['pineapple' => 2, 'apple' => 5, 'banana' => 1],
['apple' => 5, 'pineapple' => 1, 'banana' => 3],
],
'associative array with data change case 2' => [
['pineapple' => 2, 'apple' => 5, 'banana' => 1],
['pineapple' => 2, 'apple' => 3, 'banana' => 1],
],

'filling an empty array' => [
[],
['pineapple' => 3, 'apple' => 1, 'banana' => 1],
],
'zeroing the array' => [
['pineapple' => 3, 'apple' => 1, 'banana' => 17],
[],
],
];
}
}
37 changes: 37 additions & 0 deletions tests/framework/db/mysql/BaseActiveRecordTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

namespace yiiunit\framework\db\mysql;

use yiiunit\data\ar\Storage;

class BaseActiveRecordTest extends \yiiunit\framework\db\BaseActiveRecordTest
{
public $driverName = 'mysql';

/**
* @see https://github.com/yiisoft/yii2/issues/19872
*
* @dataProvider provideArrayValueWithChange
*/
public function testJsonDirtyAttributesWithDataChange($actual, $modified)
{
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');
}

$createdStorage = new Storage(['data' => $actual]);

$createdStorage->save();

$foundStorage = Storage::find()->limit(1)->one();

$this->assertNotNull($foundStorage);

$foundStorage->data = $modified;

$this->assertSame(['data' => $modified], $foundStorage->getDirtyAttributes());
}
}
46 changes: 46 additions & 0 deletions tests/framework/db/pgsql/BaseActiveRecordTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

namespace yiiunit\framework\db\pgsql;

use yii\db\JsonExpression;
use yiiunit\data\ar\ActiveRecord;

class BaseActiveRecordTest extends \yiiunit\framework\db\BaseActiveRecordTest
{
public $driverName = 'pgsql';

/**
* @see https://github.com/yiisoft/yii2/issues/19872
*
* @dataProvider provideArrayValueWithChange
*/
public function testJsonDirtyAttributesWithDataChange($actual, $modified)
{
$createdStorage = new ArrayAndJsonType([
'json_col' => new JsonExpression($actual),
]);

$createdStorage->save();

$foundStorage = ArrayAndJsonType::find()->limit(1)->one();

$this->assertNotNull($foundStorage);

$foundStorage->json_col = $modified;

$this->assertSame(['json_col' => $modified], $foundStorage->getDirtyAttributes());
}
}

/**
* {@inheritdoc}
* @property array id
* @property array json_col
*/
class ArrayAndJsonType extends ActiveRecord
{
public static function tableName()
{
return '{{%array_and_json_types}}';
}
}

0 comments on commit 323f15d

Please sign in to comment.