Skip to content

Commit

Permalink
Merge pull request #7806 from kenjis/fix-model-cast-pk
Browse files Browse the repository at this point in the history
fix: Model inserts cast $primaryKey value when using Entity
  • Loading branch information
kenjis committed Aug 15, 2023
2 parents 6815f3f + a884465 commit 513f9fc
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 4 deletions.
1 change: 1 addition & 0 deletions deptrac.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ parameters:
- I18n
Model:
- Database
- Entity
- I18n
- Pager
- Validation
Expand Down
24 changes: 20 additions & 4 deletions system/Model.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
use CodeIgniter\Database\Exceptions\DatabaseException;
use CodeIgniter\Database\Exceptions\DataException;
use CodeIgniter\Database\Query;
use CodeIgniter\Entity\Entity;
use CodeIgniter\Exceptions\ModelException;
use CodeIgniter\I18n\Time;
use CodeIgniter\Validation\ValidationInterface;
Expand Down Expand Up @@ -774,11 +775,11 @@ public function update($id = null, $data = null): bool
}

/**
* Takes a class an returns an array of it's public and protected
* Takes a class and returns an array of its public and protected
* properties as an array with raw values.
*
* @param object|string $data
* @param bool $recursive If true, inner entities will be casted as array as well
* @param bool $recursive If true, inner entities will be cast as array as well
*
* @return array|null Array
*
Expand All @@ -788,17 +789,32 @@ protected function objectToRawArray($data, bool $onlyChanged = true, bool $recur
{
$properties = parent::objectToRawArray($data, $onlyChanged);

$primaryKey = null;

if ($data instanceof Entity) {
$cast = $data->cast();

// Disable Entity casting, because raw primary key data is needed for database.
$data->cast(false);

$primaryKey = $data->{$this->primaryKey};

// Restore Entity casting setting.
$data->cast($cast);
}

// Always grab the primary key otherwise updates will fail.
if (
// @TODO Should use `$data instanceof Entity`.
method_exists($data, 'toRawArray')
&& (
! empty($properties)
&& ! empty($this->primaryKey)
&& ! in_array($this->primaryKey, $properties, true)
&& ! empty($data->{$this->primaryKey})
&& ! empty($primaryKey)
)
) {
$properties[$this->primaryKey] = $data->{$this->primaryKey};
$properties[$this->primaryKey] = $primaryKey;
}

return $properties;
Expand Down

0 comments on commit 513f9fc

Please sign in to comment.