diff --git a/modules/backend/console/CreateController.php b/modules/backend/console/CreateController.php index d256e22ed1..c853ab8ca6 100644 --- a/modules/backend/console/CreateController.php +++ b/modules/backend/console/CreateController.php @@ -1,21 +1,21 @@ (eg: Winter.Blog)} @@ -24,23 +24,22 @@ class CreateController extends GeneratorCommand {--model= : Defines the model name to use. If not provided, the singular name of the controller is used.}'; /** - * The console command description. - * - * @var string + * @var string The console command description. */ protected $description = 'Creates a new controller.'; /** - * The type of class being generated. - * - * @var string + * @var string The type of class being generated. */ protected $type = 'Controller'; /** - * A mapping of stub to generated file. - * - * @var array + * @var string The argument that the generated class name comes from + */ + protected $nameFrom = 'controller'; + + /** + * @var array A mapping of stub to generated file. */ protected $stubs = [ 'scaffold/controller/_list_toolbar.stub' => 'controllers/{{lower_name}}/_list_toolbar.htm', @@ -55,33 +54,46 @@ class CreateController extends GeneratorCommand /** * Prepare variables for stubs. - * - * return @array */ - protected function prepareVars() + protected function prepareVars(): array { - $pluginCode = $this->argument('plugin'); - - $parts = explode('.', $pluginCode); - $plugin = array_pop($parts); - $author = array_pop($parts); - - $controller = $this->argument('controller'); - + $vars = parent::prepareVars(); /* * Determine the model name to use, * either supplied or singular from the controller name. */ $model = $this->option('model'); if (!$model) { - $model = Str::singular($controller); + $model = Str::singular($vars['name']); } + $vars['model'] = $model; + + return $vars; + } + + /** + * Adds controller & model lang helpers to the vars + */ + protected function processVars($vars): array + { + $vars = parent::processVars($vars); + $vars['controller_url'] = "{$vars['plugin_url']}/{$vars['lower_name']}"; + $vars['model_lang_key_short'] = "models.{$vars['lower_model']}"; + $vars['model_lang_key'] = "{$vars['plugin_id']}::lang.{$vars['model_lang_key_short']}"; + + return $vars; + } + + /** + * Gets the localization keys and values to be stored in the plugin's localization files + * Can reference $this->vars and $this->laravel->getLocale() internally + */ + protected function getLangKeys(): array + { return [ - 'name' => $controller, - 'model' => $model, - 'author' => $author, - 'plugin' => $plugin + "{$this->vars['model_lang_key_short']}.label" => $this->vars['title_singular_name'], + "{$this->vars['model_lang_key_short']}.label_plural" => $this->vars['title_plural_name'], ]; } } diff --git a/modules/backend/console/CreateFormWidget.php b/modules/backend/console/CreateFormWidget.php index 17cf2365ef..32475e47d1 100644 --- a/modules/backend/console/CreateFormWidget.php +++ b/modules/backend/console/CreateFormWidget.php @@ -1,8 +1,8 @@ 'formwidgets/{{lower_name}}/assets/css/{{lower_name}}.css', 'scaffold/formwidget/javascript.stub' => 'formwidgets/{{lower_name}}/assets/js/{{lower_name}}.js', ]; - - /** - * Prepare variables for stubs. - * - * return @array - */ - protected function prepareVars() - { - $pluginCode = $this->argument('plugin'); - - $parts = explode('.', $pluginCode); - $plugin = array_pop($parts); - $author = array_pop($parts); - - $widget = $this->argument('widget'); - - return [ - 'name' => $widget, - 'author' => $author, - 'plugin' => $plugin - ]; - } } diff --git a/modules/backend/console/CreateReportWidget.php b/modules/backend/console/CreateReportWidget.php index be6d7f5e26..e5218fa2b4 100644 --- a/modules/backend/console/CreateReportWidget.php +++ b/modules/backend/console/CreateReportWidget.php @@ -1,8 +1,8 @@ 'reportwidgets/{{studly_name}}.php', 'scaffold/reportwidget/widget.stub' => 'reportwidgets/{{lower_name}}/partials/_{{lower_name}}.htm', ]; - - /** - * Prepare variables for stubs. - * - * return @array - */ - protected function prepareVars() - { - $pluginCode = $this->argument('plugin'); - - $parts = explode('.', $pluginCode); - $plugin = array_pop($parts); - $author = array_pop($parts); - - $widget = $this->argument('widget'); - - return [ - 'name' => $widget, - 'author' => $author, - 'plugin' => $plugin - ]; - } } diff --git a/modules/backend/console/scaffold/controller/_list_toolbar.stub b/modules/backend/console/scaffold/controller/_list_toolbar.stub index 839d456519..f062a1c33c 100644 --- a/modules/backend/console/scaffold/controller/_list_toolbar.stub +++ b/modules/backend/console/scaffold/controller/_list_toolbar.stub @@ -1,8 +1,8 @@
- New {{title_singular_name}} + trans('{{ model_lang_key }}.label')])); ?>
diff --git a/modules/backend/console/scaffold/controller/config_form.stub b/modules/backend/console/scaffold/controller/config_form.stub index f5b0f4fe57..27320fca0c 100644 --- a/modules/backend/console/scaffold/controller/config_form.stub +++ b/modules/backend/console/scaffold/controller/config_form.stub @@ -3,28 +3,28 @@ # =================================== # Record name -name: {{title_singular_name}} +name: '{{ model_lang_key }}.label' # Model Form Field configuration -form: $/{{lower_author}}/{{lower_plugin}}/models/{{lower_model}}/fields.yaml +form: $/{{ plugin_folder }}/models/{{ lower_model }}/fields.yaml # Model Class name -modelClass: {{studly_author}}\{{studly_plugin}}\Models\{{studly_model}} +modelClass: {{ plugin_namespace }}\Models\{{ studly_model }} # Default redirect location -defaultRedirect: {{lower_author}}/{{lower_plugin}}/{{lower_name}} +defaultRedirect: {{ controller_url }} # Create page create: title: backend::lang.form.create_title - redirect: {{lower_author}}/{{lower_plugin}}/{{lower_name}}/update/:id - redirectClose: {{lower_author}}/{{lower_plugin}}/{{lower_name}} + redirect: {{ controller_url }}/update/:id + redirectClose: {{ controller_url }} # Update page update: title: backend::lang.form.update_title - redirect: {{lower_author}}/{{lower_plugin}}/{{lower_name}} - redirectClose: {{lower_author}}/{{lower_plugin}}/{{lower_name}} + redirect: {{ controller_url }} + redirectClose: {{ controller_url }} # Preview page preview: diff --git a/modules/backend/console/scaffold/controller/config_list.stub b/modules/backend/console/scaffold/controller/config_list.stub index 6ffce9b3d3..0725e06da8 100644 --- a/modules/backend/console/scaffold/controller/config_list.stub +++ b/modules/backend/console/scaffold/controller/config_list.stub @@ -3,16 +3,16 @@ # =================================== # Model List Column configuration -list: $/{{lower_author}}/{{lower_plugin}}/models/{{lower_model}}/columns.yaml +list: $/{{ plugin_folder }}/models/{{ lower_model }}/columns.yaml # Model Class name -modelClass: {{studly_author}}\{{studly_plugin}}\Models\{{studly_model}} +modelClass: {{ plugin_namespace }}\Models\{{ studly_model }} # List Title -title: Manage {{title_plural_name}} +title: '{{ model_lang_key }}.label_plural' # Link URL for each record -recordUrl: {{lower_author}}/{{lower_plugin}}/{{lower_name}}/update/:id +recordUrl: {{ controller_url }}/update/:id # Message to display if the list is empty noRecordsMessage: backend::lang.list.no_records diff --git a/modules/backend/console/scaffold/controller/controller.stub b/modules/backend/console/scaffold/controller/controller.stub index 6797a76faf..0c5e1f3da9 100644 --- a/modules/backend/console/scaffold/controller/controller.stub +++ b/modules/backend/console/scaffold/controller/controller.stub @@ -1,12 +1,12 @@ - @@ -19,21 +19,21 @@ type="submit" data-request="onSave" data-hotkey="ctrl+s, cmd+s" - data-load-indicator="Creating {{singular_name}}..." + data-load-indicator=" trans('{{ model_lang_key }}.label')])); ?>" class="btn btn-primary"> - Create + - or Cancel + or @@ -43,6 +43,6 @@

fatalError) ?>

-

Return to {{lower_title_name}} list

+

diff --git a/modules/backend/console/scaffold/controller/index.stub b/modules/backend/console/scaffold/controller/index.stub index 766877d929..ea43a3636c 100644 --- a/modules/backend/console/scaffold/controller/index.stub +++ b/modules/backend/console/scaffold/controller/index.stub @@ -1,2 +1 @@ - listRender() ?> diff --git a/modules/backend/console/scaffold/controller/preview.stub b/modules/backend/console/scaffold/controller/preview.stub index df5524cd45..fbd3d7457d 100644 --- a/modules/backend/console/scaffold/controller/preview.stub +++ b/modules/backend/console/scaffold/controller/preview.stub @@ -1,6 +1,6 @@ @@ -14,6 +14,6 @@

fatalError) ?>

-

Return to {{lower_title_name}} list

+

diff --git a/modules/backend/console/scaffold/controller/update.stub b/modules/backend/console/scaffold/controller/update.stub index 7812f2b748..4d68a5571a 100644 --- a/modules/backend/console/scaffold/controller/update.stub +++ b/modules/backend/console/scaffold/controller/update.stub @@ -20,28 +20,28 @@ data-request="onSave" data-request-data="redirect:0" data-hotkey="ctrl+s, cmd+s" - data-load-indicator="Saving {{singular_name}}..." + data-load-indicator=" trans('{{ model_lang_key }}.label')])); ?>" class="btn btn-primary"> - Save + - or Cancel + or @@ -51,6 +51,6 @@

fatalError) ?>

-

Return to {{lower_title_name}} list

+

diff --git a/modules/cms/console/CreateComponent.php b/modules/cms/console/CreateComponent.php index d6eaa53d23..da9af3e3f2 100644 --- a/modules/cms/console/CreateComponent.php +++ b/modules/cms/console/CreateComponent.php @@ -1,8 +1,8 @@ 'components/{{studly_name}}.php', 'scaffold/component/default.stub' => 'components/{{lower_name}}/default.htm', ]; - - /** - * Prepare variables for stubs. - * - * return @array - */ - protected function prepareVars() - { - $pluginCode = $this->argument('plugin'); - - $parts = explode('.', $pluginCode); - $plugin = array_pop($parts); - $author = array_pop($parts); - $component = $this->argument('component'); - - return [ - 'name' => $component, - 'author' => $author, - 'plugin' => $plugin - ]; - } } diff --git a/modules/cms/console/CreateTheme.php b/modules/cms/console/CreateTheme.php index fe917827b0..bcfb3b162b 100644 --- a/modules/cms/console/CreateTheme.php +++ b/modules/cms/console/CreateTheme.php @@ -1,44 +1,38 @@ (eg: MyTheme)} {--force : Overwrite existing files with generated files.}'; /** - * The console command description. - * - * @var string + * @var string The console command description. */ protected $description = 'Creates a new theme.'; /** - * The type of class being generated. - * - * @var string + * @var string The type of class being generated. */ protected $type = 'Theme'; /** - * A mapping of stub to generated file. - * - * @var array + * @var string The argument that the generated class name comes from + */ + protected $nameFrom = 'theme'; + + /** + * @var array A mapping of stub to generated file. */ protected $stubs = [ 'scaffold/theme/assets/js/app.stub' => 'assets/js/app.js', @@ -56,32 +50,29 @@ class CreateTheme extends GeneratorCommand ]; /** - * Prepare variables for stubs. - * - * return @array + * Get the desired class name from the input. */ - protected function prepareVars() + protected function getNameInput(): string { - /* - * Extract the author and name from the plugin code - */ - $code = str_slug($this->argument('theme')); + return str_slug(parent::getNameInput()); + } + /** + * Prepare variables for stubs. + */ + protected function prepareVars(): array + { return [ - 'code' => $code, + 'code' => $this->getNameInput(), ]; } /** * Get the plugin path from the input. - * - * @return string */ - protected function getDestinationPath() + protected function getDestinationPath(): string { - $code = $this->prepareVars()['code']; - - return themes_path($code); + return themes_path($this->getNameInput()); } /** @@ -96,11 +87,12 @@ public function makeStub($stubName) } $sourceFile = $this->getSourcePath() . '/' . $stubName; - $destinationFile = $this->getDestinationPath() . '/' . $this->stubs[$stubName]; + $destinationFile = $this->getDestinationForStub($stubName); $destinationContent = $this->files->get($sourceFile); /* * Parse each variable in to the destination content and path + * @NOTE: CANNOT USE TWIG AS IT WOULD CONFLICT WITH THE TWIG TEMPLATES THEMSELVES */ foreach ($this->vars as $key => $var) { $destinationContent = str_replace('{{' . $key . '}}', $var, $destinationContent); @@ -109,13 +101,6 @@ public function makeStub($stubName) $this->makeDirectory($destinationFile); - /* - * Make sure this file does not already exist - */ - if ($this->files->exists($destinationFile) && !$this->option('force')) { - throw new Exception('Stop everything!!! This file already exists: ' . $destinationFile); - } - $this->files->put($destinationFile, $destinationContent); } } diff --git a/modules/cms/console/scaffold/component/component.stub b/modules/cms/console/scaffold/component/component.stub index 5f9bbbb7be..1e43cce065 100644 --- a/modules/cms/console/scaffold/component/component.stub +++ b/modules/cms/console/scaffold/component/component.stub @@ -4,6 +4,9 @@ use Cms\Classes\ComponentBase; class {{studly_name}} extends ComponentBase { + /** + * Gets the details for the component + */ public function componentDetails() { return [ @@ -12,6 +15,9 @@ class {{studly_name}} extends ComponentBase ]; } + /** + * Returns the properties provided by the component + */ public function defineProperties() { return []; diff --git a/modules/system/ServiceProvider.php b/modules/system/ServiceProvider.php index 1bc573b359..35dc3847aa 100644 --- a/modules/system/ServiceProvider.php +++ b/modules/system/ServiceProvider.php @@ -243,6 +243,7 @@ protected function registerConsole() * Register console commands */ $this->registerConsoleCommand('create.command', \System\Console\CreateCommand::class); + $this->registerConsoleCommand('create.migration', \System\Console\CreateMigration::class); $this->registerConsoleCommand('create.model', \System\Console\CreateModel::class); $this->registerConsoleCommand('create.plugin', \System\Console\CreatePlugin::class); $this->registerConsoleCommand('create.settings', \System\Console\CreateSettings::class); diff --git a/modules/system/console/BaseScaffoldCommand.php b/modules/system/console/BaseScaffoldCommand.php new file mode 100644 index 0000000000..57e6cdb8bc --- /dev/null +++ b/modules/system/console/BaseScaffoldCommand.php @@ -0,0 +1,111 @@ +getPluginIdentifier(); + $parts = explode('.', $pluginCode); + + if (count($parts) !== 2) { + throw new InvalidArgumentException("Invalid plugin name, either too many dots or not enough. Example: Author.PluginName"); + } + + $pluginName = array_pop($parts); + $authorName = array_pop($parts); + + return [ + 'name' => $this->getNameInput(), + 'plugin' => $pluginName, + 'author' => $authorName, + ]; + } + + /** + * Converts all variables to available modifier and case formats and adds plugin helpers + */ + protected function processVars(array $vars): array + { + $vars = parent::processVars($vars); + + $vars['plugin_id'] = "{$vars['lower_author']}.{$vars['lower_plugin']}"; + $vars['plugin_code'] = "{$vars['studly_author']}.{$vars['studly_plugin']}"; + $vars['plugin_url'] = "{$vars['lower_author']}/{$vars['lower_plugin']}"; + $vars['plugin_folder'] = "{$vars['lower_author']}/{$vars['lower_plugin']}"; + $vars['plugin_namespace'] = "{$vars['studly_author']}\\{$vars['studly_plugin']}"; + + return $vars; + } + + /** + * Get the base path to output generated stubs to + */ + protected function getDestinationPath(): string + { + $plugin = $this->getPluginIdentifier(); + + $parts = explode('.', $plugin); + $name = array_pop($parts); + $author = array_pop($parts); + + return plugins_path(strtolower($author) . '/' . strtolower($name)); + } + + /** + * Make all stubs. + */ + public function makeStubs(): void + { + parent::makeStubs(); + + // Get the language keys to be set + $langKeys = $this->getLangKeys(); + if (empty($langKeys)) { + return; + } + + // Generate the path to the localization file to modify + $langFilePath = plugins_path( + $this->vars['plugin_folder'] + . DIRECTORY_SEPARATOR + . 'lang' + . DIRECTORY_SEPARATOR + . $this->laravel->getLocale() + . DIRECTORY_SEPARATOR + . 'lang.php' + ); + if (!file_exists($langFilePath)) { + $this->makeDirectory($langFilePath); + $comment = 'File generated: ' . str_replace(base_path(), '', $langFilePath); + } else { + $comment = 'File updated: ' . str_replace(base_path(), '', $langFilePath); + } + + // Store the localization messages to the determined file path + ArrayFile::open($langFilePath)->set($langKeys)->write(); + + // Inform the user + $this->comment($comment); + } + + /** + * Gets the localization keys and values to be stored in the plugin's localization files + * Can reference $this->vars and $this->laravel->getLocale() internally + */ + protected function getLangKeys(): array + { + return []; + } +} diff --git a/modules/system/console/CreateCommand.php b/modules/system/console/CreateCommand.php index 3a5f546bca..9bda65bc15 100644 --- a/modules/system/console/CreateCommand.php +++ b/modules/system/console/CreateCommand.php @@ -1,8 +1,9 @@ (eg: Winter.Blog)} - {name : The name of the command to generate. (eg: create)} + {name : The name of the command to generate. (eg: ImportPosts)} + {--command= : The terminal command that should be assigned. (eg: blog:importposts)} {--f|force : Overwrite existing files with generated files.}'; /** @@ -22,6 +24,13 @@ class CreateCommand extends GeneratorCommand */ protected $description = 'Creates a new console command.'; + /** + * @var array List of commands that this command replaces (aliases) + */ + protected $replaces = [ + 'make:command', + ]; + /** * @var string The type of class being generated. */ @@ -36,22 +45,26 @@ class CreateCommand extends GeneratorCommand /** * Prepare variables for stubs. - * - * @return array */ - protected function prepareVars() + protected function prepareVars(): array { - $pluginCode = $this->argument('plugin'); - - $parts = explode('.', $pluginCode); + $parts = explode('.', $this->getPluginIdentifier()); $plugin = array_pop($parts); $author = array_pop($parts); - $command = $this->argument('name'); + $name = $this->getNameInput(); + $command = trim($this->option('command') ?? strtolower("{$plugin}:{$name}")); + + // More strict than the base Symfony validateName() + // method, make a PR if it's a problem for you + if (preg_match('/^[a-z]++(:[a-z]++)*$/', $command) !== 1) { + throw new InvalidArgumentException(sprintf('Command name "%s" is invalid.', $command)); + } return [ - 'name' => $command, + 'name' => $name, + 'command' => $command, 'author' => $author, - 'plugin' => $plugin + 'plugin' => $plugin, ]; } } diff --git a/modules/system/console/CreateMigration.php b/modules/system/console/CreateMigration.php new file mode 100644 index 0000000000..98835756b7 --- /dev/null +++ b/modules/system/console/CreateMigration.php @@ -0,0 +1,85 @@ +(eg: Winter.Blog)} + {name : The name of the migration to generate. (eg: CreatePostTable)} + {--f|force : Overwrite existing files with generated files.} + {--model= : The model to create a migration for. (eg: Post)} + {--table= : The table to migrate, defaults to autogenerated from the provided model. (eg: winter_blog_posts)} + {--c|create : Generate a migration that creates the specified table} + {--u|update : Generate a migration that updates the specified table} + '; + + /** + * @var string The console command description. + */ + protected $description = 'Creates a new migration.'; + + /** + * @var array List of commands that this command replaces (aliases) + */ + protected $replaces = [ + 'make:migration', + ]; + + /** + * @var string The type of class being generated. + */ + protected $type = 'Migration'; + + /** + * @var array A mapping of stubs to generated files. + */ + protected $stubs = [ + 'scaffold/migration/create_table.stub' => 'updates/create_{{snake_plural_name}}_table.php', + ]; + + /** + * Prepare variables for stubs. + */ + protected function prepareVars(): array + { + $parts = explode('.', $this->getPluginIdentifier()); + $plugin = array_pop($parts); + $author = array_pop($parts); + $name = $this->getNameInput(); + $table = $this->option('table'); + $model = $this->option('model'); + + if (empty($table) && !empty($model)) { + $modelClass = "\\{$author}\\{$plugin}\Models\\{$model}"; + if (class_exists($modelClass)) { + $table = (new $modelClass)->getTable(); + } + } + + $this->error("create:migration has not been implemented yet"); + + return [ + 'name' => $name, + 'author' => $author, + 'plugin' => $plugin, + ]; + } +} diff --git a/modules/system/console/CreateModel.php b/modules/system/console/CreateModel.php index bf425ca09c..7a1097217b 100644 --- a/modules/system/console/CreateModel.php +++ b/modules/system/console/CreateModel.php @@ -1,8 +1,9 @@ (eg: Winter.Blog)} {model : The name of the model to generate. (eg: Post)} - {--f|force : Overwrite existing files with generated files.}'; + {--f|force : Overwrite existing files with generated files.} + + {--a|all : Generate a controller, migration, & seeder for the model} + {--c|controller : Create a new controller for the model} + {--s|seed : Create a new seeder for the model} + {--p|pivot : Indicates if the generated model should be a custom intermediate table model} + {--no-migration : Don\'t create a migration file for the model} + '; /** * @var string The console command description. */ protected $description = 'Creates a new model.'; + /** + * @var array List of commands that this command replaces (aliases) + */ + protected $replaces = [ + 'make:model', + ]; + /** * @var string The type of class being generated. */ protected $type = 'Model'; + /** + * @var string The argument that the generated class name comes from + */ + protected $nameFrom = 'model'; + /** * @var array A mapping of stubs to generated files. */ @@ -34,28 +54,93 @@ class CreateModel extends GeneratorCommand 'scaffold/model/model.stub' => 'models/{{studly_name}}.php', 'scaffold/model/fields.stub' => 'models/{{lower_name}}/fields.yaml', 'scaffold/model/columns.stub' => 'models/{{lower_name}}/columns.yaml', - 'scaffold/model/create_table.stub' => 'updates/create_{{snake_plural_name}}_table.php', ]; /** - * Prepare variables for stubs. + * Execute the console command. * - * @return array + * @return void + */ + public function handle() + { + if (parent::handle() === false && !$this->option('force')) { + return false; + } + + if ($this->option('all')) { + $this->input->setOption('controller', true); + $this->input->setOption('seed', true); + } + + if ($this->option('controller')) { + $this->createController(); + } + + if ($this->option('seed')) { + $this->createSeeder(); + } + + if ($this->option('no-migration') !== false) { + $this->createMigration(); + } + } + + /** + * Adds controller & model lang helpers to the vars */ - protected function prepareVars() + protected function processVars($vars): array { - $pluginCode = $this->argument('plugin'); + $vars = parent::processVars($vars); - $parts = explode('.', $pluginCode); - $plugin = array_pop($parts); - $author = array_pop($parts); + $vars['table_name'] = "{$vars['lower_author']}_{$vars['lower_plugin']}_{$vars['snake_plural_name']}"; - $model = $this->argument('model'); + return $vars; + } + /** + * Gets the localization keys and values to be stored in the plugin's localization files + * Can reference $this->vars and $this->laravel->getLocale() internally + */ + protected function getLangKeys(): array + { return [ - 'name' => $model, - 'author' => $author, - 'plugin' => $plugin + 'models.general.id' => 'ID', + 'models.general.created_at' => 'Created At', + 'models.general.updated_at' => 'Updated At', ]; } + + /** + * Create a migration for the model. + */ + public function createMigration() + { + $this->call('create:migration', [ + 'plugin' => $this->getPluginIdentifier(), + '--model' => $this->getNameInput(), + ]); + } + + /** + * Create a seeder for the model. + */ + public function createSeeder() + { + $this->call('create:seeder', [ + 'plugin' => $this->getPluginIdentifier(), + 'model' => $this->getNameInput(), + ]); + } + + /** + * Create a controller for the model. + */ + public function createController() + { + $this->call('create:controller', [ + 'plugin' => $this->getPluginIdentifier(), + 'controller' => Str::pluralize($this->argument('model')), + '--model' => $this->getNameInput(), + ]); + } } diff --git a/modules/system/console/CreatePlugin.php b/modules/system/console/CreatePlugin.php index 85268ea7d4..6692739ea8 100644 --- a/modules/system/console/CreatePlugin.php +++ b/modules/system/console/CreatePlugin.php @@ -1,8 +1,8 @@ argument('plugin'); - $parts = explode('.', $pluginCode); + protected $validatePluginInput = false; - if (count($parts) != 2) { - $this->error('Invalid plugin name, either too many dots or not enough.'); - $this->error('Example name: AuthorName.PluginName'); - return; - } - - - $pluginName = array_pop($parts); - $authorName = array_pop($parts); + /** + * Get the desired class name from the input. + */ + protected function getNameInput(): string + { + return explode('.', $this->getPluginIdentifier())[1]; + } + /** + * Gets the localization keys and values to be stored in the plugin's localization files + * Can reference $this->vars and $this->laravel->getLocale() internally + */ + protected function getLangKeys(): array + { return [ - 'name' => $pluginName, - 'author' => $authorName, + 'plugin.name' => $this->vars['name'], + 'plugin.description' => 'No description provided yet...', + 'permissions.some_permission' => 'Some permission', ]; } } diff --git a/modules/system/console/CreateSettings.php b/modules/system/console/CreateSettings.php index 4c2b26b887..6019aa58e0 100644 --- a/modules/system/console/CreateSettings.php +++ b/modules/system/console/CreateSettings.php @@ -1,8 +1,8 @@ (eg: Winter.Blog)} - {settings : The name of the settings model to generate. (eg: BlogSettings)} + {settings? : The name of the settings model to generate. (eg: BlogSettings)} {--f|force : Overwrite existing files with generated files.}'; /** @@ -27,6 +27,11 @@ class CreateSettings extends GeneratorCommand */ protected $type = 'Settings Model'; + /** + * @var string The argument that the generated class name comes from + */ + protected $nameFrom = 'settings'; + /** * @var array A mapping of stubs to generated files. */ @@ -36,23 +41,10 @@ class CreateSettings extends GeneratorCommand ]; /** - * Prepare variables for stubs. - * - * @return array + * Get the desired class name from the input. */ - protected function prepareVars() + protected function getNameInput(): string { - $pluginCode = $this->argument('plugin'); - - $parts = explode('.', $pluginCode); - $plugin = array_pop($parts); - $author = array_pop($parts); - $settings = $this->argument('settings') ?? 'Settings'; - - return [ - 'name' => $settings, - 'author' => $author, - 'plugin' => $plugin - ]; + return parent::getNameInput() ?: 'Settings'; } } diff --git a/modules/system/console/scaffold/command/command.stub b/modules/system/console/scaffold/command/command.stub index 67ccbb43ed..24ef8b2f3e 100644 --- a/modules/system/console/scaffold/command/command.stub +++ b/modules/system/console/scaffold/command/command.stub @@ -7,12 +7,12 @@ class {{studly_name}} extends Command /** * @var string The console command name. */ - protected static $defaultName = '{{lower_plugin}}:{{lower_name}}'; + protected static $defaultName = '{{ lower_command }}'; /** * @var string The name and signature of this command. */ - protected $signature = '{{lower_plugin}}:{{lower_name}} + protected $signature = '{{ lower_command }} {myCustomArgument : Example argument. Additional information} {--f|force : Force the operation to run and ignore production warnings and confirmation questions.}'; diff --git a/modules/system/console/scaffold/migration/migration.create.stub b/modules/system/console/scaffold/migration/migration.create.stub new file mode 100644 index 0000000000..f193cd696f --- /dev/null +++ b/modules/system/console/scaffold/migration/migration.create.stub @@ -0,0 +1,31 @@ +id(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('{{ table }}'); + } +}; diff --git a/modules/system/console/scaffold/migration/migration.stub b/modules/system/console/scaffold/migration/migration.stub new file mode 100644 index 0000000000..eb54698869 --- /dev/null +++ b/modules/system/console/scaffold/migration/migration.stub @@ -0,0 +1,28 @@ +engine = 'InnoDB'; $table->increments('id'); $table->timestamps(); @@ -16,6 +16,6 @@ return new class extends Migration public function down() { - Schema::dropIfExists('{{lower_author}}_{{lower_plugin}}_{{snake_plural_name}}'); + Schema::dropIfExists('{{ table_name }}'); } }; diff --git a/modules/system/console/scaffold/model/fields.stub b/modules/system/console/scaffold/model/fields.stub index c611f31c78..b0ffc32917 100644 --- a/modules/system/console/scaffold/model/fields.stub +++ b/modules/system/console/scaffold/model/fields.stub @@ -4,5 +4,5 @@ fields: id: - label: ID + label: '{{ plugin_id }}::lang.models.general.id' disabled: true diff --git a/modules/system/console/scaffold/model/model.stub b/modules/system/console/scaffold/model/model.stub index 0816de62b0..49615c049f 100644 --- a/modules/system/console/scaffold/model/model.stub +++ b/modules/system/console/scaffold/model/model.stub @@ -1,18 +1,18 @@ - '{{name}}', - 'description' => 'No description provided yet...', - 'author' => '{{author}}', + 'name' => '{{ plugin_id }}::lang.plugin.name', + 'description' => '{{ plugin_id }}::lang.plugin.description', + 'author' => '{{ author }}', 'icon' => 'icon-leaf' ]; } /** * Register method, called when the plugin is first registered. - * - * @return void */ - public function register() + public function register(): void { } /** * Boot method, called right before the request route. - * - * @return array */ - public function boot() + public function boot(): void { } /** - * Registers any front-end components implemented in this plugin. - * - * @return array + * Registers any frontend components implemented in this plugin. */ - public function registerComponents() + public function registerComponents(): array { return []; // Remove this line to activate return [ - '{{studly_author}}\{{studly_name}}\Components\MyComponent' => 'myComponent', + '{{ plugin_namespace }}\Components\MyComponent' => 'myComponent', ]; } /** - * Registers any back-end permissions used by this plugin. - * - * @return array + * Registers any backend permissions used by this plugin. */ - public function registerPermissions() + public function registerPermissions(): array { return []; // Remove this line to activate return [ - '{{lower_author}}.{{lower_name}}.some_permission' => [ - 'tab' => '{{name}}', - 'label' => 'Some permission', + '{{ plugin_id }}.some_permission' => [ + 'tab' => '{{ plugin_id }}::lang.plugin.name', + 'label' => '{{ plugin_id }}::lang.permissions.some_permission', 'roles' => [UserRole::CODE_DEVELOPER, UserRole::CODE_PUBLISHER], ], ]; } /** - * Registers back-end navigation items for this plugin. - * - * @return array + * Registers backend navigation items for this plugin. */ - public function registerNavigation() + public function registerNavigation(): array { return []; // Remove this line to activate return [ - '{{lower_name}}' => [ - 'label' => '{{name}}', - 'url' => Backend::url('{{lower_author}}/{{lower_name}}/mycontroller'), + '{{ lower_name }}' => [ + 'label' => '{{ plugin_id }}::lang.plugin.name', + 'url' => Backend::url('{{ plugin_url }}/mycontroller'), 'icon' => 'icon-leaf', - 'permissions' => ['{{lower_author}}.{{lower_name}}.*'], + 'permissions' => ['{{ plugin_id }}.*'], 'order' => 500, ], ]; diff --git a/modules/system/console/scaffold/plugin/version.stub b/modules/system/console/scaffold/plugin/version.stub index 34b2bc0f97..57b822d815 100644 --- a/modules/system/console/scaffold/plugin/version.stub +++ b/modules/system/console/scaffold/plugin/version.stub @@ -1 +1,2 @@ -1.0.0: First version of {{name}} +'1.0.0': + - 'First version of {{ name }}' diff --git a/modules/system/console/scaffold/settings/model.stub b/modules/system/console/scaffold/settings/model.stub index 740e775a93..002b8a20e5 100644 --- a/modules/system/console/scaffold/settings/model.stub +++ b/modules/system/console/scaffold/settings/model.stub @@ -12,7 +12,7 @@ class {{studly_name}} extends Model /** * @var array Behaviors implemented by this model. */ - public $implement = ['System.Behaviors.SettingsModel']; + public $implement = [\System\Behaviors\SettingsModel::class]; /** * @var string Unique code diff --git a/modules/system/console/traits/HasPluginArgument.php b/modules/system/console/traits/HasPluginArgument.php index 0f743c3438..75978417df 100644 --- a/modules/system/console/traits/HasPluginArgument.php +++ b/modules/system/console/traits/HasPluginArgument.php @@ -16,6 +16,11 @@ trait HasPluginArgument */ // protected $hasPluginsFilter = 'enabled'; + /** + * @var bool Validate the provided plugin input against the PluginManager, default true. + */ + // protected $validatePluginInput = true; + /** * Return available plugins for autocompletion of the "plugin" argument */ @@ -52,7 +57,10 @@ public function getPluginIdentifier($identifier = null): string $pluginName = $identifier ?? $this->argument('plugin'); $pluginName = $pluginManager->normalizeIdentifier($pluginName); - if (!$pluginManager->hasPlugin($pluginName)) { + if ( + (isset($this->validatePluginInput) && $this->validatePluginInput !== false) + && !$pluginManager->hasPlugin($pluginName) + ) { throw new InvalidArgumentException(sprintf('Plugin "%s" could not be found.', $pluginName)); }