diff --git a/system/Entity/Cast/IntBoolCast.php b/system/Entity/Cast/IntBoolCast.php new file mode 100644 index 000000000000..ce572d9eba4e --- /dev/null +++ b/system/Entity/Cast/IntBoolCast.php @@ -0,0 +1,36 @@ + + * + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. + */ + +namespace CodeIgniter\Entity\Cast; + +/** + * Int Bool Cast + * + * DB column: int (0/1) <--> Class property: bool + */ +final class IntBoolCast extends BaseCast +{ + /** + * @param int $value + */ + public static function get($value, array $params = []): bool + { + return (bool) $value; + } + + /** + * @param bool|int|string $value + */ + public static function set($value, array $params = []): int + { + return (int) $value; + } +} diff --git a/system/Entity/Entity.php b/system/Entity/Entity.php index 39adf0661215..e9a4e938a7ed 100644 --- a/system/Entity/Entity.php +++ b/system/Entity/Entity.php @@ -17,6 +17,7 @@ use CodeIgniter\Entity\Cast\CSVCast; use CodeIgniter\Entity\Cast\DatetimeCast; use CodeIgniter\Entity\Cast\FloatCast; +use CodeIgniter\Entity\Cast\IntBoolCast; use CodeIgniter\Entity\Cast\IntegerCast; use CodeIgniter\Entity\Cast\JsonCast; use CodeIgniter\Entity\Cast\ObjectCast; @@ -80,6 +81,7 @@ class Entity implements JsonSerializable 'float' => FloatCast::class, 'int' => IntegerCast::class, 'integer' => IntegerCast::class, + 'int-bool' => IntBoolCast::class, 'json' => JsonCast::class, 'object' => ObjectCast::class, 'string' => StringCast::class, diff --git a/tests/system/Entity/EntityTest.php b/tests/system/Entity/EntityTest.php index 2838aa02269e..66a0a4478f9c 100644 --- a/tests/system/Entity/EntityTest.php +++ b/tests/system/Entity/EntityTest.php @@ -293,6 +293,33 @@ public function testCastInteger() $this->assertSame(3, $entity->first); } + public function testCastIntBool() + { + $entity = new class () extends Entity { + protected $casts = [ + 'active' => 'int-bool', + ]; + }; + + $entity->setAttributes(['active' => '1']); + + $this->assertTrue($entity->active); + + $entity->setAttributes(['active' => '0']); + + $this->assertFalse($entity->active); + + $entity->active = true; + + $this->assertTrue($entity->active); + $this->assertSame(['active' => 1], $entity->toRawArray()); + + $entity->active = false; + + $this->assertFalse($entity->active); + $this->assertSame(['active' => 0], $entity->toRawArray()); + } + public function testCastFloat() { $entity = $this->getCastEntity(); diff --git a/user_guide_src/source/changelogs/v4.3.0.rst b/user_guide_src/source/changelogs/v4.3.0.rst index 565a78e0127a..f45ef9a7ef86 100644 --- a/user_guide_src/source/changelogs/v4.3.0.rst +++ b/user_guide_src/source/changelogs/v4.3.0.rst @@ -59,6 +59,7 @@ Enhancements - Now **Encryption** can decrypt data encrypted with CI3's Encryption. See :ref:`encryption-compatible-with-ci3`. - Added method ``Timer::record()`` to measure performance in a callable. Also enhanced common function ``timer()`` to accept optional callable. - Now ``spark routes`` command shows route names. See :ref:`URI Routing `. +- Added new :ref:`entities-property-casting` class ``IntBoolCast`` for Entity. Changes ******* diff --git a/user_guide_src/source/models/entities.rst b/user_guide_src/source/models/entities.rst index 55187ae7a0ad..b4c705c4feae 100644 --- a/user_guide_src/source/models/entities.rst +++ b/user_guide_src/source/models/entities.rst @@ -187,6 +187,8 @@ current timezone, as set in **app/Config/App.php**: .. literalinclude:: entities/011.php +.. _entities-property-casting: + Property Casting ---------------- @@ -194,7 +196,7 @@ You can specify that properties in your Entity should be converted to common dat This option should be an array where the key is the name of the class property, and the value is the data type it should be cast to. Casting only affects when values are read. No conversions happen that affect the permanent value in either the entity or the database. Properties can be cast to any of the following data types: -**integer**, **float**, **double**, **string**, **boolean**, **object**, **array**, **datetime**, **timestamp**, and **uri**. +**integer**, **float**, **double**, **string**, **boolean**, **object**, **array**, **datetime**, **timestamp**, **uri** and **int-bool**. Add a question mark at the beginning of type to mark property as nullable, i.e., **?string**, **?integer**. For example, if you had a User entity with an ``is_banned`` property, you can cast it as a boolean: