From 293eb9e555fd76f71e42e09b84f3942dee45b9d8 Mon Sep 17 00:00:00 2001 From: Gregory Letellier Date: Thu, 9 Jan 2025 12:00:25 +0100 Subject: [PATCH] cast extended models when loading from database --- src/Model.php | 30 ++++++++++++++++-------------- src/QueryBuilder.php | 20 +++++++++++++------- tests/DbTest.php | 2 ++ 3 files changed, 31 insertions(+), 21 deletions(-) diff --git a/src/Model.php b/src/Model.php index 5bf0da9..4de99b3 100644 --- a/src/Model.php +++ b/src/Model.php @@ -26,17 +26,14 @@ class Model implements JsonSerializable private function initTable(): void { - if(!$this->ro) - { + if (!$this->ro) { if ($this->table == "") { $this->table = $this->getDefaultTableName(); } - } - else - { + } else { $this->table = "ReadOnlyModel"; $this->pk = "__idpk"; - } + } } public function getTable(): string @@ -87,7 +84,7 @@ class Model implements JsonSerializable public function find(mixed $key): mixed { - $qb = $this->newQueryBuilder(); + $qb = $this->newQueryBuilder(get_class($this)); $find = $qb->find($key); if ($find !== null) { $this->fillData($find->getValues()); @@ -99,9 +96,8 @@ class Model implements JsonSerializable public function save(): bool { $ret = false; - if(!$this->ro) - { - $qb = $this->newQueryBuilder(); + if (!$this->ro) { + $qb = $this->newQueryBuilder(""); if ($this->new) { $query = $qb->getPreparedQuery($this->values); $id = Connection::getInstance($this->connection)->insertQuery($query); @@ -126,13 +122,13 @@ class Model implements JsonSerializable } } } - } + } return $ret; } - public function newQueryBuilder(): QueryBuilder + public function newQueryBuilder($className): QueryBuilder { - return new QueryBuilder($this->table, $this->pk, $this->connection); + return new QueryBuilder($this->table, $this->pk, $this->connection, $className); } public function __set($name, $value): void @@ -152,10 +148,16 @@ class Model implements JsonSerializable } } + public static function getClassName() + { + return static::class; + } + public static function q(): QueryBuilder { + $cls = self::getClassName(); $ist = new static(); - return $ist->newQueryBuilder(); + return $ist->newQueryBuilder($cls); } public function __get($name): mixed diff --git a/src/QueryBuilder.php b/src/QueryBuilder.php index 8a5b34d..2d8d575 100644 --- a/src/QueryBuilder.php +++ b/src/QueryBuilder.php @@ -10,6 +10,7 @@ class QueryBuilder protected array $orders; protected array $groupby; protected string $table; + protected string $classname; protected string $connection; protected string $pk; protected ?int $take; @@ -20,8 +21,9 @@ class QueryBuilder public const MODE_AND = 0; public const MODE_OR = 1; - public function __construct($table, $pk = "id", $connection = "") + public function __construct($table, $pk = "id", $connection = "", $classname = "") { + $this->classname = $classname; $this->table = $table; $this->pk = $pk; $this->connection = $connection; @@ -208,7 +210,12 @@ class QueryBuilder { $ret = array(); foreach ($data as $row) { - $model = new Model(); + if ($this->classname != "") { + $model = new $this->classname(); + } else { + $model = new Model(); + } + $ret[] = $model->setPk($this->pk)->setTable($this->table)->fillData($row); } return new Collection($ret); @@ -235,11 +242,10 @@ class QueryBuilder $where = $this->getWhere(); $Orwhere = $this->getWhere(QueryBuilder::MODE_OR); - + $this->fillData($ret); - if($where!="" && $Orwhere!="") - { + if ($where != "" && $Orwhere != "") { $Orwhere = " OR " . $Orwhere; } @@ -256,8 +262,8 @@ class QueryBuilder } private function fillData(Query &$query): void - { - foreach (array_merge($this->wheres,$this->orwheres) as $expression) { + { + foreach (array_merge($this->wheres, $this->orwheres) as $expression) { if ($expression instanceof Expression) { if ($expression->hasData()) { $query->addData($expression->getValue()); diff --git a/tests/DbTest.php b/tests/DbTest.php index d732815..b2fc0c0 100644 --- a/tests/DbTest.php +++ b/tests/DbTest.php @@ -116,6 +116,8 @@ test("extending model",function() $row = $qbs->find(1); expect($row->id)->toBe(1); expect($row->col1)->toBe("test"); + + expect($row)->toBeInstanceOf(Test::class); }); test("order by", function(){