-
Notifications
You must be signed in to change notification settings - Fork 2k
Description
PHP Version
8.2
CodeIgniter4 Version
4.3.3
CodeIgniter4 Installation Method
Composer (using codeigniter4/appstarter)
Which operating systems have you tested for this bug?
Windows
Which server did you use?
cli-server (PHP built-in webserver)
Database
No response
What happened?
If I understand correctly, based on the documentation, casting only occurs when a value is read, not when a value is inserted, and only raw values are inserted.
However, when using an entity and casting the primary key, the casted value is inserted instead of the raw value.
For example, I am using the Entity constructor to generate a binary representation of UUID for the primary key:
public function __construct(?array $data = null)
{
parent::__construct($data);
$this->attributes['id'] = Services::uuid()->generateBinary();
}When using toRawArray(), all values are correct and ready to be inserted into the database. The $primaryKey value is a binary string.
When using toArray(), all values are casted correctly, including the $primaryKey being casted to a string representation.
However, when I insert the entity into the model, the inserted $primaryKey value is casted.
When I check the database, string representations are inserted instead of the raw binary representation.
Steps to Reproduce
- Create an Entity and use casting on the primary key. Here is my example:
<?php
namespace App\Entities\Application;
use CodeIgniter\Entity\Entity;
use App\Entities\Cast\Uuid as CastUuid;
use Config\Services;
/**
* @property string $id
* @property string $name
* @property string $logo
*/
class Application extends Entity
{
protected $dates = ['deleted_at'];
protected $casts = [
'id' => 'uuid',
];
protected $castHandlers = [
'uuid' => CastUuid::class
];
public function __construct(?array $data = null)
{
parent::__construct($data);
$this->attributes['id'] = Services::uuid()->generateBinary();
}
}- Create a Model and set $returnType to the Entity. Here is my example:
<?php
namespace App\Models\Application;
use CodeIgniter\Model;
use App\Entities\Application\Application as ApplicationEntitiy;
class Application extends Model
{
protected $table = 'm_application';
protected $primaryKey = 'id';
protected $useAutoIncrement = false;
protected $returnType = ApplicationEntitiy::class;
protected $useSoftDeletes = true;
protected $allowedFields = ['name', 'logo'];
// Dates
protected $useTimestamps = true;
protected $dateFormat = 'datetime';
protected $createdField = null;
protected $updatedField = null;
protected $deletedField = 'deleted_at';
public function getEntity(array $data = null): ApplicationEntitiy
{
return new ApplicationEntitiy($data);
}
}- Insert the data. In this case, I am using a Seeder:
<?php
namespace App\Database\Seeds;
use CodeIgniter\Database\Seeder;
use App\Models\Application\Application;
class ApplicationSeeder extends Seeder
{
public function run()
{
$model = model(Application::class);
$entity = $model->getEntity();
$data = [
'name' => 'User Management'
];
$entity->fill($data);
var_dump($model->insert($entity));
}
}Expected Output
The primary key should be inserted as a raw value.
Anything else?
My guess is that this code here:
Line 801 in c640145
| $properties[$this->primaryKey] = $data->{$this->primaryKey}; |
gets the property directly, instead of using
cast(false) or toRawArray().