Files
models/common/Alias/Model.php
2020-01-21 14:58:52 -03:00

155 lines
5.9 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;
abstract 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();
}
public function setRelationship(string $class_name, string $relation_key, string $self_key): Relationship {
return (new Relationship)
->setFactory($this->container->get('model'))
->setStart($class_name)
->with($class_name, $relation_key, get_called_class(), $self_key)
->setCondition(get_called_class(), $self_key, $this->$self_key);
}
}