Mercurial > packages > magicforger
view src/Generator/Model/ModelGenerator.php @ 29:010ace248d14 codex
Added support for filters, not fully there with relations or anything like that but it's a start
| author | Luka Sitas <sitas.luka.97@gmail.com> |
|---|---|
| date | Mon, 09 Jun 2025 20:51:04 -0400 |
| parents | f88d2d5dee30 |
| children |
line wrap: on
line source
<?php namespace Wizard\MagicForger\Generator\Model; use Symfony\Component\Console\Attribute\AsCommand; use Wizard\MagicForger\Generator\BaseGenerator; use Wizard\MagicForger\Helpers\RelationshipNavigator; use Illuminate\Support\Str; #[AsCommand(name: 'mf:model')] class ModelGenerator extends BaseGenerator { /** * The name and signature of the console command. * * @var string */ protected $name = 'mf:model'; /** * The console command description. * * @var string */ protected $description = 'Generates the Model File for a table.'; /** * The type of class being generated. * * @var string */ protected $type = 'Model'; protected static $cached_snippets = []; /** * Execute the console command. * * @return mixed */ public function handle() { // Delegate to parent handler (includes replacements and insertions) return parent::handle(); } /** * Get the stub file for the generator. * * @return string */ 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 * @return string */ protected function resolveStubPath($stub) { return is_file($customPath = $this->laravel->basePath(trim($stub, '/'))) ? $customPath : __DIR__.$stub; } protected function getClassName($name) { return $this->model_name($name); } /** * Get the stub file for the generator. * * @return string */ protected function getPath($name = null) { 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; } }
