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;
+    }
 }