data_folder = $data_folder; $this->image_folder = $image_folder; } public function getFolder(): string { return $this->data_folder; } public function get($file) { $filename = implode(DIRECTORY_SEPARATOR, [ $this->data_folder, $file ]); return json_decode(trim(file_get_contents($filename))); } protected function reset() { $this->class = null; $this->conditions = null; $this->limits = null; } protected $class; public function find(string $class): Model { if (!class_exists($class) or !is_subclass_of($class, \ProVM\Common\Implementation\Model::class)) { throw new \InvalidArgumentException($class . ' is not defined.'); } $this->reset(); $this->class = $class; return $this; } /** * JSON * [ * { * , * , * * }, * ... * ] * @var array */ protected $conditions; public function where(array $conditions): Model { if ($this->conditions === null) { $this->conditions = []; } foreach ($conditions as $condition) { $c = ['field' => $condition[0], 'value' => $condition[1], 'operator' => '==']; if (isset($condition[2])) { $c['operator'] = $condition[2]; } $this->conditions []= (object) $c; } return $this; } protected function parseWhere(array $data): array { if ($this->conditions === null) { return $data; } foreach ($this->conditions as $condition) { $str = implode(' ', [ $condition->field, $condition->operator, (is_string($condition->value)) ? "'" . $condition->value . "'" : $condition->value ]); return array_filter($data, function($item) use ($str) { $bool = true; eval("\$bool = (\$item->" . $str . ');'); return $bool; }); } } protected $limits; public function limit(int $limit): Model { if ($this->limits === null) { $this->limits = (object) ['limit' => null, 'offset' => 0]; } $this->limits->limit = $limit; return $this; } public function offset(int $offset): Model { if ($this->limits === null) { $this->limits = (object) ['limit' => null, 'offset' => 0]; } $this->limits->offset = $offset; return $this; } protected function parseLimits(array $data): array { if ($this->limits === null or $this->limits->limit === null) { return $data; } return array_slice($data, $this->limits->offset, $this->limits->limit); } protected function getFilename(): string { $data = explode("\\", $this->class); return implode(DIRECTORY_SEPARATOR, [ $this->data_folder, str_replace(' ', '_', mb_strtolower(array_pop($data))) . 's.json' ]); } protected function build(): array { $filename = $this->getFilename(); $data = json_decode(trim(file_get_contents($filename))); $data = $this->parseWhere($data); $data = $this->parseLimits($data); return $data; } protected function fillObject($data): BaseModel { $obj = new $this->class; $obj->map($data); $obj->setFactory($this); $obj->setImageFolder($this->image_folder); return $obj; } public function one(): BaseModel { $data = $this->limit(1)->build(); $item = $data[0]; $obj = $this->fillObject($item); return $obj; } public function many(): array { $data = $this->build(); foreach ($data as &$item) { $obj = $this->fillObject($item); $item = $obj; } return $data; } public function array(): array { return $this->build(); } public function create(string $class, $data) { $obj = new $class; $obj->map($data); $obj->setFactory($this); $obj->setImageFolder($this->image_folder); return $obj; } }