205 lines
4.6 KiB
PHP
205 lines
4.6 KiB
PHP
<?php
|
|
namespace App\Service;
|
|
|
|
use Stringy\Stringy;
|
|
|
|
class Factory
|
|
{
|
|
protected $class;
|
|
protected $is_aggregator;
|
|
public function __construct($class)
|
|
{
|
|
$this->class = $class;
|
|
$this->is_aggregator = true;
|
|
if (is_subclass_of($class, 'Model')) {
|
|
$this->is_aggregator = false;
|
|
}
|
|
}
|
|
public function new()
|
|
{
|
|
$class = $this->class;
|
|
if ($this->is_aggregator) {
|
|
return new $class();
|
|
}
|
|
return model($class)->create();
|
|
}
|
|
public function create($data)
|
|
{
|
|
$class = $this->class;
|
|
if ($this->is_aggregator) {
|
|
$obj = new $class();
|
|
$obj->create($data);
|
|
return $obj;
|
|
}
|
|
return model($class)->create($data);
|
|
}
|
|
/**
|
|
* [column => value, column => [value, operator]]
|
|
* @var array
|
|
*/
|
|
protected $conditions;
|
|
public function where(array $data)
|
|
{
|
|
if ($this->conditions == null) {
|
|
$this->conditions = $data;
|
|
return $this;
|
|
}
|
|
$this->conditions = array_merge($this->conditions, $data);
|
|
return $this;
|
|
}
|
|
/**
|
|
* [column, column => order]
|
|
* @var array
|
|
*/
|
|
protected $order;
|
|
public function order(array $data)
|
|
{
|
|
if ($this->order == null) {
|
|
$this->order = $data;
|
|
return $this;
|
|
}
|
|
$this->order = array_merge($this->order, $data);
|
|
return $this;
|
|
}
|
|
protected $limit;
|
|
public function limit(array $data)
|
|
{
|
|
if (!isset($data['limit'])) {
|
|
$data['limit'] = $data[0];
|
|
}
|
|
if (!isset($data['offset'])) {
|
|
$data['offset'] = 0;
|
|
if (isset($data[1])) {
|
|
$data['offset'] = $data[1];
|
|
}
|
|
}
|
|
$this->limit = (object) ['limit' => $data['limit'], 'offset' => $data['offset']];
|
|
return $this;
|
|
}
|
|
protected $many;
|
|
public function find($many = false)
|
|
{
|
|
$this->many = $many;
|
|
if ($this->is_aggregator) {
|
|
return $this->findAggregator();
|
|
}
|
|
return $this->findModel();
|
|
}
|
|
|
|
protected function findModel()
|
|
{
|
|
$objs = model($this->class);
|
|
$objs = $this->parseLimit($this->parseOrder($this->parseConditions($objs)));
|
|
|
|
if ($this->many) {
|
|
return $objs->findMany();
|
|
}
|
|
return $objs->findOne();
|
|
}
|
|
protected function parseConditions($orm)
|
|
{
|
|
if ($this->conditions == null) {
|
|
return $orm;
|
|
}
|
|
foreach ($this->conditions as $column => $value) {
|
|
if (is_array($value)) {
|
|
list($value, $op) = $value;
|
|
switch ($op) {
|
|
case '>':
|
|
case 'gt':
|
|
$orm = $orm->whereGt($column, $value);
|
|
break;
|
|
}
|
|
} else {
|
|
$orm = $orm->where($column, $value);
|
|
}
|
|
}
|
|
return $orm;
|
|
}
|
|
protected function parseOrder($orm)
|
|
{
|
|
if ($this->order == null) {
|
|
return $orm;
|
|
}
|
|
foreach ($this->order as $column => $order) {
|
|
if (is_numeric($column)) {
|
|
$column = $order;
|
|
$order = 'asc';
|
|
}
|
|
switch (strtolower($order)) {
|
|
case 'asc':
|
|
default:
|
|
$orm = $orm->orderByAsc($column);
|
|
break;
|
|
case 'desc':
|
|
$orm = $orm->orderByDesc($column);
|
|
break;
|
|
case 'expr':
|
|
$orm = $orm->orderByExpr($column);
|
|
break;
|
|
}
|
|
}
|
|
return $orm;
|
|
}
|
|
protected function parseLimit($orm)
|
|
{
|
|
if ($this->limit == null) {
|
|
return $orm;
|
|
}
|
|
$orm = $orm->limit($this->limit->limit);
|
|
if (isset($this->limit->offset)) {
|
|
$orm = $orm->offset($this->limit->offset);
|
|
}
|
|
return $orm;
|
|
}
|
|
protected function findAggregator()
|
|
{
|
|
$model = $this->modelName($this->class);
|
|
$ids = $this->getIds($model);
|
|
$class = $this->class;
|
|
if (count($ids) == 0) {
|
|
return false;
|
|
}
|
|
if ($this->many) {
|
|
$objs = [];
|
|
foreach ($ids as $id) {
|
|
$objs []= new $class($id);
|
|
}
|
|
} else {
|
|
$objs = new $class($ids[0]);
|
|
}
|
|
return $objs;
|
|
}
|
|
protected function getIds($model)
|
|
{
|
|
$id = $this->getModelId($model);
|
|
$table = $this->getTable($model);
|
|
$st = \ORM::forTable($table)->select($id);
|
|
$st = $this->parseConditions($st);
|
|
$results = $st->findArray();
|
|
$output = array_map(function($a) use($id) {
|
|
return $a[$id];
|
|
}, $results);
|
|
return $output;
|
|
}
|
|
protected function modelName($class)
|
|
{
|
|
$arr = explode("\\", $class);
|
|
\array_push($arr, end($arr));
|
|
return implode("\\", $arr);
|
|
}
|
|
protected function getModelId($model)
|
|
{
|
|
$table = $this->getTable($model);
|
|
$query = "SHOW KEYS FROM {$table} WHERE Key_name = 'PRIMARY'";
|
|
$st = \ORM::getDb()->query($query);
|
|
$results = $st->fetchAll(\PDO::FETCH_OBJ);
|
|
return $results[0]->Column_name;
|
|
}
|
|
protected function getTable($model)
|
|
{
|
|
$arr = explode("\\", $model);
|
|
return Stringy::create(end($arr))->toLowerCase() . '';
|
|
}
|
|
}
|