This repository has been archived on 2023-12-29. You can view files and clone it, but cannot push or open issues or pull requests.
dogstats/web/inc/classes/Model.class.php
Chris 6aed7dd976
All checks were successful
Build and push / Pulling repo on server (push) Successful in 3s
test
2023-10-30 23:33:22 +01:00

264 lines
7.7 KiB
PHP

<?php
class Model {
public $data;
public $id = false;
public $redis;
function __construct()
{
//redis
if ($GLOBALS['redis'])
$GLOBALS['redis'] = $GLOBALS['redis'];
}
/**
* 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;
}
public function getField($field,$id=false)
{
if(!$id)
$id = $this->id;
return $GLOBALS['redis']->hget($this->dbTable.':'.$id,$field);
}
public function save()
{
$newgen = false;
if (!$this->id)
{
$this->id = gen_ulid();
$newgen = true;
}
if (!$this->validate($newgen))
return false;
foreach($this->dbFields as $field=>$options)
{
if(isset($this->data[$field]))
{
if($options['type']=='array' && is_array($this->data[$field]))
$GLOBALS['redis']->hset($this->dbTable.':'.$this->id,$field,json_encode($this->data[$field]));
else if($options['type']=='array' && !is_array($this->data[$field]))
$GLOBALS['redis']->hset($this->dbTable.':'.$this->id,$field,json_encode([]));
else
{
$GLOBALS['redis']->hset($this->dbTable.':'.$this->id,$field,$this->data[$field]);
}
}
}
return $this->id;
}
/**
* @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
*/
public function load($value=false,$field='id')
{
if(!$value)
$value = $this->id;
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;
if(!$GLOBALS['redis']->exists($this->dbTable.':'.$this->id))
throw new Exception($this->dbTable.':'.$this->id.' not found');
$keys = array_keys($this->dbFields);
foreach($keys as $key)
{
$value = $GLOBALS['redis']->hget($this->dbTable.':'.$this->id,$key);
//var_dump("BEFORE[".$this->dbTable.':'.$this->id."] Loading from DB $key: '$value'");
if($value!==NULL) //we'll leave null values alone
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':
if(!$value)
$value = [];
else if(is_string($value))
$value = json_decode($value,true);
break;
}
//var_dump("AFTER[".$this->dbTable.':'.$this->id."] Loading from DB $key: '$value'");
$this->data[$key] = $value;
}
return true;
}
/**
* @param array $data
*/
private function validate($newgen=false)
{
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;
// if (isset($desc[0]))
// $type = $desc[0];
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;
}
if($options['default']!==null && $newgen === true && !$value)
{
$value = $options['default'];
$this->data[$key] = $value;
}
if ($required && strlen($value) == 0) {
throw new Exception($this->dbTable . "." . $key . " is required but is set to '$value'");
}
if ($value == null)
continue;
switch ($type) {
case 'email':
$regexp = null;
if (!filter_var($value, FILTER_VALIDATE_EMAIL)) {
throw new Exception("$type validation failed");
}
break;
case 'array':
if(!is_array($value))
throw new Exception('Dogs validation failed');
break;
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;
}
function exists($id)
{
return $GLOBALS['redis']->exists($this->dbTable.':'.$id);
}
function delete()
{
return $GLOBALS['redis']->del($this->dbTable.':'.$this->id);
}
function gen_shorthash(){
return substr(uniqid(),-7);
}
function getDateTime($time=false)
{
return date('Y-m-d H:i:s',($time?$time:time()));
}
}