<?php
namespace Empire\Core;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\DBALException;
use Doctrine\DBAL\FetchMode;
abstract class AbstractEntity implements Entity {
public static $CACHE;
public $id;
public $type;
public function __construct($initialize = false) {
if($initialize)
$this->initialize();
}
/**
* @param int[] $ids
* @param bool $forceArray
* @param bool $cache
* @return static[]|static
*/
static function load(array $ids, $forceArray=false, $cache = true) {
if(count($ids) < 1) {
return $forceArray ? [] : null;
}
$class = get_called_class();
if($cache && count($ids) == 1 && isset(self::$CACHE[$class][$ids[0]])) {
$res = [self::$CACHE[$class][$ids[0]]];
} else {
/** @var static $temp */
$temp = new $class;
try {
$stmt = Core::db()->executeQuery(sprintf("SELECT * FROM %s WHERE %s IN (?)", $temp->getTable(), $temp->getPrimaryField()),
[$ids],
[Connection::PARAM_INT_ARRAY]);
} catch (DBALException $e) {
return $forceArray ? [] : null;
}
/** @var AbstractEntity[] $res */
$res = $stmt->fetchAll(FetchMode::CUSTOM_OBJECT, $class, [true]);
foreach ($res as $r) $r->initialize(); // This is necessary when not using Empire\Legacy\db, because the constructor isn't always called.
if($cache && count($ids) == 1) {
self::$CACHE[$class][$res[0]->id] = $res[0];
}
}
if(isset($res[1]) || $forceArray == true) {
return $res;
}
return array_shift($res);
}
function getID(){
return $this->id;
}
function uid($separator = ':'){
return (int)($this->type) . $separator . (int)($this->id);
}
/**
* @param static $other
* @return bool
*/
function is($other){
if(!$other){
return false;
}
return $this->uid() == $other->uid();
}
/**
* @param array $fields
* @return int|bool
* @throws DBALException
*/
function updateFields(array $fields = array()) {
return Core::db()->update($this->getTable(), $fields, [$this->getPrimaryField() => $this->getID()]);
}
function refresh() {
/** @var static $class */
$class = get_called_class();
$new = $class::load([$this->getID()], false, false);
//delete everything from the old object
foreach($this as $key => $value){
unset($this->$key);
}
//and set it again from our new object
foreach($new as $key => $value){
$this->$key = $value;
}
return $this;
}
/**
* Function to delete by unique ID.
*
* Can be overwritten in the child classes to provide for more checking
* (child units, etc)
*/
function delete() {
Core::db()->executeQuery( sprintf("DELETE FROM %s WHERE %s = ?", $this->getTable(), $this->getPrimaryField()), [$this->getID()]);
$this->isDeleted = true;
return true;
}
}