2023-10-22 01:46:22 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
class Model {
|
|
|
|
public $data;
|
|
|
|
public $id = false;
|
|
|
|
public $redis;
|
|
|
|
|
|
|
|
function __construct()
|
|
|
|
{
|
|
|
|
//redis
|
|
|
|
if ($GLOBALS['redis'])
|
2023-10-29 17:37:28 +01:00
|
|
|
$GLOBALS['redis'] = $GLOBALS['redis'];
|
2023-10-22 01:46:22 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Magic getter function
|
|
|
|
*
|
|
|
|
* @param $name Variable name
|
|
|
|
*
|
|
|
|
* @return mixed
|
|
|
|
*/
|
|
|
|
public function __get($name)
|
|
|
|
{
|
|
|
|
if (isset($this->data[$name]))
|
|
|
|
return $this->data[$name];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Magic setter function
|
|
|
|
*
|
|
|
|
* @return mixed
|
|
|
|
*/
|
|
|
|
public function __set($name, $value)
|
|
|
|
{
|
|
|
|
$this->data[$name] = $value;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getDBFields()
|
|
|
|
{
|
|
|
|
return $this->dbFields;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns all data fields but removes filtered datapoints like passwords, etc
|
|
|
|
*/
|
|
|
|
public function getDataFiltered()
|
|
|
|
{
|
|
|
|
$data = $this->data;
|
|
|
|
if(is_array($this->hidden))
|
|
|
|
foreach($this->hidden as $secretfield)
|
|
|
|
unset($data[$secretfield]);
|
|
|
|
foreach($this->dbFields as $field=>$options)
|
|
|
|
if($options['type']=='csv')
|
|
|
|
$data[$field] = ($data[$field]?explode(';',$data[$field]):[]);
|
|
|
|
return $data;
|
|
|
|
}
|
|
|
|
|
2023-10-29 17:37:28 +01:00
|
|
|
public function getField($field,$id=false)
|
|
|
|
{
|
|
|
|
if(!$id)
|
|
|
|
$id = $this->id;
|
|
|
|
return $GLOBALS['redis']->hget($this->dbTable.':'.$id,$field);
|
|
|
|
}
|
|
|
|
|
2023-10-22 01:46:22 +02:00
|
|
|
public function save()
|
|
|
|
{
|
2023-10-26 17:50:54 +02:00
|
|
|
$newgen = false;
|
2023-10-22 23:05:24 +02:00
|
|
|
if (!$this->id)
|
2023-10-26 17:50:54 +02:00
|
|
|
{
|
2023-10-22 23:05:24 +02:00
|
|
|
$this->id = gen_ulid();
|
2023-10-26 17:50:54 +02:00
|
|
|
$newgen = true;
|
|
|
|
}
|
|
|
|
if (!$this->validate($newgen))
|
2023-10-22 01:46:22 +02:00
|
|
|
return false;
|
|
|
|
foreach($this->dbFields as $field=>$options)
|
|
|
|
{
|
|
|
|
if(isset($this->data[$field]))
|
2023-10-22 23:05:24 +02:00
|
|
|
{
|
2023-10-29 09:16:10 +01:00
|
|
|
if($options['type']=='array' && is_array($this->data[$field]))
|
2023-10-22 23:05:24 +02:00
|
|
|
$GLOBALS['redis']->hset($this->dbTable.':'.$this->id,$field,json_encode($this->data[$field]));
|
2023-10-29 09:16:10 +01:00
|
|
|
else if($options['type']=='array' && !is_array($this->data[$field]))
|
|
|
|
$GLOBALS['redis']->hset($this->dbTable.':'.$this->id,$field,json_encode([]));
|
2023-10-22 23:05:24 +02:00
|
|
|
else
|
|
|
|
{
|
|
|
|
$GLOBALS['redis']->hset($this->dbTable.':'.$this->id,$field,$this->data[$field]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-10-22 01:46:22 +02:00
|
|
|
}
|
2023-10-22 23:05:24 +02:00
|
|
|
|
|
|
|
return $this->id;
|
2023-10-22 01:46:22 +02:00
|
|
|
}
|
|
|
|
|
2023-10-29 17:37:28 +01:00
|
|
|
/**
|
|
|
|
* @param $value The value to search for
|
|
|
|
* @param string $field The field to search in. HAS to be marked as unique otherwise will throw error
|
|
|
|
*/
|
2023-10-30 22:36:18 +01:00
|
|
|
public function load($value=false,$field='id')
|
2023-10-22 01:46:22 +02:00
|
|
|
{
|
2023-10-30 22:36:18 +01:00
|
|
|
if(!$value)
|
|
|
|
$value = $this->id;
|
2023-10-29 17:37:28 +01:00
|
|
|
if($field!='id')
|
|
|
|
{
|
|
|
|
//sanity check. Check if $field is marked as unique
|
|
|
|
if(!in_array('unique',$this->dbFields[$field]))
|
|
|
|
throw new Exception($field.' is not unique');
|
|
|
|
//we need to find the id first
|
|
|
|
$keys = $GLOBALS['redis']->keys($this->dbTable.':*');
|
|
|
|
foreach($keys as $key){
|
|
|
|
$id = end(explode(':',$key));
|
|
|
|
$thisval = $GLOBALS['redis']->hget($this->dbTable.':'.$id,$field);
|
|
|
|
if($thisval==$value)
|
|
|
|
{
|
|
|
|
$this->id = $id;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
$this->id = $value;
|
2023-10-22 23:05:24 +02:00
|
|
|
if(!$GLOBALS['redis']->exists($this->dbTable.':'.$this->id))
|
2023-10-23 10:00:19 +02:00
|
|
|
throw new Exception($this->dbTable.':'.$this->id.' not found');
|
2023-10-22 01:46:22 +02:00
|
|
|
$keys = array_keys($this->dbFields);
|
|
|
|
|
|
|
|
foreach($keys as $key)
|
|
|
|
{
|
2023-10-22 23:05:24 +02:00
|
|
|
$value = $GLOBALS['redis']->hget($this->dbTable.':'.$this->id,$key);
|
2023-10-22 01:46:22 +02:00
|
|
|
|
2023-10-30 23:13:44 +01:00
|
|
|
//var_dump("BEFORE[".$this->dbTable.':'.$this->id."] Loading from DB $key: '$value'");
|
2023-10-30 22:57:31 +01:00
|
|
|
|
2023-10-29 17:37:28 +01:00
|
|
|
if($value!==NULL) //we'll leave null values alone
|
2023-10-22 23:05:24 +02:00
|
|
|
switch($this->dbFields[$key]['type'])
|
|
|
|
{
|
|
|
|
case 'int': $value = intval($value);break;
|
|
|
|
case 'bool': $value = boolval($value);break;
|
|
|
|
case 'float': $value = floatval($value);break;
|
|
|
|
case 'double': $value = doubleval($value);break;
|
|
|
|
case 'array':
|
2023-10-29 09:16:10 +01:00
|
|
|
if(!$value)
|
2023-10-22 23:05:24 +02:00
|
|
|
$value = [];
|
2023-10-29 09:16:10 +01:00
|
|
|
else if(is_string($value))
|
|
|
|
$value = json_decode($value,true);
|
2023-10-22 23:05:24 +02:00
|
|
|
break;
|
|
|
|
}
|
2023-10-30 23:13:44 +01:00
|
|
|
//var_dump("AFTER[".$this->dbTable.':'.$this->id."] Loading from DB $key: '$value'");
|
2023-10-22 01:46:22 +02:00
|
|
|
$this->data[$key] = $value;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param array $data
|
|
|
|
*/
|
2023-10-30 23:30:23 +01:00
|
|
|
private function validate($newgen=false)
|
2023-10-22 01:46:22 +02:00
|
|
|
{
|
|
|
|
if (!$this->dbFields)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
$data = $this->data;
|
|
|
|
|
|
|
|
foreach ($this->dbFields as $key => $options) {
|
|
|
|
$type = null;
|
|
|
|
$required = false;
|
|
|
|
|
|
|
|
if(in_array('autoupdate',$options))
|
|
|
|
$this->data[$key] = NULL;
|
|
|
|
|
|
|
|
if (isset($data[$key]))
|
|
|
|
$value = $data[$key];
|
|
|
|
else
|
|
|
|
$value = null;
|
|
|
|
|
|
|
|
if (is_array($value))
|
|
|
|
continue;
|
|
|
|
|
2023-10-26 17:50:54 +02:00
|
|
|
// if (isset($desc[0]))
|
|
|
|
// $type = $desc[0];
|
2023-10-22 01:46:22 +02:00
|
|
|
if (in_array('required',$options))
|
|
|
|
$required = true;
|
|
|
|
|
|
|
|
if($value===null && $options['autoValMethod'])
|
|
|
|
{
|
|
|
|
if(method_exists($this,$options['autoValMethod']))
|
|
|
|
$value = $this->{$options['autoValMethod']}();
|
|
|
|
else if(function_exists($options['autoValMethod']))
|
|
|
|
$value = $options['autoValMethod']();
|
|
|
|
else
|
|
|
|
$value = null;
|
|
|
|
$this->data[$key] = $value;
|
|
|
|
}
|
|
|
|
|
2023-10-30 23:36:56 +01:00
|
|
|
if($options['default']!==null && $newgen === true && $value===null)
|
2023-10-26 17:50:54 +02:00
|
|
|
{
|
2023-10-22 01:46:22 +02:00
|
|
|
$value = $options['default'];
|
2023-10-26 17:50:54 +02:00
|
|
|
$this->data[$key] = $value;
|
|
|
|
}
|
2023-10-22 01:46:22 +02:00
|
|
|
|
|
|
|
if ($required && strlen($value) == 0) {
|
2023-10-30 23:33:22 +01:00
|
|
|
throw new Exception($this->dbTable . "." . $key . " is required but is set to '$value'");
|
2023-10-22 01:46:22 +02:00
|
|
|
}
|
|
|
|
if ($value == null)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
switch ($type) {
|
|
|
|
case 'email':
|
|
|
|
$regexp = null;
|
|
|
|
if (!filter_var($value, FILTER_VALIDATE_EMAIL)) {
|
|
|
|
throw new Exception("$type validation failed");
|
|
|
|
}
|
|
|
|
break;
|
2023-10-22 23:05:24 +02:00
|
|
|
case 'array':
|
|
|
|
if(!is_array($value))
|
|
|
|
throw new Exception('Dogs validation failed');
|
|
|
|
break;
|
2023-10-22 01:46:22 +02:00
|
|
|
case 'csv':
|
|
|
|
case "text":
|
|
|
|
$regexp = null;
|
|
|
|
break;
|
|
|
|
case "int":
|
|
|
|
$regexp = "/^[0-9]*$/";
|
|
|
|
break;
|
|
|
|
case "double":
|
|
|
|
$regexp = "/^[0-9\.]*$/";
|
|
|
|
break;
|
|
|
|
case "bool":
|
|
|
|
$regexp = '/^(yes|no|0|1|true|false)$/i';
|
|
|
|
break;
|
|
|
|
case "datetime":
|
|
|
|
$regexp = "/^[0-9a-zA-Z -:]*$/";
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
$regexp = $type;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (!$regexp)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (!preg_match($regexp, $value)) {
|
|
|
|
throw new Exception("$type validation failed");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2023-10-23 14:36:28 +02:00
|
|
|
function exists($id)
|
|
|
|
{
|
|
|
|
return $GLOBALS['redis']->exists($this->dbTable.':'.$id);
|
|
|
|
}
|
|
|
|
|
2023-10-22 01:46:22 +02:00
|
|
|
function delete()
|
|
|
|
{
|
2023-10-22 23:05:24 +02:00
|
|
|
return $GLOBALS['redis']->del($this->dbTable.':'.$this->id);
|
2023-10-22 01:46:22 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
function gen_shorthash(){
|
|
|
|
return substr(uniqid(),-7);
|
|
|
|
}
|
|
|
|
|
|
|
|
function getDateTime($time=false)
|
|
|
|
{
|
|
|
|
return date('Y-m-d H:i:s',($time?$time:time()));
|
|
|
|
}
|
|
|
|
}
|