comparison src/Generator/Factory/FactoryGenerator.php @ 45:c7fd31303024 default tip

merging down to default
author Luka Sitas <sitas.luka.97@gmail.com>
date Thu, 12 Nov 2026 21:19:53 -0500
parents 59eb5b4424ca
children
comparison
equal deleted inserted replaced
34:f65ab84ee47f 45:c7fd31303024
1 <?php
2
3 namespace Wizard\MagicForger\Generator\Factory;
4
5 use Illuminate\Support\Str;
6 use Symfony\Component\Console\Attribute\AsCommand;
7 use Wizard\MagicForger\Generator\BaseGenerator;
8 use Wizard\MagicForger\Helpers\RelationshipNavigator;
9
10 #[AsCommand(name: 'mf:factory')]
11 class FactoryGenerator extends BaseGenerator
12 {
13 /**
14 * The name and signature of the console command.
15 *
16 * @var string
17 */
18 protected $name = 'mf:factory';
19
20 /**
21 * The console command description.
22 *
23 * @var string
24 */
25 protected $description = 'Generates the Factory File for a table.';
26
27 /**
28 * The type of class being generated.
29 *
30 * @var string
31 */
32 protected $type = 'Factory';
33
34 protected static $cached_snippets = [];
35
36 /**
37 * Execute the console command.
38 *
39 * @return mixed
40 */
41 public function handle()
42 {
43 // Delegate to parent handler (includes replacements and insertions)
44 return parent::handle();
45 }
46
47 /**
48 * Get the stub file for the generator.
49 *
50 * @return string
51 */
52 protected function getStub()
53 {
54 return $this->resolveStubPath('/stubs/factory.stub');
55 }
56
57 /**
58 * Resolve the fully-qualified path to the stub.
59 *
60 * @param string $stub
61 * @return string
62 */
63 protected function resolveStubPath($stub)
64 {
65 return is_file($customPath = $this->laravel->basePath(trim($stub, '/')))
66 ? $customPath
67 : __DIR__.$stub;
68 }
69
70 protected function getClassName($name)
71 {
72 return $this->factory_name($name);
73 }
74
75 /**
76 * Get the stub file for the generator.
77 *
78 * @return string
79 */
80 protected function getPath($name = null)
81 {
82 return str_replace(['App\\', '\\'], ['app/', '/'], $this->getFactoryNamespace().'/'.$this->factory_name($this->getTableInput()).'.php');
83 }
84
85 protected function gatherRelations()
86 {
87 $relations = RelationshipNavigator::getRelations($this->getCurrentTable());
88 foreach ($relations as $relation_type => $relation_values) {
89 $relations[$relation_type] = array_column($relation_values, null, 'column');
90 }
91
92 return $relations;
93 }
94
95 protected function renderColumns()
96 {
97 $values = [];
98 $relations = $this->gatherRelations();
99
100 foreach ($this->get_columns() as $column) {
101 if (in_array($column['name'], $this->columns_to_ignore)) {
102 continue;
103 }
104
105 $value = $this->getFakeValue($column, $relations);
106 $snippet = $this->getSnippet('value');
107
108 // Replace placeholders with actual values
109 $values[] = str_replace(['{{value}}', '{{column_name}}'], [$value, $column['name']], $snippet);
110 }
111
112 return implode("\n", $values);
113 }
114
115 protected function getFakeValue($column, $relations)
116 {
117 $value = '$this->faker';
118 $nullable = ($column['nullable'] ? '->optional($weight = 0.5)' : '');
119
120 switch ($column['type_name']) {
121 case 'date':
122 return "$value${nullable}->date()";
123 case 'timestamp':
124 return "$value${nullable}->timestamp()";
125 case 'tinyint':
126 return "$value${nullable}->numberBetween(0,1)";
127 case 'bigint':
128 if (isset($relations['belongsTo'][$column['name']])) {
129 $related = $this->getNamespacedModel($relations['belongsTo'][$column['name']]['table']);
130 return "$related::factory()";
131 }
132 // fall through to int for lack of better option
133 case 'int':
134 return "$value${nullable}->randomNumber()";
135 case 'float':
136 return "$value${nullable}->randomFloat()";
137 default:
138 return "$value${nullable}->text()";
139 }
140 }
141
142 /**
143 * Get available insertions including model relationships.
144 */
145 public function get_available_inserts(): array
146 {
147 // Merge parent insertions (attributes, fillable, etc.)
148 $inserts = parent::get_available_inserts();
149
150 // Gather and render relationships for this model
151 $columns = $this->renderColumns();
152
153 // Assign to stub placeholders
154 $inserts['# {{ factoryInsertPoint }}'] = $columns;
155
156 return $inserts;
157 }
158 }