Mercurial > packages > magicforger
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 } |
