diff --git a/system/Database/MySQLi/Result.php b/system/Database/MySQLi/Result.php index 550fc0abf835..90bf314964c5 100644 --- a/system/Database/MySQLi/Result.php +++ b/system/Database/MySQLi/Result.php @@ -146,7 +146,7 @@ protected function fetchAssoc() protected function fetchObject(string $className = 'stdClass') { if (is_subclass_of($className, Entity::class)) { - return empty($data = $this->fetchAssoc()) ? false : (new $className())->setAttributes($data); + return empty($data = $this->fetchAssoc()) ? false : (new $className())->injectRawData($data); } return $this->resultID->fetch_object($className); diff --git a/system/Database/OCI8/Result.php b/system/Database/OCI8/Result.php index cb192de325f1..f20dcaddb88e 100644 --- a/system/Database/OCI8/Result.php +++ b/system/Database/OCI8/Result.php @@ -102,7 +102,7 @@ protected function fetchObject(string $className = 'stdClass') return $row; } if (is_subclass_of($className, Entity::class)) { - return (new $className())->setAttributes((array) $row); + return (new $className())->injectRawData((array) $row); } $instance = new $className(); diff --git a/system/Database/Postgre/Result.php b/system/Database/Postgre/Result.php index c3fce412223d..ebda4f9e9b02 100644 --- a/system/Database/Postgre/Result.php +++ b/system/Database/Postgre/Result.php @@ -112,7 +112,7 @@ protected function fetchAssoc() protected function fetchObject(string $className = 'stdClass') { if (is_subclass_of($className, Entity::class)) { - return empty($data = $this->fetchAssoc()) ? false : (new $className())->setAttributes($data); + return empty($data = $this->fetchAssoc()) ? false : (new $className())->injectRawData($data); } return pg_fetch_object($this->resultID, null, $className); diff --git a/system/Database/SQLSRV/Result.php b/system/Database/SQLSRV/Result.php index 6e172d8ac770..541dbe34d31e 100755 --- a/system/Database/SQLSRV/Result.php +++ b/system/Database/SQLSRV/Result.php @@ -152,7 +152,7 @@ protected function fetchAssoc() protected function fetchObject(string $className = 'stdClass') { if (is_subclass_of($className, Entity::class)) { - return empty($data = $this->fetchAssoc()) ? false : (new $className())->setAttributes($data); + return empty($data = $this->fetchAssoc()) ? false : (new $className())->injectRawData($data); } return sqlsrv_fetch_object($this->resultID, $className); diff --git a/system/Database/SQLite3/Result.php b/system/Database/SQLite3/Result.php index 05994469e5eb..3f6169970571 100644 --- a/system/Database/SQLite3/Result.php +++ b/system/Database/SQLite3/Result.php @@ -140,7 +140,7 @@ protected function fetchObject(string $className = 'stdClass') $classObj = new $className(); if (is_subclass_of($className, Entity::class)) { - return $classObj->setAttributes($row); + return $classObj->injectRawData($row); } $classSet = Closure::bind(function ($key, $value) { diff --git a/system/Entity/Entity.php b/system/Entity/Entity.php index 92cedeff213f..5220ae5b0aa8 100644 --- a/system/Entity/Entity.php +++ b/system/Entity/Entity.php @@ -279,7 +279,7 @@ public function hasChanged(?string $key = null): bool * * @return $this */ - public function setAttributes(array $data) + public function injectRawData(array $data) { $this->attributes = $data; @@ -288,6 +288,18 @@ public function setAttributes(array $data) return $this; } + /** + * Set raw data array without any mutations + * + * @return $this + * + * @deprecated Use injectRawData() instead. + */ + public function setAttributes(array $data) + { + return $this->injectRawData($data); + } + /** * Checks the datamap to see if this property name is being mapped, * and returns the db column name, if any, or the original property name. @@ -449,7 +461,7 @@ public function __set(string $key, $value = null) // so maybe wants to do sth with null value automatically $method = 'set' . str_replace(' ', '', ucwords(str_replace(['-', '_'], ' ', $key))); - if (method_exists($this, $method)) { + if (method_exists($this, $method) && $method !== 'setAttributes') { $this->{$method}($value); return $this; diff --git a/tests/system/Entity/EntityTest.php b/tests/system/Entity/EntityTest.php index 1e03157ab188..79aeb53f3199 100644 --- a/tests/system/Entity/EntityTest.php +++ b/tests/system/Entity/EntityTest.php @@ -34,6 +34,36 @@ final class EntityTest extends CIUnitTestCase { use ReflectionHelper; + public function testSetStringToPropertyNamedAttributes() + { + $entity = $this->getEntity(); + + $entity->attributes = 'attributes'; + + $this->assertSame('attributes', $entity->attributes); + } + + /** + * @see https://github.com/codeigniter4/CodeIgniter4/issues + */ + public function testSetArrayToPropertyNamedAttributes() + { + $entity = new Entity(); + + $entity->a = 1; + $entity->attributes = [1, 2, 3]; + + $expected = [ + 'a' => 1, + 'attributes' => [ + 0 => 1, + 1 => 2, + 2 => 3, + ], + ]; + $this->assertSame($expected, $entity->toRawArray()); + } + public function testSimpleSetAndGet() { $entity = $this->getEntity();