254 lines
6.7 KiB
PHP
254 lines
6.7 KiB
PHP
<?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;
|
|
}
|
|
}
|