diff --git a/system/BaseModel.php b/system/BaseModel.php index 8578fef233da..7ba3a27a0f4b 100644 --- a/system/BaseModel.php +++ b/system/BaseModel.php @@ -20,7 +20,7 @@ use CodeIgniter\Database\Exceptions\DataException; use CodeIgniter\Database\Query; use CodeIgniter\DataConverter\DataConverter; -use CodeIgniter\Entity\Entity; +use CodeIgniter\Entity\EntityInterface; use CodeIgniter\Exceptions\ModelException; use CodeIgniter\I18n\Time; use CodeIgniter\Pager\Pager; @@ -1796,7 +1796,7 @@ protected function timeToString(array $properties): array protected function objectToRawArray($object, bool $onlyChanged = true, bool $recursive = false): array { // Entity::toRawArray() returns array. - if (method_exists($object, 'toRawArray')) { + if ($object instanceof EntityInterface) { $properties = $object->toRawArray($onlyChanged, $recursive); } else { $mirror = new ReflectionClass($object); diff --git a/system/Database/BaseResult.php b/system/Database/BaseResult.php index 2ef3ae7a5866..c3ffa2b9b0d4 100644 --- a/system/Database/BaseResult.php +++ b/system/Database/BaseResult.php @@ -13,7 +13,7 @@ namespace CodeIgniter\Database; -use CodeIgniter\Entity\Entity; +use CodeIgniter\Entity\EntityInterface; use stdClass; /** @@ -159,7 +159,7 @@ public function getCustomResultObject(string $className) $this->customResultObject[$className] = []; while ($row = $this->fetchObject($className)) { - if (! is_subclass_of($row, Entity::class) && method_exists($row, 'syncOriginal')) { + if (! is_subclass_of($row, EntityInterface::class) && method_exists($row, 'syncOriginal')) { $row->syncOriginal(); } @@ -240,7 +240,7 @@ public function getResultObject(): array } while ($row = $this->fetchObject()) { - if (! is_subclass_of($row, Entity::class) && method_exists($row, 'syncOriginal')) { + if (! is_subclass_of($row, EntityInterface::class) && method_exists($row, 'syncOriginal')) { $row->syncOriginal(); } @@ -539,7 +539,7 @@ abstract protected function fetchAssoc(); * * Overridden by child classes. * - * @return Entity|false|object|stdClass + * @return EntityInterface|false|object|stdClass */ abstract protected function fetchObject(string $className = 'stdClass'); } diff --git a/system/Database/MySQLi/Result.php b/system/Database/MySQLi/Result.php index 873bbd08b9d9..7b7e2633247b 100644 --- a/system/Database/MySQLi/Result.php +++ b/system/Database/MySQLi/Result.php @@ -14,7 +14,7 @@ namespace CodeIgniter\Database\MySQLi; use CodeIgniter\Database\BaseResult; -use CodeIgniter\Entity\Entity; +use CodeIgniter\Entity\EntityInterface; use mysqli; use mysqli_result; use stdClass; @@ -145,11 +145,11 @@ protected function fetchAssoc() * * Overridden by child classes. * - * @return Entity|false|object|stdClass + * @return EntityInterface|false|object|stdClass */ protected function fetchObject(string $className = 'stdClass') { - if (is_subclass_of($className, Entity::class)) { + if (is_subclass_of($className, EntityInterface::class)) { return empty($data = $this->fetchAssoc()) ? false : (new $className())->injectRawData($data); } diff --git a/system/Database/OCI8/Result.php b/system/Database/OCI8/Result.php index 0039e90ae9b4..4565ffdda036 100644 --- a/system/Database/OCI8/Result.php +++ b/system/Database/OCI8/Result.php @@ -14,7 +14,7 @@ namespace CodeIgniter\Database\OCI8; use CodeIgniter\Database\BaseResult; -use CodeIgniter\Entity\Entity; +use CodeIgniter\Entity\EntityInterface; use stdClass; /** @@ -95,7 +95,7 @@ protected function fetchAssoc() * * Overridden by child classes. * - * @return Entity|false|object|stdClass + * @return EntityInterface|false|object|stdClass */ protected function fetchObject(string $className = 'stdClass') { @@ -104,7 +104,7 @@ protected function fetchObject(string $className = 'stdClass') if ($className === 'stdClass' || ! $row) { return $row; } - if (is_subclass_of($className, Entity::class)) { + if (is_subclass_of($className, EntityInterface::class)) { return (new $className())->injectRawData((array) $row); } diff --git a/system/Database/Postgre/Result.php b/system/Database/Postgre/Result.php index e5d78c519c17..4fcb317de589 100644 --- a/system/Database/Postgre/Result.php +++ b/system/Database/Postgre/Result.php @@ -14,7 +14,7 @@ namespace CodeIgniter\Database\Postgre; use CodeIgniter\Database\BaseResult; -use CodeIgniter\Entity\Entity; +use CodeIgniter\Entity\EntityInterface; use PgSql\Connection as PgSqlConnection; use PgSql\Result as PgSqlResult; use stdClass; @@ -111,11 +111,11 @@ protected function fetchAssoc() * * Overridden by child classes. * - * @return Entity|false|object|stdClass + * @return EntityInterface|false|object|stdClass */ protected function fetchObject(string $className = 'stdClass') { - if (is_subclass_of($className, Entity::class)) { + if (is_subclass_of($className, EntityInterface::class)) { return empty($data = $this->fetchAssoc()) ? false : (new $className())->injectRawData($data); } diff --git a/system/Database/SQLSRV/Result.php b/system/Database/SQLSRV/Result.php index 4d9b836fdda0..36d9bb5b87c9 100755 --- a/system/Database/SQLSRV/Result.php +++ b/system/Database/SQLSRV/Result.php @@ -14,7 +14,7 @@ namespace CodeIgniter\Database\SQLSRV; use CodeIgniter\Database\BaseResult; -use CodeIgniter\Entity\Entity; +use CodeIgniter\Entity\EntityInterface; use stdClass; /** @@ -151,11 +151,11 @@ protected function fetchAssoc() /** * Returns the result set as an object. * - * @return Entity|false|object|stdClass + * @return EntityInterface|false|object|stdClass */ protected function fetchObject(string $className = 'stdClass') { - if (is_subclass_of($className, Entity::class)) { + if (is_subclass_of($className, EntityInterface::class)) { return empty($data = $this->fetchAssoc()) ? false : (new $className())->injectRawData($data); } diff --git a/system/Database/SQLite3/Result.php b/system/Database/SQLite3/Result.php index 70d8dc47d2b6..cb5ed5e867b4 100644 --- a/system/Database/SQLite3/Result.php +++ b/system/Database/SQLite3/Result.php @@ -16,7 +16,7 @@ use Closure; use CodeIgniter\Database\BaseResult; use CodeIgniter\Database\Exceptions\DatabaseException; -use CodeIgniter\Entity\Entity; +use CodeIgniter\Entity\EntityInterface; use SQLite3; use SQLite3Result; use stdClass; @@ -143,7 +143,7 @@ protected function fetchObject(string $className = 'stdClass') $classObj = new $className(); - if (is_subclass_of($className, Entity::class)) { + if (is_subclass_of($className, EntityInterface::class)) { return $classObj->injectRawData($row); } diff --git a/system/Entity/Entity.php b/system/Entity/Entity.php index f7242103f2ce..00c321c87a90 100644 --- a/system/Entity/Entity.php +++ b/system/Entity/Entity.php @@ -38,7 +38,7 @@ * * @see \CodeIgniter\Entity\EntityTest */ -class Entity implements JsonSerializable +class Entity implements EntityInterface, JsonSerializable { /** * Maps names used in sets and gets against unique diff --git a/system/Entity/EntityInterface.php b/system/Entity/EntityInterface.php new file mode 100644 index 000000000000..f6752b622a9f --- /dev/null +++ b/system/Entity/EntityInterface.php @@ -0,0 +1,41 @@ + + * + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. + */ + +namespace CodeIgniter\Entity; + +/** + * Entity encapsulation, for use with CodeIgniter\Model + * + * @see \CodeIgniter\Entity\EntityTest + */ +interface EntityInterface +{ + /** + * Returns the raw values of the current attributes. + * + * @param bool $onlyChanged If true, only return values that have changed since object creation + * @param bool $recursive If true, inner entities will be cast as array as well. + * + * @return array + */ + public function toRawArray(bool $onlyChanged = false, bool $recursive = false): array; + + /** + * Set raw data array without any mutations + * + * @param array $data + * + * @return $this + */ + public function injectRawData(array $data); +} diff --git a/user_guide_src/source/changelogs/v4.5.0.rst b/user_guide_src/source/changelogs/v4.5.0.rst index d4219c7b0333..afb51268aa72 100644 --- a/user_guide_src/source/changelogs/v4.5.0.rst +++ b/user_guide_src/source/changelogs/v4.5.0.rst @@ -72,6 +72,11 @@ Forge Others ------ +- **Entity:** + - Added ``CodeIgniter\Entity\EntityInterface`` for better extensibility. + - Now ``Entity`` implements ``EntityInterface``. + - Now ``BaseModel`` and ``Result`` classes use ``EntityInterface`` instead of ``Entity``. + Model =====