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() . ''; } }