Mercurial > packages > magicforger
comparison 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 |
comparison
equal
deleted
inserted
replaced
| 10:a9ff874afdbd | 34:f65ab84ee47f |
|---|---|
| 1 <?php | 1 <?php |
| 2 | 2 |
| 3 namespace Wizzard\MagicForger\Generator\Model; | 3 namespace Wizard\MagicForger\Generator\Model; |
| 4 | 4 |
| 5 use Symfony\Component\Console\Attribute\AsCommand; | 5 use Symfony\Component\Console\Attribute\AsCommand; |
| 6 use Wizzard\MagicForger\Generator\BaseGenerator; | 6 use Wizard\MagicForger\Generator\BaseGenerator; |
| 7 use Wizard\MagicForger\Helpers\RelationshipNavigator; | |
| 8 use Illuminate\Support\Str; | |
| 7 | 9 |
| 8 #[AsCommand(name: 'mf:model')] | 10 #[AsCommand(name: 'mf:model')] |
| 9 class ModelGenerator extends BaseGenerator | 11 class ModelGenerator extends BaseGenerator |
| 10 { | 12 { |
| 11 /** | 13 /** |
| 27 * | 29 * |
| 28 * @var string | 30 * @var string |
| 29 */ | 31 */ |
| 30 protected $type = 'Model'; | 32 protected $type = 'Model'; |
| 31 | 33 |
| 34 protected static $cached_snippets = []; | |
| 35 | |
| 32 /** | 36 /** |
| 33 * Execute the console command. | 37 * Execute the console command. |
| 38 * | |
| 39 * @return mixed | |
| 34 */ | 40 */ |
| 35 public function handle() | 41 public function handle() |
| 36 { | 42 { |
| 37 parent::handle(); | 43 // Delegate to parent handler (includes replacements and insertions) |
| 44 return parent::handle(); | |
| 38 } | 45 } |
| 39 | 46 |
| 40 /** | 47 /** |
| 41 * Get the stub file for the generator. | 48 * Get the stub file for the generator. |
| 42 * | 49 * |
| 43 * @return string | 50 * @return string |
| 44 */ | 51 */ |
| 45 protected function getStub() | 52 protected function getStub() |
| 46 { | 53 { |
| 54 if (! is_null(RelationshipNavigator::isPivot($this->getCurrentTable()))) { | |
| 55 return $this->resolveStubPath('/stubs/model.pivot.stub'); | |
| 56 } | |
| 57 | |
| 47 return $this->resolveStubPath('/stubs/model.stub'); | 58 return $this->resolveStubPath('/stubs/model.stub'); |
| 48 } | 59 } |
| 49 | 60 |
| 50 /** | 61 /** |
| 51 * Resolve the fully-qualified path to the stub. | 62 * Resolve the fully-qualified path to the stub. |
| 52 * | 63 * |
| 53 * @param string $stub | 64 * @param string $stub |
| 54 * | |
| 55 * @return string | 65 * @return string |
| 56 */ | 66 */ |
| 57 protected function resolveStubPath($stub) | 67 protected function resolveStubPath($stub) |
| 58 { | 68 { |
| 59 return is_file($customPath = $this->laravel->basePath(trim($stub, '/'))) | 69 return is_file($customPath = $this->laravel->basePath(trim($stub, '/'))) |
| 73 */ | 83 */ |
| 74 protected function getPath($name = null) | 84 protected function getPath($name = null) |
| 75 { | 85 { |
| 76 return str_replace(['App\\', '\\'], ['app/', '/'], $this->getModelNamespace().'/'.$this->model_name($this->getTableInput()).'.php'); | 86 return str_replace(['App\\', '\\'], ['app/', '/'], $this->getModelNamespace().'/'.$this->model_name($this->getTableInput()).'.php'); |
| 77 } | 87 } |
| 88 | |
| 89 protected function gatherRelations() { | |
| 90 $relations = RelationshipNavigator::getRelations($this->getCurrentTable()); | |
| 91 | |
| 92 return $relations; | |
| 93 | |
| 94 } | |
| 95 | |
| 96 protected function renderFilters() { | |
| 97 $insert = ''; | |
| 98 foreach ($this->get_columns() as $column) { | |
| 99 if (in_array($column['name'], $this->columns_to_ignore)) { | |
| 100 continue; | |
| 101 } | |
| 102 $snippet = $this->getSnippet('filter'); | |
| 103 $tableName = $this->getCurrentTable(); | |
| 104 $value = 'value'; // TODO: this should be determined based on column type | |
| 105 $columnName = $column['name']; | |
| 106 $columnDisplay = Str::headline($columnName); | |
| 107 | |
| 108 // Replace placeholders with actual values | |
| 109 $string = str_replace( | |
| 110 ['{{value}}', '{{columnDisplay}}', '{{tableName}}', '{{columnName}}'], | |
| 111 [$value, $columnDisplay, $tableName, $columnName], | |
| 112 $snippet | |
| 113 ); | |
| 114 $insert .= sprintf("%s", $string); | |
| 115 } | |
| 116 | |
| 117 return $insert; | |
| 118 } | |
| 119 | |
| 120 protected function renderRelations($relations) { | |
| 121 $renders = [ | |
| 122 'belongsTo' => [], | |
| 123 'hasMany' => [], | |
| 124 'belongsToMany' => [], | |
| 125 ]; | |
| 126 // Render belongsTo relations | |
| 127 foreach (($relations['belongsTo'] ?? []) as $relation) { | |
| 128 $renders['belongsTo'][] = $this->renderBelongsTo($relation); | |
| 129 } | |
| 130 | |
| 131 // Render hasMany relations | |
| 132 foreach (($relations['hasMany'] ?? []) as $relation) { | |
| 133 $renders['hasMany'][] = $this->renderHasMany($relation); | |
| 134 } | |
| 135 | |
| 136 // Render belongsToMany (many-to-many) via hasManyThrough pivot relations | |
| 137 foreach (($relations['hasManyThrough'] ?? []) as $relation) { | |
| 138 $renders['belongsToMany'][] = $this->renderBelongsToMany($relation); | |
| 139 } | |
| 140 return $renders; | |
| 141 } | |
| 142 | |
| 143 protected function renderBelongsTo($relationship) | |
| 144 { | |
| 145 $snippet = $this->getSnippet('belongs_to_relation'); | |
| 146 $relationName = Str::singular($relationship['table']); | |
| 147 $relatedModel = $this->getClassName($relationship['table']); | |
| 148 $columnName = $relationship['column']; | |
| 149 | |
| 150 // Replace placeholders with actual values | |
| 151 $string = str_replace( | |
| 152 ['{{relationName}}', '{{relatedModel}}', '{{columnName}}'], | |
| 153 [$relationName, $relatedModel, $columnName], | |
| 154 $snippet | |
| 155 ); | |
| 156 | |
| 157 return $string; | |
| 158 } | |
| 159 | |
| 160 /** | |
| 161 * Render a hasMany relation. | |
| 162 * | |
| 163 * @param array $relationship | |
| 164 * @return string | |
| 165 */ | |
| 166 protected function renderHasMany($relationship) | |
| 167 { | |
| 168 $snippet = $this->getSnippet('has_many_relation'); | |
| 169 // Method name uses camel case for plural relation | |
| 170 $relationName = Str::camel($relationship['table']); | |
| 171 $relatedModel = $this->getClassName($relationship['table']); | |
| 172 $columnName = $relationship['column']; | |
| 173 | |
| 174 // Replace placeholders with actual values | |
| 175 $string = str_replace( | |
| 176 ['{{relationName}}', '{{relatedModel}}', '{{columnName}}'], | |
| 177 [$relationName, $relatedModel, $columnName], | |
| 178 $snippet | |
| 179 ); | |
| 180 | |
| 181 return $string; | |
| 182 } | |
| 183 | |
| 184 protected function renderBelongsToMany($relationship) | |
| 185 { | |
| 186 $snippet = $this->getSnippet('belongs_to_many_relation'); | |
| 187 $relationName = $relationship['table']; | |
| 188 $relatedModel = $this->getClassName($relationship['table']); | |
| 189 $pivotTable = $relationship['through']['table']; | |
| 190 $foreignPivotKey = $relationship['through']['external_column']; | |
| 191 $relatedPivotKey = $relationship['through']['internal_column']; | |
| 192 | |
| 193 // Replace placeholders with actual values | |
| 194 $string = str_replace( | |
| 195 ['{{relationName}}', '{{relatedModel}}', '{{pivotTable}}', '{{foreignPivotKey}}', '{{relatedPivotKey}}'], | |
| 196 [$relationName, $relatedModel, $pivotTable, $foreignPivotKey, $relatedPivotKey], | |
| 197 $snippet | |
| 198 ); | |
| 199 | |
| 200 return $string; | |
| 201 } | |
| 202 | |
| 203 /** | |
| 204 * Get available insertions including model relationships. | |
| 205 * | |
| 206 * @return array | |
| 207 */ | |
| 208 public function get_available_inserts(): array | |
| 209 { | |
| 210 // Merge parent insertions (attributes, fillable, etc.) | |
| 211 $inserts = parent::get_available_inserts(); | |
| 212 | |
| 213 // Gather and render relationships for this model | |
| 214 $relations = $this->gatherRelations(); | |
| 215 $rendered = $this->renderRelations($relations); | |
| 216 $filters = $this->renderFilters(); | |
| 217 | |
| 218 // Build code blocks for each relation type | |
| 219 $belongs = !empty($rendered['belongsTo']) ? implode("\n ", $rendered['belongsTo']) : ''; | |
| 220 $hasMany = !empty($rendered['hasMany']) ? implode("\n ", $rendered['hasMany']) : ''; | |
| 221 $belongsMany = !empty($rendered['belongsToMany']) ? implode("\n ", $rendered['belongsToMany']) : ''; | |
| 222 | |
| 223 // Default relations are based on the belongsTo relationship | |
| 224 $default_relations = implode(", \n", array_map(function ($rel) {return '\'' . Str::singular($rel['table']) . '\''; }, $relations['belongsTo'])); | |
| 225 | |
| 226 // Assign to stub placeholders | |
| 227 $inserts['# {{ belongs_to_relationships }}'] = $belongs; | |
| 228 $inserts['# {{ has_many_relationships }}'] = $hasMany; | |
| 229 $inserts['# {{ has_many_through_relationships }}'] = $belongsMany; | |
| 230 $inserts['# {{ defaultRelationsInsertPoint }}'] = $default_relations; | |
| 231 $inserts['# {{ defaultFiltersInsertPoint }}'] = $filters; | |
| 232 | |
| 233 return $inserts; | |
| 234 } | |
| 78 } | 235 } |
