From 422d9a6dbdda953055bbad91c694df5959a93810 Mon Sep 17 00:00:00 2001 From: Aldarien Date: Mon, 10 Oct 2022 16:36:47 -0300 Subject: [PATCH] Improve mapping --- src/Alias/Model/Repository.php | 93 +++++++++++- src/Concept/Model/Factory.php | 37 +++++ src/Concept/Model/Repository.php | 241 ++++++++++++++++++++++++++++++- src/Implement/Model/Factory.php | 15 ++ 4 files changed, 376 insertions(+), 10 deletions(-) diff --git a/src/Alias/Model/Repository.php b/src/Alias/Model/Repository.php index 3ba812a..3e6aed4 100644 --- a/src/Alias/Model/Repository.php +++ b/src/Alias/Model/Repository.php @@ -73,6 +73,54 @@ abstract class Repository implements RepositoryInterface { return $this->table; } + protected array $mappings; + public function getMappings(): array + { + if (isset($this->mappings)) { + return $this->mappings; + } + $mappings = []; + foreach ($this->getColumns() as $column) { + $mappings []= (object) ['column' => $column, 'property' => $column]; + } + return $mappings; + } + public function addMapping(string $column, string $property): Repository + { + $this->mappings []= (object) compact('column', 'property'); + return $this; + } + public function setMappings(array $mappings): Repository + { + foreach ($mappings as $mapping) { + if (is_array($mapping)) { + $this->addMapping($mapping['column'], $mapping['property']); + } + if (is_object($mapping)) { + $this->addMapping($mapping->column, $mapping->property); + } + } + return $this; + } + public function findColumnByProperty(string $property): string + { + foreach ($this->getMappings() as $mapping) { + if ($mapping->property === $property) { + return $mapping->column; + } + } + throw new \InvalidArgumentException("Property {$property} not found in mapping in " . get_called_class()); + } + public function findPropertyByColumn(string $column): string + { + foreach ($this->getMappings() as $mapping) { + if ($mapping->column === $column) { + return $mapping->property; + } + } + throw new \InvalidArgumentException("Column {$column} not found in mapping in " . get_called_class()); + } + protected array $columns; public function setColumns(array $columns): RepositoryInterface { @@ -90,6 +138,23 @@ abstract class Repository implements RepositoryInterface { return $this->columns; } + protected array $properties; + public function getProperties(): array + { + return $this->properties; + } + public function addProperty(string $property): RepositoryInterface + { + $this->properties []= $property; + return $this; + } + public function setProperties(array $properties): RepositoryInterface + { + foreach ($properties as $property) { + $this->addProperty($property); + } + return $this; + } protected array $required; public function setRequired(array $columns): RepositoryInterface { @@ -131,9 +196,9 @@ abstract class Repository implements RepositoryInterface return $this->optional ?? []; } - public function getMethod(string $column, bool $get = true): string + public function getMethod(string $property, bool $get = true): string { - $m = str_replace(' ', '', ucwords(str_replace('_', ' ', $column))); + $m = str_replace(' ', '', ucwords(str_replace('_', ' ', $property))); if ($get) { return "get{$m}"; } @@ -149,18 +214,28 @@ abstract class Repository implements RepositoryInterface } public function fillData(Model $model, array $data): Model { - foreach ($this->getRequired() as $column) { - $m = $this->getMethod($column, false); + foreach ($this->getColumns() as $column) { + try { + $property = $this->findPropertyByColumn($column); + } catch (\InvalidArgumentException $e) { + continue; + } + $m = $this->getMethod($property, false); if (!method_exists($model, $m)) { continue; } $model->{$m}($data[$column]); } foreach ($this->getOptional() as $column) { + try { + $property = $this->findPropertyByColumn($column); + } catch (\InvalidArgumentException $e) { + continue; + } + $m = $this->getMethod($property, false); if (!isset($data[$column])) { continue; } - $m = $this->getMethod($column, false); if (!method_exists($model, $m)) { continue; } @@ -170,11 +245,13 @@ abstract class Repository implements RepositoryInterface } public function mapArray(Model $model, array $data): array { - foreach ($this->getColumns() as $column) { - if (isset($data[$column])) { + foreach ($this->getProperties() as $property) { + try { + $column = $this->findColumnByProperty($property); + } catch (\InvalidArgumentException $e) { continue; } - $m = $this->getMethod($column); + $m = $this->getMethod($property); if (!method_exists($model, $m)) { continue; } diff --git a/src/Concept/Model/Factory.php b/src/Concept/Model/Factory.php index 8e1f566..1ab4a94 100644 --- a/src/Concept/Model/Factory.php +++ b/src/Concept/Model/Factory.php @@ -1,11 +1,48 @@ getContainer()->get($repository_class); } + public function getByModel(string $model_class): Repository + { + $class = str_replace('Model', 'Repository', $model_class); + return $this->get($class); + } + + public function fetchById(string $model_class, int $id): Model + { + return $this->getByModel($model_class)->fetchById($id); + } + public function fetchAll(string $model_class): array + { + return $this->getByModel($model_class)->fetchAll(); + } }