Files
KI/provm/common/Factory/Model.php
2020-05-29 18:36:56 -04:00

149 lines
3.9 KiB
PHP

<?php
namespace ProVM\Common\Factory;
use ProVM\Common\Implementation\Model as BaseModel;
class Model {
protected $data_folder;
protected $image_folder;
public function __construct(string $data_folder, string $image_folder) {
$this->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
* [
* {
* <field>,
* <value>,
* <operator>
* },
* ...
* ]
* @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;
}
}