Last active
May 29, 2017 10:51
-
-
Save artygrand/1bbca0a8f091a17b4fcc18cd83cbda8b to your computer and use it in GitHub Desktop.
Repo - entity - fields
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Module\Entity\Models; | |
use Sydes\Database; | |
use Sydes\PDO; | |
class Repository | |
{ | |
/** @var PDO */ | |
protected $db; | |
/** @var Entity */ | |
protected $model; | |
/** @var PDO */ | |
protected $result; | |
public function __construct(Database $db) | |
{ | |
$this->db = $db; | |
} | |
/** | |
* @param string $model Model name | |
* @return $this | |
*/ | |
public function forModel($model) | |
{ | |
$this->model = model($model); | |
$this->db = $this->db->connection($this->model->getConnection()); | |
return $this; | |
} | |
/** | |
* @return Entity | |
*/ | |
public function getModel() | |
{ | |
return $this->model; | |
} | |
/** | |
* Creates table from entity fields | |
*/ | |
public function makeTable() | |
{ | |
$table = $this->model->getTable(); | |
$fields = $this->model->getFields(); | |
if ($this->model->hasLocalized()) { | |
$cols = [ | |
"entity_id INTEGER NOT NULL REFERENCES {$table}(id) ON DELETE CASCADE", | |
'locale TEXT NOT NULL', | |
]; | |
foreach ($this->model->getLocalized() as $col) { | |
$cols[] = $fields[$col]->getSchema(); | |
unset($fields[$col]); | |
} | |
$cols[] = 'UNIQUE (entity_id, locale)'; | |
$this->db->exec("CREATE TABLE {$table}_localized (\n".implode(",\n", $cols)."\n)"); | |
} | |
$cols = [ | |
$this->model->getPk().' INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT', | |
]; | |
foreach ($fields as $field) { | |
$cols[] = $field->getSchema(); | |
} | |
if ($this->model->usesTimestamps()) { | |
$cols[] = 'created_at INTEGER'; | |
$cols[] = 'updated_at INTEGER'; | |
} | |
$this->db->exec("CREATE TABLE {$table} (\n".implode(",\n", $cols)."\n)"); | |
if ($this->model->usesEav()) { | |
$this->db->exec("CREATE TABLE {$table}_eav ( | |
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, | |
entity_id INTEGER NOT NULL REFERENCES {$table}(id) ON DELETE CASCADE, | |
key TEXT NOT NULL, | |
value TEXT, | |
UNIQUE (entity_id, key)\n)"); | |
} | |
} | |
/** | |
* Removes table for this entity | |
*/ | |
public function dropTable() | |
{ | |
$table = $this->model->getTable(); | |
if ($this->model->hasLocalized()) { | |
$this->db->drop($table.'_localized'); | |
} | |
if ($this->model->usesEav()) { | |
$this->db->drop($table.'_eav'); | |
} | |
$this->db->drop($table); | |
} | |
/** | |
* @param mixed $criteria | |
* @param array $cols | |
* @param array $opts | |
* @return $this | |
*/ | |
public function find($criteria, array $cols = ['*'], $opts = []) | |
{ | |
if (is_numeric($criteria)) { | |
$criteria = ['id', $criteria]; | |
} | |
// если $criterion[0] не поле и не мета, искать id в локализованных или еав | |
// найдя id | |
// или иначе, получить данные со всех таблиц | |
$this->result = $this->db->select($this->model->getTable(), $cols, $criteria, $opts); | |
return $this; | |
} | |
public function first() | |
{ | |
$model = clone $this->model; | |
$item = $this->result->first(); | |
return $model->fill($item)->withProps($item); | |
} | |
public function all() | |
{ | |
$results = []; | |
foreach ($this->result->all() as $item) { | |
$model = clone $this->model; | |
$results[] = $model->fill($item)->withProps($item); | |
} | |
return $results; | |
} | |
public function save(Entity $entity) | |
{ | |
} | |
public function destroy(Entity $entity) | |
{ | |
} | |
public function __call($name, $args) { | |
if (substr($name, 0, 6) == 'findBy') { | |
$field = strtolower(substr($name, 6)); | |
if (!isset($args[1])) { | |
$args[1] = ['*']; | |
} | |
return $this->find([$field, $args[0]], $args[1]); | |
} | |
throw new \InvalidArgumentException('Wrong method '.$name); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Module\Entity\Models; | |
use Module\Fields\Plugin\Fields\FieldInterface; | |
abstract class Entity | |
{ | |
protected $connection = 'site'; | |
protected $table; | |
protected $primaryKey = 'id'; | |
protected $timestamps = true; | |
protected $eav = false; | |
protected $localized = []; | |
protected $fields = []; | |
protected $attributes = []; | |
protected $data = []; | |
/** | |
* Entity constructor. | |
* | |
* @param array $attrs | |
*/ | |
public function __construct(array $attrs = []) | |
{ | |
$this->fill($attrs); | |
} | |
/** | |
* @param array $attrs | |
* @return $this | |
*/ | |
public static function create(array $attrs) | |
{ | |
return new static($attrs); | |
} | |
/** | |
* @param array $attrs | |
* @return $this | |
*/ | |
public function fill(array $attrs) | |
{ | |
foreach (array_intersect_key($attrs, $this->fields) as $key => $value) { | |
$this->data[$key] = $value; | |
} | |
return $this; | |
} | |
/** | |
* @param array $props | |
* @return $this | |
*/ | |
public function withProps(array $props) | |
{ | |
foreach (array_intersect_key($props, [ | |
$this->primaryKey => 1, | |
'status' => 1, | |
'created_at' => 1, | |
'updated_at' => 1, | |
]) as $key => $value) { | |
$this->data[$key] = $value; | |
} | |
return $this; | |
} | |
/** | |
* @param string $name | |
* @return FieldInterface | |
*/ | |
public function getField($name) | |
{ | |
if (!isset($this->attributes[$name])) { | |
$this->initField($name); | |
} | |
return $this->attributes[$name]; | |
} | |
/** | |
* @param string $name | |
*/ | |
protected function initField($name) | |
{ | |
$class = app('formFields')[$this->fields[$name]['type']]; | |
$this->attributes[$name] = new $class($name, $this->data[$name], $this->fields[$name]['settings']); | |
} | |
/** | |
* @return array | |
*/ | |
public function toArray() | |
{ | |
return $this->data; | |
} | |
/** | |
* @return string | |
*/ | |
public function getTable() | |
{ | |
if ($this->table) { | |
return $this->table; | |
} else { | |
$name = get_class($this); | |
return snake_case(($pos = strrpos($name, '\\')) ? substr($name, $pos + 1) : $name).'s'; | |
} | |
} | |
/** | |
* @param mixed $table | |
*/ | |
public function setTable($table) | |
{ | |
$this->table = $table; | |
} | |
/** | |
* @return array | |
*/ | |
public function getFields() | |
{ | |
return $this->fields; | |
} | |
/** | |
* @param array $fields | |
*/ | |
public function setFields($fields) | |
{ | |
$this->fields = $fields; | |
} | |
/** | |
* @return string | |
*/ | |
public function getConnection() | |
{ | |
return $this->connection; | |
} | |
/** | |
* @param string $name | |
*/ | |
public function setConnection($name) | |
{ | |
$this->connection = $name; | |
} | |
/** | |
* @return bool | |
*/ | |
public function usesTimestamps() | |
{ | |
return $this->timestamps; | |
} | |
/** | |
* @return string | |
*/ | |
public function getPk() | |
{ | |
return $this->primaryKey; | |
} | |
/** | |
* @return bool | |
*/ | |
public function usesEav() | |
{ | |
return $this->eav; | |
} | |
/** | |
* @return bool | |
*/ | |
public function hasLocalized() | |
{ | |
return !empty($this->localized); | |
} | |
/** | |
* @return array | |
*/ | |
public function getLocalized() | |
{ | |
return $this->localized; | |
} | |
/** | |
* @param string $key | |
* @return FieldInterface | |
*/ | |
public function __get($key) | |
{ | |
return $this->getField($key)->render(); | |
} | |
/** | |
* @param string $key | |
* @param mixed $value | |
*/ | |
public function __set($key, $value) | |
{ | |
$this->getField($key)->set($value); | |
} | |
/** | |
* @param string $key | |
* @return bool | |
*/ | |
public function __isset($key) | |
{ | |
return array_key_exists($key, $this->attributes); | |
} | |
/** | |
* @param string $key | |
*/ | |
public function __unset($key) | |
{ | |
$this->getField($key)->set(''); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Module\Test; | |
use Module\Entity\Models\Repository; | |
use Sydes\Route; | |
class Controller | |
{ | |
public static function routes(Route $r) | |
{ | |
$r->get('/admin/test', 'Test@index'); | |
} | |
public function install(Repository $repo) | |
{ | |
$repo->forModel('Test')->makeTable(); | |
} | |
public function uninstall(Repository $repo) | |
{ | |
$repo->forModel('Test')->dropTable(); | |
} | |
public function index(Repository $repo) | |
{ | |
$tests = $repo->forModel('Test')->find(['code', 'between', ['2', '4']])->all(); | |
$d = document([ | |
'content' => view('test/list', compact('tests')), | |
]); | |
return $d; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Module\Test\Models; | |
use Module\Entity\Models\Entity; | |
class Test extends Entity | |
{ | |
protected $fields = [ | |
'code' => [ | |
'type' => 'Text', | |
'settings' => [ | |
'label' => 'test code', | |
'required' => true, | |
], | |
'position' => 1, | |
], | |
'name' => [ | |
'type' => 'Text', | |
'settings' => [ | |
'label' => 'test_name', | |
'required' => true, | |
], | |
'position' => 3, | |
], | |
'data' => [ | |
'type' => 'Text', | |
'settings' => [ | |
'label' => 'test_data', | |
'rows' => 12, | |
'required' => true, | |
], | |
'position' => 2, | |
], | |
]; | |
protected $eav = true; | |
protected $localized = [ | |
'name', | |
'data', | |
]; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment