Mercurial > packages > magicforger
diff src/Generator/Model/ModelGenerator.php @ 34:f65ab84ee47f default
merge with codex
| author | luka |
|---|---|
| date | Wed, 10 Sep 2025 21:00:47 -0400 |
| parents | 010ace248d14 |
| children |
line wrap: on
line diff
--- a/src/Generator/Model/ModelGenerator.php Sat Dec 02 10:20:32 2023 -0500 +++ b/src/Generator/Model/ModelGenerator.php Wed Sep 10 21:00:47 2025 -0400 @@ -1,9 +1,11 @@ <?php -namespace Wizzard\MagicForger\Generator\Model; +namespace Wizard\MagicForger\Generator\Model; use Symfony\Component\Console\Attribute\AsCommand; -use Wizzard\MagicForger\Generator\BaseGenerator; +use Wizard\MagicForger\Generator\BaseGenerator; +use Wizard\MagicForger\Helpers\RelationshipNavigator; +use Illuminate\Support\Str; #[AsCommand(name: 'mf:model')] class ModelGenerator extends BaseGenerator @@ -29,12 +31,17 @@ */ protected $type = 'Model'; + protected static $cached_snippets = []; + /** * Execute the console command. + * + * @return mixed */ public function handle() { - parent::handle(); + // Delegate to parent handler (includes replacements and insertions) + return parent::handle(); } /** @@ -44,14 +51,17 @@ */ protected function getStub() { + if (! is_null(RelationshipNavigator::isPivot($this->getCurrentTable()))) { + return $this->resolveStubPath('/stubs/model.pivot.stub'); + } + return $this->resolveStubPath('/stubs/model.stub'); } /** * Resolve the fully-qualified path to the stub. * - * @param string $stub - * + * @param string $stub * @return string */ protected function resolveStubPath($stub) @@ -75,4 +85,151 @@ { return str_replace(['App\\', '\\'], ['app/', '/'], $this->getModelNamespace().'/'.$this->model_name($this->getTableInput()).'.php'); } + + protected function gatherRelations() { + $relations = RelationshipNavigator::getRelations($this->getCurrentTable()); + + return $relations; + + } + + protected function renderFilters() { + $insert = ''; + foreach ($this->get_columns() as $column) { + if (in_array($column['name'], $this->columns_to_ignore)) { + continue; + } + $snippet = $this->getSnippet('filter'); + $tableName = $this->getCurrentTable(); + $value = 'value'; // TODO: this should be determined based on column type + $columnName = $column['name']; + $columnDisplay = Str::headline($columnName); + + // Replace placeholders with actual values + $string = str_replace( + ['{{value}}', '{{columnDisplay}}', '{{tableName}}', '{{columnName}}'], + [$value, $columnDisplay, $tableName, $columnName], + $snippet + ); + $insert .= sprintf("%s", $string); + } + + return $insert; + } + + protected function renderRelations($relations) { + $renders = [ + 'belongsTo' => [], + 'hasMany' => [], + 'belongsToMany' => [], + ]; + // Render belongsTo relations + foreach (($relations['belongsTo'] ?? []) as $relation) { + $renders['belongsTo'][] = $this->renderBelongsTo($relation); + } + + // Render hasMany relations + foreach (($relations['hasMany'] ?? []) as $relation) { + $renders['hasMany'][] = $this->renderHasMany($relation); + } + + // Render belongsToMany (many-to-many) via hasManyThrough pivot relations + foreach (($relations['hasManyThrough'] ?? []) as $relation) { + $renders['belongsToMany'][] = $this->renderBelongsToMany($relation); + } + return $renders; + } + + protected function renderBelongsTo($relationship) + { + $snippet = $this->getSnippet('belongs_to_relation'); + $relationName = Str::singular($relationship['table']); + $relatedModel = $this->getClassName($relationship['table']); + $columnName = $relationship['column']; + + // Replace placeholders with actual values + $string = str_replace( + ['{{relationName}}', '{{relatedModel}}', '{{columnName}}'], + [$relationName, $relatedModel, $columnName], + $snippet + ); + + return $string; + } + + /** + * Render a hasMany relation. + * + * @param array $relationship + * @return string + */ + protected function renderHasMany($relationship) + { + $snippet = $this->getSnippet('has_many_relation'); + // Method name uses camel case for plural relation + $relationName = Str::camel($relationship['table']); + $relatedModel = $this->getClassName($relationship['table']); + $columnName = $relationship['column']; + + // Replace placeholders with actual values + $string = str_replace( + ['{{relationName}}', '{{relatedModel}}', '{{columnName}}'], + [$relationName, $relatedModel, $columnName], + $snippet + ); + + return $string; + } + + protected function renderBelongsToMany($relationship) + { + $snippet = $this->getSnippet('belongs_to_many_relation'); + $relationName = $relationship['table']; + $relatedModel = $this->getClassName($relationship['table']); + $pivotTable = $relationship['through']['table']; + $foreignPivotKey = $relationship['through']['external_column']; + $relatedPivotKey = $relationship['through']['internal_column']; + + // Replace placeholders with actual values + $string = str_replace( + ['{{relationName}}', '{{relatedModel}}', '{{pivotTable}}', '{{foreignPivotKey}}', '{{relatedPivotKey}}'], + [$relationName, $relatedModel, $pivotTable, $foreignPivotKey, $relatedPivotKey], + $snippet + ); + + return $string; + } + + /** + * Get available insertions including model relationships. + * + * @return array + */ + public function get_available_inserts(): array + { + // Merge parent insertions (attributes, fillable, etc.) + $inserts = parent::get_available_inserts(); + + // Gather and render relationships for this model + $relations = $this->gatherRelations(); + $rendered = $this->renderRelations($relations); + $filters = $this->renderFilters(); + + // Build code blocks for each relation type + $belongs = !empty($rendered['belongsTo']) ? implode("\n ", $rendered['belongsTo']) : ''; + $hasMany = !empty($rendered['hasMany']) ? implode("\n ", $rendered['hasMany']) : ''; + $belongsMany = !empty($rendered['belongsToMany']) ? implode("\n ", $rendered['belongsToMany']) : ''; + + // Default relations are based on the belongsTo relationship + $default_relations = implode(", \n", array_map(function ($rel) {return '\'' . Str::singular($rel['table']) . '\''; }, $relations['belongsTo'])); + + // Assign to stub placeholders + $inserts['# {{ belongs_to_relationships }}'] = $belongs; + $inserts['# {{ has_many_relationships }}'] = $hasMany; + $inserts['# {{ has_many_through_relationships }}'] = $belongsMany; + $inserts['# {{ defaultRelationsInsertPoint }}'] = $default_relations; + $inserts['# {{ defaultFiltersInsertPoint }}'] = $filters; + + return $inserts; + } }
