From 1c26761793956993006a98c2154538682d447ff8 Mon Sep 17 00:00:00 2001 From: michalsn Date: Sat, 7 Dec 2024 21:39:44 +0100 Subject: [PATCH 1/3] fix primary key mapping for the entity in the model --- system/Model.php | 8 +++-- tests/system/Models/SaveModelTest.php | 40 +++++++++++++++++++++ user_guide_src/source/changelogs/v4.5.6.rst | 2 +- 3 files changed, 46 insertions(+), 4 deletions(-) diff --git a/system/Model.php b/system/Model.php index d5df3f861b97..5417a47c418d 100644 --- a/system/Model.php +++ b/system/Model.php @@ -592,9 +592,9 @@ protected function doErrors() */ public function getIdValue($row) { - if (is_object($row) && isset($row->{$this->primaryKey})) { + if (is_object($row)) { // Get the raw primary key value of the Entity. - if ($row instanceof Entity) { + if ($row instanceof Entity && $row->{$this->primaryKey} !== null) { $cast = $row->cast(); // Disable Entity casting, because raw primary key value is needed for database. @@ -608,7 +608,9 @@ public function getIdValue($row) return $primaryKey; } - return $row->{$this->primaryKey}; + if (! $row instanceof Entity && isset($row->{$this->primaryKey})) { + return $row->{$this->primaryKey}; + } } if (is_array($row) && isset($row[$this->primaryKey])) { diff --git a/tests/system/Models/SaveModelTest.php b/tests/system/Models/SaveModelTest.php index 29f2959878e4..317ea3305949 100644 --- a/tests/system/Models/SaveModelTest.php +++ b/tests/system/Models/SaveModelTest.php @@ -365,4 +365,44 @@ public function testUseAutoIncrementSetToFalseSaveObject(): void $this->assertSame($insert['key'], $this->model->getInsertID()); $this->seeInDatabase('without_auto_increment', $update); } + + /** + * @see https://github.com/codeigniter4/CodeIgniter4/issues/9306 + */ + public function testSaveNewEntityWithMappedPrimaryKey(): void + { + $entity = new class () extends Entity { + protected $name; + protected $attributes = [ + 'id' => null, + 'name' => null, + ]; + protected $original = [ + 'id' => null, + 'name' => null, + ]; + protected $datamap = [ + 'new_kid_in_the_block' => 'id', + ]; + }; + + $testModel = new class () extends Model { + protected $table = 'empty'; + protected $allowedFields = [ + 'name', + ]; + protected $returnType = 'object'; + }; + + $entity->name = 'New'; + $this->assertTrue($testModel->save($entity)); + $this->seeInDatabase('empty', ['id' => 1, 'name' => 'New']); + + $entity->new_kid_in_the_block = 1; + $entity->name = 'Updated'; + $this->assertTrue($testModel->save($entity)); + + $this->seeInDatabase('empty', ['id' => 1, 'name' => 'Updated']); + $testModel->truncate(); + } } diff --git a/user_guide_src/source/changelogs/v4.5.6.rst b/user_guide_src/source/changelogs/v4.5.6.rst index 9490e62e4e80..569c5a542ecd 100644 --- a/user_guide_src/source/changelogs/v4.5.6.rst +++ b/user_guide_src/source/changelogs/v4.5.6.rst @@ -38,10 +38,10 @@ Bugs Fixed - **DownloadResponse:** Fixed a bug that prevented setting custom cache headers. We can now also use the ``setCache()`` method. - **DownloadResponse:** Fixed a bug involving sending a custom "Expires-Disposition" header. - **Routing:** Fixed a TypeError in `str_replace()` when `Routing::$translateURIDashes` is set to `true` and a route is defined using a closure. - - **Validation:** Fixed a bug where complex language strings were not properly handled. - **CURLRequest:** Added support for handling proxy responses using HTTP versions other than 1.1. - **Database:** Fixed a bug that caused ``Postgre\Connection::reconnect()`` method to throw an error when the connection had not yet been established. +- **Model** Fixed a bug that caused the ``Model::getIdValue()`` method to not correctly recognize the primary key in the ``Entity`` object if a data mapping for the primary key was used. See the repo's `CHANGELOG.md `_ From 984006ab0f469ac63746f7bf792122d56e258e37 Mon Sep 17 00:00:00 2001 From: michalsn Date: Sat, 7 Dec 2024 22:05:14 +0100 Subject: [PATCH 2/3] fix phpstan --- phpstan-baseline.php | 6 ------ tests/system/Models/SaveModelTest.php | 6 +++--- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/phpstan-baseline.php b/phpstan-baseline.php index e775d6b9f5ef..62024ad2462c 100644 --- a/phpstan-baseline.php +++ b/phpstan-baseline.php @@ -15835,12 +15835,6 @@ 'count' => 1, 'path' => __DIR__ . '/tests/system/Models/PaginateModelTest.php', ]; -$ignoreErrors[] = [ - // identifier: method.notFound - 'message' => '#^Call to an undefined method class@anonymous/tests/system/Models/SaveModelTest\\.php\\:288\\:\\:truncate\\(\\)\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/tests/system/Models/SaveModelTest.php', -]; $ignoreErrors[] = [ // identifier: property.nonObject 'message' => '#^Cannot access property \\$description on array\\.$#', diff --git a/tests/system/Models/SaveModelTest.php b/tests/system/Models/SaveModelTest.php index 317ea3305949..193624f06857 100644 --- a/tests/system/Models/SaveModelTest.php +++ b/tests/system/Models/SaveModelTest.php @@ -301,7 +301,7 @@ public function testSaveNewEntityWithDate(): void $this->setPrivateProperty($testModel, 'useTimestamps', true); $this->assertTrue($testModel->save($entity)); - $testModel->truncate(); + $testModel->db->table('empty')->truncate(); } public function testInvalidAllowedFieldException(): void @@ -372,7 +372,7 @@ public function testUseAutoIncrementSetToFalseSaveObject(): void public function testSaveNewEntityWithMappedPrimaryKey(): void { $entity = new class () extends Entity { - protected $name; + protected string $name; protected $attributes = [ 'id' => null, 'name' => null, @@ -403,6 +403,6 @@ public function testSaveNewEntityWithMappedPrimaryKey(): void $this->assertTrue($testModel->save($entity)); $this->seeInDatabase('empty', ['id' => 1, 'name' => 'Updated']); - $testModel->truncate(); + $testModel->db->table('empty')->truncate(); } } From 6c5dc122d73a5a6b6c7c42440722b4d0b1cd13a3 Mon Sep 17 00:00:00 2001 From: michalsn Date: Tue, 10 Dec 2024 17:49:29 +0100 Subject: [PATCH 3/3] update comment in the code --- system/Model.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/Model.php b/system/Model.php index 5417a47c418d..6f04adcfa2b7 100644 --- a/system/Model.php +++ b/system/Model.php @@ -593,7 +593,7 @@ protected function doErrors() public function getIdValue($row) { if (is_object($row)) { - // Get the raw primary key value of the Entity. + // Get the raw or mapped primary key value of the Entity. if ($row instanceof Entity && $row->{$this->primaryKey} !== null) { $cast = $row->cast();