view src/Generator/Factory/FactoryGenerator.php @ 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
children 76584181267a
line wrap: on
line source

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