From 471a39b144d2aed074fb5e10a8eeb6a11e56b205 Mon Sep 17 00:00:00 2001 From: Sam Maosa Date: Sat, 6 Apr 2024 21:34:15 +0300 Subject: [PATCH] New Feature: Controller Make Command - Can generate a controller for a module - Can generate a controller together with the model - TODO: Fix bug: model not found even if it exists --- src/Commands/ControllerMakeCommand.php | 127 ++++++++++++++++++ src/Commands/ModelMakeCommand.php | 6 +- src/Module.php | 2 +- .../Concerns/GeneratesModularFiles.php | 19 ++- 4 files changed, 150 insertions(+), 4 deletions(-) create mode 100644 src/Commands/ControllerMakeCommand.php diff --git a/src/Commands/ControllerMakeCommand.php b/src/Commands/ControllerMakeCommand.php new file mode 100644 index 0000000..763776d --- /dev/null +++ b/src/Commands/ControllerMakeCommand.php @@ -0,0 +1,127 @@ +parseModel($this->option('parent')); + + if (! class_exists($parentModelClass, false) && + confirm("A {$parentModelClass} model does not exist. Do you want to generate it?", default: true)) { + $this->call('modular:make-model', ['name' => $parentModelClass, 'module' => $this->getModule()->name()]); + } + + return [ + 'ParentDummyFullModelClass' => $parentModelClass, + '{{ namespacedParentModel }}' => $parentModelClass, + '{{namespacedParentModel}}' => $parentModelClass, + 'ParentDummyModelClass' => class_basename($parentModelClass), + '{{ parentModel }}' => class_basename($parentModelClass), + '{{parentModel}}' => class_basename($parentModelClass), + 'ParentDummyModelVariable' => lcfirst(class_basename($parentModelClass)), + '{{ parentModelVariable }}' => lcfirst(class_basename($parentModelClass)), + '{{parentModelVariable}}' => lcfirst(class_basename($parentModelClass)), + ]; + } + + /** + * Build the model replacement values. + * + * @param array $replace + * @return array + */ + protected function buildModelReplacements(array $replace): array + { + $modelClass = $this->parseModel($this->option('model')); + + if (! class_exists($modelClass, false) && confirm("A {$modelClass} model does not exist. Do you want to generate it?", default: true)) { + $this->call('modular:make-model', ['name' => $modelClass,'module' => $this->getModule()->name()]); + } + + $replace = $this->buildFormRequestReplacements($replace, $modelClass); + + return array_merge($replace, [ + 'DummyFullModelClass' => $modelClass, + '{{ namespacedModel }}' => $modelClass, + '{{namespacedModel}}' => $modelClass, + 'DummyModelClass' => class_basename($modelClass), + '{{ model }}' => class_basename($modelClass), + '{{model}}' => class_basename($modelClass), + 'DummyModelVariable' => lcfirst(class_basename($modelClass)), + '{{ modelVariable }}' => lcfirst(class_basename($modelClass)), + '{{modelVariable}}' => lcfirst(class_basename($modelClass)), + ]); + } + + protected function buildFormRequestReplacements(array $replace, $modelClass): array + { + [$namespace, $storeRequestClass, $updateRequestClass] = [ + 'Illuminate\\Http', 'Request', 'Request', + ]; + + if ($this->option('requests')) { + $namespace = $this->getModule()->makeNamespace('\\Http\\Requests'); + + [$storeRequestClass, $updateRequestClass] = $this->generateFormRequests( + $modelClass, $storeRequestClass, $updateRequestClass + ); + } + + $namespacedRequests = $namespace.'\\'.$storeRequestClass.';'; + + if ($storeRequestClass !== $updateRequestClass) { + $namespacedRequests .= PHP_EOL.'use '.$namespace.'\\'.$updateRequestClass.';'; + } + + return array_merge($replace, [ + '{{ storeRequest }}' => $storeRequestClass, + '{{storeRequest}}' => $storeRequestClass, + '{{ updateRequest }}' => $updateRequestClass, + '{{updateRequest}}' => $updateRequestClass, + '{{ namespacedStoreRequest }}' => $namespace.'\\'.$storeRequestClass, + '{{namespacedStoreRequest}}' => $namespace.'\\'.$storeRequestClass, + '{{ namespacedUpdateRequest }}' => $namespace.'\\'.$updateRequestClass, + '{{namespacedUpdateRequest}}' => $namespace.'\\'.$updateRequestClass, + '{{ namespacedRequests }}' => $namespacedRequests, + '{{namespacedRequests}}' => $namespacedRequests, + ]); + } + + /** + * @param $modelClass + * @param $storeRequestClass + * @param $updateRequestClass + * @return string[] + * TODO: Replace this with a call to the modular:make-request command + */ + protected function generateFormRequests($modelClass, $storeRequestClass, $updateRequestClass): array + { + $storeRequestClass = 'Store'.class_basename($modelClass).'Request'; + + $this->call('make:request', [ + 'name' => $storeRequestClass, + ]); + + $updateRequestClass = 'Update'.class_basename($modelClass).'Request'; + + $this->call('make:request', [ + 'name' => $updateRequestClass, + ]); + + return [$storeRequestClass, $updateRequestClass]; + } +} diff --git a/src/Commands/ModelMakeCommand.php b/src/Commands/ModelMakeCommand.php index 0e6940e..206e37d 100644 --- a/src/Commands/ModelMakeCommand.php +++ b/src/Commands/ModelMakeCommand.php @@ -53,8 +53,9 @@ protected function createSeeder(): void { $seeder = Str::studly(class_basename($this->argument('name'))); - $this->call('make:seeder', [ + $this->call('modular:make-seeder', [ 'name' => "{$seeder}Seeder", + 'module' => $this->getModule()->name(), ]); } @@ -67,7 +68,8 @@ protected function createController(): void $modelName = $this->qualifyClass($this->getNameInput()); - $this->call('make:controller', array_filter([ + $this->call('modular:make-controller', array_filter([ + 'module' => $this->getModule()->name(), 'name' => "{$controller}Controller", '--model' => $this->option('resource') || $this->option('api') ? $modelName : null, '--api' => $this->option('api'), diff --git a/src/Module.php b/src/Module.php index a0a0001..88bd4b8 100644 --- a/src/Module.php +++ b/src/Module.php @@ -25,7 +25,7 @@ public function __construct(string $name) $this->title = Str::of($name)->kebab()->title()->replace('-', ' ')->toString(); // If the module does not exist, throw an error if (! is_dir(app()->basePath(config('modular.path').DIRECTORY_SEPARATOR.$this->name))) { - abort(404, "Module $name does not exist"); + abort(404, "Module $this->title does not exist"); } $this->studlyName = Str::of($name)->studly()->toString(); $this->namespace = config('modular.namespace').'\\'.$this->studlyName; diff --git a/src/Support/Concerns/GeneratesModularFiles.php b/src/Support/Concerns/GeneratesModularFiles.php index c1f80da..a3e4a6a 100644 --- a/src/Support/Concerns/GeneratesModularFiles.php +++ b/src/Support/Concerns/GeneratesModularFiles.php @@ -6,6 +6,7 @@ use Savannabits\Modular\Facades\Modular; use Savannabits\Modular\Module; use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Finder\Finder; trait GeneratesModularFiles { @@ -24,7 +25,12 @@ protected function resolveStubPath($stub): string } public function getModule(): Module { - return Modular::module($this->argument('module')); + try { + return Modular::module($this->argument('module')); + } catch (\Throwable $e) { + $this->error($e->getMessage()); + exit(1); + } } protected function getDefaultNamespace($rootNamespace): string @@ -48,4 +54,15 @@ protected function getPath($name): string return $this->getModule()->srcPath(str_replace('\\', '/', $name).'.php'); } + + protected function possibleModels() + { + $modelPath = $this->getModule()->srcPath('Models'); + + return collect(Finder::create()->files()->depth(0)->in($modelPath)) + ->map(fn ($file) => $file->getBasename('.php')) + ->sort() + ->values() + ->all(); + } }