This commit is contained in:
2019-09-13 17:32:42 -03:00
parent 7e565657f1
commit 2f3de1145a
5 changed files with 527 additions and 0 deletions

253
common/Factory/Model.php Normal file
View File

@ -0,0 +1,253 @@
<?php
namespace Aldarien\Common\Factory;
use Psr\Container\ContainerInterface;
use \ORM as ORM;
use \Model as BaseFactory;
class Model {
protected $container;
public function __construct(ContainerInterface $container) {
$this->container = $container;
}
public function reset() {
foreach ($this as $property => $value) {
if ($property == 'container') {
continue;
}
$this->$property = null;
}
}
protected $class;
public function find(string $model_class): Model {
$this->reset();
if (!class_exists($model_class)) {
throw new \InvalidArgumentException($model_class . ' not found.');
}
$this->class = $model_class;
return $this;
}
protected $columns;
public function select($columns): Model {
if ($this->columns == null) {
$this->columns = [];
}
if (!is_array($columns)) {
$columns = [$columns];
}
$this->columns = array_merge($this->columns, $columns);
return $this;
}
protected function parseSelect(ORM $orm): ORM {
if ($this->columns == null or count($this->columns) == 0) {
return $orm;
}
foreach ($this->columns as $column => $alias) {
if (is_numeric($column)) {
$orm = $orm->select($alias);
continue;
}
$orm = $orm->select($column, $alias);
}
return $orm;
}
protected $joins;
public function join(array $joins): Model {
if ($this->joins == null) {
$this->joins = [];
}
$this->joins = array_merge($this->joins, $joins);
return $this;
}
public function parseJoin(ORM $orm): ORM {
if ($this->joins == null or count($this->joins) == 0) {
return $orm;
}
foreach ($this->joins as $join) {
$method = 'join';
if (isset($join['type'])) {
switch (strtolower($join['type'])) {
case 'left':
$method = 'leftOuterJoin';
break;
case 'right':
$method = 'rightOuterJoin';
break;
case 'raw':
$method = 'rawJoin';
break;
}
}
$table = $join[0];
if (isset($join['table'])) {
$table = $join['table'];
}
$field1 = $join[1];
if (isset($join['field1'])) {
$field1 = $join['field1'];
}
$op = '=';
if (isset($join['operator'])) {
$op = $join['operator'];
}
$field2 = $join[2];
if (isset($join['field2'])) {
$field2 = $join['field2'];
}
$alias = null;
if (isset($join['alias'])) {
$alias = $join['alias'];
}
$orm = $orm->{$method}($table, [$field1, $op, $field2], $alias);
}
return $orm;
}
protected $conditions;
public function where(array $conditions): Model {
if ($this->conditions == null) {
$this->conditions = [];
}
$this->conditions = array_merge($this->conditions, $conditions);
return $this;
}
protected function parseWhere(ORM $orm): ORM {
if ($this->conditions == null or count($this->conditions) == 0) {
return $orm;
}
foreach ($this->conditions as $condition) {
$method = 'where';
$op = '=';
if (isset($condition[2])) {
$op = strtolower($condition[2]);
}
if (isset($condition['operator'])) {
$op = strtolower($condition['operator']);
}
$mod = ['=' => '', '>' => 'Gt', '>=' => 'Gte', '<' => 'Lt', '<=', 'Lte'];
if (isset($mod[$op])) {
$method .= $mod[$op];
} else {
switch ($op) {
case 'raw':
$method = 'rawWhere';
break;
}
}
$column = $condition[0];
if (isset($condition['column'])) {
$column = $condition['column'];
}
$value = $condition[1];
if (isset($condition['value'])) {
$value = $condition['value'];
}
$orm = $orm->{$method}($column, $value);
}
return $orm;
}
protected $ordering;
public function order($orders): Model {
if ($this->ordering == null) {
$this->ordering = [];
}
if (!is_array($orders)) {
$orders = [$orders];
}
$this->ordering = array_merge($this->ordering, $orders);
return $this;
}
protected function parseOrder(ORM $orm): ORM {
if ($this->ordering == null or count($this->ordering) == 0) {
return $orm;
}
foreach ($this->ordering as $order => $dir) {
if (is_numeric($order)) {
$order = $dir;
$dir = 'asc';
}
$method = 'orderBy' . ucfirst(strtolower($dir));
$orm = $orm->{$method}($order);
}
return $orm;
}
protected $grouping;
public function group($groups): Model {
if ($this->grouping == null) {
$this->grouping = [];
}
if (!is_array($groups)) {
$groups = [$groups];
}
$this->grouping = array_merge($this->grouping, $groups);
return $this;
}
protected function parseGroup(ORM $orm): ORM {
if ($this->grouping == null or count($this->grouping) == 0) {
return $orm;
}
foreach ($this->grouping as $group) {
$orm = $orm->groupBy($group);
}
return $orm;
}
protected $limits;
public function limit(int $limit, int $offset = 0): Model {
$this->limits = (object) ['limit' => $limit, 'offset' => $offset];
return $this;
}
protected function parseLimit(ORM $orm): ORM {
if ($this->limits == null) {
return $orm;
}
$orm = $orm->limit($this->limits->limit);
if ($this->limits->offset > 0) {
$orm = $orm->offset($this->limits->offset);
}
return $orm;
}
public function build(): ORM {
$orm = BaseFactory::factory($this->class);
$methods = ['select', 'join', 'where', 'order', 'group', 'limit'];
foreach ($methods as $m) {
$method = 'parse' . ucfirst($m);
$orm = $this->{$method}($orm);
}
return $orm;
}
public function one($key = null) {
$model = $this->build()->findOne($key);
if ($model === false) {
return false;
}
$model->setContainer($this->container);
return $model;
}
public function many(): array {
$models = $this->build()->findMany();
array_walk($models, function(&$item, $key, $container) {
$item->setContainer($container);
}, $this->container);
return $models;
}
public function array(): array {
$models = $this->many();
return array_map(function($item) {
return $item->toArray();
}, $models);
}
public function create(string $model_class, array $data) {
$factory = new Model($this->container);
$where = [];
foreach ($data as $column => $condition) {
$where []= [$column, $condition];
}
$obj = $factory->find($model_class)->where($where)->one();
if ($obj === false) {
$obj = BaseFactory::factory($model_class)->create($data);
$obj->save();
$obj->setContainer($this->container);
}
return $obj;
}
}