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:
|
$properties[$this->primaryKey] = $data->{$this->primaryKey}; |
gets the property directly, instead of using
cast(false) or
toRawArray().
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:
When using
toRawArray(), all values are correct and ready to be inserted into the database. The$primaryKeyvalue is a binary string.When using
toArray(), all values are casted correctly, including the$primaryKeybeing casted to a string representation.However, when I insert the entity into the model, the inserted
$primaryKeyvalue is casted.When I check the database, string representations are inserted instead of the raw binary representation.
Steps to Reproduce
Expected Output
The primary key should be inserted as a raw value.
Anything else?
My guess is that this code here:
CodeIgniter4/system/Model.php
Line 801 in c640145
gets the property directly, instead of using
cast(false)ortoRawArray().