Mercurial > packages > magicforger
changeset 23:827efbf4d73c main-dev
Huge changes to the relationships for models and more complex
line wrap: on
line diff
--- a/.hgignore Wed Feb 26 20:12:17 2025 -0500 +++ b/.hgignore Fri Apr 11 20:50:20 2025 -0400 @@ -5,4 +5,5 @@ *.env.production .php-cs-fixer.cache *.aichat +tags
--- a/.vimrc Wed Feb 26 20:12:17 2025 -0500 +++ b/.vimrc Fri Apr 11 20:50:20 2025 -0400 @@ -28,30 +28,6 @@ " Committing commands map <C-k> :wa<CR>:!hg addremove && hg commit <CR> -" Git commands, for now don't port to hg -" function! GitDiffCached() -" let files = system('git diff --cached --name-only') -" -" if v:shell_error -" echo "Error running git diff" -" return -" endif -" -" let filelist = split(files, "\n") -" let chosen_file = inputlist(filelist) -" -" if chosen_file != -1 -" let cmd = 'tabnew ' . filelist[chosen_file] -" execute cmd -" endif -" endfunction -" -" execute "set <M-d>=\033d" -" map <M-d> :call GitDiffCached()<CR> -" -" -" -" function! SendBufferToProgram()
--- a/src/ConfigHelper.php Wed Feb 26 20:12:17 2025 -0500 +++ b/src/ConfigHelper.php Fri Apr 11 20:50:20 2025 -0400 @@ -69,8 +69,7 @@ * * @see https://www.php.net/manual/en/function.var-export.php * - * @param bool $return - * + * @param bool $return * @return string|string[]|null */ public static function varexport(mixed $expression, $return = false): string|array|null @@ -125,9 +124,9 @@ $foreign_keys_list = $table_foreign_keys[$table]; foreach ($foreign_keys_list as $fk) { $foreign_keys[$fk->getLocalColumns()[0]] = [ - 'foreign_table' => $fk->getForeignTableName(), - 'foreign_column' => $fk->getForeignColumns()[0], - ]; + 'foreign_table' => $fk->getForeignTableName(), + 'foreign_column' => $fk->getForeignColumns()[0], + ]; } foreach ($table_columns as $column) { @@ -136,14 +135,14 @@ $class_name = end($class_parts); $columns[$column->getName()] = [ - 'type' => $class_name, - 'should_insert' => [ - 'controller' => true, - 'model' => true, - 'requests' => true, - 'views' => true, - ], - ]; + 'type' => $class_name, + 'should_insert' => [ + 'controller' => true, + 'model' => true, + 'requests' => true, + 'views' => true, + ], + ]; } // Check foreign key references to this table foreach ($tables as $other_table) { @@ -152,9 +151,9 @@ foreach ($foreign_keys_list as $fk) { if ($fk->getForeignTableName() == $table) { $foreign_keys_reverse[] = [ - 'table' => $other_table, - 'column' => $fk->getLocalColumns()[0], - ]; + 'table' => $other_table, + 'column' => $fk->getLocalColumns()[0], + ]; } } } @@ -174,14 +173,14 @@ /** * Merge two arrays and ensure priority values do not get overwritten. * - * @param array $priority - * @param array $merged + * @param array $priority + * @param array $merged */ private static function merge_array_priority(&$priority, $merged): void { foreach ($merged as $key => $value) { // if the priority key is not set, automatically add the merged values - if (!isset($priority[$key])) { + if (! isset($priority[$key])) { $priority[$key] = $value; } else { // if the value is an array recursively merge with priority
--- a/src/Generator/BaseGenerator.php Wed Feb 26 20:12:17 2025 -0500 +++ b/src/Generator/BaseGenerator.php Fri Apr 11 20:50:20 2025 -0400 @@ -3,27 +3,30 @@ namespace Wizard\MagicForger\Generator; use Illuminate\Console\GeneratorCommand; +use Illuminate\Support\Facades\Schema; 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; - protected string $schema; - protected array $tables; - protected $currentTable; + protected $schema = null; + + protected $tables = null; + + protected $currentTable = null; public function handle() { - if (!$this->tableExists($this->getTableInput())) { - $this->components->error('The table: "' . $this->getTableInput() . '" does not exist in the database.'); + + if (! $this->tableExists($this->getTableInput())) { + $this->components->error('The table: "'.$this->getTableInput().'" does not exist in the database.'); + return false; } @@ -44,7 +47,7 @@ if (is_null($input->getArgument('table'))) { $prompted = true; $table = null; - while (null === $table) { + while ($table === null) { $table = $this->components->askWithCompletion( 'What Table should we use?', $this->possibleTables() @@ -91,7 +94,7 @@ protected function getFile($name): string { - if (!($this->hasOption('fresh') && $this->option('fresh')) && $this->fileExists($name)) { + if (! ($this->hasOption('fresh') && $this->option('fresh')) && $this->fileExists($name)) { return $this->files->get($name); } @@ -116,26 +119,60 @@ protected function getTables(): array { if (is_null($this->tables)) { - $this->tables = DB::connection()->getDoctrineSchemaManager()->listTableNames(); + $this->tables = Schema::getTableListing(schema: config('database.connections.mariadb.database'), schemaQualified: false); } return $this->tables; } - - protected function getSchema() - { - if (is_null($this->schema)) { - $this->schema = DB::connection()->getDoctrineSchemaManager(); - } - - return $this->schema; - } protected function getTable(string $table_name) { return $this->getSchema()->introspectTable($table_name); } + /* + * returns array of columns in the form of: + * + [ + "name" => "column_type" + "type_name" => "bigint" + "type" => "bigint(20) unsigned" + "collation" => null + "nullable" => true + "default" => "NULL" + "auto_increment" => false + "comment" => null + "generation" => null + ] + */ + protected static function getTableColumns(string $table_name) + { + return Schema::getColumns($table_name); + } + + /* + * returns array of foreign keys in the form of: + * + [ + "name" => "foreign_key_name" + "columns" => [ + 0 => "local_column_name" + ] + "foreign_schema" => "schema_name" + "foreign_table" => "foreign_table_name" + "foreign_columns" => [ + 0 => "foreign_column_name" + ] + "on_update" => "restrict" + "on_delete" => "restrict" + ] + * + */ + protected static function getTableForeignKeys(string $table_name) + { + return Schema::getForeignKeys($table_name); + } + protected function getCurrentTable() { return $this->currentTable; @@ -143,11 +180,11 @@ protected function setCurrentTable(string $table_name): void { - $this->currentTable = !empty(trim($table_name)) ? $this->getTable($table_name) : null; + $this->currentTable = $table_name; } protected function format_file(string $path): void { - exec('php-cs-fixer fix ' . escapeshellarg($path)); + exec('./vendor/bin/pint '.escapeshellarg($path)); } }
--- a/src/Generator/Controller/ControllerGenerator.php Wed Feb 26 20:12:17 2025 -0500 +++ b/src/Generator/Controller/ControllerGenerator.php Fri Apr 11 20:50:20 2025 -0400 @@ -31,8 +31,6 @@ /** * Execute the console command. - * - * @return void */ public function handle(): void { @@ -41,8 +39,6 @@ /** * Get the stub file for the generator. - * - * @return string */ protected function getStub(): string { @@ -51,15 +47,12 @@ /** * 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; + return is_file($customPath) ? $customPath : __DIR__.$stub; } /** @@ -70,15 +63,12 @@ return str_replace( ['App\\', '\\'], ['app/', '/'], - $this->getControllerNamespace() . '/' . $this->controller_name($this->getTableInput()) . '.php' + $this->getControllerNamespace().'/'.$this->controller_name($this->getTableInput()).'.php' ); } /** * Get the class name for the controller. - * - * @param string $name - * @return string */ protected function getClassName(string $name): string {
--- a/src/Generator/Controller/stubs/controller.stub Wed Feb 26 20:12:17 2025 -0500 +++ b/src/Generator/Controller/stubs/controller.stub Fri Apr 11 20:50:20 2025 -0400 @@ -43,8 +43,7 @@ { $validated = $request->validated(); - ${{ modelVariable }} = new {{ model }}($validated); - ${{ modelVariable }}->save(); + {{ model }}::create($validated); return redirect()->route('{{ tableName }}.index'); } @@ -90,8 +89,7 @@ { $validated = $request->validated(); - ${{ modelVariable }}->map_values($validated); - ${{ modelVariable }}->save(); + ${{ modelVariable }}->update($validated); return redirect()->route('{{ tableName }}.index'); }
--- a/src/Generator/Generator.php Wed Feb 26 20:12:17 2025 -0500 +++ b/src/Generator/Generator.php Fri Apr 11 20:50:20 2025 -0400 @@ -29,8 +29,9 @@ */ public function handle() { + // First we need to ensure that the table exists, then we can - if (!$this->tableExists($this->getTableInput())) { + if (! $this->tableExists($this->getTableInput())) { $this->components->error('The table: "'.$this->getTableInput().'" does not exist in the database.'); return false; @@ -80,8 +81,6 @@ /** * Get the console command options. - * - * @return array */ protected function getOptions(): array { @@ -96,16 +95,10 @@ /** * Interact further with the user if they were prompted for missing arguments. - * - * @return void */ - protected function afterPromptingForMissingArguments(InputInterface $input, OutputInterface $output):void - { - } + protected function afterPromptingForMissingArguments(InputInterface $input, OutputInterface $output): void {} - protected function getStub():void - { - } + protected function getStub(): void {} protected function createController(): void {
--- a/src/Generator/Model/ModelGenerator.php Wed Feb 26 20:12:17 2025 -0500 +++ b/src/Generator/Model/ModelGenerator.php Fri Apr 11 20:50:20 2025 -0400 @@ -4,6 +4,7 @@ use Symfony\Component\Console\Attribute\AsCommand; use Wizard\MagicForger\Generator\BaseGenerator; +use Wizard\MagicForger\Helpers\RelationshipNavigator; #[AsCommand(name: 'mf:model')] class ModelGenerator extends BaseGenerator @@ -29,12 +30,19 @@ */ protected $type = 'Model'; + protected static $cached_snippets = []; + /** * Execute the console command. */ public function handle() { - parent::handle(); + + $belongs_to_many_relations = RelationshipNavigator::getRelations($this->getTableInput()); + dd($belongs_to_many_relations); + echo $this->renderBelongsToMany($belongs_to_many_relations['hasManyThrough'][0]); + dd('here'); + /* parent::handle(); */ } /** @@ -44,14 +52,17 @@ */ protected function getStub() { + if (! is_null(RelationshipNavigator::isPivot($this->getCurrentTable()))) { + return $this->resolveStubPath('/stubs/model.pivot.stub'); + } + return $this->resolveStubPath('/stubs/model.stub'); } /** * Resolve the fully-qualified path to the stub. * - * @param string $stub - * + * @param string $stub * @return string */ protected function resolveStubPath($stub) @@ -75,4 +86,77 @@ { return str_replace(['App\\', '\\'], ['app/', '/'], $this->getModelNamespace().'/'.$this->model_name($this->getTableInput()).'.php'); } + + protected function getSnippet($snippet_name) + { + if (! isset($cached_snippets[$snippet_name])) { + $cached_snippets[$snippet_name] = $this->files->get( + $this->resolveStubPath("/snippets/$snippet_name.stub")); + } + + return $cached_snippets[$snippet_name]; + } + + protected function gatherRelations() { + $relations = RelationshipNavigator::getRelations($this->getCurrentTable()); + + return renderRelations($relations); + + } + + protected function renderRelations($relations) { + $renders = [ + 'belongsTo' => [], + 'hasMany' => [], + 'belongsToMany' => [], + ]; + foreach($relations['belongsTo'] as $belongs_to_relation) { + $renders['belongsTo'] = $this->renderBelongsTo($belongs_to_relation); + } + + foreach($relations['hasMany'] as $has_many_relation) { + $renders['hasMany'] = $this->renderHasMany($has_many_relation); + } + + foreach($relations['belongsToMany'] as $belongs_to_many_relation) { + $renders['belongsToMany'] = $this->renderBelongsToMany($belongs_to_many_relation); + } + return $renders; + } + + protected function renderBelongsTo($relationship) + { + $snippet = $this->getSnippet('belongs_to_relation'); + $relationName = Str::singular($relationship['table']); + $relatedModel = $this->getClassName($relationship['table']); + $columnName = $relationship['column']; + + // Replace placeholders with actual values + $string = str_replace( + ['{{relationName}}', '{{relatedModel}}', '{{pivotTable}}', '{{foreignPivotKey}}', '{{relatedPivotKey}}'], + [$relationName, $relatedModel, $pivotTable, $foreignPivotKey, $relatedPivotKey], + $snippet + ); + + return $string; + } + + protected function renderBelongsToMany($relationship) + { + $snippet = $this->getSnippet('belongs_to_many_relation'); + $relationName = $relationship['table']; + $relatedModel = $this->getClassName($relationship['table']); + $pivotTable = $relationship['through']['table']; + $foreignPivotKey = $relationship['through']['external_column']; + $relatedPivotKey = $relationship['through']['internal_column']; + + // Replace placeholders with actual values + $string = str_replace( + ['{{relationName}}', '{{relatedModel}}', '{{pivotTable}}', '{{foreignPivotKey}}', '{{relatedPivotKey}}'], + [$relationName, $relatedModel, $pivotTable, $foreignPivotKey, $relatedPivotKey], + $snippet + ); + + return $string; + } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/Generator/Model/snippets/belongs_to_many_relation.stub Fri Apr 11 20:50:20 2025 -0400 @@ -0,0 +1,6 @@ + +public function {{relationName}}() +{ + return $this->belongsToMany({{relatedModel}}::class, '{{pivotTable}}', '{{foreignPivotKey}}', '{{relatedPivotKey}}'); +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/Generator/Model/snippets/belongs_to_relation.stub Fri Apr 11 20:50:20 2025 -0400 @@ -0,0 +1,6 @@ + +public function {{relationName}}() +{ + return $this->belongsTo({{relatedModel}}::class, '{{columnName}}'); +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/Generator/Model/snippets/has_many_relation.stub Fri Apr 11 20:50:20 2025 -0400 @@ -0,0 +1,4 @@ +public function {{ $relationhip_name }}() +{ + return $this->hasMany({{ external_class_name }}::class, '{{ column_name }}'); +}
--- a/src/Generator/Model/stubs/model.pivot.stub Wed Feb 26 20:12:17 2025 -0500 +++ b/src/Generator/Model/stubs/model.pivot.stub Fri Apr 11 20:50:20 2025 -0400 @@ -10,12 +10,22 @@ /** * Indicates if the model should be timestamped. - * By default our pivots will not use timestamps + * By default our pivots will not use timestamps * * @var bool */ public $timestamps = false; + //relations + + // BelongsTo + # {{ belongs_to_relationships }} + + // HasMany + # {{ has_may_relationships }} + + // HasManyThrough + # {{ has_many_through_relationships }} }
--- a/src/Generator/Model/stubs/model.stub Wed Feb 26 20:12:17 2025 -0500 +++ b/src/Generator/Model/stubs/model.stub Fri Apr 11 20:50:20 2025 -0400 @@ -27,6 +27,10 @@ # {{ atributeInsertPoint }} ]; + protected $fillable =[ + # {{ fillableInsertPoint }} + ]; + public static function boot() : void { parent::boot(); @@ -45,8 +49,12 @@ //relations // BelongsTo + # {{ belongs_to_relationships }} // HasMany + # {{ has_may_relationships }} + // HasManyThrough + # {{ has_many_through_relationships }} }
--- a/src/Generator/Requests/RequestGenerator.php Wed Feb 26 20:12:17 2025 -0500 +++ b/src/Generator/Requests/RequestGenerator.php Fri Apr 11 20:50:20 2025 -0400 @@ -38,7 +38,7 @@ public function handle() { // First we need to ensure that the table exists, then we can - if (!$this->tableExists($this->getTableInput())) { + if (! $this->tableExists($this->getTableInput())) { $this->components->error('The table: "'.$this->getTableInput().'" does not exist in the database.'); return false; @@ -60,10 +60,8 @@ /** * Get the console command options. - * - * @return array */ - protected function getOptions():array + protected function getOptions(): array { return array_merge(parent::getOptions(), [ ['all', 'a', InputOption::VALUE_NONE, 'Generate all request classes for the table.'], @@ -74,21 +72,15 @@ /** * Interact further with the user if they were prompted for missing arguments. - * - * @return void */ - protected function afterPromptingForMissingArguments(InputInterface $input, OutputInterface $output):void - { - } + protected function afterPromptingForMissingArguments(InputInterface $input, OutputInterface $output): void {} /** * Get the stub file for the generator. * * @return string */ - protected function getStub() - { - } + protected function getStub() {} protected function createStoreRequest() {
--- a/src/Generator/Requests/StoreRequestGenerator.php Wed Feb 26 20:12:17 2025 -0500 +++ b/src/Generator/Requests/StoreRequestGenerator.php Fri Apr 11 20:50:20 2025 -0400 @@ -50,8 +50,7 @@ /** * Resolve the fully-qualified path to the stub. * - * @param string $stub - * + * @param string $stub * @return string */ protected function resolveStubPath($stub)
--- a/src/Generator/Requests/UpdateRequestGenerator.php Wed Feb 26 20:12:17 2025 -0500 +++ b/src/Generator/Requests/UpdateRequestGenerator.php Fri Apr 11 20:50:20 2025 -0400 @@ -50,8 +50,7 @@ /** * Resolve the fully-qualified path to the stub. * - * @param string $stub - * + * @param string $stub * @return string */ protected function resolveStubPath($stub)
--- a/src/Generator/Route/RouteGenerator.php Wed Feb 26 20:12:17 2025 -0500 +++ b/src/Generator/Route/RouteGenerator.php Fri Apr 11 20:50:20 2025 -0400 @@ -50,8 +50,7 @@ /** * Resolve the fully-qualified path to the stub. * - * @param string $stub - * + * @param string $stub * @return string */ protected function resolveStubPath($stub)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/Helpers/RelationshipNavigator.php Fri Apr 11 20:50:20 2025 -0400 @@ -0,0 +1,205 @@ +<?php + +namespace Wizard\MagicForger\Helpers; + +use Illuminate\Support\Facades\DB; + +class RelationshipNavigator +{ + public static function handle() + { + $tables = DB::select('SHOW TABLES'); + $tableNames = array_map(function ($table) { + return current((array) $table); + }, $tables); + + foreach ($tableNames as $table) { + echo "Table: $table \n"; + + $relations = self::getRelations($table); + echo "Relationships: \n"; + foreach ($relations as $relation => $related_tables) { + echo $relation.": \n"; + foreach ($related_tables as $related_table) { + echo "\t"; + foreach ($related_table as $key => $value) { + echo "$key : "; + if (is_array($value)) { + foreach ($related_table as $key => $value) { + echo "\n\t\t"; + echo "$key: $value"; + } + } else { + echo $value.' '; + } + } + echo "\n"; + } + } + echo "\n --- \n"; + } + } + + public static function getRelations($table) + { + $relations = [ + 'belongsTo' => [], + 'hasMany' => [], + 'hasManyThrough' => [], + ]; + + $foreignKeys = DB::select("SHOW KEYS FROM $table WHERE Key_name != 'PRIMARY'"); + $referencedTables = self::getAllReferencedTables($table); + + // BelongsTo Relationships + foreach ($foreignKeys as $fk) { + $column = $fk->Column_name; + + // skip created and updated by + if (in_array($column, ['created_by', 'updated_by'])) { + continue; + } + + $referencedTable = $referencedTables[$column] ?? null; + + if ($referencedTable) { + $relations['belongsTo'][] = ['column' => $column, 'table' => $referencedTable->REFERENCED_TABLE_NAME]; + } + + } + + // HasMany Relationships + if ($reverseRelation = self::findReverseRelation($table)) { + foreach ($reverseRelation as $relatedTable) { + $relations['hasMany'][] = $relatedTable; + } + } + + // HasManyThrough Relationships + if ($hasManyThroughRelations = self::findHasManyThroughRelations($table)) { + foreach ($hasManyThroughRelations as $relatedTable) { + $relations['hasManyThrough'][] = $relatedTable; + } + } + + return $relations; + } + + public static function getAllReferencedTables($table) + { + $results = DB::select(" + SELECT TABLE_NAME, COLUMN_NAME, CONSTRAINT_NAME, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME + FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE + WHERE TABLE_SCHEMA = DATABASE() + AND TABLE_NAME = '$table' + "); + + $tables = self::re_key_array($results, 'COLUMN_NAME'); + + return (count($tables) > 0) ? $tables : null; + } + + public static function findReverseRelation($table) + { + $relations = DB::select(" + SELECT TABLE_NAME, COLUMN_NAME + FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE + WHERE TABLE_SCHEMA = DATABASE() + AND REFERENCED_TABLE_NAME = '$table' + AND REFERENCED_COLUMN_NAME = 'id' + AND COLUMN_NAME != 'created_by' + AND COLUMN_NAME != 'updated_by' + "); + + $relatedTables = array_map(function ($rel) { + return ['table' => $rel->TABLE_NAME, 'column' => $rel->COLUMN_NAME]; + }, $relations); + + return $relatedTables ? $relatedTables : null; + } + + public static function findHasManyThroughRelations($table) + { + $relations = []; + + // Find potential intermediary tables + $intermediaryTables = self::findReverseRelation($table); + + if (! is_null($intermediaryTables)) { + + foreach ($intermediaryTables as $intermediary) { + + if ($is_pivot = self::isPivot($intermediary['table'])) { + $is_pivot = current($is_pivot); + + // reformat the table based on the current and external + $potential_tables = array_keys($is_pivot['tables']); + $external_table = $potential_tables[0] == $table ? $is_pivot['tables'][$potential_tables[1]] : $is_pivot['tables'][$potential_tables[0]]; + $internal_table = $potential_tables[0] == $table ? $is_pivot['tables'][$potential_tables[0]] : $is_pivot['tables'][$potential_tables[1]]; + + $hasManyThrough = [ + 'table' => $external_table['table_name'], + 'through' => [ + 'table' => $is_pivot['table'], + 'external_column' => $external_table['column'], + 'internal_column' => $internal_table['column'] + ] + ]; + $relations[] = $hasManyThrough; + } + } + + } + + return $relations; + } + + public static function isPivot($table) + { + + $relations = []; + // TODO: alsot get the columns that are relevant + $pivotTables = DB::select(" + SELECT TABLE_NAME, TABLE_COMMENT + FROM INFORMATION_SCHEMA.TABLES + WHERE TABLE_SCHEMA = DATABASE() + AND TABLE_NAME = '{$table}' + AND TABLE_COMMENT != '' + "); + + if(!is_null($pivotTables) && count($pivotTables) > 0) { + $ref = current($pivotTables); + + $pivots = json_decode(str_replace('PIVOT:', '', $ref->TABLE_COMMENT), true); + + $tables = []; + if (count($pivots) > 0) { + //re-key array + $references = self::getAllReferencedTables($table); + $references = self::re_key_array($references, 'REFERENCED_TABLE_NAME'); + + foreach($pivots as $key => $value) { + if($ref_data = ($references[$value] ?? null)) { + $tables[$value] = [ + 'table_name' => $value, + 'column' => $ref_data->COLUMN_NAME + ]; + } + } + } + $relations[] = ['table' => $ref->TABLE_NAME, 'tables' => $tables]; + } + + return $relations != [] ? $relations : null; + } + + public static function re_key_array($old_array, $key) { + $new_array = []; + if (count($old_array) > 0) { + foreach ($old_array as $array) { + $new_array[$array->$key] = $array; + } + } + return $new_array; + } +}
--- a/src/Replacer/Replacer.php Wed Feb 26 20:12:17 2025 -0500 +++ b/src/Replacer/Replacer.php Fri Apr 11 20:50:20 2025 -0400 @@ -9,25 +9,18 @@ /** * Prefix and Suffix for controller. * Usage is up to the user. - * - * @var string */ protected string $controller_prefix = ''; /** * Prefix and Suffix for controller. * Usage is up to the user. - * - * @var string */ 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. - * - * @param string $target - * @return array */ public function get_all_keywords(string $target): array { @@ -42,9 +35,6 @@ /** * Apply replacements to the target string. - * - * @param string $target - * @return string */ public function apply_replacements(string $target): string { @@ -60,8 +50,6 @@ /** * Get available replacements for string replacements. - * - * @return array */ public function get_available_replacements(): array { @@ -72,7 +60,7 @@ '{{ 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), + '{{ namespace }}' => $this->{'get'.$this->type.'Namespace'}($table_name), '{{ namespacedModel }}' => $this->getNamespacedModel($table_name), '{{ requestUses }}' => $this->getRequestUses($table_name), '{{ rootNamespace }}' => $this->getRootNamespace(), @@ -86,9 +74,6 @@ /** * Generate model name in Studly case. - * - * @param string $name - * @return string */ public function model_name(string $name): string { @@ -97,9 +82,6 @@ /** * Generate singular model variable name. - * - * @param string $name - * @return string */ public function model_variable(string $name): string { @@ -108,37 +90,28 @@ /** * 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'; } // Namespace Methods @@ -146,8 +119,6 @@ /** * Get the root namespace for the application. - * - * @return string */ public function getRootNamespace(): string { @@ -156,53 +127,38 @@ /** * 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 { @@ -211,9 +167,6 @@ /** * Get the update request namespace. - * - * @param string $name - * @return string */ public function getUpdateRequestNamespace(string $name): string { @@ -222,15 +175,12 @@ /** * 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).';', ]); } @@ -239,9 +189,6 @@ /** * Convert a string to a human-readable format. * Assumes camel case input. - * - * @param string $name - * @return string */ public function human_readable(string $name): string { @@ -251,9 +198,6 @@ /** * Convert a string to a lowercase human-readable format. * Assumes camel case input. - * - * @param string $name - * @return string */ public function human_readable_lc(string $name): string {
--- a/src/Replacer/TableReplacer.php Wed Feb 26 20:12:17 2025 -0500 +++ b/src/Replacer/TableReplacer.php Fri Apr 11 20:50:20 2025 -0400 @@ -6,15 +6,22 @@ { protected ?array $columns = null; + protected array $columns_to_ignore = [ + 'id', + 'created_at', + 'updated_at', + 'created_by', + 'updated_by', + 'deleted_at', + ]; + /** * Retrieve columns for the current table. - * - * @return array */ protected function get_columns(): array { if (is_null($this->columns)) { - $this->columns = $this->getCurrentTable()->getColumns(); + $this->columns = $this->getTableColumns($this->getCurrentTable()); } return $this->columns; @@ -22,14 +29,13 @@ /** * Get a string representation of values for creation. - * - * @return string */ protected function getValuesForCreation(): string { $insert = ''; foreach ($this->get_columns() as $column) { - $insert .= sprintf('$item->%s = $validated["%s"] ?? NULL;', $column->getName(), $column->getName()) . "\n"; + $column_name = $column['name']; + $insert .= sprintf('$item->%s = $validated["%s"] ?? NULL;', $column_name, $column_name)."\n"; } return $insert; @@ -37,14 +43,31 @@ /** * Get a string representation of table attributes. - * - * @return string */ protected function getAttributes(): string { $insert = ''; foreach ($this->get_columns() as $column) { - $insert .= sprintf("'%s' => '',", $column->getName()) . "\n"; + if (in_array($column['name'], $this->columns_to_ignore)) { + continue; + } + $insert .= sprintf("'%s' => '',", $column['name'])."\n"; + } + + return $insert; + } + + /** + * Get a string representation of table fillable columns. + */ + protected function getFillable(): string + { + $insert = ''; + foreach ($this->get_columns() as $column) { + if (in_array($column['name'], $this->columns_to_ignore)) { + continue; + } + $insert .= sprintf("'%s',", $column['name'])."\n"; } return $insert; @@ -52,14 +75,15 @@ /** * Get formatted validation rules for table columns. - * - * @return string */ protected function getValuesForValidation(): string { $insert = ''; foreach ($this->get_columns() as $column) { - $insert .= sprintf("'%s' => 'nullable',", $column->getName()) . "\n"; + if (in_array($column['name'], $this->columns_to_ignore)) { + continue; + } + $insert .= sprintf("'%s' => 'nullable',", $column['name'])."\n"; } return $insert; @@ -67,9 +91,6 @@ /** * Apply insertions in the target template. - * - * @param string $target - * @return string */ public function apply_inserts(string $target): string { @@ -85,14 +106,13 @@ /** * Get available insertion points for the template. - * - * @return array */ public function get_available_inserts(): array { return [ '// {{ valuesForCreation }}' => $this->getValuesForCreation(), '# {{ attributeInsertPoint }}' => $this->getAttributes(), + '# {{ fillableInsertPoint }}' => $this->getFillable(), '// {{ valuesForValidation }}' => $this->getValuesForValidation(), ]; }
