Mercurial > packages > magicforger
changeset 25:1a717c7b211f codex
added support for some basic views
| author | Luka Sitas <sitas.luka.97@gmail.com> |
|---|---|
| date | Sun, 11 May 2025 21:03:51 -0400 |
| parents | 31109c61ce02 |
| children | 555bfaa500ac |
| files | src/Generator/Controller/stubs/controller.stub src/Generator/Generator.php src/Generator/View/CreateEditViewGenerator.php src/Generator/View/IndexViewGenerator.php src/Generator/View/ShowViewGenerator.php src/Generator/View/ViewGenerator.php src/Generator/View/stubs/create_edit.stub src/Generator/View/stubs/index.stub src/Generator/View/stubs/show.stub src/MagicForgerServiceProvider.php src/Replacer/Replacer.php |
| diffstat | 11 files changed, 533 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/src/Generator/Controller/stubs/controller.stub Tue Apr 22 21:37:44 2025 -0400 +++ b/src/Generator/Controller/stubs/controller.stub Sun May 11 21:03:51 2025 -0400 @@ -17,6 +17,7 @@ { $data = []; $data['items'] = {{ model }}::all(); + $data['fields'] = (new {{ model }}()->getFillable()); return view('{{ tableName }}.index', $data); } @@ -29,6 +30,7 @@ public function create() { $data = []; + $data['fields'] = (new {{ model }}()->getFillable()); return view('{{ tableName }}.create_edit', $data); } @@ -58,6 +60,7 @@ { $data = []; $data['item'] = ${{ modelVariable }}; + $data['fields'] = (new {{ model }}()->getFillable()); return view('{{ tableName }}.show', $data); } @@ -72,6 +75,7 @@ { $data = []; $data['item'] = ${{ modelVariable }}; + $data['fields'] = (new {{ model }}()->getFillable()); // Load data for relationships
--- a/src/Generator/Generator.php Tue Apr 22 21:37:44 2025 -0400 +++ b/src/Generator/Generator.php Sun May 11 21:03:51 2025 -0400 @@ -47,6 +47,7 @@ $this->input->setOption('controller', true); $this->input->setOption('model', true); $this->input->setOption('request', true); + $this->input->setOption('view', true); $this->input->setOption('route', true); } @@ -74,6 +75,10 @@ $this->createRequest(); } + if ($this->option('view')) { + $this->createView(); + } + if ($this->option('route')) { $this->createRoute(); } @@ -89,6 +94,7 @@ ['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.'], + ['view', '', InputOption::VALUE_NONE, 'Generate base views for the table.'], ['route', 'w', InputOption::VALUE_NONE, 'Generate base routes classes for the table.'], ]); } @@ -115,6 +121,11 @@ $this->call('mf:request', ['table' => $this->getTableInput(), '--fresh' => $this->option('fresh'), '--all' => true]); } + protected function createView() + { + $this->call('mf:view', ['table' => $this->getTableInput(), '--fresh' => $this->option('fresh'), '--all' => true]); + } + protected function createRoute() { $this->call('mf:route', ['table' => $this->getTableInput(), '--fresh' => $this->option('fresh')]);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/Generator/View/CreateEditViewGenerator.php Sun May 11 21:03:51 2025 -0400 @@ -0,0 +1,77 @@ +<?php + +namespace Wizard\MagicForger\Generator\View; + +use Symfony\Component\Console\Attribute\AsCommand; +use Wizard\MagicForger\Generator\BaseGenerator; + +#[AsCommand(name: 'mf:create_edit_view')] +class CreateEditViewGenerator extends BaseGenerator +{ + /** + * The name and signature of the console command. + * + * @var string + */ + protected $name = 'mf:create_edit_view'; + + /** + * The console command description. + * + * @var string + */ + protected $description = 'Generates the CreateEditView File for a table.'; + + /** + * The type of class being generated. + * + * @var string + */ + protected $type = 'CreateEditView'; + + /** + * 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/create_edit.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->create_edit_view_name($name); + } + + /** + * Get the stub file for the generator. + * + * @return string + */ + protected function getPath($name = null) + { + return str_replace(['Resources\\', '\\'], ['resources/', '/'], $this->getViewNamespace($this->getTableInput()).'create_edit.blade.php'); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/Generator/View/IndexViewGenerator.php Sun May 11 21:03:51 2025 -0400 @@ -0,0 +1,77 @@ +<?php + +namespace Wizard\MagicForger\Generator\View; + +use Symfony\Component\Console\Attribute\AsCommand; +use Wizard\MagicForger\Generator\BaseGenerator; + +#[AsCommand(name: 'mf:index_view')] +class IndexViewGenerator extends BaseGenerator +{ + /** + * The name and signature of the console command. + * + * @var string + */ + protected $name = 'mf:index_view'; + + /** + * The console command description. + * + * @var string + */ + protected $description = 'Generates the IndexView File for a table.'; + + /** + * The type of class being generated. + * + * @var string + */ + protected $type = 'IndexView'; + + /** + * 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/index.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->index_view_name($name); + } + + /** + * Get the stub file for the generator. + * + * @return string + */ + protected function getPath($name = null) + { + return str_replace(['Resources\\', '\\'], ['resources/', '/'], $this->getViewNamespace($this->getTableInput()).'index.blade.php'); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/Generator/View/ShowViewGenerator.php Sun May 11 21:03:51 2025 -0400 @@ -0,0 +1,77 @@ +<?php + +namespace Wizard\MagicForger\Generator\View; + +use Symfony\Component\Console\Attribute\AsCommand; +use Wizard\MagicForger\Generator\BaseGenerator; + +#[AsCommand(name: 'mf:show_view')] +class ShowViewGenerator extends BaseGenerator +{ + /** + * The name and signature of the console command. + * + * @var string + */ + protected $name = 'mf:show_view'; + + /** + * The console command description. + * + * @var string + */ + protected $description = 'Generates the ShowView File for a table.'; + + /** + * The type of class being generated. + * + * @var string + */ + protected $type = 'ShowView'; + + /** + * 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/show.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->show_view_name($name); + } + + /** + * Get the stub file for the generator. + * + * @return string + */ + protected function getPath($name = null) + { + return str_replace(['Resources\\', '\\'], ['resources/', '/'], $this->getViewNamespace($this->getTableInput()).'show.blade.php'); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/Generator/View/ViewGenerator.php Sun May 11 21:03:51 2025 -0400 @@ -0,0 +1,105 @@ +<?php + +namespace Wizard\MagicForger\Generator\View; + +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 Wizard\MagicForger\Generator\BaseGenerator; + +#[AsCommand(name: 'mf:view')] +class ViewGenerator extends BaseGenerator +{ + /** + * The name and signature of the console command. + * + * @var string + */ + protected $name = 'mf:view'; + + /** + * The console command description. + * + * @var string + */ + protected $description = 'Generates the View File for a table.'; + + /** + * The type of class being generated. + * + * @var string + */ + protected $type = 'View'; + + /** + * 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('index_view', true); + $this->input->setOption('create_edit_view', true); + $this->input->setOption('show_view', true); + } + + if ($this->option('index_view')) { + $this->createIndexView(); + } + + if ($this->option('create_edit_view')) { + $this->createCreateEditView(); + } + + if ($this->option('show_view')) { + $this->createShowView(); + } + } + + /** + * Get the console command options. + */ + protected function getOptions(): array + { + return array_merge(parent::getOptions(), [ + ['all', 'a', InputOption::VALUE_NONE, 'Generate all views for the table.'], + ['index_view', 'i', InputOption::VALUE_NONE, 'Generate index view for the table.'], + ['create_edit_view', 'c', InputOption::VALUE_NONE, 'Generate create_edit view for the table.'], + ['show_view', 's', InputOption::VALUE_NONE, 'Generate show view for the table.'], + ]); + } + + /** + * Interact further with the user if they were prompted for missing arguments. + */ + protected function afterPromptingForMissingArguments(InputInterface $input, OutputInterface $output): void {} + + /** + * Get the stub file for the generator. + * + * @return string + */ + protected function getStub() {} + + protected function createIndexView() + { + $this->call('mf:index_view', ['table' => $this->getTableInput()]); + } + + protected function createCreateEditView() + { + $this->call('mf:create_edit_view', ['table' => $this->getTableInput()]); + } + + protected function createShowView() + { + $this->call('mf:show_view', ['table' => $this->getTableInput()]); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/Generator/View/stubs/create_edit.stub Sun May 11 21:03:51 2025 -0400 @@ -0,0 +1,39 @@ +<x-app-layout> + <x-slot name="header"> + <h2 class="font-semibold text-xl text-gray-800 leading-tight"> + {{ isset($item) ? 'Edit' : 'Create' }} {{ ucfirst('{{ modelVariable }}') }} + </h2> + </x-slot> + + <div class="py-12"> + <div class="max-w-2xl mx-auto sm:px-6 lg:px-8"> + <div class="bg-white overflow-hidden shadow-sm sm:rounded-lg p-6"> + <form method="POST" action="{{ isset($item) ? route('{{ tableName }}.update', $item) : route('{{ tableName }}.store') }}"> + @csrf + @if(isset($item)) + @method('PUT') + @endif + + @foreach($fields as $field) + <div class="mb-4"> + <label for="{{ $field }}" class="block text-gray-700">{{ ucfirst($field) }}</label> + <input type="text" name="{{ $field }}" id="{{ $field }}" + class="mt-1 block w-full rounded border-gray-300 shadow-sm focus:ring focus:ring-blue-200" + value="{{ old('$field', isset($item) ? $item->$field : '') }}"> + @error($field) + <span class="text-red-600 text-sm">{{ $message }}</span> + @enderror + </div> + @endforeach + + <div class="flex justify-end"> + <a href="{{ route('{{ tableName }}.index') }}" class="mr-2 px-4 py-2 bg-gray-200 rounded hover:bg-gray-300">Back</a> + <button type="submit" class="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700"> + {{ isset($item) ? 'Update' : 'Create' }} + </button> + </div> + </form> + </div> + </div> + </div> +</x-app-layout>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/Generator/View/stubs/index.stub Sun May 11 21:03:51 2025 -0400 @@ -0,0 +1,52 @@ +<x-app-layout> + <x-slot name="header"> + <h2 class="font-semibold text-xl text-gray-800 leading-tight"> + All {{ Str::plural(ucfirst('{{ modelVariable }}')) }} + </h2> + </x-slot> + + <div class="py-12"> + <div class="max-w-7xl mx-auto sm:px-6 lg:px-8"> + <div class="bg-white overflow-hidden shadow-sm sm:rounded-lg p-6"> + <div class="flex items-center justify-between mb-4"> + <span></span> + <a href="{{ route('{{ tableName }}.create') }}" class="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700"> + + New {{ ucfirst('{{ modelVariable }}') }} + </a> + </div> + <table class="w-full text-left border-collapse"> + <thead> + <tr> + @foreach($fields as $field) + <th class="border-b p-2">{{ ucfirst($field) }}</th> + @endforeach + <th class="border-b p-2">Actions</th> + </tr> + </thead> + <tbody> + @forelse ($items as $item) + <tr> + @foreach($fields as $field) + <td class="border-b p-2">{{ $item->$field }}</td> + @endforeach + <td class="border-b p-2 flex space-x-2"> + <a href="{{ route('{{ tableName }}.show', $item) }}" class="text-blue-600 hover:underline">View</a> + <a href="{{ route('{{ tableName }}.edit', $item) }}" class="text-yellow-600 hover:underline">Edit</a> + <form action="{{ route('{{ tableName }}.destroy', $item) }}" method="POST" class="inline"> + @csrf + @method('DELETE') + <button type="submit" class="text-red-600 hover:underline" onclick="return confirm('Delete?')">Delete</button> + </form> + </td> + </tr> + @empty + <tr> + <td class="p-2" colspan="{{ count($fields)+1 }}">No {{ tableName }} found.</td> + </tr> + @endforelse + </tbody> + </table> + </div> + </div> + </div> +</x-app-layout>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/Generator/View/stubs/show.stub Sun May 11 21:03:51 2025 -0400 @@ -0,0 +1,26 @@ +<x-app-layout> + <x-slot name="header"> + <h2 class="font-semibold text-xl text-gray-800 leading-tight"> + {{ ucfirst('{{ modelVariable }}') }} Details + </h2> + </x-slot> + + <div class="py-12"> + <div class="max-w-2xl mx-auto sm:px-6 lg:px-8"> + <div class="bg-white overflow-hidden shadow-sm sm:rounded-lg p-6"> + <div class="space-y-4"> + @foreach($fields as $field) + <div> + <span class="font-semibold">{{ ucfirst($field) }}:</span> + <span class="ml-2">{{ $item->$field }}</span> + </div> + @endforeach + </div> + <div class="flex justify-end mt-6"> + <a href="{{ route('{{ tableName }}.edit', $item) }}" class="mr-2 px-4 py-2 bg-yellow-400 text-white rounded hover:bg-yellow-500">Edit</a> + <a href="{{ route('{{ tableName }}.index') }}" class="px-4 py-2 bg-gray-200 rounded hover:bg-gray-300">Back</a> + </div> + </div> + </div> + </div> +</x-app-layout>
--- a/src/MagicForgerServiceProvider.php Tue Apr 22 21:37:44 2025 -0400 +++ b/src/MagicForgerServiceProvider.php Sun May 11 21:03:51 2025 -0400 @@ -10,6 +10,10 @@ use Wizard\MagicForger\Generator\Requests\StoreRequestGenerator; use Wizard\MagicForger\Generator\Requests\UpdateRequestGenerator; use Wizard\MagicForger\Generator\Route\RouteGenerator; +use Wizard\MagicForger\Generator\View\ViewGenerator; +use Wizard\MagicForger\Generator\View\IndexViewGenerator; +use Wizard\MagicForger\Generator\View\CreateEditViewGenerator; +use Wizard\MagicForger\Generator\View\ShowViewGenerator; class MagicForgerServiceProvider extends ServiceProvider { @@ -27,6 +31,10 @@ StoreRequestGenerator::class, UpdateRequestGenerator::class, RouteGenerator::class, + ViewGenerator::class, + IndexViewGenerator::class, + CreateEditViewGenerator::class, + ShowViewGenerator::class, ]); }
--- a/src/Replacer/Replacer.php Tue Apr 22 21:37:44 2025 -0400 +++ b/src/Replacer/Replacer.php Sun May 11 21:03:51 2025 -0400 @@ -114,6 +114,30 @@ return 'Update'.$this->model_name($name).'Request'; } + + /** + * Generate the index view name. + */ + public function index_view_name(string $name): string + { + return ''; + } + + /** + * Generate the create_edit view name. + */ + public function create_edit_view_name(string $name): string + { + return ''; + } + + /** + * Generate the show view name. + */ + public function show_view_name(string $name): string + { + return ''; + } // Namespace Methods // These methods handle the formation of various namespaces used within the replacements. @@ -174,6 +198,39 @@ } /** + * Get the view namespace. + */ + public function getViewNamespace(string $name): string + { + return $this->viewPath($name) . '\\'; + } + + /** + * Get the index view namespace. + */ + public function getIndexViewNamespace(string $name): string + { + return $this->getViewNamespace($name) . '\\'; + } + + /** + * Get the create_edit view namespace. + */ + public function getCreateEditViewNamespace(string $name): string + { + return $this->getViewNamespace($name) . '\\'; + } + + /** + * Get the show view namespace. + */ + public function getShowViewNamespace(string $name): string + { + return $this->getViewNamespace($name) . '\\'; + } + + + /** * Get the request uses string for replacement. */ public function getRequestUses(string $name): string
