diff --git a/common/Factory/Model.php b/common/Factory/Model.php new file mode 100644 index 0000000..2aef844 --- /dev/null +++ b/common/Factory/Model.php @@ -0,0 +1,204 @@ +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() . ''; + } +}