table = $table; $this->pk = $pk; $this->db = Db::getInstance(); $this->reset(); } public function reset() { $this->columns = []; $this->wheres = []; $this->orders = []; $this->offset = null; $this->take = null; $this->raw_query = ""; } public function raw(string $query) { $this->raw_query = $query; return $this; } public function take(?int $nb) { $this->take = $nb; return $this; } public function offset(?int $offset) { $this->offset = $offset; return $this; } public function orderBy($columns, $sort = "ASC") { if (is_array($columns)) { foreach ($columns as $column) { $this->orders[] = $column . " " . $sort; } } else { $this->orders[] = $columns . " " . $sort; } return $this; } public function columns($columns) { if (is_array($columns)) { $this->columns = array_merge($this->columns, $columns); } if (is_string($columns)) { $this->columns[] = $columns; } return $this; } public function where($condition, $operator, $value = null) { if ($value === null) { $this->wheres[] = new Expression($condition, "=", $operator); } else { $this->wheres[] = new Expression($condition, $operator, $value); } return $this; } public function whereRaw(string $raw) { $this->wheres[] = $raw; return $this; } public function find($id): mixed { $this->reset(); $expression = new Expression($this->pk, "=", $id); $this->wheres = [$expression]; $this->columns = ["*"]; $data = $this->getData(); if (count($data) > 0) { return $this->prepareModels($data)[0]; } return null; } public function get(): mixed { $data = $this->getData(); return $this->prepareModels($data); } public function getPreparedQuery(array $data, $insert = true): Query { $ret = new Query(); $columns = implode(",", array_keys($data)); $query = ""; if ($insert) { $keys = implode(",", str_split(str_repeat("?", count($data)))); $query = "INSERT INTO " . $this->table . " (" . $columns . ") VALUES (" . $keys . ");"; foreach ($data as $key => $value) { $ret->addData($value); } } else { $query = "UPDATE " . $this->table . " SET "; $up = ""; foreach ($data as $key => $value) { if ($up != "") { $up .= ", "; } $up .= $key . " = ? "; $ret->addData($value); } $query .= $up . " WHERE " . $this->pk . " = ? ;"; $ret->addData($data[$this->pk]); } $ret->setQuery($query); return $ret; } private function prepareModels(mixed $data): mixed { $ret = array(); foreach ($data as $row) { $model = new Model(); $ret[] = $model->setPk($this->pk)->setTable($this->table)->fillData($row); } return $ret; } private function getData(): mixed { return $this->db->getSelectQuery($this->getQuery()); } private function getConstructedQuery(): Query { $ret = new Query(); $ret->setQuery(""); $ret->setData([]); if (count($this->columns) == 0) { $this->columns("*"); } $columns = implode(",", $this->columns); $where = ""; foreach ($this->wheres as $expression) { $sw = ""; if ($expression instanceof Expression) { $sw = $expression->raw(); $ret->addData($expression->getValue()); } if ($expression instanceof string) { if (trim($expression) !== "") { $sw = "(" . $expression . ")"; } } if ($where != "" && $sw != "") { $where .= " AND "; } $where .= $sw; } $query = "SELECT " . $columns . " FROM " . $this->table ; if ($where != "") { $query .= " WHERE " . $where; } if (count($this->orders) > 0) { $query .= " ORDER BY "; $iOrder = 0; foreach ($this->orders as $order) { if ($iOrder > 0) { $query .= ","; } $query .= $order; $iOrder++; } } $query .= $this->getLimit(); $ret->setQuery($query); return $ret; } private function getLimit(): string { if ($this->take !== null || $this->offset !== null) { $ret = ""; if ($this->take !== null) { $ret = " LIMIT " . $this->take; } if ($this->offset !== null) { $ret .= " OFFSET " . $this->offset; } return $ret; } else { return ""; } } private function getQuery(): Query { if ($this->raw_query !== "") { $query = new Query(); $query->setQuery($this->raw_query); $query->setData([]); return $query; } else { return $this->getConstructedQuery(); } } }