diff --git a/phpstan-baseline.php b/phpstan-baseline.php index 93705a8a1121..b24ee06ed922 100644 --- a/phpstan-baseline.php +++ b/phpstan-baseline.php @@ -15727,12 +15727,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/system/Model.php b/system/Model.php index 7213189010c8..fb1ebceda516 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})) { - // Get the raw primary key value of the Entity. - if ($row instanceof Entity) { + if (is_object($row)) { + // Get the raw or mapped primary key value of the 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..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 @@ -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 string $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->db->table('empty')->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 `_