379 lines
9.9 KiB
PHP
379 lines
9.9 KiB
PHP
<?php
|
|
|
|
/**
|
|
* Does most of the dirty work in getting Database entries into
|
|
* an object.
|
|
* Takes an ID, or FronkDB table row for automatic loading
|
|
* @param optional ID or table row $_
|
|
* @author fronk
|
|
*/
|
|
|
|
if(!defined("FRONKDB")) {
|
|
define("FRONKDB", true);
|
|
}
|
|
|
|
class mfBaseModel {
|
|
public $id;
|
|
public $data;
|
|
public $_old_data;
|
|
protected $create;
|
|
protected $edit;
|
|
private $worker;
|
|
protected $forcestr;
|
|
|
|
protected $mode = "new";
|
|
protected $saved = 0;
|
|
protected $db;
|
|
protected $log;
|
|
protected $table = false;
|
|
protected $fieldprefix = false;
|
|
|
|
/**
|
|
* Takes ID or DB row as arguments
|
|
* @param id or table row $_
|
|
*/
|
|
public function __construct($_ = NULL, $new_db_connection = false) {
|
|
$this->log = mfLoghandler::singleton();
|
|
$this->table = get_class($this);
|
|
$this->data = new stdClass();
|
|
$this->_old_data = new stdClass();
|
|
|
|
if(defined("MFMODEL_USEFIELDPREFIX") && MFMODEL_USEFIELDPREFIX == true) {
|
|
$this->prefixfields = true;
|
|
}
|
|
|
|
$this->data = new stdClass();
|
|
|
|
if(FRONKDB) {
|
|
$this->db = FronkDB::singleton();
|
|
if($new_db_connection) {
|
|
$this->db->reconnect();
|
|
}
|
|
}
|
|
|
|
if(method_exists($this, "init")) {
|
|
$this->init($_);
|
|
}
|
|
|
|
if(is_numeric($_)) {
|
|
$this->fetch($_);
|
|
} elseif(is_object($_)) {
|
|
$this->load($_);
|
|
}
|
|
}
|
|
|
|
public function reconnectDB() {
|
|
$this->db->reconnect();
|
|
}
|
|
|
|
public function load($row) {
|
|
if(!is_object($this->data)) {
|
|
$this->data = new stdClass();
|
|
}
|
|
|
|
foreach($row as $field => $value) {
|
|
if($this->fieldprefix) {
|
|
if(preg_match('/^' . $this->fieldprefix . '_(.+)$/', $field, $m)) {
|
|
$field = $m[1];
|
|
}
|
|
}
|
|
if($field == "id"
|
|
|| $field == "create"
|
|
|| $field == "edit") continue;
|
|
$this->data->$field = $value;
|
|
}
|
|
|
|
$this->id = $row->id;
|
|
|
|
if(!property_exists($row, "create")) {
|
|
$row->create = date("U");
|
|
}
|
|
if(!property_exists($row, "edit")) {
|
|
$row->edit = date("U");
|
|
}
|
|
|
|
$this->create = $row->create;
|
|
$this->edit = $row->edit;
|
|
if($this->fieldprefix) {
|
|
$prop = $this->fieldprefix . "_id";
|
|
$this->id = $row->$prop;
|
|
}
|
|
|
|
$this->_old_data = clone($this->data);
|
|
$this->_old_data->id = $this->id;
|
|
$this->_old_data->create = $this->create;
|
|
$this->_old_data->edit = $this->edit;
|
|
|
|
$this->mode = "update";
|
|
|
|
if(method_exists($this, "afterLoad")) {
|
|
$this->afterLoad();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public function fetch($id) {
|
|
$where = "id=$id";
|
|
if($this->fieldprefix) {
|
|
$where = $this->fieldprefix . "_id=$id";
|
|
}
|
|
|
|
$res = $this->db->select($this->table, "*", "$where");
|
|
if($this->db->num_rows($res)) {
|
|
$data = $this->db->fetch_object($res);
|
|
$this->load($data);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public function update(array $data) {
|
|
if(method_exists($this, "beforeUpdate")) {
|
|
$data = $this->beforeUpdate($data);
|
|
}
|
|
|
|
foreach($data as $key => $value) {
|
|
if($value === null) {
|
|
$this->$key = null;
|
|
} else {
|
|
$this->$key = $value;
|
|
}
|
|
}
|
|
|
|
if(method_exists($this, "afterUpdate")) {
|
|
$this->afterUpdate($data);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public function save() {
|
|
if(method_exists($this, "beforeSave")) {
|
|
$this->beforeSave();
|
|
}
|
|
$fields = $this->buildFields();
|
|
|
|
$forcestr = array();
|
|
|
|
if(!$this->fieldprefix && is_array($this->forcestr) && count($this->forcestr)) {
|
|
$forcestr = $this->forcestr;
|
|
}
|
|
|
|
if(is_array($this->forcestr) && count($this->forcestr)) {
|
|
foreach($this->forcestr as $fstr) {
|
|
$forcestr[] = $this->fieldprefix . "_$fstr";
|
|
}
|
|
}
|
|
|
|
if(!is_array($fields) or !count($fields)) {
|
|
return false;
|
|
}
|
|
|
|
if($this->id) {
|
|
$id = $this->id;
|
|
$where = "`id`=$id";
|
|
if($this->fieldprefix) {
|
|
$where = "`" . $this->fieldprefix . "_id`=$id";
|
|
}
|
|
if($this->db->update($this->table, $fields, $where, $forcestr)) {
|
|
$this->saved++;
|
|
if(method_exists($this, "afterSave")) {
|
|
$this->afterSave();
|
|
}
|
|
return $id;
|
|
}
|
|
} else {
|
|
if($this->db->insert($this->table, $fields, $forcestr)) {
|
|
$id = mysqli_insert_id($this->db->link);
|
|
$this->id = $id;
|
|
$this->saved++;
|
|
if(method_exists($this, "afterSave")) {
|
|
$this->afterSave();
|
|
}
|
|
return $id;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
protected function buildFields() {
|
|
$fields = array();
|
|
foreach($this->data as $field => $value) {
|
|
if($this->fieldprefix && !strstr($field, "_")) {
|
|
$field = $this->fieldprefix . "_$field";
|
|
}
|
|
$fields[$field] = $value;
|
|
}
|
|
|
|
if(!$this->create) {
|
|
$this->create = date('U');
|
|
}
|
|
$this->edit = date('U');
|
|
|
|
foreach(array("create", "edit") as $f) {
|
|
$fields[$f] = $this->$f;
|
|
}
|
|
|
|
if(method_exists($this, "afterBuildFields")) {
|
|
$fields = $this->afterBuildFields($fields);
|
|
}
|
|
|
|
return $fields;
|
|
}
|
|
|
|
public function delete() {
|
|
if($this->id) {
|
|
$id = $this->id;
|
|
$where = "id=$id";
|
|
if($this->fieldprefix && !strstr($field, "_")) {
|
|
$where = $this->fieldprefix . "_id=$id";
|
|
}
|
|
if(method_exists($this, "beforeDelete")) {
|
|
// delete can be canceled
|
|
if(!$this->beforeDelete()) {
|
|
return false;
|
|
}
|
|
}
|
|
if($this->db->delete($this->table, $where)) {
|
|
if(method_exists($this, "afterDelete")) {
|
|
$this->afterDelete();
|
|
}
|
|
$this->data = new stdClass();
|
|
$this->id = "";
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
protected function getChangedFields($include_system = false) {
|
|
if(!is_object($this->_old_data) || !property_exists($this->_old_data, "id") || !$this->_old_data->id) return [];
|
|
|
|
if(!is_object($this->data) || !is_object($this->_old_data)) {
|
|
return [];
|
|
}
|
|
|
|
$changes = [];
|
|
|
|
foreach($this->data as $field => $value) {
|
|
if(!$include_system && in_array($field, ["id", "create_by", "edit_by", "create", "edit"])) continue;
|
|
if(is_object($value)) continue;
|
|
|
|
if(!property_exists($this->_old_data, $field)) {
|
|
$changes[] = $field;
|
|
continue;
|
|
}
|
|
if($value != $this->_old_data->$field) {
|
|
$changes[] = $field;
|
|
}
|
|
}
|
|
|
|
foreach($this->_old_data as $field => $value) {
|
|
if(!$include_system && in_array($field, ["id", "create_by", "edit_by", "create", "edit"])) continue;
|
|
if(is_object($value)) continue;
|
|
|
|
if(in_array($field, $changes)) {
|
|
continue;
|
|
}
|
|
if(!property_exists($this->data, $field)) {
|
|
$changes[] = $field;
|
|
continue;
|
|
}
|
|
|
|
if($value != $this->data->$field) {
|
|
$changes[] = $field;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
return $changes;
|
|
}
|
|
|
|
public function new() {
|
|
if($this->mode == "new" && $this->saved <= 1) {
|
|
return "new";
|
|
} else {
|
|
return "update";
|
|
}
|
|
}
|
|
|
|
public function startTransaction() {
|
|
$this->db->query("START TRANSACTION");
|
|
}
|
|
|
|
public function commitTransaction() {
|
|
$this->db->query("COMMIT");
|
|
}
|
|
|
|
public function rollbackTransaction() {
|
|
$this->db->query("ROLLBACK");
|
|
}
|
|
|
|
// generic functions for entity-classes
|
|
public function toArray() {
|
|
if(!$this->id) {
|
|
return [];
|
|
}
|
|
|
|
$item = [];
|
|
$item['id'] = $this->id;
|
|
foreach($this->data as $key => $value) {
|
|
$item[$key] = $value;
|
|
}
|
|
|
|
return $item;
|
|
}
|
|
|
|
|
|
public function __toString() {
|
|
return (string)$this->data->Name;
|
|
}
|
|
|
|
public function __get($name) {
|
|
if($name == "create" || $name == "edit") {
|
|
if(isset($this->data->$name)) {
|
|
return $this->data->$name;
|
|
} else {
|
|
return $this->$name;
|
|
}
|
|
}
|
|
|
|
|
|
if(isset($this->data->$name)) {
|
|
return $this->data->$name;
|
|
} elseif(property_exists($this, $name)) {
|
|
if(method_exists($this, "getProperty")) {
|
|
$prop = $this->getProperty($name);
|
|
if($prop === null) {
|
|
return null;
|
|
}
|
|
return $prop;
|
|
} else {
|
|
return $this->$name;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public function __set($name, $value) {
|
|
if($name == "create") {
|
|
$this->create = intval($value);
|
|
}
|
|
$this->data->$name = $value;
|
|
return true;
|
|
}
|
|
|
|
public function __unset($name) {
|
|
unset($this->data->$name);
|
|
}
|
|
|
|
public function __debugInfo() {
|
|
$vars = get_object_vars($this);
|
|
if(is_object($vars['db'])) $vars['db'] = "object(FronkDB)";
|
|
if(is_object($vars['log'])) $vars['log'] = 'object(mfLoghandler)';
|
|
return $vars;
|
|
}
|
|
}
|