211 lines
6.0 KiB
PHP
211 lines
6.0 KiB
PHP
<?php
|
|
|
|
//namespace models;
|
|
|
|
define("DATABASE", Config::get('database', "database"));
|
|
|
|
abstract class Model {
|
|
protected static $database = DATABASE;
|
|
protected static $table;
|
|
protected static $tableExtends = null;
|
|
protected static $fields;
|
|
protected $isLoaded = false;
|
|
protected $initialValues = [];
|
|
protected $errors = [];
|
|
|
|
public function __construct($id = 0){
|
|
foreach (static::$fields as $field => $type){
|
|
switch ($type){
|
|
case "INT":
|
|
$this->{$field} = 0;
|
|
break;
|
|
case "VARCHAR":
|
|
case "TEXT":
|
|
default:
|
|
$this->{$field} = "";
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
if($id > 0){
|
|
try {
|
|
$firstField = array_keys(static::$fields)[0];
|
|
$result = DB::query("SELECT `".implode("`, `", array_keys(static::$fields))."` FROM ".static::$database.".".static::$table . " t1 WHERE `$firstField` = ?", $id )->fetch_assoc();
|
|
|
|
$values = [];
|
|
foreach (static::$fields as $field => $type){
|
|
$this->{ $field } = $result[$field];
|
|
|
|
// cache initial value
|
|
$values[$field] = $this->{$field};
|
|
}
|
|
|
|
$this->isLoaded = true;
|
|
|
|
} catch (DatabaseException $e) {
|
|
$this->errors[] = $e;
|
|
}
|
|
}
|
|
|
|
$this->initialValues = $this->asArray();
|
|
}
|
|
|
|
/**
|
|
* @throws DatabaseException
|
|
*/
|
|
public static function get($filter = null){
|
|
if(!self::verify()) {
|
|
return false;
|
|
}
|
|
|
|
$fields = array_keys(static::$fields);
|
|
|
|
if(is_array( static::$tableExtends) ){
|
|
$ext = new static::$tableExtends['model']();
|
|
|
|
$fields = array_merge(
|
|
$fields,
|
|
array_keys($ext::$fields)
|
|
);
|
|
|
|
$duplicateKeys = array_intersect(array_keys(static::$fields), array_keys($ext::$fields));
|
|
foreach ($duplicateKeys as $dkey){
|
|
$fieldsKey = array_search($dkey, $fields);
|
|
$fields[$fieldsKey] = "t1`.`".$fields[$fieldsKey];
|
|
|
|
$fieldsKey = array_search($dkey, $fields);
|
|
$fields[$fieldsKey] = "t2`.`".$fields[$fieldsKey];
|
|
}
|
|
|
|
$extendSql = sprintf(
|
|
" LEFT JOIN %s.%s t2 ON t2.%s = t1.%s",
|
|
$ext::$database,
|
|
$ext::$table,
|
|
static::$tableExtends['internalKey'],
|
|
static::$tableExtends['foreignKey']
|
|
);
|
|
}
|
|
|
|
|
|
|
|
$args = array();
|
|
|
|
$sql = "SELECT `".implode("`, `", $fields)."`";
|
|
$sql .= " FROM ".static::$database.".".static::$table . " t1";
|
|
|
|
$sql .= $extendSql ?? '';
|
|
|
|
if(!empty($filter)){
|
|
$filterSql = array();
|
|
foreach ($filter as $key => $value){
|
|
if(is_array($value)){
|
|
$filterSql[] = sprintf("%s %s ?", $key, $value[0]);
|
|
$args[] = $value[1];
|
|
}
|
|
else {
|
|
$filterSql[] = "$key = ?";
|
|
$args[] = $value;
|
|
}
|
|
}
|
|
$sql .= ' WHERE '. implode(',', $filterSql);
|
|
}
|
|
|
|
// if(DEBUG){
|
|
// $q = DB::queryTest($sql, $args);
|
|
// }
|
|
// else {
|
|
$q = DB::query($sql, $args);
|
|
// }
|
|
|
|
$result = array();
|
|
while($row = $q->fetch_assoc()){
|
|
$res = new static();
|
|
$res->isLoaded = true;
|
|
|
|
/* Alternative for non-joined queries:
|
|
foreach (static::$fields as $key => $ignore){
|
|
$res->{ $key } = $row[$key];
|
|
} /* */
|
|
|
|
foreach (array_keys($row) as $col){
|
|
$res->{ $col } = $row[$col];
|
|
}
|
|
$result[] = $res;
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
private static function verify(): bool {
|
|
if(is_array(static::$fields) && !empty(static::$table)){
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public function isLoaded() : bool {
|
|
return $this->isLoaded;
|
|
}
|
|
|
|
// public function set($value, )
|
|
|
|
/**
|
|
* @throws DatabaseException
|
|
*/
|
|
public function save(){
|
|
|
|
$newFields = [];
|
|
$newValues = [];
|
|
$allExceptFirstFields = [];
|
|
$allExceptFirstValues = [];
|
|
|
|
$fieldCount = 0;
|
|
foreach(static::$fields as $field => $type){
|
|
$currValue = $this->{ $field };
|
|
if(!empty($this->initialValues) && $currValue != $this->initialValues[$field]){
|
|
$newFields[] = $field;
|
|
$newValues[] = $currValue;
|
|
}
|
|
if($fieldCount > 0){
|
|
$allExceptFirstFields[] = $field;
|
|
$allExceptFirstValues[] = $currValue;
|
|
}
|
|
|
|
$fieldCount++;
|
|
}
|
|
|
|
if(!empty($this->initialValues) && empty($newValues)){
|
|
return false;
|
|
}
|
|
|
|
if($this->isLoaded()){
|
|
$updateSets = [];
|
|
foreach($newFields as $field){
|
|
$updateSets[] = "`$field` = ?";
|
|
}
|
|
|
|
DB::query(sprintf('UPDATE %s.%s SET %s WHERE %s LIMIT 1', static::$database, static::$table, implode(', ', $updateSets), "`" . array_keys(static::$fields)[0] . "` = ?"), array_merge($newValues, [$this->{array_keys(static::$fields)[0]}]));
|
|
}
|
|
else {
|
|
$sql = sprintf('INSERT INTO %s.%s (%s) VALUE (%s)', static::$database, static::$table, implode(', ', $newFields), implode(', ', array_fill(0, count($newFields), '?')));
|
|
|
|
DB::query($sql, $newValues);
|
|
$insertid = DB::insert_id();
|
|
$this->{ array_keys(static::$fields)[0] } = $insertid;
|
|
$this->isLoaded = true;
|
|
return $insertid;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public function asArray(): array {
|
|
$arr = [];
|
|
foreach ($this as $key => $val){
|
|
$arr[$key] = $val;
|
|
}
|
|
return $arr;
|
|
}
|
|
} |