Skip to content

Commit 539436f

Browse files
authored
fix: primary key mapping in the model for the entity (#9307)
* fix primary key mapping for the entity in the model * fix phpstan * update comment in the code
1 parent dae379f commit 539436f

File tree

4 files changed

+48
-12
lines changed

4 files changed

+48
-12
lines changed

phpstan-baseline.php

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15727,12 +15727,6 @@
1572715727
'count' => 1,
1572815728
'path' => __DIR__ . '/tests/system/Models/PaginateModelTest.php',
1572915729
];
15730-
$ignoreErrors[] = [
15731-
// identifier: method.notFound
15732-
'message' => '#^Call to an undefined method class@anonymous/tests/system/Models/SaveModelTest\\.php\\:288\\:\\:truncate\\(\\)\\.$#',
15733-
'count' => 1,
15734-
'path' => __DIR__ . '/tests/system/Models/SaveModelTest.php',
15735-
];
1573615730
$ignoreErrors[] = [
1573715731
// identifier: property.nonObject
1573815732
'message' => '#^Cannot access property \\$description on array\\.$#',

system/Model.php

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -592,9 +592,9 @@ protected function doErrors()
592592
*/
593593
public function getIdValue($row)
594594
{
595-
if (is_object($row) && isset($row->{$this->primaryKey})) {
596-
// Get the raw primary key value of the Entity.
597-
if ($row instanceof Entity) {
595+
if (is_object($row)) {
596+
// Get the raw or mapped primary key value of the Entity.
597+
if ($row instanceof Entity && $row->{$this->primaryKey} !== null) {
598598
$cast = $row->cast();
599599

600600
// Disable Entity casting, because raw primary key value is needed for database.
@@ -608,7 +608,9 @@ public function getIdValue($row)
608608
return $primaryKey;
609609
}
610610

611-
return $row->{$this->primaryKey};
611+
if (! $row instanceof Entity && isset($row->{$this->primaryKey})) {
612+
return $row->{$this->primaryKey};
613+
}
612614
}
613615

614616
if (is_array($row) && isset($row[$this->primaryKey])) {

tests/system/Models/SaveModelTest.php

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ public function testSaveNewEntityWithDate(): void
301301

302302
$this->setPrivateProperty($testModel, 'useTimestamps', true);
303303
$this->assertTrue($testModel->save($entity));
304-
$testModel->truncate();
304+
$testModel->db->table('empty')->truncate();
305305
}
306306

307307
public function testInvalidAllowedFieldException(): void
@@ -365,4 +365,44 @@ public function testUseAutoIncrementSetToFalseSaveObject(): void
365365
$this->assertSame($insert['key'], $this->model->getInsertID());
366366
$this->seeInDatabase('without_auto_increment', $update);
367367
}
368+
369+
/**
370+
* @see https://github.com/codeigniter4/CodeIgniter4/issues/9306
371+
*/
372+
public function testSaveNewEntityWithMappedPrimaryKey(): void
373+
{
374+
$entity = new class () extends Entity {
375+
protected string $name;
376+
protected $attributes = [
377+
'id' => null,
378+
'name' => null,
379+
];
380+
protected $original = [
381+
'id' => null,
382+
'name' => null,
383+
];
384+
protected $datamap = [
385+
'new_kid_in_the_block' => 'id',
386+
];
387+
};
388+
389+
$testModel = new class () extends Model {
390+
protected $table = 'empty';
391+
protected $allowedFields = [
392+
'name',
393+
];
394+
protected $returnType = 'object';
395+
};
396+
397+
$entity->name = 'New';
398+
$this->assertTrue($testModel->save($entity));
399+
$this->seeInDatabase('empty', ['id' => 1, 'name' => 'New']);
400+
401+
$entity->new_kid_in_the_block = 1;
402+
$entity->name = 'Updated';
403+
$this->assertTrue($testModel->save($entity));
404+
405+
$this->seeInDatabase('empty', ['id' => 1, 'name' => 'Updated']);
406+
$testModel->db->table('empty')->truncate();
407+
}
368408
}

user_guide_src/source/changelogs/v4.5.6.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,10 @@ Bugs Fixed
3838
- **DownloadResponse:** Fixed a bug that prevented setting custom cache headers. We can now also use the ``setCache()`` method.
3939
- **DownloadResponse:** Fixed a bug involving sending a custom "Expires-Disposition" header.
4040
- **Routing:** Fixed a TypeError in `str_replace()` when `Routing::$translateURIDashes` is set to `true` and a route is defined using a closure.
41-
4241
- **Validation:** Fixed a bug where complex language strings were not properly handled.
4342
- **CURLRequest:** Added support for handling proxy responses using HTTP versions other than 1.1.
4443
- **Database:** Fixed a bug that caused ``Postgre\Connection::reconnect()`` method to throw an error when the connection had not yet been established.
44+
- **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.
4545

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

0 commit comments

Comments
 (0)