From 038a1578bb617597479de30e32bb3845e8b91634 Mon Sep 17 00:00:00 2001 From: MGatner Date: Sat, 15 May 2021 20:01:20 +0000 Subject: [PATCH 1/3] Add URI cast --- system/Entity/Cast/URICast.php | 28 ++++++ system/Entity/Entity.php | 11 +-- tests/system/EntityTest.php | 102 ++++++++++++++-------- user_guide_src/source/models/entities.rst | 2 +- 4 files changed, 101 insertions(+), 42 deletions(-) create mode 100644 system/Entity/Cast/URICast.php diff --git a/system/Entity/Cast/URICast.php b/system/Entity/Cast/URICast.php new file mode 100644 index 000000000000..13a161c50a94 --- /dev/null +++ b/system/Entity/Cast/URICast.php @@ -0,0 +1,28 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace CodeIgniter\Entity\Cast; + +use CodeIgniter\HTTP\URI; + +/** + * Class URICast + */ +class URICast extends BaseCast +{ + /** + * @inheritDoc + */ + public static function get($value, array $params = []): object + { + return $value instanceof URI ? $value : new URI($value); + } +} diff --git a/system/Entity/Entity.php b/system/Entity/Entity.php index 92f5179573cb..9ae6d5e71441 100644 --- a/system/Entity/Entity.php +++ b/system/Entity/Entity.php @@ -22,6 +22,7 @@ use CodeIgniter\Entity\Cast\ObjectCast; use CodeIgniter\Entity\Cast\StringCast; use CodeIgniter\Entity\Cast\TimestampCast; +use CodeIgniter\Entity\Cast\URICast; use CodeIgniter\Entity\Exceptions\CastException; use CodeIgniter\I18n\Time; use Exception; @@ -82,6 +83,7 @@ class Entity implements JsonSerializable 'object' => ObjectCast::class, 'string' => StringCast::class, 'timestamp' => TimestampCast::class, + 'uri' => URICast::class, ]; /** @@ -226,7 +228,6 @@ public function toRawArray(bool $onlyChanged = false, bool $recursive = false): } return $value; - }, $this->attributes); } @@ -305,7 +306,7 @@ public function hasChanged(string $key = null): bool /** * Set raw data array without any mutations * - * @param array $data + * @param array $data * * @return $this */ @@ -461,7 +462,7 @@ public function jsonSerialize() /** * Change the value of the private $_cast property * - * @param boolean|null $cast + * @param boolean|null $cast * * @return boolean|Entity */ @@ -509,7 +510,7 @@ public function __set(string $key, $value = null) // insert this value. should be outside $isNullable check, // so maybe wants to do sth with null value automatically $method = 'set' . str_replace(' ', '', ucwords(str_replace(['-', '_'], ' ', $key))); - + if (method_exists($this, $method)) { $this->$method($value); @@ -603,7 +604,7 @@ public function __isset(string $key): bool * Unsets an attribute property. * * @param string $key - * + * * @return void */ public function __unset(string $key): void diff --git a/tests/system/EntityTest.php b/tests/system/EntityTest.php index 664ace9f9c9a..6dd89c8d280b 100644 --- a/tests/system/EntityTest.php +++ b/tests/system/EntityTest.php @@ -4,6 +4,7 @@ use CodeIgniter\Entity\Exceptions\CastException; use CodeIgniter\I18n\Time; +use CodeIgniter\HTTP\URI; use CodeIgniter\Test\CIUnitTestCase; use CodeIgniter\Test\ReflectionHelper; use DateTime; @@ -497,6 +498,32 @@ public function testCastNullable() //-------------------------------------------------------------------- + public function testCastURI() + { + $entity = $this->getCastEntity(); + + $data = 'https://codeigniter.com/banana'; + + $entity->thirteenth = $data; + $this->assertInstanceOf(URI::class, $entity->thirteenth); + $this->assertSame($data, (string) $entity->thirteenth); + $this->assertSame('/banana', $entity->thirteenth->getPath()); + } + + public function testURICastURI() + { + $entity = $this->getCastEntity(); + + $data = 'https://codeigniter.com/banana'; + + $entity->thirteenth = new URI($data); + $this->assertInstanceOf(URI::class, $entity->thirteenth); + $this->assertSame($data, (string) $entity->thirteenth); + $this->assertSame('/banana', $entity->thirteenth->getPath()); + } + + //-------------------------------------------------------------------- + public function testCastAsJSON() { $entity = $this->getCastEntity(); @@ -1050,49 +1077,52 @@ protected function getCastEntity($data = null) : Entity return new class($data) extends Entity { protected $attributes = [ - 'first' => null, - 'second' => null, - 'third' => null, - 'fourth' => null, - 'fifth' => null, - 'sixth' => null, - 'seventh' => null, - 'eighth' => null, - 'ninth' => null, - 'tenth' => null, - 'eleventh' => null, - 'twelfth' => null, + 'first' => null, + 'second' => null, + 'third' => null, + 'fourth' => null, + 'fifth' => null, + 'sixth' => null, + 'seventh' => null, + 'eighth' => null, + 'ninth' => null, + 'tenth' => null, + 'eleventh' => null, + 'twelfth' => null, + 'thirteenth' => null, ]; protected $_original = [ - 'first' => null, - 'second' => null, - 'third' => null, - 'fourth' => null, - 'fifth' => null, - 'sixth' => null, - 'seventh' => null, - 'eighth' => null, - 'ninth' => null, - 'tenth' => null, - 'eleventh' => null, - 'twelfth' => null, + 'first' => null, + 'second' => null, + 'third' => null, + 'fourth' => null, + 'fifth' => null, + 'sixth' => null, + 'seventh' => null, + 'eighth' => null, + 'ninth' => null, + 'tenth' => null, + 'eleventh' => null, + 'twelfth' => null, + 'thirteenth' => null, ]; // 'bar' is db column, 'foo' is internal representation protected $casts = [ - 'first' => 'integer', - 'second' => 'float', - 'third' => 'double', - 'fourth' => 'string', - 'fifth' => 'boolean', - 'sixth' => 'object', - 'seventh' => 'array', - 'eighth' => 'datetime', - 'ninth' => 'timestamp', - 'tenth' => 'json', - 'eleventh' => 'json-array', - 'twelfth' => 'csv', + 'first' => 'integer', + 'second' => 'float', + 'third' => 'double', + 'fourth' => 'string', + 'fifth' => 'boolean', + 'sixth' => 'object', + 'seventh' => 'array', + 'eighth' => 'datetime', + 'ninth' => 'timestamp', + 'tenth' => 'json', + 'eleventh' => 'json-array', + 'twelfth' => 'csv', + 'thirteenth' => 'uri', ]; public function setSeventh($seventh) diff --git a/user_guide_src/source/models/entities.rst b/user_guide_src/source/models/entities.rst index 3a6ce6f5cd7c..f4ce50924633 100644 --- a/user_guide_src/source/models/entities.rst +++ b/user_guide_src/source/models/entities.rst @@ -330,7 +330,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**, and **timestamp**. +**integer**, **float**, **double**, **string**, **boolean**, **object**, **array**, **datetime**, **timestamp**, and **URI**. 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:: From d91ae4f06932395758556887f678df1c06d3a398 Mon Sep 17 00:00:00 2001 From: MGatner Date: Sun, 16 May 2021 09:13:36 -0400 Subject: [PATCH 2/3] Update system/Entity/Cast/URICast.php Co-authored-by: Abdul Malik Ikhsan --- system/Entity/Cast/URICast.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/Entity/Cast/URICast.php b/system/Entity/Cast/URICast.php index 13a161c50a94..337998877e9a 100644 --- a/system/Entity/Cast/URICast.php +++ b/system/Entity/Cast/URICast.php @@ -21,7 +21,7 @@ class URICast extends BaseCast /** * @inheritDoc */ - public static function get($value, array $params = []): object + public static function get($value, array $params = []): URI { return $value instanceof URI ? $value : new URI($value); } From 4f02255ff4b05f74752c0661ecbd3e75751b080c Mon Sep 17 00:00:00 2001 From: MGatner Date: Sun, 16 May 2021 09:18:00 -0400 Subject: [PATCH 3/3] Update user_guide_src/source/models/entities.rst --- user_guide_src/source/models/entities.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_guide_src/source/models/entities.rst b/user_guide_src/source/models/entities.rst index f4ce50924633..0d8ae47377bc 100644 --- a/user_guide_src/source/models/entities.rst +++ b/user_guide_src/source/models/entities.rst @@ -330,7 +330,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**, and **uri**. 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::