Mercurial > packages > magicforger
changeset 35:55d2e5c5dad9 ls_dev_2025_09
Working on the factory, it's in a semi working state but obviously not complete
| author | Luka Sitas <sitas.luka.97@gmail.com> |
|---|---|
| date | Thu, 11 Sep 2025 21:25:51 -0400 |
| parents | f65ab84ee47f |
| children | 76584181267a |
| files | .vimrc src/Generator/Factory/FactoryGenerator.php src/Generator/Factory/snippets/column.stub src/Generator/Factory/stubs/factory.stub src/MagicForgerServiceProvider.php src/Replacer/Replacer.php |
| diffstat | 6 files changed, 244 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/.vimrc Wed Sep 10 21:00:47 2025 -0400 +++ b/.vimrc Thu Sep 11 21:25:51 2025 -0400 @@ -11,6 +11,11 @@ nnoremap <C-l> :ALECodeAction <cr> set mouse=a +function! GeneratePhpCtags() + let command = 'ctags -R --fields=+aimS --php-kinds=cdfint --languages=php --extras=+q --tag-relative=yes --exclude=".git" --exclude=".hg" --exclude="node_modules" --exclude="composer.phar" --totals=yes' + let output = system(command) +endfunction + function! FixPhpFiles() " Save the current cursor position let save_cursor = getpos(".")
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/Generator/Factory/FactoryGenerator.php Thu Sep 11 21:25:51 2025 -0400 @@ -0,0 +1,180 @@ +<?php + +namespace Wizard\MagicForger\Generator\Factory; + +use Symfony\Component\Console\Attribute\AsCommand; +use Wizard\MagicForger\Generator\BaseGenerator; +use Wizard\MagicForger\Helpers\RelationshipNavigator; +use Illuminate\Support\Str; + +#[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()); + + return $relations; + + } + + protected function renderColumns() { + $insert = ''; + foreach ($this->get_columns() as $column) { + if (in_array($column['name'], $this->columns_to_ignore)) { + continue; + } + + + $type = $column['type_name']; + $nullable = ($column['nullable'] ? '->optional($weight = 0.5)' : '' ); + $name = $column['name']; + + // Get the expected header name + $replacements = [ + '{{value}}' => 'fake()' . $nullable . '->text()', + '{{column_name}}' => $name, + ]; + + // date + if (in_array($type, ['date'])) { + $replacements['{{value}}'] = 'fake()' . $nullable . '->date()'; + } + // time + if (in_array($type, ['timestamp'])) { + $replacements['{{value}}'] = 'fake()' . $nullable . '->timestamp()'; + } + // checkbox + if (in_array($type, ['tinyint'])) { + $replacements['{{value}}'] = 'fake()' . $nullable . '->boolean()'; + } + // select + elseif (in_array($type, ['bigint']) && array_key_exists($name, $selects)) { + $replacements['{{header}}'] = Str::headline(Str::singular($selects[$name])); + $replacements['{{value}}'] = '{{ $item->'.Str::singular($selects[$name]).'?->name ?? "" }}'; + } + // bigint, float + elseif (in_array($type, ['bigint', 'float', 'int'])) { + $replacements['{{valueClass}}'] .= ' text-start'; + } else { + // text area + // varchar, , etc + } + + $snippet = $this->getSnippet('index/value'); + // Replace placeholders with actual values + $values[] = str_replace( + array_keys($replacements), + $replacements, + $snippet + ); + + + + $tableName = $this->getCurrentTable(); + $value = 'value'; // TODO: this should be determined based on column type + $columnName = $column['name']; + + // Replace placeholders with actual values + $string = str_replace( + ['{{value}}', '{{columnName}}'], + [$value, $columnName], + $snippet + ); + $insert .= sprintf("%s", $string); + } + dd('done'); + + return $insert; + } + + /** + * 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 + $columns = $this->renderColumns(); + + // Assign to stub placeholders + $inserts['# {{ factoryInsertPoint }}'] = $columns; + + return $inserts; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/Generator/Factory/snippets/column.stub Thu Sep 11 21:25:51 2025 -0400 @@ -0,0 +1,6 @@ +'{{columnName}}' => [ + 'column_name' => '{{columnName}}', + 'table' => '{{tableName}}', + 'display' => '{{columnDisplay}}', + 'type' => '{{value}}', +],
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/Generator/Factory/stubs/factory.stub Thu Sep 11 21:25:51 2025 -0400 @@ -0,0 +1,35 @@ +<?php + +namespace Database\Factories; + +use App\Models\{{ modelName }}; +use Illuminate\Database\Eloquent\Factories\Factory; +use Illuminate\Support\Facades\Hash; +use Illuminate\Support\Str; + +/** + * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\{{ modelName }}> + */ +class {{ class }} extends Factory +{ + + /** + * The name of the factory's corresponding model. + * + * @var class-string<\Illuminate\Database\Eloquent\Model> + */ + protected $model = {{ modelName }}::class; + + /** + * Define the model's default state. + * + * @return array<string, mixed> + */ + public function definition(): array + { + return [ + # {{ factoryInsertPoint }} + ]; + } + +}
--- a/src/MagicForgerServiceProvider.php Wed Sep 10 21:00:47 2025 -0400 +++ b/src/MagicForgerServiceProvider.php Thu Sep 11 21:25:51 2025 -0400 @@ -5,6 +5,7 @@ use Illuminate\Support\ServiceProvider; use Wizard\MagicForger\Generator\Controller\ControllerGenerator; use Wizard\MagicForger\Generator\Generator; +use Wizard\MagicForger\Generator\Factory\FactoryGenerator; use Wizard\MagicForger\Generator\Model\ModelGenerator; use Wizard\MagicForger\Generator\Requests\RequestGenerator; use Wizard\MagicForger\Generator\Requests\FilterRequestGenerator; @@ -37,6 +38,7 @@ IndexViewGenerator::class, CreateEditViewGenerator::class, ShowViewGenerator::class, + FactoryGenerator::class, ]); }
--- a/src/Replacer/Replacer.php Wed Sep 10 21:00:47 2025 -0400 +++ b/src/Replacer/Replacer.php Thu Sep 11 21:25:51 2025 -0400 @@ -157,6 +157,14 @@ return Str::singular(Str::studly($name)); } + /** + * Generate factory name in Studly case. + */ + public function factory_name(string $name): string + { + return Str::singular(Str::studly($name)) . 'Factory'; + } + // Namespace Methods // These methods handle the formation of various namespaces used within the replacements. @@ -267,6 +275,14 @@ return $this->getViewNamespace($name) . '\\'; } + /** + * Get the factory namespace. + */ + public function getFactoryNamespace(string $name = ''): string + { + return database_path() + . DIRECTORY_SEPARATOR . 'factories' ; + } /** * Get the request uses string for replacement.
