# HG changeset patch # User Luka Sitas # Date 1740617108 18000 # Node ID f0b0d014e448d1673d44f418aa17253f84984a93 # Parent 81a76472ba21b2a41f884a67e643ba743f489392 Cleaning up code based on AI overlord review diff -r 81a76472ba21 -r f0b0d014e448 src/Generator/BaseGenerator.php --- a/src/Generator/BaseGenerator.php Wed Feb 26 19:29:55 2025 -0500 +++ b/src/Generator/BaseGenerator.php Wed Feb 26 19:45:08 2025 -0500 @@ -2,77 +2,43 @@ namespace Wizard\MagicForger\Generator; -use DB; use Illuminate\Console\GeneratorCommand; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; use Wizard\MagicForger\Replacer\Replacer; use Wizard\MagicForger\Replacer\TableReplacer; +use Illuminate\Support\Facades\DB; +use InvalidArgumentException; abstract class BaseGenerator extends GeneratorCommand { use Replacer; use TableReplacer; - /** - * The schema of the database. - * - * @var string - */ - protected $schema; - - /** - * The tables available in the schema. - * - * @var array - */ - protected $tables; - - /** - * The current Table being used. - * - * @var table - */ + protected string $schema; + protected array $tables; protected $currentTable; - /** - * Execute the console command. - */ public function handle() { - // First we need to ensure that the table exists, then we can if (!$this->tableExists($this->getTableInput())) { - $this->components->error('The table: "'.$this->getTableInput().'" does not exist in the database.'); - + $this->components->error('The table: "' . $this->getTableInput() . '" does not exist in the database.'); return false; } $this->setCurrentTable($this->getTableInput()); - $path = $this->getPath(); - $file = $this->getFile($path); - $file = $this->apply_replacements($file); - $file = $this->apply_inserts($file); - $this->makeDirectory($path); - $this->files->put($path, $this->sortImports($file)); - $this->format_file($path); - - $info = $this->type; - - $this->components->info(sprintf('%s [%s] created successfully.', $info, $path)); + $this->components->info(sprintf('%s [%s] created successfully.', $this->type, $path)); } - /** - * Override the original so that we can prompt for a table with autocomplete. - */ - protected function promptForMissingArguments(InputInterface $input, OutputInterface $output) + protected function promptForMissingArguments(InputInterface $input, OutputInterface $output): void { $prompted = false; if (is_null($input->getArgument('table'))) { @@ -84,133 +50,82 @@ $this->possibleTables() ); } - $input->setArgument('table', $table); } parent::promptForMissingArguments($input, $output); - // This will get missed if we prompt here but not in the parent if ($prompted) { $this->afterPromptingForMissingArguments($input, $output); } } - /** - * Get the console command arguments. - * - * @return array - */ - protected function getArguments() + protected function getArguments(): array { return [ ['table', InputOption::VALUE_REQUIRED, 'The table to generate files for.'], ]; } - /** - * Prompt for missing input arguments using the returned questions. - * - * @return array - */ - protected function promptForMissingArgumentsUsing() + protected function promptForMissingArgumentsUsing(): array { - return [ - ]; + return []; } - /** - * Get the console command options. - * - * @return array - */ - protected function getOptions() + protected function getOptions(): array { return [ ['fresh', 'f', InputOption::VALUE_NONE, 'Start from the stub or use existing if possible.'], ]; } - /** - * Interact further with the user if they were prompted for missing arguments. - * - * @return void - */ - protected function afterPromptingForMissingArguments(InputInterface $input, OutputInterface $output) + protected function afterPromptingForMissingArguments(InputInterface $input, OutputInterface $output): void { + // Additional logic after prompting goes here } - /** - * Determines if the file exists. - */ protected function fileExists(string $path): bool { return $this->files->exists($path); } - /** - * Gets the file that will be worked on. If there is already an existing file - * then we can open that. However if we are forcing the operation, then we - * will start with an empty stub. - */ - protected function getFile($name) + protected function getFile($name): string { - if (!($this->hasOption('fresh') - && $this->option('fresh')) - && $this->fileExists($name)) { - // Working with an existing file + if (!($this->hasOption('fresh') && $this->option('fresh')) && $this->fileExists($name)) { return $this->files->get($name); } - // Working with a stub return $this->files->get($this->getStub()); } - /** - * Get the desired class table from the input. - * - * @return string - */ - protected function getTableInput() + protected function getTableInput(): string { return trim($this->argument('table')); } - /** - * Determines if the table exists in the current database. - */ protected function tableExists(string $table_name): bool { return in_array($table_name, $this->getTables()); } - /** - * Get a list of possible table names. - */ - protected function possibleTables() + protected function possibleTables(): array { return $this->getTables(); } - /** - * Get the tables in the schema. - */ - protected function getTables() + protected function getTables(): array { if (is_null($this->tables)) { - $this->tables = collect($this->getSchema()->listTableNames())->all(); + $this->tables = DB::connection()->getDoctrineSchemaManager()->listTableNames(); } return $this->tables; } - - /** - * Get the database schema for DB interactions. - */ + protected function getSchema() { if (is_null($this->schema)) { - $this->schema = \DB::connection()->getDoctrineSchemaManager(); + $this->schema = DB::connection()->getDoctrineSchemaManager(); } return $this->schema; @@ -226,17 +141,13 @@ return $this->currentTable; } - protected function setCurrentTable(string $table_name) + protected function setCurrentTable(string $table_name): void { - $table = null; - if (!is_null($table_name) && '' !== trim($table_name)) { - $table = $this->getTable($table_name); - } - $this->currentTable = $table; + $this->currentTable = !empty(trim($table_name)) ? $this->getTable($table_name) : null; } - protected function format_file(string $path) + protected function format_file(string $path): void { - exec('php-cs-fixer fix '.$path); + exec('php-cs-fixer fix ' . escapeshellarg($path)); } } diff -r 81a76472ba21 -r f0b0d014e448 src/Generator/Controller/ControllerGenerator.php --- a/src/Generator/Controller/ControllerGenerator.php Wed Feb 26 19:29:55 2025 -0500 +++ b/src/Generator/Controller/ControllerGenerator.php Wed Feb 26 19:45:08 2025 -0500 @@ -31,8 +31,10 @@ /** * Execute the console command. + * + * @return void */ - public function handle() + public function handle(): void { parent::handle(); } @@ -42,7 +44,7 @@ * * @return string */ - protected function getStub() + protected function getStub(): string { return $this->resolveStubPath('/stubs/controller.stub'); } @@ -51,28 +53,38 @@ * Resolve the fully-qualified path to the stub. * * @param string $stub + * @return string + */ + protected function resolveStubPath(string $stub): string + { + $customPath = $this->laravel->basePath(trim($stub, '/')); + + return is_file($customPath) ? $customPath : __DIR__ . $stub; + } + + /** + * Get the path for the generated file. * + * @param string|null $name * @return string */ - protected function resolveStubPath($stub) + protected function getPath(?string $name = null): string { - return is_file($customPath = $this->laravel->basePath(trim($stub, '/'))) - ? $customPath - : __DIR__.$stub; + return str_replace( + ['App\\', '\\'], + ['app/', '/'], + $this->getControllerNamespace() . '/' . $this->controller_name($this->getTableInput()) . '.php' + ); } - protected function getClassName($name) + /** + * Get the class name for the controller. + * + * @param string $name + * @return string + */ + protected function getClassName(string $name): string { return $this->controller_name($name); } - - /** - * Get the stub file for the generator. - * - * @return string - */ - protected function getPath($name = null) - { - return str_replace(['App\\', '\\'], ['app/', '/'], $this->getControllerNamespace().'/'.$this->controller_name($this->getTableInput()).'.php'); - } } diff -r 81a76472ba21 -r f0b0d014e448 src/Generator/Controller/stubs/controller.stub --- a/src/Generator/Controller/stubs/controller.stub Wed Feb 26 19:29:55 2025 -0500 +++ b/src/Generator/Controller/stubs/controller.stub Wed Feb 26 19:45:08 2025 -0500 @@ -10,90 +10,102 @@ { /** * Display a listing of the resource. + * + * @return \Illuminate\View\View */ public function index() { - $data = []; - - $data['items'] = {{ model }}::all(); + $data = []; + $data['items'] = {{ model }}::all(); return view('{{ tableName }}.index', $data); } /** * Show the form for creating a new resource. + * + * @return \Illuminate\View\View */ public function create() { - $data = []; + $data = []; return view('{{ tableName }}.create_edit', $data); } /** * Store a newly created resource in storage. + * + * @param {{ storeRequest }} $request + * @return \Illuminate\Http\RedirectResponse */ public function store({{ storeRequest }} $request) { - $validated = $request->validated(); + $validated = $request->validated(); - // - ${{ modelVariable }} = new {{ model }}($validated); - - ${{ modelVariable }}->save(); + ${{ modelVariable }} = new {{ model }}($validated); + ${{ modelVariable }}->save(); return redirect()->route('{{ tableName }}.index'); } /** * Display the specified resource. + * + * @param {{ model }} ${{ modelVariable }} + * @return \Illuminate\View\View */ public function show({{ model }} ${{ modelVariable }}) { - $data = []; - - $data['item'] = ${{ modelVariable }}; + $data = []; + $data['item'] = ${{ modelVariable }}; - return view('{{ tableName }}.show', $data); + return view('{{ tableName }}.show', $data); } /** * Show the form for editing the specified resource. + * + * @param {{ model }} ${{ modelVariable }} + * @return \Illuminate\View\View */ public function edit({{ model }} ${{ modelVariable }}) { - $data = []; - - $data['item'] = ${{ modelVariable }}; + $data = []; + $data['item'] = ${{ modelVariable }}; - //load data for relationships + // Load data for relationships - return view('{{ tableName }}.create_edit', $data); + return view('{{ tableName }}.create_edit', $data); } /** * Update the specified resource in storage. + * + * @param {{ updateRequest }} $request + * @param {{ model }} ${{ modelVariable }} + * @return \Illuminate\Http\RedirectResponse */ public function update({{ updateRequest }} $request, {{ model }} ${{ modelVariable }}) { - $validated = $request->validated(); + $validated = $request->validated(); - // Set the variables ${{ modelVariable }}->map_values($validated); + ${{ modelVariable }}->save(); - ${{ modelVariable }}->save(); - - return redirect()->route('{{ tableName }}.index'); + return redirect()->route('{{ tableName }}.index'); } /** * Remove the specified resource from storage. + * + * @param {{ model }} ${{ modelVariable }} + * @return \Illuminate\Http\RedirectResponse */ public function destroy({{ model }} ${{ modelVariable }}) { - // - ${{ modelVariable }}->delete(); + ${{ modelVariable }}->delete(); - return redirect()->route('{{ tableName }}.index'); + return redirect()->route('{{ tableName }}.index'); } } diff -r 81a76472ba21 -r f0b0d014e448 src/Replacer/Replacer.php --- a/src/Replacer/Replacer.php Wed Feb 26 19:29:55 2025 -0500 +++ b/src/Replacer/Replacer.php Wed Feb 26 19:45:08 2025 -0500 @@ -12,7 +12,7 @@ * * @var string */ - protected $controller_prefix = ''; + protected string $controller_prefix = ''; /** * Prefix and Suffix for controller. @@ -20,16 +20,18 @@ * * @var string */ - protected $controller_suffix = 'Controller'; + protected string $controller_suffix = 'Controller'; /** * Finds all places in a string that could be replaced. - * Returns an array of all potential replacements as they - * appear in the target. + * Returns an array of all potential replacements as they appear in the target. + * + * @param string $target + * @return array */ public function get_all_keywords(string $target): array { - // find all the matches to our expected syntax + // find all matches to our expected syntax $matches = []; preg_match_all('/{{[\sa-zA-Z\-_]+}}/', $target, $matches); // sort the array and return unique values @@ -38,46 +40,55 @@ return array_values(array_unique($matches[0])); } + /** + * Apply replacements to the target string. + * + * @param string $target + * @return string + */ public function apply_replacements(string $target): string { $inserts = $this->get_all_keywords($target); $available_replacements = $this->get_available_replacements(); - $target = str_replace( + return str_replace( array_keys($available_replacements), $available_replacements, $target ); - - return $target; } + /** + * Get available replacements for string replacements. + * + * @return array + */ public function get_available_replacements(): array { $table_name = $this->getTableInput(); - $replacements = [ - '{{ class }}' => $this->getClassName($table_name), - '{{ controllerName }}' => $this->controller_name($table_name), - '{{ model }}' => $this->model_name($table_name), - '{{ modelVariable }}' => $this->model_variable($table_name), - '{{ namespace }}' => $this->{'get'.$this->type.'Namespace'}($table_name), - '{{ namespacedModel }}' => $this->getNamespacedModel($table_name), - '{{ requestUses }}' => $this->getRequestUses($table_name), - '{{ rootNamespace }}' => $this->getRootNamespace(), - '{{ storeRequest }}' => $this->store_request_name($table_name), - '{{ tableName }}' => $table_name, - '{{ updateRequest }}' => $this->update_request_name($table_name), + + return [ + '{{ class }}' => $this->getClassName($table_name), + '{{ controllerName }}' => $this->controller_name($table_name), + '{{ model }}' => $this->model_name($table_name), + '{{ modelVariable }}' => $this->model_variable($table_name), + '{{ namespace }}' => $this->{'get' . $this->type . 'Namespace'}($table_name), + '{{ namespacedModel }}' => $this->getNamespacedModel($table_name), + '{{ requestUses }}' => $this->getRequestUses($table_name), + '{{ rootNamespace }}' => $this->getRootNamespace(), + '{{ storeRequest }}' => $this->store_request_name($table_name), + '{{ tableName }}' => $table_name, + '{{ updateRequest }}' => $this->update_request_name($table_name), ]; - - return $replacements; } - // ////////////////////////////////////////// - // Internals and Classes // - // ////////////////////////////////////////// + // Model and Controller Naming /** - * Model names are generated in uppercase first Camel case. + * Generate model name in Studly case. + * + * @param string $name + * @return string */ public function model_name(string $name): string { @@ -85,95 +96,152 @@ } /** - * Model variable is standardly just a singular version of the table name. + * Generate singular model variable name. + * + * @param string $name + * @return string */ public function model_variable(string $name): string { return Str::singular($name); - /* return 'item'; */ } /** - * Controller names are generated in uppercase first Camel case - * and wrapped in the prefix and suffix. + * Generate controller name using prefix/suffix and studly case. + * + * @param string $name + * @return string */ public function controller_name(string $name): string { - return $this->controller_prefix. - $this->model_name($name). + return $this->controller_prefix . + $this->model_name($name) . $this->controller_suffix; } + /** + * Generate the store request name. + * + * @param string $name + * @return string + */ public function store_request_name(string $name): string { - return 'Store'.$this->model_name($name).'Request'; + return 'Store' . $this->model_name($name) . 'Request'; } + /** + * Generate the update request name. + * + * @param string $name + * @return string + */ public function update_request_name(string $name): string { - return 'Update'.$this->model_name($name).'Request'; + return 'Update' . $this->model_name($name) . 'Request'; } - // ////////////////////////////////////////// - // Namespaces // - // ////////////////////////////////////////// + // Namespace Methods + // These methods handle the formation of various namespaces used within the replacements. + /** + * Get the root namespace for the application. + * + * @return string + */ public function getRootNamespace(): string { return $this->laravel->getNamespace(); } + /** + * Get the model namespace. + * + * @param string $name + * @return string + */ public function getModelNamespace(string $name = ''): string { - return $this->getRootNamespace().'Models'; + return $this->getRootNamespace() . 'Models'; } + /** + * Get the fully-qualified namespaced model class. + * + * @param string $name + * @return string + */ public function getNamespacedModel(string $name = ''): string { - return $this->getModelNamespace().'\\'.$this->model_name($name); + return $this->getModelNamespace() . '\\' . $this->model_name($name); } + /** + * Get the controller namespace. + * + * @param string $name + * @return string + */ public function getControllerNamespace(string $name = ''): string { - return $this->getRootNamespace().'Http\\Controllers'; + return $this->getRootNamespace() . 'Http\\Controllers'; } + /** + * Get the request namespace. + * + * @param string $name + * @return string + */ public function getRequestNamespace(string $name): string { - return $this->getRootNamespace().'Http\\Requests\\'.$this->model_name($name); + return $this->getRootNamespace() . 'Http\\Requests\\' . $this->model_name($name); } + /** + * Get the store request namespace. + * + * @param string $name + * @return string + */ public function getStoreRequestNamespace(string $name): string { return $this->getRequestNamespace($name); } + /** + * Get the update request namespace. + * + * @param string $name + * @return string + */ public function getUpdateRequestNamespace(string $name): string { return $this->getRequestNamespace($name); } + /** + * Get the request uses string for replacement. + * + * @param string $name + * @return string + */ public function getRequestUses(string $name): string { return implode("\n", [ - 'use '.$this->getRequestNamespace($name).'\\'.$this->store_request_name($name).';', - 'use '.$this->getRequestNamespace($name).'\\'.$this->update_request_name($name).';', + 'use ' . $this->getRequestNamespace($name) . '\\' . $this->store_request_name($name) . ';', + 'use ' . $this->getRequestNamespace($name) . '\\' . $this->update_request_name($name) . ';', ]); } - public function getRouteNamespace(string $name = ''): string - { - return $this->getRootNamespace().'Http\\Controllers'; - } - - // ////////////////////////////////////////// - // Language and Presentables // - // ////////////////////////////////////////// + // Text Manipulation /** - * Breaks up a string and makes it human readable. + * Convert a string to a human-readable format. + * Assumes camel case input. * - * This function assumes that the inputted name is camel case + * @param string $name + * @return string */ public function human_readable(string $name): string { @@ -181,9 +249,11 @@ } /** - * Breaks up a string and makes it human readable and lowecase. + * Convert a string to a lowercase human-readable format. + * Assumes camel case input. * - * This function assumes that the inputted name is camel case + * @param string $name + * @return string */ public function human_readable_lc(string $name): string { diff -r 81a76472ba21 -r f0b0d014e448 src/Replacer/TableReplacer.php --- a/src/Replacer/TableReplacer.php Wed Feb 26 19:29:55 2025 -0500 +++ b/src/Replacer/TableReplacer.php Wed Feb 26 19:45:08 2025 -0500 @@ -4,9 +4,14 @@ trait TableReplacer { - protected $columns; + protected ?array $columns = null; - protected function get_columns() + /** + * Retrieve columns for the current table. + * + * @return array + */ + protected function get_columns(): array { if (is_null($this->columns)) { $this->columns = $this->getCurrentTable()->getColumns(); @@ -15,67 +20,80 @@ return $this->columns; } - protected function get_attributes() - { - } - + /** + * Get a string representation of values for creation. + * + * @return string + */ protected function getValuesForCreation(): string { $insert = ''; foreach ($this->get_columns() as $column) { - $insert .= '$item->'.$column->getName().' = $validated["'.$column->getName().'"] ?? NULL;'."\n"; + $insert .= sprintf('$item->%s = $validated["%s"] ?? NULL;', $column->getName(), $column->getName()) . "\n"; } return $insert; } + /** + * Get a string representation of table attributes. + * + * @return string + */ protected function getAttributes(): string { $insert = ''; foreach ($this->get_columns() as $column) { - $insert .= "'".$column->getName()."' => '',\n"; + $insert .= sprintf("'%s' => '',", $column->getName()) . "\n"; } return $insert; } + /** + * Get formatted validation rules for table columns. + * + * @return string + */ protected function getValuesForValidation(): string { $insert = ''; foreach ($this->get_columns() as $column) { - $insert .= "'".$column->getName()."' => 'nullable',\n"; + $insert .= sprintf("'%s' => 'nullable',", $column->getName()) . "\n"; } return $insert; } + /** + * Apply insertions in the target template. + * + * @param string $target + * @return string + */ public function apply_inserts(string $target): string { $inserts = $this->get_all_keywords($target); - $available_replacements = $this->get_available_inserts(); + $available_insertions = $this->get_available_inserts(); - $target = str_replace( - array_keys($available_replacements), - $available_replacements, + return str_replace( + array_keys($available_insertions), + $available_insertions, $target ); - - return $target; } - public function get_available_inserts() + /** + * Get available insertion points for the template. + * + * @return array + */ + public function get_available_inserts(): array { - $table_name = $this->getTableInput(); - $replacements = [ - '// {{ valuesForCreation }}' => self::getValuesForCreation(), - '# {{ atributeInsertPoint }}' => self::getAttributes(), - '// {{ valuesForValidation }}' => self::getValuesForValidation(), - ]; - - foreach ($replacements as $key => &$replacement) { - $replacement = $replacement."\n".$key; - } - - return $replacements; + return [ + '// {{ valuesForCreation }}' => $this->getValuesForCreation(), + '# {{ attributeInsertPoint }}' => $this->getAttributes(), + '// {{ valuesForValidation }}' => $this->getValuesForValidation(), + ]; } }