Skip to content

Commit ac2023f

Browse files
committed
apply code review suggestions
1 parent 7de6017 commit ac2023f

4 files changed

Lines changed: 160 additions & 3 deletions

File tree

system/Entity/Entity.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -465,15 +465,15 @@ private function normalizeValue(mixed $data): mixed
465465
];
466466
} elseif ($data instanceof JsonSerializable) {
467467
$objectData = $data->jsonSerialize();
468+
} elseif (method_exists($data, 'toArray')) {
469+
$objectData = $data->toArray();
468470
} elseif ($data instanceof Traversable) {
469471
$objectData = iterator_to_array($data);
470472
} elseif ($data instanceof DateTimeInterface) {
471473
return [
472474
'__class' => $data::class,
473475
'__datetime' => $data->format(DATE_RFC3339_EXTENDED),
474476
];
475-
} elseif (method_exists($data, 'toArray')) {
476-
$objectData = $data->toArray();
477477
} else {
478478
$objectData = get_object_vars($data);
479479

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* This file is part of CodeIgniter 4 framework.
7+
*
8+
* (c) CodeIgniter Foundation <admin@codeigniter.com>
9+
*
10+
* For the full copyright and license information, please view
11+
* the LICENSE file that was distributed with this source code.
12+
*/
13+
14+
namespace Tests\Support\Enum;
15+
16+
use JsonSerializable;
17+
18+
enum JsonSerializableStateUnitEnum implements JsonSerializable
19+
{
20+
case DRAFT;
21+
case PUBLISHED;
22+
23+
public function jsonSerialize(): mixed
24+
{
25+
return ['json' => $this->name];
26+
}
27+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* This file is part of CodeIgniter 4 framework.
7+
*
8+
* (c) CodeIgniter Foundation <admin@codeigniter.com>
9+
*
10+
* For the full copyright and license information, please view
11+
* the LICENSE file that was distributed with this source code.
12+
*/
13+
14+
namespace Tests\Support\Enum;
15+
16+
enum StateUnitEnum
17+
{
18+
case DRAFT;
19+
case PUBLISHED;
20+
21+
public function toArray(): array
22+
{
23+
return self::cases();
24+
}
25+
}

tests/system/Entity/EntityTest.php

Lines changed: 106 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,10 @@
3434
use Tests\Support\Entity\Cast\CastPassParameters;
3535
use Tests\Support\Entity\Cast\NotExtendsBaseCast;
3636
use Tests\Support\Enum\ColorEnum;
37+
use Tests\Support\Enum\JsonSerializableStateUnitEnum;
3738
use Tests\Support\Enum\RoleEnum;
3839
use Tests\Support\Enum\StateEnum;
40+
use Tests\Support\Enum\StateUnitEnum;
3941
use Tests\Support\Enum\StatusEnum;
4042
use Tests\Support\SomeEntity;
4143

@@ -1049,7 +1051,7 @@ public function testCastEnumSetWithUnitEnumObject(): void
10491051
/**
10501052
* @see https://github.com/codeigniter4/CodeIgniter4/issues/10136
10511053
*/
1052-
public function testInjectRawDataWithEnumThatHasToArrayMethod(): void
1054+
public function testInjectRawDataWithBackedEnumThatHasToArrayMethod(): void
10531055
{
10541056
$entity = new class () extends Entity {};
10551057

@@ -1059,6 +1061,32 @@ public function testInjectRawDataWithEnumThatHasToArrayMethod(): void
10591061
$this->assertFalse($entity->hasChanged('state'));
10601062
}
10611063

1064+
/**
1065+
* @see https://github.com/codeigniter4/CodeIgniter4/issues/10136
1066+
*/
1067+
public function testInjectRawDataWithUnitEnumThatHasToArrayMethod(): void
1068+
{
1069+
$entity = new class () extends Entity {};
1070+
1071+
$entity->injectRawData(['state' => StateUnitEnum::DRAFT]);
1072+
1073+
$this->assertSame(StateUnitEnum::DRAFT, $entity->toRawArray()['state']);
1074+
$this->assertFalse($entity->hasChanged('state'));
1075+
}
1076+
1077+
/**
1078+
* @see https://github.com/codeigniter4/CodeIgniter4/issues/10136
1079+
*/
1080+
public function testInjectRawDataWithUnitEnumThatImplementsJsonSerializable(): void
1081+
{
1082+
$entity = new class () extends Entity {};
1083+
1084+
$entity->injectRawData(['state' => JsonSerializableStateUnitEnum::DRAFT]);
1085+
1086+
$this->assertSame(JsonSerializableStateUnitEnum::DRAFT, $entity->toRawArray()['state']);
1087+
$this->assertFalse($entity->hasChanged('state'));
1088+
}
1089+
10621090
public function testAsArray(): void
10631091
{
10641092
$entity = $this->getEntity();
@@ -1989,6 +2017,41 @@ public function jsonSerialize(): mixed
19892017
$this->assertTrue($entity->hasChanged('data'));
19902018
}
19912019

2020+
public function testHasChangedPrefersJsonSerializableOverToArray(): void
2021+
{
2022+
$entity = new class () extends Entity {
2023+
protected $attributes = [
2024+
'data' => null,
2025+
];
2026+
};
2027+
2028+
$entity->data = new class ('original') implements JsonSerializable {
2029+
public function __construct(private string $value)
2030+
{
2031+
}
2032+
2033+
public function jsonSerialize(): mixed
2034+
{
2035+
return ['json' => $this->value];
2036+
}
2037+
2038+
public function setValue(string $value): void
2039+
{
2040+
$this->value = $value;
2041+
}
2042+
2043+
public function toArray(): array
2044+
{
2045+
return ['array' => 'same'];
2046+
}
2047+
};
2048+
$entity->syncOriginal();
2049+
2050+
$entity->data->setValue('modified');
2051+
2052+
$this->assertTrue($entity->hasChanged('data'));
2053+
}
2054+
19922055
public function testHasChangedDoesNotDetectUnchangedObject(): void
19932056
{
19942057
$entity = new class () extends Entity {
@@ -2292,6 +2355,48 @@ public function toArray(): array
22922355
$this->assertTrue($entity->hasChanged('custom'));
22932356
}
22942357

2358+
public function testHasChangedPrefersToArrayOverTraversable(): void
2359+
{
2360+
$entity = new class () extends Entity {
2361+
protected $attributes = [
2362+
'items' => null,
2363+
];
2364+
};
2365+
2366+
$entity->items = new class (['iterator' => 'original']) extends ArrayObject {
2367+
public function toArray(): array
2368+
{
2369+
return ['array' => 'same'];
2370+
}
2371+
};
2372+
$entity->syncOriginal();
2373+
2374+
$entity->items->exchangeArray(['iterator' => 'modified']);
2375+
2376+
$this->assertFalse($entity->hasChanged('items'));
2377+
}
2378+
2379+
public function testHasChangedPrefersToArrayOverDateTimeInterface(): void
2380+
{
2381+
$entity = new class () extends Entity {
2382+
protected $attributes = [
2383+
'date' => null,
2384+
];
2385+
};
2386+
2387+
$entity->date = new class ('2024-01-01 00:00:00') extends DateTime {
2388+
public function toArray(): array
2389+
{
2390+
return ['date' => 'same'];
2391+
}
2392+
};
2393+
$entity->syncOriginal();
2394+
2395+
$entity->date->modify('+1 day');
2396+
2397+
$this->assertFalse($entity->hasChanged('date'));
2398+
}
2399+
22952400
public function testHasChangedScalarOptimizationWithNullValues(): void
22962401
{
22972402
$entity = new class () extends Entity {

0 commit comments

Comments
 (0)