Skip to content

Commit e7ee5b0

Browse files
gr8manmichalsn
andauthored
fix(model): pass $recursive parameter to parent in objectToRawArray (#10258)
* fix: pass $recursive parameter to parent in Model::objectToRawArray * Update tests/system/Models/ObjectToRawArrayModelTest.php Co-authored-by: Michal Sniatala <michal@sniatala.pl> * fix: remove redundant objectToRawArray method and update changelog * Update tests/system/Models/ObjectToRawArrayModelTest.php Co-authored-by: Michal Sniatala <michal@sniatala.pl> * Update tests/system/Models/ObjectToRawArrayModelTest.php Co-authored-by: Michal Sniatala <michal@sniatala.pl> * Update test comment: indicate fix for model‑recursive PR #10258 * test: Fix PHPStan missing type in callObjectToRawArray * style: remove redundant comment in ObjectToRawArrayModelTest.php --------- Co-authored-by: Michal Sniatala <michal@sniatala.pl>
1 parent 1bee883 commit e7ee5b0

3 files changed

Lines changed: 130 additions & 5 deletions

File tree

system/Model.php

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -711,11 +711,6 @@ public function update($id = null, $row = null): bool
711711
return parent::update($id, $row);
712712
}
713713

714-
protected function objectToRawArray($object, bool $onlyChanged = true, bool $recursive = false): array
715-
{
716-
return parent::objectToRawArray($object, $onlyChanged);
717-
}
718-
719714
/**
720715
* Provides/instantiates the builder/db connection and model's table/primary key names and return type.
721716
*
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
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 CodeIgniter\Models;
15+
16+
use CodeIgniter\Entity\Entity;
17+
use CodeIgniter\Model;
18+
use CodeIgniter\Test\CIUnitTestCase;
19+
use PHPUnit\Framework\Attributes\Group;
20+
21+
/**
22+
* @internal
23+
*/
24+
#[Group('Others')]
25+
final class ObjectToRawArrayModelTest extends CIUnitTestCase
26+
{
27+
private function createModel(): Model
28+
{
29+
return new class () extends Model {
30+
public function __construct()
31+
{
32+
// Skip DB connection — we only test objectToRawArray
33+
}
34+
35+
protected $table = 'test';
36+
protected $allowedFields = ['name', 'nested', 'entity'];
37+
protected $returnType = 'array';
38+
protected $useSoftDeletes = false;
39+
};
40+
}
41+
42+
/**
43+
* Call protected objectToRawArray via reflection.
44+
*
45+
* @return array<string, mixed>
46+
*/
47+
private function callObjectToRawArray(Model $model, object $object, bool $onlyChanged, bool $recursive): array
48+
{
49+
$method = self::getPrivateMethodInvoker($model, 'objectToRawArray');
50+
51+
return $method($object, $onlyChanged, $recursive);
52+
}
53+
54+
public function testObjectToRawArrayPassesRecursiveTrue(): void
55+
{
56+
$model = $this->createModel();
57+
58+
$inner = new class () extends Entity {
59+
protected $attributes = ['name' => 'inner'];
60+
protected $original = ['name' => 'inner'];
61+
};
62+
63+
$outer = new class () extends Entity {
64+
protected $attributes = ['name' => 'outer', 'nested' => null];
65+
protected $original = ['name' => 'outer', 'nested' => null];
66+
};
67+
$outer->nested = $inner;
68+
69+
$result = $this->callObjectToRawArray($model, $outer, false, true);
70+
71+
$this->assertArrayHasKey('name', $result);
72+
$this->assertSame('outer', $result['name']);
73+
$this->assertArrayHasKey('nested', $result);
74+
$this->assertIsArray($result['nested']);
75+
$this->assertSame(['name' => 'inner'], $result['nested']);
76+
}
77+
78+
public function testObjectToRawArrayPassesRecursiveFalse(): void
79+
{
80+
$model = $this->createModel();
81+
82+
$inner = new class () extends Entity {
83+
protected $attributes = ['name' => 'inner'];
84+
protected $original = ['name' => 'inner'];
85+
};
86+
87+
$outer = new class () extends Entity {
88+
protected $attributes = ['name' => 'outer', 'nested' => null];
89+
protected $original = ['name' => 'outer', 'nested' => null];
90+
};
91+
$outer->nested = $inner;
92+
93+
$result = $this->callObjectToRawArray($model, $outer, false, false);
94+
95+
$this->assertArrayHasKey('name', $result);
96+
$this->assertSame('outer', $result['name']);
97+
$this->assertArrayHasKey('nested', $result);
98+
// With recursive=false, nested Entity should remain as object
99+
$this->assertInstanceOf(Entity::class, $result['nested']);
100+
}
101+
102+
public function testObjectToRawArrayNonEntity(): void
103+
{
104+
$model = $this->createModel();
105+
106+
$obj = new class () {
107+
public string $name = 'test';
108+
public string $value = '123';
109+
};
110+
111+
$result = $this->callObjectToRawArray($model, $obj, false, false);
112+
113+
$this->assertSame(['name' => 'test', 'value' => '123'], $result);
114+
}
115+
116+
public function testObjectToRawArrayOnlyChanged(): void
117+
{
118+
$model = $this->createModel();
119+
$entity = new class () extends Entity {
120+
protected $attributes = ['name' => 'original', 'value' => 'keep'];
121+
protected $original = ['name' => 'original', 'value' => 'keep'];
122+
};
123+
$entity->name = 'modified';
124+
125+
$result = $this->callObjectToRawArray($model, $entity, true, false);
126+
127+
$this->assertSame(['name' => 'modified'], $result);
128+
}
129+
}

user_guide_src/source/changelogs/v4.7.4.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ Bugs Fixed
3333
- **API:** Fixed a bug in Transformers where the root request's ``fields`` and ``include`` query parameters leaked into nested transformers created inside ``include*()`` methods, causing incorrect field filtering, unexpected includes, or infinite recursion.
3434
- **Database:** Fixed a bug where ``updateBatch()`` could be called after Query Builder ``where()`` conditions, even though it's not supported. In this situation, now the ``DatabaseException`` is thrown.
3535
- **HTTP:** Fixed a bug where the User Agent library reported Safari's WebKit version instead of the browser version from the ``Version`` token.
36+
- **Model:** Fixed a bug in ``Model::objectToRawArray()`` where the ``$recursive`` parameter was ignored.
3637

3738
See the repo's
3839
`CHANGELOG.md <https://github.com/codeigniter4/CodeIgniter4/blob/develop/CHANGELOG.md>`_

0 commit comments

Comments
 (0)