changeset 5:b0b2e79ad8e6

Not exatly sure what was changed but commiting to it :)
author luka
date Thu, 12 Oct 2023 19:41:04 -0400
parents a20439b1c9d3
children b46922d4a301
files .php-cs-fixer.cache examples/ExampleGenerator.php.stub src/Generator/BaseGenerator.php src/Generator/Controller/ControllerGenerator.php src/Generator/Controller/stubs/controller.stub src/Generator/Generator.php src/Generator/Model/ModelGenerator.php src/Generator/Model/stubs/model.pivot.stub src/Generator/Model/stubs/model.stub src/Generator/Replacer.php src/Generator/Requests/RequestGenerator.php src/Generator/Requests/StoreRequestGenerator.php src/Generator/Requests/UpdateRequestGenerator.php src/Generator/Requests/stubs/request.stub src/Generator/Route/RouteGenerator.php src/Generator/Route/stubs/route.stub src/Helpers/Replacer.php src/MagicForgerServiceProvider.php src/Replacer.php src/Replacer/Replacer.php src/Replacer/TableReplacer.php
diffstat 21 files changed, 726 insertions(+), 306 deletions(-) [+]
line wrap: on
line diff
--- a/.php-cs-fixer.cache	Tue Jun 27 20:16:55 2023 -0400
+++ b/.php-cs-fixer.cache	Thu Oct 12 19:41:04 2023 -0400
@@ -1,1 +1,1 @@
-{"php":"8.2.7","version":"3.19.1","indent":"    ","lineEnding":"\n","rules":{"blank_line_after_opening_tag":true,"blank_line_between_import_groups":true,"blank_lines_before_namespace":true,"class_definition":{"inline_constructor_arguments":false,"space_before_parenthesis":true},"compact_nullable_typehint":true,"curly_braces_position":{"allow_single_line_empty_anonymous_classes":true},"declare_equal_normalize":true,"lowercase_cast":true,"lowercase_static_reference":true,"new_with_braces":true,"no_blank_lines_after_class_opening":true,"no_leading_import_slash":true,"no_whitespace_in_blank_line":true,"ordered_class_elements":{"order":["use_trait"]},"ordered_imports":{"imports_order":["class","function","const"],"sort_algorithm":"none"},"return_type_declaration":true,"short_scalar_cast":true,"single_import_per_statement":{"group_to_single_imports":false},"single_trait_insert_per_statement":true,"ternary_operator_spaces":true,"visibility_required":true,"blank_line_after_namespace":true,"constant_case":true,"control_structure_braces":true,"control_structure_continuation_position":true,"elseif":true,"function_declaration":true,"indentation_type":true,"line_ending":true,"lowercase_keywords":true,"method_argument_space":{"on_multiline":"ensure_fully_multiline"},"no_break_comment":true,"no_closing_tag":true,"no_multiple_statements_per_line":true,"no_space_around_double_colon":true,"no_spaces_after_function_name":true,"no_spaces_inside_parenthesis":true,"no_trailing_whitespace":true,"no_trailing_whitespace_in_comment":true,"single_blank_line_at_eof":true,"single_class_element_per_statement":{"elements":["property"]},"single_line_after_imports":true,"statement_indentation":true,"switch_case_semicolon_to_colon":true,"switch_case_space":true,"encoding":true,"full_opening_tag":true},"hashes":{"src\/Generator\/BaseGenerator.php":"409aadd181fbd4f216fe31f4f42ca3e2","src\/Replacer.php":"c6b5f421259f41016014c00270ca001c","src\/MagicForgerServiceProvider.php":"e56f92adc0181e9b7681de8ca8aca6eb","src\/Generator\/Controller\/ControllerGenerator.php":"075e65a43e5ecc55fbc4dcd7636dfcc1","src\/Generator\/Generator.php":"794271f48bed8f156878fc36a25ff60f","src\/Generator\/Replacer.php":"5a7f98d22504edb6aba92b061ddd9803","src\/Generator\/Model\/ModelGenerator.php":"e78c07fc13bd9c379991e8b01b13c672"}}
\ No newline at end of file
+{"php":"8.2.10","version":"3.19.1","indent":"    ","lineEnding":"\n","rules":{"blank_line_after_opening_tag":true,"blank_line_between_import_groups":true,"blank_lines_before_namespace":true,"class_definition":{"inline_constructor_arguments":false,"space_before_parenthesis":true},"compact_nullable_typehint":true,"curly_braces_position":{"allow_single_line_empty_anonymous_classes":true},"declare_equal_normalize":true,"lowercase_cast":true,"lowercase_static_reference":true,"new_with_braces":true,"no_blank_lines_after_class_opening":true,"no_leading_import_slash":true,"no_whitespace_in_blank_line":true,"ordered_class_elements":{"order":["use_trait"]},"ordered_imports":{"imports_order":["class","function","const"],"sort_algorithm":"none"},"return_type_declaration":true,"short_scalar_cast":true,"single_import_per_statement":{"group_to_single_imports":false},"single_trait_insert_per_statement":true,"ternary_operator_spaces":true,"visibility_required":true,"blank_line_after_namespace":true,"constant_case":true,"control_structure_braces":true,"control_structure_continuation_position":true,"elseif":true,"function_declaration":true,"indentation_type":true,"line_ending":true,"lowercase_keywords":true,"method_argument_space":{"on_multiline":"ensure_fully_multiline"},"no_break_comment":true,"no_closing_tag":true,"no_multiple_statements_per_line":true,"no_space_around_double_colon":true,"no_spaces_after_function_name":true,"no_spaces_inside_parenthesis":true,"no_trailing_whitespace":true,"no_trailing_whitespace_in_comment":true,"single_blank_line_at_eof":true,"single_class_element_per_statement":{"elements":["property"]},"single_line_after_imports":true,"statement_indentation":true,"switch_case_semicolon_to_colon":true,"switch_case_space":true,"encoding":true,"full_opening_tag":true},"hashes":{"src\/Generator\/Route\/RouteGenerator.php":"4145e6208d253b08e9415339655c43e8","src\/Generator\/Controller\/ControllerGenerator.php":"cda3b688502c4427a50680c41b3a0f9d","src\/Generator\/Model\/ModelGenerator.php":"ded0f28024f6b6cbbfda97fbe14fda5a","src\/Generator\/Generator.php":"32b046d691dd2c24388e0741f875b184","src\/Generator\/Requests\/UpdateRequestGenerator.php":"ed745b244a7151bf0c12439af236f99b","src\/Generator\/Requests\/RequestGenerator.php":"29917ee19288caa73d92b46645c54905","src\/Generator\/Requests\/StoreRequestGenerator.php":"04b9c38f3339e02be4dc2d1c7545a370","src\/Generator\/BaseGenerator.php":"e59b94348fbc89dabdfea4098d4dfacb","src\/MagicForgerServiceProvider.php":"38024b0e807b2bc4cdd756ab456965a0","src\/Replacer\/Replacer.php":"830af5da740df6688a6def60966d38d7","src\/Replacer\/TableReplacer.php":"52736f1760b4c556cb3390e3d51a8812"}}
\ No newline at end of file
--- a/examples/ExampleGenerator.php.stub	Tue Jun 27 20:16:55 2023 -0400
+++ b/examples/ExampleGenerator.php.stub	Thu Oct 12 19:41:04 2023 -0400
@@ -1,6 +1,6 @@
 <?php
 
-namespace Wizzard\MagicForger\Generator\Controller;
+namespace Wizzard\MagicForger\Generator\{{ Class Name }};
 
 use Symfony\Component\Console\Attribute\AsCommand;
 use Wizzard\MagicForger\Generator\BaseGenerator;
--- a/src/Generator/BaseGenerator.php	Tue Jun 27 20:16:55 2023 -0400
+++ b/src/Generator/BaseGenerator.php	Thu Oct 12 19:41:04 2023 -0400
@@ -11,27 +11,34 @@
 use Symfony\Component\Console\Input\InputOption;
 use Symfony\Component\Console\Output\OutputInterface;
 
-use Wizzard\MagicForger\Generator\Replacer;
+use Wizzard\MagicForger\Replacer\Replacer;
 
 abstract class BaseGenerator extends GeneratorCommand
 {
     use Replacer;
 
     /**
-     * The console command description.
+     * The schema of the database.
      *
      * @var string
      */
     protected $schema;
 
     /**
-     * The console command description.
+     * The tables available in the schema.
      *
-     * @var string
+     * @var array 
      */
     protected $tables;
 
     /**
+     * The current Table being used.
+     *
+     * @var table
+     */
+    protected $currentTable;
+
+    /**
      * Execute the console command.
      */
     public function handle()
@@ -159,6 +166,7 @@
         return $this->files->get($this->getStub());
     }
 
+
     /**
      * Get the desired class table from the input.
      *
@@ -209,4 +217,23 @@
 
         return $this->schema;
     }
+
+    protected function getTable(string $table_name)
+    {
+        return $this->getSchema()->introspectTable($table_name);
+    }
+
+    protected function getCurrentTable()
+    {
+        return $this->currentTable;
+    }
+
+    protected function setCurrentTable(string $table_name)
+    {
+        $table = null;
+        if(!is_null($table_name) && trim($table_name) !== '') {
+            $table = $this->getTable($table_name);
+        }
+        $this->currentTable = $table;
+    }
 }
--- a/src/Generator/Controller/ControllerGenerator.php	Tue Jun 27 20:16:55 2023 -0400
+++ b/src/Generator/Controller/ControllerGenerator.php	Thu Oct 12 19:41:04 2023 -0400
@@ -4,7 +4,6 @@
 
 use Symfony\Component\Console\Attribute\AsCommand;
 use Wizzard\MagicForger\Generator\BaseGenerator;
-use Wizzard\MagicForger\Replacer;
 use Illuminate\Support\Str;
 
 #[AsCommand(name: 'mf:controller')]
@@ -36,6 +35,7 @@
      */
     public function handle()
     {
+        $table = $this->getTable($this->getTableInput());
         parent::handle();
     }
 
--- a/src/Generator/Controller/stubs/controller.stub	Tue Jun 27 20:16:55 2023 -0400
+++ b/src/Generator/Controller/stubs/controller.stub	Thu Oct 12 19:41:04 2023 -0400
@@ -35,10 +35,13 @@
      */
     public function store({{ storeRequest }} $request)
     {
+				$validated = $request->validated();
+
         //
 				${{ modelVariable }} = new {{ model }}();
 
 				//insert the values into the model
+				//{{ valuesForCreation }}
 
 				${{ modelVariable }}->save();
 
@@ -74,7 +77,11 @@
      */
     public function update({{ updateRequest }} $request, {{ model }} ${{ modelVariable }})
     {
+				$validated = $request->validated();
+
         // Set the variables
+				//{{ valuesForCreation }}
+
 				${{ modelVariable }}->save();
 
 				return redirect()->route('{{ tableName }}.index');
--- a/src/Generator/Generator.php	Tue Jun 27 20:16:55 2023 -0400
+++ b/src/Generator/Generator.php	Thu Oct 12 19:41:04 2023 -0400
@@ -11,7 +11,6 @@
 use Illuminate\Support\Str;
 
 use Wizzard\MagicForger\Generator\BaseGenerator;
-use Wizzard\MagicForger\Replacer;
 
 #[AsCommand(name: 'mf')]
 class Generator extends BaseGenerator
@@ -44,12 +43,17 @@
             return false;
         }
 
+				$this->setCurrentTable($this->getTableInput());
+				dd($this->getCurrentTable()->getForeignKeys());
+
         if ($this->option('all')) {
             /* $this->input->setOption('factory', true); */
             /* $this->input->setOption('seed', true); */
             /* $this->input->setOption('migration', true); */
             $this->input->setOption('controller', true);
-            /* $this->input->setOption('model', true); */
+            $this->input->setOption('model', true);
+            $this->input->setOption('request', true);
+            $this->input->setOption('route', true);
         }
 
         /* if ($this->option('factory')) { */
@@ -68,9 +72,17 @@
             $this->createController();
         }
 
-        /* if ($this->option('model')) { */
-        /*     $this->createModel(); */
-        /* } */
+        if ($this->option('model')) {
+            $this->createModel();
+        }
+
+        if ($this->option('request')) {
+            $this->createRequest();
+        }
+
+        if ($this->option('route')) {
+            $this->createRoute();
+        }
 
     }
 
@@ -81,10 +93,13 @@
      */
     protected function getOptions()
     {
-        return [
+        return array_merge(parent::getOptions(), [
             ['all', 'a', InputOption::VALUE_NONE, 'Generate a migration, seeder, factory, policy, resource controller, and form request classes for the table.'],
             ['controller', 'c', InputOption::VALUE_NONE, 'Generate a controller class for the table.'],
-        ];
+            ['model', 'm', InputOption::VALUE_NONE, 'Generate a model class for the table.'],
+            ['request', 'r', InputOption::VALUE_NONE, 'Generate base request classes for the table.'],
+            ['route', 'w', InputOption::VALUE_NONE, 'Generate base routes classes for the table.'],
+        ]);
     }
 
     /**
@@ -102,6 +117,21 @@
 
     protected function createController()
     {
-        $this->call('mf:controller', ['table' => $this->getTableInput()]);
+        $this->call('mf:controller', ['table' => $this->getTableInput(), '--fresh' => $this->option('fresh')]);
+    }
+
+    protected function createModel()
+    {
+        $this->call('mf:model', ['table' => $this->getTableInput(), '--fresh' => $this->option('fresh')]);
+    }
+
+    protected function createRequest()
+    {
+        $this->call('mf:request', ['table' => $this->getTableInput(), '--fresh' => $this->option('fresh'), '--all' => true]);
+    }
+
+    protected function createRoute()
+    {
+        $this->call('mf:route', ['table' => $this->getTableInput(), '--fresh' => $this->option('fresh')]);
     }
 }
--- a/src/Generator/Model/ModelGenerator.php	Tue Jun 27 20:16:55 2023 -0400
+++ b/src/Generator/Model/ModelGenerator.php	Thu Oct 12 19:41:04 2023 -0400
@@ -1,6 +1,6 @@
 <?php
 
-namespace Wizzard\MagicForger\Generator\Controller;
+namespace Wizzard\MagicForger\Generator\Model;
 
 use Symfony\Component\Console\Attribute\AsCommand;
 use Wizzard\MagicForger\Generator\BaseGenerator;
--- a/src/Generator/Model/stubs/model.pivot.stub	Tue Jun 27 20:16:55 2023 -0400
+++ b/src/Generator/Model/stubs/model.pivot.stub	Thu Oct 12 19:41:04 2023 -0400
@@ -7,4 +7,15 @@
 class {{ class }} extends Pivot
 {
     //
+
+    /**
+     * Indicates if the model should be timestamped.
+		 * By default our pivots will not use timestamps
+     *
+     * @var bool
+     */
+    public $timestamps = false;
+
+
+
 }
--- a/src/Generator/Model/stubs/model.stub	Tue Jun 27 20:16:55 2023 -0400
+++ b/src/Generator/Model/stubs/model.stub	Thu Oct 12 19:41:04 2023 -0400
@@ -4,8 +4,40 @@
 
 use Illuminate\Database\Eloquent\Factories\HasFactory;
 use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\SoftDeletes;
 
 class {{ class }} extends Model
 {
-    use HasFactory;
+    //use HasFactory;
+    use SoftDeletes;
+
+    /**
+     * The table associated with the model.
+     *
+     * @var string
+     */
+    protected $table = '{{ tableName }}';
+
+		/**
+     * The model's default values for attributes.
+     *
+     * @var array
+     */
+    protected $attributes = [
+			# {{ atributeInsertPoint }}
+    ];
+
+
+		public static function boot() : void {
+			parent::boot();
+
+			self::creating(function ($item) {
+				$item->created_by = \Auth::user()->id;
+				$item->updated_by = \Auth::user()->id;
+			});
+
+			self::saving(function ($item) {
+				$item->updated_by = \Auth::user()->id;
+			});
+		}
 }
--- a/src/Generator/Replacer.php	Tue Jun 27 20:16:55 2023 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,174 +0,0 @@
-<?php
-
-namespace Wizzard\MagicForger\Generator;
-
-use Illuminate\Support\Str;
-
-trait Replacer
-{
-    /**
-     * Prefix and Suffix for controller.
-     * Usage is up to the user.
-     *
-     * @var string
-     */
-    protected $controller_prefix = "";
-
-
-    /**
-     * Prefix and Suffix for controller.
-     * Usage is up to the user.
-     *
-     * @var string
-     */
-    protected $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.
-     */
-    public function get_all_inserts(string $target): array
-    {
-        //find all the matches to our expected syntax
-        $matches = [];
-        preg_match_all('/{{[\sa-zA-Z\-_]+}}/', $target, $matches);
-        // sort the array and return unique values
-        sort($matches[0]);
-        return array_values(array_unique($matches[0]));
-    }
-
-
-    public function apply_replacements(string $target): string
-    {
-        $inserts = $this->get_all_inserts($target);
-        $available_replacements = $this->get_available_replacements();
-
-        $target = str_replace(
-            array_keys($available_replacements),
-            $available_replacements,
-            $target
-        );
-
-        return $target;
-    }
-
-    public function get_available_replacements()
-    {
-        $table_name = $this->getTableInput();
-        $replacements = [
-                    "{{ class }}" => $this->getClassName($table_name),
-                    "{{ model }}" => $this->model_name($table_name),
-                    "{{ modelVariable }}" => $this->model_variable($table_name),
-                    "{{ namespace }}" => $this->{'get' . $this->type . 'Namespace'}(),
-                    "{{ namespacedModel }}" => $this->getModelNamespace(),
-                    "{{ 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 names are generated in uppercase first Camel case
-     */
-    public function model_name(string $name): string
-    {
-        return Str::singular(Str::studly($name));
-    }
-
-    /**
-     * Model variable is standardly just a singular version of the table name
-     */
-    public function model_variable(string $name): string
-    {
-        return Str::singular($name);
-    }
-
-    /**
-     * Controller names are generated in uppercase first Camel case
-     * and wrapped in the prefix and suffix
-     */
-    public function controller_name(string $name): string
-    {
-        return $this->controller_prefix .
-            $this->model_name($name) .
-            $this->controller_suffix;
-    }
-
-    public function store_request_name(string $name): string
-    {
-        return 'Store' . $this->model_name($name);
-    }
-
-    public function update_request_name(string $name): string
-    {
-        return 'Update' . $this->model_name($name);
-    }
-
-
-    ////////////////////////////////////////////
-    //							Namespaces			   				//
-    ////////////////////////////////////////////
-
-    public function getRootNamespace()
-    {
-        return $this->laravel->getNamespace();
-    }
-
-    public function getModelNamespace()
-    {
-        return $this->getRootNamespace() . 'Models';
-    }
-
-    public function getControllerNamespace()
-    {
-        return $this->getRootNamespace() . 'Http\\Controllers';
-    }
-
-    public function getRequestNamespace(string $name)
-    {
-        return $this->getRootNamespace() . 'Http\\Requests\\' . $this->model_name($name);
-    }
-
-    public function getRequestUses(string $name)
-    {
-        return implode("\n", [
-            "use " . $this->getRequestNamespace($name) . '\\' . $this->store_request_name($name),
-            "use " . $this->getRequestNamespace($name) . '\\' . $this->update_request_name($name),
-        ]);
-    }
-
-
-    ////////////////////////////////////////////
-    //				Language and Presentables				//
-    ////////////////////////////////////////////
-
-    /**
-     * Breaks up a string and makes it human readable
-     *
-     * This function assumes that the inputted name is camel case
-     */
-    public function human_readable(string $name): string
-    {
-        return Str::title(Str::replace('_', ' ', $name));
-    }
-
-    /**
-     * Breaks up a string and makes it human readable and lowecase
-     *
-     * This function assumes that the inputted name is camel case
-     */
-    public function human_readable_lc(string $name): string
-    {
-        return Str::lower($this->human_readable($name));
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Generator/Requests/RequestGenerator.php	Thu Oct 12 19:41:04 2023 -0400
@@ -0,0 +1,103 @@
+<?php
+
+namespace Wizzard\MagicForger\Generator\Requests;
+
+use Symfony\Component\Console\Attribute\AsCommand;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+use Wizzard\MagicForger\Generator\BaseGenerator;
+use Illuminate\Support\Str;
+
+#[AsCommand(name: 'mf:request')]
+class RequestGenerator extends BaseGenerator
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $name = 'mf:request';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = 'Generates the Request File for a table.';
+
+    /**
+     * The type of class being generated.
+     *
+     * @var string
+     */
+    protected $type = 'Request';
+
+    /**
+     * 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.');
+
+            return false;
+        }
+
+        if ($this->option('all')) {
+            $this->input->setOption('store_request', true);
+            $this->input->setOption('update_request', true);
+        }
+
+        if ($this->option('store_request')) {
+            $this->createStoreRequest();
+        }
+
+        if ($this->option('update_request')) {
+            $this->createUpdateRequest();
+        }
+    }
+
+    /**
+     * Get the console command options.
+     *
+     * @return array
+     */
+    protected function getOptions()
+    {
+        return array_merge(parent::getOptions(), [
+            ['all', 'a', InputOption::VALUE_NONE, 'Generate all request classes for the table.'],
+            ['store_request', 's', InputOption::VALUE_NONE, 'Generate store request class for the table.'],
+            ['update_request', 'u', InputOption::VALUE_NONE, 'Generate update request class for the table.'],
+        ]);
+    }
+
+    /**
+     * Interact further with the user if they were prompted for missing arguments.
+     *
+     * @return void
+     */
+    protected function afterPromptingForMissingArguments(InputInterface $input, OutputInterface $output)
+    {
+    }
+    /**
+     * Get the stub file for the generator.
+     *
+     * @return string
+     */
+    protected function getStub()
+    {
+    }
+
+    protected function createStoreRequest()
+    {
+        $this->call('mf:store_request', ['table' => $this->getTableInput()]);
+    }
+
+    protected function createUpdateRequest()
+    {
+        $this->call('mf:update_request', ['table' => $this->getTableInput()]);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Generator/Requests/StoreRequestGenerator.php	Thu Oct 12 19:41:04 2023 -0400
@@ -0,0 +1,79 @@
+<?php
+
+namespace Wizzard\MagicForger\Generator\Requests;
+
+use Symfony\Component\Console\Attribute\AsCommand;
+use Wizzard\MagicForger\Generator\BaseGenerator;
+use Wizzard\MagicForger\Replacer;
+use Illuminate\Support\Str;
+
+#[AsCommand(name: 'mf:store_request')]
+class StoreRequestGenerator extends BaseGenerator
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $name = 'mf:store_request';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = 'Generates the StoreRequest File for a table.';
+
+    /**
+     * The type of class being generated.
+     *
+     * @var string
+     */
+    protected $type = 'StoreRequest';
+
+    /**
+     * Execute the console command.
+     */
+    public function handle()
+    {
+        parent::handle();
+    }
+
+    /**
+     * Get the stub file for the generator.
+     *
+     * @return string
+     */
+    protected function getStub()
+    {
+        return $this->resolveStubPath('/stubs/request.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->store_request_name($name);
+    }
+
+    /**
+     * Get the stub file for the generator.
+     *
+     * @return string
+     */
+    protected function getPath($name = null)
+    {
+        return str_replace(['App\\', '\\'], ['app/', '/'], $this->getRequestNamespace($this->getTableInput()) . '/' . $this->store_request_name($this->getTableInput()) . '.php');
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Generator/Requests/UpdateRequestGenerator.php	Thu Oct 12 19:41:04 2023 -0400
@@ -0,0 +1,79 @@
+<?php
+
+namespace Wizzard\MagicForger\Generator\Requests;
+
+use Symfony\Component\Console\Attribute\AsCommand;
+use Wizzard\MagicForger\Generator\BaseGenerator;
+use Wizzard\MagicForger\Replacer;
+use Illuminate\Support\Str;
+
+#[AsCommand(name: 'mf:update_request')]
+class UpdateRequestGenerator extends BaseGenerator
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $name = 'mf:update_request';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = 'Generates the UpdateRequest File for a table.';
+
+    /**
+     * The type of class being generated.
+     *
+     * @var string
+     */
+    protected $type = 'UpdateRequest';
+
+    /**
+     * Execute the console command.
+     */
+    public function handle()
+    {
+        parent::handle();
+    }
+
+    /**
+     * Get the stub file for the generator.
+     *
+     * @return string
+     */
+    protected function getStub()
+    {
+        return $this->resolveStubPath('/stubs/request.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->update_request_name($name);
+    }
+
+    /**
+     * Get the stub file for the generator.
+     *
+     * @return string
+     */
+    protected function getPath($name = null)
+    {
+        return str_replace(['App\\', '\\'], ['app/', '/'], $this->getRequestNamespace($this->getTableInput()) . '/' . $this->update_request_name($this->getTableInput()) . '.php');
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Generator/Requests/stubs/request.stub	Thu Oct 12 19:41:04 2023 -0400
@@ -0,0 +1,28 @@
+<?php
+
+namespace {{ namespace }};
+
+use Illuminate\Foundation\Http\FormRequest;
+
+class {{ class }} extends FormRequest
+{
+    /**
+     * Determine if the user is authorized to make this request.
+     */
+    public function authorize(): bool
+    {
+        return true;
+    }
+
+    /**
+     * Get the validation rules that apply to the request.
+     *
+     * @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array|string>
+     */
+    public function rules(): array
+    {
+        return [
+            //
+        ];
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Generator/Route/RouteGenerator.php	Thu Oct 12 19:41:04 2023 -0400
@@ -0,0 +1,79 @@
+<?php
+
+namespace Wizzard\MagicForger\Generator\Route;
+
+use Symfony\Component\Console\Attribute\AsCommand;
+use Wizzard\MagicForger\Generator\BaseGenerator;
+use Wizzard\MagicForger\Replacer;
+use Illuminate\Support\Str;
+
+#[AsCommand(name: 'mf:routes')]
+class RouteGenerator extends BaseGenerator
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $name = 'mf:routes';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = 'Generates the Route File for a table.';
+
+    /**
+     * The type of class being generated.
+     *
+     * @var string
+     */
+    protected $type = 'Route';
+
+    /**
+     * Execute the console command.
+     */
+    public function handle()
+    {
+        parent::handle();
+    }
+
+    /**
+     * Get the stub file for the generator.
+     *
+     * @return string
+     */
+    protected function getStub()
+    {
+        return $this->resolveStubPath('/stubs/routes.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->routes_name($name);
+    }
+
+    /**
+     * Get the stub file for the generator.
+     *
+     * @return string
+     */
+    protected function getPath($name = null)
+    {
+        return str_replace(['App\\', '\\'], ['app/', '/'], $this->getRouteNamespace() . '/' . $this->routes_name($this->getTableInput()) . '.php');
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Generator/Route/stubs/route.stub	Thu Oct 12 19:41:04 2023 -0400
@@ -0,0 +1,13 @@
+<?php
+Route::controller({{ controllerName }}::class)
+	->prefix('{{ tableName }}') 
+	->alias('{{ tableName }}.')
+	->group( function () {
+		Route::get('/', 'index')->name('index');
+		Route::get('/create', 'create')->name('create');
+		Route::get('/edit', 'edit')->name('edit');
+
+		Route::post('/store', 'store')->name('store');
+		Route::put('/udpate/{id}', 'update')->name('update');
+		Route::delete('/delete/{id}', 'delete')->name('delete');
+	});
--- a/src/Helpers/Replacer.php	Tue Jun 27 20:16:55 2023 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-<?php
-namespace Magicforger/Helpers;
-
-
-/*
- * Replacer
- *
- * A class that handles all replacements necessary
- *
- * General flow:
- * Read a line looking for a replacement string
- * 
- * A replacement string will consist of 2 values
- * Reference Object, and Replacement Function
- *
- * After the replacement is made, the Object, function
- * are stored in an array to be cached for future replacements
- *
- * Basically lazy loading the replacements.
- * */
-class Replacer {
-
-
-/*
- * The array of cached replacements 
- *
- * Object name => [
- * 	function => replacement text,
- * ]
- *
- * */
-protected $replacement_cache [];
-
-
-/*
- * Static instance of inflector for 
- * string manipulation.
- *
- * */
-private static $inflector = null;
-
-public function __construct() {
-	if(is_null(self::$inflector)) {
-		self::$inflector = InflectorFactory::create()->build();
-	}
-}
-
-
-
-
-protected function extract_replacement_values(string $replacement_string): string {
-	$matches = [];
-	preg_match('/o:([^\s]+)\s+f:([^\s]+)/', $replacement_string, $matches);
-	$name = $matches[1];
-	$function = $matches[2];
-
-	return ['name' => $name, 'function' => $function];
-}
-
-protected function get_replacement(string $replacement_string): string {
-
-	
-
-
-	return $replacement;
-}
-
-
-
-
-}
--- a/src/MagicForgerServiceProvider.php	Tue Jun 27 20:16:55 2023 -0400
+++ b/src/MagicForgerServiceProvider.php	Thu Oct 12 19:41:04 2023 -0400
@@ -6,6 +6,10 @@
 use Wizzard\MagicForger\Generator\Generator;
 use Wizzard\MagicForger\Generator\Controller\ControllerGenerator;
 use Wizzard\MagicForger\Generator\Model\ModelGenerator;
+use Wizzard\MagicForger\Generator\Requests\RequestGenerator;
+use Wizzard\MagicForger\Generator\Requests\StoreRequestGenerator;
+use Wizzard\MagicForger\Generator\Requests\UpdateRequestGenerator;
+use Wizzard\MagicForger\Generator\Route\RouteGenerator;
 
 class MagicForgerServiceProvider extends ServiceProvider
 {
@@ -19,6 +23,10 @@
                 Generator::class,
                 ControllerGenerator::class,
                 ModelGenerator::class,
+                RequestGenerator::class,
+                StoreRequestGenerator::class,
+                UpdateRequestGenerator::class,
+                RouteGenerator::class,
             ]);
         }
     }
--- a/src/Replacer.php	Tue Jun 27 20:16:55 2023 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-<?php
-
-namespace Wizzard\MagicForger;
-
-use Illuminate\Support\Str;
-
-class Replacer
-{
-    /**
-     * Cached replacements for re-use.
-     *
-     * @var array
-     */
-    protected $replacement_cache = [];
-
-
-
-
-    /**
-     * The lowest level to show log outputs.
-     *
-     * @var int
-     */
-    private $log_level = 1;
-
-
-    public function __construct()
-    {
-        /* parent::__construct(); */
-    }
-
-
-    /**
-     * Outputs a log for the replacements based on log level.
-     */
-    public function log(string $str, int $log_level = 1): void
-    {
-
-        if($this->log_level <= $log_level) {
-            print($str . "\n");
-        }
-
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Replacer/Replacer.php	Thu Oct 12 19:41:04 2023 -0400
@@ -0,0 +1,196 @@
+<?php
+
+namespace Wizzard\MagicForger\Replacer;
+
+use Illuminate\Support\Str;
+
+trait Replacer
+{
+    /**
+     * Prefix and Suffix for controller.
+     * Usage is up to the user.
+     *
+     * @var string
+     */
+    protected $controller_prefix = "";
+
+
+    /**
+     * Prefix and Suffix for controller.
+     * Usage is up to the user.
+     *
+     * @var string
+     */
+    protected $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.
+     */
+    public function get_all_inserts(string $target): array
+    {
+        //find all the matches to our expected syntax
+        $matches = [];
+        preg_match_all('/{{[\sa-zA-Z\-_]+}}/', $target, $matches);
+        // sort the array and return unique values
+        sort($matches[0]);
+        return array_values(array_unique($matches[0]));
+    }
+
+
+    public function apply_replacements(string $target): string
+    {
+        $inserts = $this->get_all_inserts($target);
+        $available_replacements = $this->get_available_replacements();
+
+        $target = str_replace(
+            array_keys($available_replacements),
+            $available_replacements,
+            $target
+        );
+
+        return $target;
+    }
+
+    public function get_available_replacements()
+    {
+        $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 $replacements;
+    }
+
+    ////////////////////////////////////////////
+    //				Internals and Classes   				//
+    ////////////////////////////////////////////
+
+    /**
+     * Model names are generated in uppercase first Camel case
+     */
+    public function model_name(string $name): string
+    {
+        return Str::singular(Str::studly($name));
+    }
+
+    /**
+     * Model variable is standardly just a singular version of the table name
+     */
+    public function model_variable(string $name): string
+    {
+        return Str::singular($name);
+    }
+
+    /**
+     * Controller names are generated in uppercase first Camel case
+     * and wrapped in the prefix and suffix
+     */
+    public function controller_name(string $name): string
+    {
+        return $this->controller_prefix .
+            $this->model_name($name) .
+            $this->controller_suffix;
+    }
+
+    public function store_request_name(string $name): string
+    {
+        return 'Store' . $this->model_name($name) . 'Request';
+    }
+
+    public function update_request_name(string $name): string
+    {
+        return 'Update' . $this->model_name($name) . 'Request';
+    }
+
+
+    ////////////////////////////////////////////
+    //							Namespaces			   				//
+    ////////////////////////////////////////////
+
+    public function getRootNamespace()
+    {
+        return $this->laravel->getNamespace();
+    }
+
+    public function getModelNamespace(string $name = '')
+    {
+        return $this->getRootNamespace() . 'Models';
+    }
+
+    public function getNamespacedModel(string $name = '')
+    {
+        return $this->getModelNamespace() . '\\' . $this->model_name($name);
+    }
+
+    public function getControllerNamespace(string $name = '')
+    {
+        return $this->getRootNamespace() . 'Http\\Controllers';
+    }
+
+    public function getRequestNamespace(string $name)
+    {
+        return $this->getRootNamespace() . 'Http\\Requests\\' . $this->model_name($name);
+    }
+
+    public function getStoreRequestNamespace(string $name)
+    {
+        return $this->getRequestNamespace($name);
+    }
+
+    public function getUpdateRequestNamespace(string $name)
+    {
+        return $this->getRequestNamespace($name);
+    }
+
+    public function getRequestUses(string $name)
+    {
+        return implode("\n", [
+            "use " . $this->getRequestNamespace($name) . '\\' . $this->store_request_name($name) . ';',
+            "use " . $this->getRequestNamespace($name) . '\\' . $this->update_request_name($name) . ';',
+        ]);
+    }
+
+
+    public function getRouteNamespace(string $name = '')
+    {
+        return $this->getRootNamespace() . 'Http\\Controllers';
+    }
+
+
+    ////////////////////////////////////////////
+    //				Language and Presentables				//
+    ////////////////////////////////////////////
+
+    /**
+     * Breaks up a string and makes it human readable
+     *
+     * This function assumes that the inputted name is camel case
+     */
+    public function human_readable(string $name): string
+    {
+        return Str::title(Str::replace('_', ' ', $name));
+    }
+
+    /**
+     * Breaks up a string and makes it human readable and lowecase
+     *
+     * This function assumes that the inputted name is camel case
+     */
+    public function human_readable_lc(string $name): string
+    {
+        return Str::lower($this->human_readable($name));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Replacer/TableReplacer.php	Thu Oct 12 19:41:04 2023 -0400
@@ -0,0 +1,17 @@
+<?php
+
+namespace Wizzard\MagicForger\Replacer;
+
+use Illuminate\Support\Str;
+
+trait Replacer
+{
+    protected function get_columns()
+    {
+        return $this->getTables()->getColumns();
+    }
+
+    protected function get_attributes()
+    {
+    }
+}