147 lines
5.6 KiB
PHP
147 lines
5.6 KiB
PHP
|
<?php
|
||
|
namespace Aldarien\Common\Alias;
|
||
|
|
||
|
use Psr\Container\ContainerInterface;
|
||
|
use \ORM as ORM;
|
||
|
use \Model as BaseModel;
|
||
|
use Aldarien\Common\Definition\Model as ModelInterface;
|
||
|
use Aldarien\Common\Factory\Model as ModelFactory;
|
||
|
|
||
|
class Model extends BaseModel implements ModelInterface {
|
||
|
const CHILD_KEY = 'child_key';
|
||
|
const PARENT_KEY = 'parent_key';
|
||
|
const SELF_KEY = 'self_key';
|
||
|
const SELF_THROUGH_KEY = 'self_through_key';
|
||
|
const SIBLING_THROUGH_KEY = 'sibling_through_key';
|
||
|
const SIBLING_KEY = 'sibling_key';
|
||
|
|
||
|
public static function getTable(string $model_class): string {
|
||
|
return self::_get_table_name($model_class);
|
||
|
}
|
||
|
protected $container;
|
||
|
public function setContainer(ContainerInterface $container): ModelInterface {
|
||
|
$this->container = $container;
|
||
|
return $this;
|
||
|
}
|
||
|
public function save() {
|
||
|
$pdo = ORM::getDb();
|
||
|
$pdo->beginTransaction();
|
||
|
try {
|
||
|
$result = parent::save();
|
||
|
$pdo->commit();
|
||
|
return $result;
|
||
|
} catch (\Exception $e) {
|
||
|
$pdo->rollBack();
|
||
|
throw $e;
|
||
|
}
|
||
|
}
|
||
|
const KEY_EXCEPTION = 'Exception';
|
||
|
protected function parseKeys(string $called_function, array $definitions, array $defaults) {
|
||
|
foreach ($defaults as $key => $value) {
|
||
|
if (!isset($definitions[$key])) {
|
||
|
if ($value == self::KEY_EXCEPTION) {
|
||
|
throw new \InvalidArgumentException("Missing '" . $key . "' in '" . $called_function . "' for " . get_called_class());
|
||
|
}
|
||
|
$definitions[$key] = $value;
|
||
|
}
|
||
|
}
|
||
|
return (object) $definitions;
|
||
|
}
|
||
|
protected function validateVar(string $var) {
|
||
|
if (!isset($this->$var)) {
|
||
|
throw new \Exception("'" . $var . "' not found in '" . get_called_class() . "'.");
|
||
|
}
|
||
|
}
|
||
|
public function childOf(string $parent_class, array $id_definitions, $var = '') {
|
||
|
$id_definitions = $this->parseKeys('childOf', $id_definitions, [self::SELF_KEY => self::KEY_EXCEPTION, self::PARENT_KEY => 'id']);
|
||
|
if ($var == '') {
|
||
|
return $this->container->model->find($parent_class)
|
||
|
->where([[$id_definitions->parent_key, $this->{$id_definitions->self_key}]])
|
||
|
->one();
|
||
|
}
|
||
|
$this->validateVar($var);
|
||
|
if ($this->$var == null) {
|
||
|
$this->$var = $this->container->model->find($parent_class)
|
||
|
->where([[$id_definitions->parent_key, $this->{$id_definitions->self_key}]])
|
||
|
->one();
|
||
|
}
|
||
|
return $this->$var;
|
||
|
}
|
||
|
public function parentOf(string $child_class, array $id_definitions, $var = ''): ModelFactory {
|
||
|
$id_definitions = $this->parseKeys('parentOf', $id_definitions, [self::SELF_KEY => 'id', self::CHILD_KEY => self::KEY_EXCEPTION]);
|
||
|
if ($var == '') {
|
||
|
return $this->container->model->find($child_class)
|
||
|
->where([[$id_definitions->child_key, $this->{$id_definitions->self_key}]]);
|
||
|
}
|
||
|
$this->validateVar($var);
|
||
|
if ($this->$var == null) {
|
||
|
$this->$var = $this->container->model->find($child_class)
|
||
|
->where([[$id_definitions->child_key, $this->{$id_definitions->self_key}]]);
|
||
|
}
|
||
|
return $this->$var;
|
||
|
}
|
||
|
public function parentOfOne(string $child_class, array $id_definitions, $var = '') {
|
||
|
$factory = $this->parentOf($child_class, $id_definitions, $var);
|
||
|
return $factory->one();
|
||
|
}
|
||
|
public function parentOfMany(string $child_class, array $id_definitions, $var = '') {
|
||
|
$factory = $this->parentOf($child_class, $id_definitions, $var);
|
||
|
return $factory->many();
|
||
|
}
|
||
|
public function siblingOf(string $sibling_class, string $table_through, array $id_definitions, $var = ''): ModelFactory {
|
||
|
$id_definitions = $this->parseKeys('siblingOf', $id_definitions, [
|
||
|
self::SIBLING_THROUGH_KEY => self::KEY_EXCEPTION,
|
||
|
self::SIBLING_KEY => 'id',
|
||
|
self::SELF_THROUGH_KEY => self::KEY_EXCEPTION,
|
||
|
self::SELF_KEY => 'id'
|
||
|
]);
|
||
|
$sibling_table = self::getTable($sibling_class);
|
||
|
if ($var == '') {
|
||
|
return $this->container->model->find($sibling_class)
|
||
|
->select($sibling_table . '.*')
|
||
|
->join([
|
||
|
[$table_through, $table_through . '.' . $id_definitions->sibling_through_key, $sibling_table . '.' . $id_definitions->sibling_key]
|
||
|
])
|
||
|
->where([[$table_through . '.' . $id_definitions->self_through_key, $this->{$id_definitions->self_key}]]);
|
||
|
}
|
||
|
$this->validateVar($var);
|
||
|
if ($this->$var == null) {
|
||
|
$this->$var = $this->container->model->find($sibling_class)
|
||
|
->select($sibling_table . '.*')
|
||
|
->join([
|
||
|
[$table_through, $table_through . '.' . $id_definitions->sibling_through_key, $sibling_table . '.' . $id_definitions->sibling_key]
|
||
|
])
|
||
|
->where([[$table_through . '.' . $id_definitions->self_through_key, $this->{$id_definitions->self_key}]]);
|
||
|
}
|
||
|
return $this->$var;
|
||
|
}
|
||
|
public function siblingOfOne(string $sibling_class, string $table_through, array $id_definitions, $var = '') {
|
||
|
$factory = $this->siblingOf($sibling_class, $table_through, $id_definitions, $var);
|
||
|
if ($var == '') {
|
||
|
return $factory->one();
|
||
|
}
|
||
|
$this->validateVar($var);
|
||
|
if (!is_a($this->$var, $sibling_class)) {
|
||
|
$this->$var = $factory->one();
|
||
|
}
|
||
|
return $this->$var;
|
||
|
}
|
||
|
public function siblingOfMany(string $sibling_class, string $table_through, array $id_definitions, $var = '') {
|
||
|
$factory = $this->siblingOf($sibling_class, $table_through, $id_definitions, $var);
|
||
|
if ($var == '') {
|
||
|
return $factory->many();
|
||
|
}
|
||
|
$this->validateVar($var);
|
||
|
if (!is_a($this->$var, $sibling_class)) {
|
||
|
$this->$var = $factory->many();
|
||
|
}
|
||
|
return $this->$var;
|
||
|
}
|
||
|
public function toArray(): array {
|
||
|
return $this->asArray();
|
||
|
}
|
||
|
public function jsonSerialize() {
|
||
|
return $this->toArray();
|
||
|
}
|
||
|
}
|