From 7ad1395696c4a2e355af59c589bae7137bd5f4e5 Mon Sep 17 00:00:00 2001 From: Raf <7909000@gmail.com> Date: Wed, 15 Apr 2020 00:32:23 +0500 Subject: [PATCH 1/2] support belongsToMany relationship --- src/Generators/MigrationGenerator.php | 63 +++++++++++++++++++++++++++ src/Generators/ModelGenerator.php | 2 +- src/Lexers/ModelLexer.php | 1 + src/Models/Model.php | 17 ++++++++ 4 files changed, 82 insertions(+), 1 deletion(-) diff --git a/src/Generators/MigrationGenerator.php b/src/Generators/MigrationGenerator.php index bce28294..cc5a0cca 100644 --- a/src/Generators/MigrationGenerator.php +++ b/src/Generators/MigrationGenerator.php @@ -15,6 +15,8 @@ class MigrationGenerator implements Generator /** @var \Illuminate\Contracts\Filesystem\Filesystem */ private $files; + private $pivotTables = []; + public function __construct($files) { $this->files = $files; @@ -34,6 +36,26 @@ public function output(array $tree): array $this->files->put($path, $this->populateStub($stub, $model)); $output['created'][] = $path; + + if(!empty($modelPivots = $model->pivotTables())) { + foreach($modelPivots as $pivotSegments) { + $pivotTable = $this->getPivotTableName($pivotSegments); + if(!isset($this->pivotTables[$pivotTable])) { + $this->pivotTables[$pivotTable] = [ + 'tableName' => $pivotTable, + 'segments' => $pivotSegments + ]; + } + } + } + } + + if(!empty($this->pivotTables)) { + foreach($this->pivotTables as $pivotTable) { + $path = $this->getPivotTablePath($pivotTable['tableName'], $sequential_timestamp->addSecond()); + $this->files->put($path, $this->populatePivotStub($stub, $pivotTable['segments'])); + $output['created'][] = $path; + } } return $output; @@ -48,6 +70,15 @@ protected function populateStub(string $stub, Model $model) return $stub; } + protected function populatePivotStub(string $stub, array $segments) + { + $stub = str_replace('DummyClass', $this->getPivotClassName($segments), $stub); + $stub = str_replace('DummyTable', $this->getPivotTableName($segments), $stub); + $stub = str_replace('// definition...', $this->buildPivotTableDefinition($segments), $stub); + + return $stub; + } + protected function buildDefinition(Model $model) { $definition = ''; @@ -107,6 +138,19 @@ protected function buildDefinition(Model $model) return trim($definition); } + protected function buildPivotTableDefinition(array $segments, $dataType = 'bigIncrements') + { + $definition = ''; + + foreach($segments as $segment) + { + $column = $segment . '_id'; + $definition .= self::INDENT . '$table->' . $dataType . "('{$column}');" . PHP_EOL; + } + + return trim($definition); + } + protected function getClassName(Model $model) { return 'Create' . Str::studly($model->tableName()) . 'Table'; @@ -117,8 +161,27 @@ protected function getPath(Model $model, Carbon $timestamp) return 'database/migrations/' . $timestamp->format('Y_m_d_His') . '_create_' . $model->tableName() . '_table.php'; } + protected function getPivotTablePath($tableName, Carbon $timestamp) + { + return 'database/migrations/' . $timestamp->format('Y_m_d_His') . '_create_' . $tableName . '_table.php'; + } + protected function isLaravel7orNewer() { return version_compare(App::version(), '7.0.0', '>='); } + + protected function getPivotClassName(array $segments) + { + return 'Create' . Str::studly($this->getPivotTableName($segments)) . 'PivotTable'; + } + + protected function getPivotTableName(array $segments) + { + $segments = array_map(function($name) { + return Str::snake($name); + }, $segments); + sort($segments); + return strtolower(implode('_', $segments)); + } } diff --git a/src/Generators/ModelGenerator.php b/src/Generators/ModelGenerator.php index 0cf82899..d0250370 100644 --- a/src/Generators/ModelGenerator.php +++ b/src/Generators/ModelGenerator.php @@ -135,7 +135,7 @@ private function buildRelationships(Model $model) $class = Str::studly($class ?? $name); $relationship = sprintf("\$this->%s(%s::class)", $type, '\\' . $model->fullyQualifiedNamespace() . '\\' . $class); - $method_name = $type === 'hasMany' ? Str::plural($name) : $name; + $method_name = $type === 'hasMany' || $type === 'belongsToMany' ? Str::plural($name) : $name; $method = str_replace('DummyName', Str::camel($method_name), $template); $method = str_replace('null', $relationship, $method); $methods .= PHP_EOL . $method; diff --git a/src/Lexers/ModelLexer.php b/src/Lexers/ModelLexer.php index bb6062b1..c5d62dcc 100644 --- a/src/Lexers/ModelLexer.php +++ b/src/Lexers/ModelLexer.php @@ -12,6 +12,7 @@ class ModelLexer implements Lexer 'belongsto' => 'belongsTo', 'hasone' => 'hasOne', 'hasmany' => 'hasMany', + 'belongstomany' => 'belongsToMany' ]; private static $dataTypes = [ diff --git a/src/Models/Model.php b/src/Models/Model.php index 39062e47..cdf6c805 100644 --- a/src/Models/Model.php +++ b/src/Models/Model.php @@ -12,6 +12,7 @@ class Model private $softDeletes = false; private $columns = []; private $relationships = []; + private $pivotTables = []; /** * @param $name @@ -132,6 +133,22 @@ public function addRelationship(string $type, string $reference) $this->relationships[$type] = []; } + if($type === 'belongsToMany') { + $this->addPivotTable($reference); + } + $this->relationships[$type][] = $reference; } + + public function addPivotTable(string $reference) + { + $segments = [$this->name(), strtolower($reference)]; + sort($segments); + $this->pivotTables[] = $segments; + } + + public function pivotTables() : array + { + return $this->pivotTables; + } } From fed6ba635cc26679969ba10fb8cb30dec21c8ae5 Mon Sep 17 00:00:00 2001 From: Raf <7909000@gmail.com> Date: Wed, 15 Apr 2020 00:44:44 +0500 Subject: [PATCH 2/2] fix code style --- src/Generators/MigrationGenerator.php | 15 +++++++-------- src/Models/Model.php | 4 ++-- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/Generators/MigrationGenerator.php b/src/Generators/MigrationGenerator.php index cc5a0cca..df481e57 100644 --- a/src/Generators/MigrationGenerator.php +++ b/src/Generators/MigrationGenerator.php @@ -37,10 +37,10 @@ public function output(array $tree): array $output['created'][] = $path; - if(!empty($modelPivots = $model->pivotTables())) { - foreach($modelPivots as $pivotSegments) { + if (!empty($modelPivots = $model->pivotTables())) { + foreach ($modelPivots as $pivotSegments) { $pivotTable = $this->getPivotTableName($pivotSegments); - if(!isset($this->pivotTables[$pivotTable])) { + if (!isset($this->pivotTables[$pivotTable])) { $this->pivotTables[$pivotTable] = [ 'tableName' => $pivotTable, 'segments' => $pivotSegments @@ -50,8 +50,8 @@ public function output(array $tree): array } } - if(!empty($this->pivotTables)) { - foreach($this->pivotTables as $pivotTable) { + if (!empty($this->pivotTables)) { + foreach ($this->pivotTables as $pivotTable) { $path = $this->getPivotTablePath($pivotTable['tableName'], $sequential_timestamp->addSecond()); $this->files->put($path, $this->populatePivotStub($stub, $pivotTable['segments'])); $output['created'][] = $path; @@ -142,8 +142,7 @@ protected function buildPivotTableDefinition(array $segments, $dataType = 'bigIn { $definition = ''; - foreach($segments as $segment) - { + foreach ($segments as $segment) { $column = $segment . '_id'; $definition .= self::INDENT . '$table->' . $dataType . "('{$column}');" . PHP_EOL; } @@ -178,7 +177,7 @@ protected function getPivotClassName(array $segments) protected function getPivotTableName(array $segments) { - $segments = array_map(function($name) { + $segments = array_map(function ($name) { return Str::snake($name); }, $segments); sort($segments); diff --git a/src/Models/Model.php b/src/Models/Model.php index cdf6c805..c58512c9 100644 --- a/src/Models/Model.php +++ b/src/Models/Model.php @@ -133,7 +133,7 @@ public function addRelationship(string $type, string $reference) $this->relationships[$type] = []; } - if($type === 'belongsToMany') { + if ($type === 'belongsToMany') { $this->addPivotTable($reference); } @@ -147,7 +147,7 @@ public function addPivotTable(string $reference) $this->pivotTables[] = $segments; } - public function pivotTables() : array + public function pivotTables(): array { return $this->pivotTables; }