Mercurial > packages > magicforger
view src/Generator/Factory/FactoryGenerator.php @ 40:2cf26b593f4a ls_dev_2025_09 tip
better support for different column types
| author | Luka Sitas <sitas.luka.97@gmail.com> |
|---|---|
| date | Thu, 16 Oct 2025 10:54:04 -0400 |
| parents | b5c6ebd33547 |
| children |
line wrap: on
line source
<?php namespace Wizard\MagicForger\Generator\Factory; use Illuminate\Support\Str; use Symfony\Component\Console\Attribute\AsCommand; use Wizard\MagicForger\Generator\BaseGenerator; use Wizard\MagicForger\Helpers\RelationshipNavigator; #[AsCommand(name: 'mf:factory')] class FactoryGenerator extends BaseGenerator { /** * The name and signature of the console command. * * @var string */ protected $name = 'mf:factory'; /** * The console command description. * * @var string */ protected $description = 'Generates the Factory File for a table.'; /** * The type of class being generated. * * @var string */ protected $type = 'Factory'; 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() { return $this->resolveStubPath('/stubs/factory.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->factory_name($name); } /** * Get the stub file for the generator. * * @return string */ protected function getPath($name = null) { return str_replace(['App\\', '\\'], ['app/', '/'], $this->getFactoryNamespace().'/'.$this->factory_name($this->getTableInput()).'.php'); } protected function gatherRelations() { $relations = RelationshipNavigator::getRelations($this->getCurrentTable()); foreach ($relations as $relation_type => $relation_values) { $relations[$relation_type] = array_column($relation_values, null, 'column'); } return $relations; } protected function renderColumns() { $values = []; $relations = $this->gatherRelations(); foreach ($this->get_columns() as $column) { if (in_array($column['name'], $this->columns_to_ignore)) { continue; } $value = $this->getFakeValue($column, $relations); $snippet = $this->getSnippet('value'); // Replace placeholders with actual values $values[] = str_replace(['{{value}}', '{{column_name}}'], [$value, $column['name']], $snippet); } return implode("\n", $values); } protected function getFakeValue($column, $relations) { $value = '$this->faker'; $nullable = ($column['nullable'] ? '->optional($weight = 0.5)' : ''); switch ($column['type_name']) { case 'date': return "$value$nullable->date()"; case 'timestamp': return "$value$nullable->timestamp()"; case 'tinyint': return "$value$nullable->numberBetween(0,1)"; case 'bigint': if (isset($relations['belongsTo'][$column['name']])) { $related = $this->getNamespacedModel($relations['belongsTo'][$column['name']]['table']); return "$related::factory()"; } // fall through to int for lack of better option case 'int': return "$value$nullable->randomNumber()"; case 'float': return "$value$nullable->randomFloat()"; default: return "$value$nullable->text()"; } } /** * Get available insertions including model relationships. */ public function get_available_inserts(): array { // Merge parent insertions (attributes, fillable, etc.) $inserts = parent::get_available_inserts(); // Gather and render relationships for this model $columns = $this->renderColumns(); // Assign to stub placeholders $inserts['# {{ factoryInsertPoint }}'] = $columns; return $inserts; } }
