Factory 1.0.0
This commit is contained in:
204
common/Factory/Model.php
Normal file
204
common/Factory/Model.php
Normal file
@ -0,0 +1,204 @@
|
||||
<?php
|
||||
namespace Incoviba\Common\Factory;
|
||||
|
||||
use Stringy\Stringy;
|
||||
|
||||
class Model
|
||||
{
|
||||
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() . '';
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user