diff --git a/modules/backend/ServiceProvider.php b/modules/backend/ServiceProvider.php index 047f30a545..04489786a4 100644 --- a/modules/backend/ServiceProvider.php +++ b/modules/backend/ServiceProvider.php @@ -20,6 +20,7 @@ class ServiceProvider extends ModuleServiceProvider */ public function register() { + $this->registerConsole(); $this->registerMailer(); $this->registerAssetBundles(); @@ -45,6 +46,16 @@ public function boot() parent::boot('backend'); } + /** + * Register console commands + */ + protected function registerConsole() + { + $this->registerConsoleCommand('create.controller', \Backend\Console\CreateController::class); + $this->registerConsoleCommand('create.formwidget', \Backend\Console\CreateFormWidget::class); + $this->registerConsoleCommand('create.reportwidget', \Backend\Console\CreateReportWidget::class); + } + /** * Register mail templates */ diff --git a/modules/backend/console/CreateController.php b/modules/backend/console/CreateController.php new file mode 100644 index 0000000000..d256e22ed1 --- /dev/null +++ b/modules/backend/console/CreateController.php @@ -0,0 +1,87 @@ +(eg: Winter.Blog)} + {controller : The name of the controller to generate. (eg: Posts)} + {--force : Overwrite existing files with generated files.} + {--model= : Defines the model name to use. If not provided, the singular name of the controller is used.}'; + + /** + * The console command description. + * + * @var string + */ + protected $description = 'Creates a new controller.'; + + /** + * The type of class being generated. + * + * @var string + */ + protected $type = 'Controller'; + + /** + * A mapping of stub to generated file. + * + * @var array + */ + protected $stubs = [ + 'scaffold/controller/_list_toolbar.stub' => 'controllers/{{lower_name}}/_list_toolbar.htm', + 'scaffold/controller/config_form.stub' => 'controllers/{{lower_name}}/config_form.yaml', + 'scaffold/controller/config_list.stub' => 'controllers/{{lower_name}}/config_list.yaml', + 'scaffold/controller/create.stub' => 'controllers/{{lower_name}}/create.htm', + 'scaffold/controller/index.stub' => 'controllers/{{lower_name}}/index.htm', + 'scaffold/controller/preview.stub' => 'controllers/{{lower_name}}/preview.htm', + 'scaffold/controller/update.stub' => 'controllers/{{lower_name}}/update.htm', + 'scaffold/controller/controller.stub' => 'controllers/{{studly_name}}.php', + ]; + + /** + * Prepare variables for stubs. + * + * return @array + */ + protected function prepareVars() + { + $pluginCode = $this->argument('plugin'); + + $parts = explode('.', $pluginCode); + $plugin = array_pop($parts); + $author = array_pop($parts); + + $controller = $this->argument('controller'); + + /* + * Determine the model name to use, + * either supplied or singular from the controller name. + */ + $model = $this->option('model'); + if (!$model) { + $model = Str::singular($controller); + } + + return [ + 'name' => $controller, + 'model' => $model, + 'author' => $author, + 'plugin' => $plugin + ]; + } +} diff --git a/modules/backend/console/CreateFormWidget.php b/modules/backend/console/CreateFormWidget.php new file mode 100644 index 0000000000..17cf2365ef --- /dev/null +++ b/modules/backend/console/CreateFormWidget.php @@ -0,0 +1,71 @@ +(eg: Winter.Blog)} + {widget : The name of the form widget to generate. (eg: PostList)} + {--force : Overwrite existing files with generated files.}'; + + /** + * The console command description. + * + * @var string + */ + protected $description = 'Creates a new form widget.'; + + /** + * The type of class being generated. + * + * @var string + */ + protected $type = 'FormWidget'; + + /** + * A mapping of stub to generated file. + * + * @var array + */ + protected $stubs = [ + 'scaffold/formwidget/formwidget.stub' => 'formwidgets/{{studly_name}}.php', + 'scaffold/formwidget/partial.stub' => 'formwidgets/{{lower_name}}/partials/_{{lower_name}}.htm', + 'scaffold/formwidget/stylesheet.stub' => '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 new file mode 100644 index 0000000000..be6d7f5e26 --- /dev/null +++ b/modules/backend/console/CreateReportWidget.php @@ -0,0 +1,69 @@ +(eg: Winter.Blog)} + {widget : The name of the report widget to generate. (eg: PostViews)} + {--force : Overwrite existing files with generated files.}'; + + /** + * The console command description. + * + * @var string + */ + protected $description = 'Creates a new report widget.'; + + /** + * The type of class being generated. + * + * @var string + */ + protected $type = 'ReportWidget'; + + /** + * A mapping of stub to generated file. + * + * @var array + */ + protected $stubs = [ + 'scaffold/reportwidget/reportwidget.stub' => '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 new file mode 100644 index 0000000000..839d456519 --- /dev/null +++ b/modules/backend/console/scaffold/controller/_list_toolbar.stub @@ -0,0 +1,21 @@ +
+ + New {{title_singular_name}} + + + +
diff --git a/modules/backend/console/scaffold/controller/config_form.stub b/modules/backend/console/scaffold/controller/config_form.stub new file mode 100644 index 0000000000..f5b0f4fe57 --- /dev/null +++ b/modules/backend/console/scaffold/controller/config_form.stub @@ -0,0 +1,31 @@ +# =================================== +# Form Behavior Config +# =================================== + +# Record name +name: {{title_singular_name}} + +# Model Form Field configuration +form: $/{{lower_author}}/{{lower_plugin}}/models/{{lower_model}}/fields.yaml + +# Model Class name +modelClass: {{studly_author}}\{{studly_plugin}}\Models\{{studly_model}} + +# Default redirect location +defaultRedirect: {{lower_author}}/{{lower_plugin}}/{{lower_name}} + +# 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}} + +# Update page +update: + title: backend::lang.form.update_title + redirect: {{lower_author}}/{{lower_plugin}}/{{lower_name}} + redirectClose: {{lower_author}}/{{lower_plugin}}/{{lower_name}} + +# Preview page +preview: + title: backend::lang.form.preview_title diff --git a/modules/backend/console/scaffold/controller/config_list.stub b/modules/backend/console/scaffold/controller/config_list.stub new file mode 100644 index 0000000000..6ffce9b3d3 --- /dev/null +++ b/modules/backend/console/scaffold/controller/config_list.stub @@ -0,0 +1,50 @@ +# =================================== +# List Behavior Config +# =================================== + +# Model List Column configuration +list: $/{{lower_author}}/{{lower_plugin}}/models/{{lower_model}}/columns.yaml + +# Model Class name +modelClass: {{studly_author}}\{{studly_plugin}}\Models\{{studly_model}} + +# List Title +title: Manage {{title_plural_name}} + +# Link URL for each record +recordUrl: {{lower_author}}/{{lower_plugin}}/{{lower_name}}/update/:id + +# Message to display if the list is empty +noRecordsMessage: backend::lang.list.no_records + +# Records to display per page +recordsPerPage: 20 + +# Options to provide the user when selecting how many records to display per page +perPageOptions: [20, 40, 80, 100, 120] + +# Display page numbers with pagination, disable to improve performance +showPageNumbers: true + +# Displays the list column set up button +showSetup: true + +# Displays the sorting link on each column +showSorting: true + +# Default sorting column +# defaultSort: +# column: created_at +# direction: desc + +# Display checkboxes next to each record +showCheckboxes: true + +# Toolbar widget configuration +toolbar: + # Partial for toolbar buttons + buttons: list_toolbar + + # Search widget configuration + search: + prompt: backend::lang.list.search_prompt diff --git a/modules/backend/console/scaffold/controller/controller.stub b/modules/backend/console/scaffold/controller/controller.stub new file mode 100644 index 0000000000..6797a76faf --- /dev/null +++ b/modules/backend/console/scaffold/controller/controller.stub @@ -0,0 +1,25 @@ + + + + +fatalError): ?> + + 'layout']) ?> + +
+ formRender() ?> +
+ +
+
+ + + + or Cancel + +
+
+ + + + + +

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 new file mode 100644 index 0000000000..766877d929 --- /dev/null +++ b/modules/backend/console/scaffold/controller/index.stub @@ -0,0 +1,2 @@ + +listRender() ?> diff --git a/modules/backend/console/scaffold/controller/preview.stub b/modules/backend/console/scaffold/controller/preview.stub new file mode 100644 index 0000000000..df5524cd45 --- /dev/null +++ b/modules/backend/console/scaffold/controller/preview.stub @@ -0,0 +1,19 @@ + + + + +fatalError): ?> + +
+ formRenderPreview() ?> +
+ + + +

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 new file mode 100644 index 0000000000..7812f2b748 --- /dev/null +++ b/modules/backend/console/scaffold/controller/update.stub @@ -0,0 +1,56 @@ + + + + +fatalError): ?> + + 'layout']) ?> + +
+ formRender() ?> +
+ +
+
+ + + + + or Cancel + +
+
+ + + + + +

fatalError) ?>

+

Return to {{lower_title_name}} list

+ + diff --git a/modules/backend/console/scaffold/formwidget/formwidget.stub b/modules/backend/console/scaffold/formwidget/formwidget.stub new file mode 100644 index 0000000000..9fcf5045b0 --- /dev/null +++ b/modules/backend/console/scaffold/formwidget/formwidget.stub @@ -0,0 +1,57 @@ +prepareVars(); + return $this->makePartial('{{lower_name}}'); + } + + /** + * Prepares the form widget view data + */ + public function prepareVars() + { + $this->vars['name'] = $this->formField->getName(); + $this->vars['value'] = $this->getLoadValue(); + $this->vars['model'] = $this->model; + } + + /** + * @inheritDoc + */ + public function loadAssets() + { + $this->addCss('css/{{lower_name}}.css', '{{author}}.{{plugin}}'); + $this->addJs('js/{{lower_name}}.js', '{{author}}.{{plugin}}'); + } + + /** + * @inheritDoc + */ + public function getSaveValue($value) + { + return $value; + } +} diff --git a/modules/backend/console/scaffold/formwidget/javascript.stub b/modules/backend/console/scaffold/formwidget/javascript.stub new file mode 100644 index 0000000000..d4765f0b0c --- /dev/null +++ b/modules/backend/console/scaffold/formwidget/javascript.stub @@ -0,0 +1,5 @@ +/* + * This is a sample JavaScript file used by {{name}} + * + * You can delete this file if you want + */ diff --git a/modules/backend/console/scaffold/formwidget/partial.stub b/modules/backend/console/scaffold/formwidget/partial.stub new file mode 100644 index 0000000000..f311f175c0 --- /dev/null +++ b/modules/backend/console/scaffold/formwidget/partial.stub @@ -0,0 +1,17 @@ +previewMode): ?> + +
+ +
+ + + + + + diff --git a/modules/backend/console/scaffold/formwidget/stylesheet.stub b/modules/backend/console/scaffold/formwidget/stylesheet.stub new file mode 100644 index 0000000000..203c17affa --- /dev/null +++ b/modules/backend/console/scaffold/formwidget/stylesheet.stub @@ -0,0 +1,5 @@ +/* + * This is a sample StyleSheet file used by {{name}} + * + * You can delete this file if you want + */ diff --git a/modules/backend/console/scaffold/reportwidget/reportwidget.stub b/modules/backend/console/scaffold/reportwidget/reportwidget.stub new file mode 100644 index 0000000000..bfe197259e --- /dev/null +++ b/modules/backend/console/scaffold/reportwidget/reportwidget.stub @@ -0,0 +1,63 @@ + [ + 'title' => 'backend::lang.dashboard.widget_title_label', + 'default' => '{{title_name}} Report Widget', + 'type' => 'string', + 'validationPattern' => '^.+$', + 'validationMessage' => 'backend::lang.dashboard.widget_title_error', + ], + ]; + } + + /** + * Adds widget specific asset files. Use $this->addJs() and $this->addCss() + * to register new assets to include on the page. + * @return void + */ + protected function loadAssets() + { + } + + /** + * Renders the widget's primary contents. + * @return string HTML markup supplied by this widget. + */ + public function render() + { + try { + $this->prepareVars(); + } catch (Exception $ex) { + $this->vars['error'] = $ex->getMessage(); + } + + return $this->makePartial('{{lower_name}}'); + } + + /** + * Prepares the report widget view data + */ + public function prepareVars() + { + } +} diff --git a/modules/backend/console/scaffold/reportwidget/widget.stub b/modules/backend/console/scaffold/reportwidget/widget.stub new file mode 100644 index 0000000000..13f9152e82 --- /dev/null +++ b/modules/backend/console/scaffold/reportwidget/widget.stub @@ -0,0 +1,9 @@ +
+

property('title')) ?>

+ + +

This is the default partial content.

+ +

+ +
diff --git a/modules/cms/ServiceProvider.php b/modules/cms/ServiceProvider.php index d2fa63a562..846a7b790c 100644 --- a/modules/cms/ServiceProvider.php +++ b/modules/cms/ServiceProvider.php @@ -78,6 +78,9 @@ public function boot() */ protected function registerConsole() { + $this->registerConsoleCommand('create.component', \Cms\Console\CreateComponent::class); + $this->registerConsoleCommand('create.theme', \Cms\Console\CreateTheme::class); + $this->registerConsoleCommand('theme.install', \Cms\Console\ThemeInstall::class); $this->registerConsoleCommand('theme.remove', \Cms\Console\ThemeRemove::class); $this->registerConsoleCommand('theme.list', \Cms\Console\ThemeList::class); diff --git a/modules/cms/console/CreateComponent.php b/modules/cms/console/CreateComponent.php new file mode 100644 index 0000000000..d6eaa53d23 --- /dev/null +++ b/modules/cms/console/CreateComponent.php @@ -0,0 +1,68 @@ +(eg: Winter.Blog)} + {component : The name of the component to generate. (eg: Posts)} + {--force : Overwrite existing files with generated files.}'; + + /** + * The console command description. + * + * @var string + */ + protected $description = 'Creates a new plugin component.'; + + /** + * The type of class being generated. + * + * @var string + */ + protected $type = 'Component'; + + /** + * A mapping of stub to generated file. + * + * @var array + */ + protected $stubs = [ + 'scaffold/component/component.stub' => '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 new file mode 100644 index 0000000000..fe917827b0 --- /dev/null +++ b/modules/cms/console/CreateTheme.php @@ -0,0 +1,121 @@ +(eg: MyTheme)} + {--force : Overwrite existing files with generated files.}'; + + /** + * The console command description. + * + * @var string + */ + protected $description = 'Creates a new theme.'; + + /** + * The type of class being generated. + * + * @var string + */ + protected $type = 'Theme'; + + /** + * A mapping of stub to generated file. + * + * @var array + */ + protected $stubs = [ + 'scaffold/theme/assets/js/app.stub' => 'assets/js/app.js', + 'scaffold/theme/assets/less/theme.stub' => 'assets/less/theme.less', + 'scaffold/theme/layouts/default.stub' => 'layouts/default.htm', + 'scaffold/theme/pages/404.stub' => 'pages/404.htm', + 'scaffold/theme/pages/error.stub' => 'pages/error.htm', + 'scaffold/theme/pages/home.stub' => 'pages/home.htm', + 'scaffold/theme/partials/meta/seo.stub' => 'partials/meta/seo.htm', + 'scaffold/theme/partials/meta/styles.stub' => 'partials/meta/styles.htm', + 'scaffold/theme/partials/site/header.stub' => 'partials/site/header.htm', + 'scaffold/theme/partials/site/footer.stub' => 'partials/site/footer.htm', + 'scaffold/theme/theme.stub' => 'theme.yaml', + 'scaffold/theme/version.stub' => 'version.yaml', + ]; + + /** + * Prepare variables for stubs. + * + * return @array + */ + protected function prepareVars() + { + /* + * Extract the author and name from the plugin code + */ + $code = str_slug($this->argument('theme')); + + return [ + 'code' => $code, + ]; + } + + /** + * Get the plugin path from the input. + * + * @return string + */ + protected function getDestinationPath() + { + $code = $this->prepareVars()['code']; + + return themes_path($code); + } + + /** + * Make a single stub. + * + * @param string $stubName The source filename for the stub. + */ + public function makeStub($stubName) + { + if (!isset($this->stubs[$stubName])) { + return; + } + + $sourceFile = $this->getSourcePath() . '/' . $stubName; + $destinationFile = $this->getDestinationPath() . '/' . $this->stubs[$stubName]; + $destinationContent = $this->files->get($sourceFile); + + /* + * Parse each variable in to the destination content and path + */ + foreach ($this->vars as $key => $var) { + $destinationContent = str_replace('{{' . $key . '}}', $var, $destinationContent); + $destinationFile = str_replace('{{' . $key . '}}', $var, $destinationFile); + } + + $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 new file mode 100644 index 0000000000..5f9bbbb7be --- /dev/null +++ b/modules/cms/console/scaffold/component/component.stub @@ -0,0 +1,19 @@ + '{{name}} Component', + 'description' => 'No description provided yet...' + ]; + } + + public function defineProperties() + { + return []; + } +} diff --git a/modules/cms/console/scaffold/component/default.stub b/modules/cms/console/scaffold/component/default.stub new file mode 100644 index 0000000000..c9069b3759 --- /dev/null +++ b/modules/cms/console/scaffold/component/default.stub @@ -0,0 +1,3 @@ +

This is the default markup for component {{name}}

+ +You can delete this file if you want diff --git a/modules/cms/console/scaffold/theme/assets/js/app.stub b/modules/cms/console/scaffold/theme/assets/js/app.stub new file mode 100644 index 0000000000..235a2e31a0 --- /dev/null +++ b/modules/cms/console/scaffold/theme/assets/js/app.stub @@ -0,0 +1,33 @@ +/* + * Application + */ +(function($) { + "use strict"; + + jQuery(document).ready(function($) { + /*------------------------------- + WINTER CMS FLASH MESSAGE HANDLING + ---------------------------------*/ + $(document).on('ajaxSetup', function(event, context) { + // Enable AJAX handling of Flash messages on all AJAX requests + context.options.flash = true; + + // Enable the StripeLoadIndicator on all AJAX requests + context.options.loading = $.oc.stripeLoadIndicator; + + // Handle Flash Messages + context.options.handleFlashMessage = function(message, type) { + $.oc.flashMsg({ text: message, class: type }); + }; + + // Handle Error Messages + context.options.handleErrorMessage = function(message) { + $.oc.flashMsg({ text: message, class: 'error' }); + }; + }); + }); +}(jQuery)); + +if (typeof(gtag) !== 'function') { + gtag = function() { console.log('GoogleAnalytics not present.'); } +} \ No newline at end of file diff --git a/modules/cms/console/scaffold/theme/assets/less/theme.stub b/modules/cms/console/scaffold/theme/assets/less/theme.stub new file mode 100644 index 0000000000..1628f3a057 --- /dev/null +++ b/modules/cms/console/scaffold/theme/assets/less/theme.stub @@ -0,0 +1,5 @@ +.content { + margin: 2em auto; + max-width: 1080px; + text-align: center; +} \ No newline at end of file diff --git a/modules/cms/console/scaffold/theme/layouts/default.stub b/modules/cms/console/scaffold/theme/layouts/default.stub new file mode 100644 index 0000000000..060d9ab281 --- /dev/null +++ b/modules/cms/console/scaffold/theme/layouts/default.stub @@ -0,0 +1,7 @@ +description = "Default layout" +== +{% partial "site/header" %} + + {% page %} + +{% partial "site/footer" %} \ No newline at end of file diff --git a/modules/cms/console/scaffold/theme/pages/404.stub b/modules/cms/console/scaffold/theme/pages/404.stub new file mode 100644 index 0000000000..e9c4e27cc0 --- /dev/null +++ b/modules/cms/console/scaffold/theme/pages/404.stub @@ -0,0 +1,8 @@ +title = "Page not found (404)" +url = "/404" +layout = "default" +== +
+

Page not found

+

We're sorry, but the page you requested cannot be found.

+
\ No newline at end of file diff --git a/modules/cms/console/scaffold/theme/pages/error.stub b/modules/cms/console/scaffold/theme/pages/error.stub new file mode 100644 index 0000000000..6767bc687b --- /dev/null +++ b/modules/cms/console/scaffold/theme/pages/error.stub @@ -0,0 +1,8 @@ +title = "Error page (500)" +url = "/error" +layout = "default" +== +
+

Error

+

We're sorry, but something went wrong and the page cannot be displayed.

+
\ No newline at end of file diff --git a/modules/cms/console/scaffold/theme/pages/home.stub b/modules/cms/console/scaffold/theme/pages/home.stub new file mode 100644 index 0000000000..ca87de8cbf --- /dev/null +++ b/modules/cms/console/scaffold/theme/pages/home.stub @@ -0,0 +1,7 @@ +title = "Home" +url = "/" +layout = "default" +== +
+

Home Page

+
\ No newline at end of file diff --git a/modules/cms/console/scaffold/theme/partials/meta/seo.stub b/modules/cms/console/scaffold/theme/partials/meta/seo.stub new file mode 100644 index 0000000000..332bb2b08a --- /dev/null +++ b/modules/cms/console/scaffold/theme/partials/meta/seo.stub @@ -0,0 +1,11 @@ +{% if this.theme.googleanalytics_id is not empty %} + + + +{% endif %} diff --git a/modules/cms/console/scaffold/theme/partials/meta/styles.stub b/modules/cms/console/scaffold/theme/partials/meta/styles.stub new file mode 100644 index 0000000000..8c4144b470 --- /dev/null +++ b/modules/cms/console/scaffold/theme/partials/meta/styles.stub @@ -0,0 +1,4 @@ + + +{% styles %} +{% placeholder head %} diff --git a/modules/cms/console/scaffold/theme/partials/site/footer.stub b/modules/cms/console/scaffold/theme/partials/site/footer.stub new file mode 100644 index 0000000000..565e8bd4e6 --- /dev/null +++ b/modules/cms/console/scaffold/theme/partials/site/footer.stub @@ -0,0 +1,17 @@ + + + {% scripts %} + + {% flash %} +

+ {{ message }} +

+ {% endflash %} + + \ No newline at end of file diff --git a/modules/cms/console/scaffold/theme/partials/site/header.stub b/modules/cms/console/scaffold/theme/partials/site/header.stub new file mode 100644 index 0000000000..cadd5efcf8 --- /dev/null +++ b/modules/cms/console/scaffold/theme/partials/site/header.stub @@ -0,0 +1,20 @@ + + + + + + + {% placeholder page_title default %}{{ this.page.title }}{% endplaceholder %} + {% partial "meta/styles" %} + {% partial "meta/seo" %} + + + {% set pageId = this.page.id %} + {% set pageTitle = this.page.title %} + {% if pageId is empty %} + {% set pageId = page.id %} + {% endif %} + {% if pageTitle is empty %} + {% set pageTitle = page.title %} + {% endif %} + \ No newline at end of file diff --git a/modules/cms/console/scaffold/theme/theme.stub b/modules/cms/console/scaffold/theme/theme.stub new file mode 100644 index 0000000000..ef6ca860fd --- /dev/null +++ b/modules/cms/console/scaffold/theme/theme.stub @@ -0,0 +1,9 @@ +name: "{{code}}" +description: "No description provided yet..." +author: "Winter CMS Scaffold" +homepage: "https://example.com" +code: "{{code}}" +form: + fields: + googleanalytics_id: + label: 'Google Analytics ID' \ No newline at end of file diff --git a/modules/cms/console/scaffold/theme/version.stub b/modules/cms/console/scaffold/theme/version.stub new file mode 100644 index 0000000000..bd1f5e6b1d --- /dev/null +++ b/modules/cms/console/scaffold/theme/version.stub @@ -0,0 +1 @@ +1.0.1: 'Initial version' diff --git a/modules/system/ServiceProvider.php b/modules/system/ServiceProvider.php index 28aa72b1e1..b0d857d988 100644 --- a/modules/system/ServiceProvider.php +++ b/modules/system/ServiceProvider.php @@ -245,26 +245,31 @@ protected function registerConsole() /* * Register console commands */ - $this->registerConsoleCommand('winter.up', 'System\Console\WinterUp'); - $this->registerConsoleCommand('winter.down', 'System\Console\WinterDown'); - $this->registerConsoleCommand('winter.update', 'System\Console\WinterUpdate'); - $this->registerConsoleCommand('winter.util', 'System\Console\WinterUtil'); - $this->registerConsoleCommand('winter.mirror', 'System\Console\WinterMirror'); - $this->registerConsoleCommand('winter.fresh', 'System\Console\WinterFresh'); - $this->registerConsoleCommand('winter.env', 'System\Console\WinterEnv'); - $this->registerConsoleCommand('winter.install', 'System\Console\WinterInstall'); - $this->registerConsoleCommand('winter.passwd', 'System\Console\WinterPasswd'); - $this->registerConsoleCommand('winter.version', 'System\Console\WinterVersion'); - $this->registerConsoleCommand('winter.manifest', 'System\Console\WinterManifest'); - $this->registerConsoleCommand('winter.test', 'System\Console\WinterTest'); - - $this->registerConsoleCommand('plugin.install', 'System\Console\PluginInstall'); - $this->registerConsoleCommand('plugin.remove', 'System\Console\PluginRemove'); - $this->registerConsoleCommand('plugin.disable', 'System\Console\PluginDisable'); - $this->registerConsoleCommand('plugin.enable', 'System\Console\PluginEnable'); - $this->registerConsoleCommand('plugin.refresh', 'System\Console\PluginRefresh'); - $this->registerConsoleCommand('plugin.rollback', 'System\Console\PluginRollback'); - $this->registerConsoleCommand('plugin.list', 'System\Console\PluginList'); + $this->registerConsoleCommand('create.command', \System\Console\CreateCommand::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); + + $this->registerConsoleCommand('winter.up', \System\Console\WinterUp::class); + $this->registerConsoleCommand('winter.down', \System\Console\WinterDown::class); + $this->registerConsoleCommand('winter.update', \System\Console\WinterUpdate::class); + $this->registerConsoleCommand('winter.util', \System\Console\WinterUtil::class); + $this->registerConsoleCommand('winter.mirror', \System\Console\WinterMirror::class); + $this->registerConsoleCommand('winter.fresh', \System\Console\WinterFresh::class); + $this->registerConsoleCommand('winter.env', \System\Console\WinterEnv::class); + $this->registerConsoleCommand('winter.install', \System\Console\WinterInstall::class); + $this->registerConsoleCommand('winter.passwd', \System\Console\WinterPasswd::class); + $this->registerConsoleCommand('winter.version', \System\Console\WinterVersion::class); + $this->registerConsoleCommand('winter.manifest', \System\Console\WinterManifest::class); + $this->registerConsoleCommand('winter.test', \System\Console\WinterTest::class); + + $this->registerConsoleCommand('plugin.install', \System\Console\PluginInstall::class); + $this->registerConsoleCommand('plugin.remove', \System\Console\PluginRemove::class); + $this->registerConsoleCommand('plugin.disable', \System\Console\PluginDisable::class); + $this->registerConsoleCommand('plugin.enable', \System\Console\PluginEnable::class); + $this->registerConsoleCommand('plugin.refresh', \System\Console\PluginRefresh::class); + $this->registerConsoleCommand('plugin.rollback', \System\Console\PluginRollback::class); + $this->registerConsoleCommand('plugin.list', \System\Console\PluginList::class); $this->registerConsoleCommand('mix.install', \System\Console\MixInstall::class); $this->registerConsoleCommand('mix.list', \System\Console\MixList::class); diff --git a/modules/system/aliases.php b/modules/system/aliases.php index e305c37e6f..85b36035b0 100644 --- a/modules/system/aliases.php +++ b/modules/system/aliases.php @@ -88,4 +88,25 @@ // Illuminate's HtmlDumper was "dumped" in Laravel 6 - we'll route this to Symfony's HtmlDumper as Laravel have done. 'Illuminate\Support\Debug\HtmlDumper' => Symfony\Component\VarDumper\Dumper\HtmlDumper::class, + + // Scaffolds were moved from the Storm library into their corresponding modules. + 'Winter\Storm\Scaffold\Console\CreateCommand' => System\Console\CreateCommand::class, + 'Winter\Storm\Scaffold\Console\CreateModel' => System\Console\CreateModel::class, + 'Winter\Storm\Scaffold\Console\CreatePlugin' => System\Console\CreatePlugin::class, + 'Winter\Storm\Scaffold\Console\CreateSettings' => System\Console\CreateSettings::class, + 'Winter\Storm\Scaffold\Console\CreateController' => Backend\Console\CreateController::class, + 'Winter\Storm\Scaffold\Console\CreateFormWidget' => Backend\Console\CreateFormWidget::class, + 'Winter\Storm\Scaffold\Console\CreateReportWidget' => Backend\Console\CreateReportWidget::class, + 'Winter\Storm\Scaffold\Console\CreateTheme' => Cms\Console\CreateTheme::class, + 'Winter\Storm\Scaffold\Console\CreateComponent' => Cms\Console\CreateComponent::class, + + 'October\Rain\Scaffold\Console\CreateCommand' => System\Console\CreateCommand::class, + 'October\Rain\Scaffold\Console\CreateModel' => System\Console\CreateModel::class, + 'October\Rain\Scaffold\Console\CreatePlugin' => System\Console\CreatePlugin::class, + 'October\Rain\Scaffold\Console\CreateSettings' => System\Console\CreateSettings::class, + 'October\Rain\Scaffold\Console\CreateController' => Backend\Console\CreateController::class, + 'October\Rain\Scaffold\Console\CreateFormWidget' => Backend\Console\CreateFormWidget::class, + 'October\Rain\Scaffold\Console\CreateReportWidget' => Backend\Console\CreateReportWidget::class, + 'October\Rain\Scaffold\Console\CreateTheme' => Cms\Console\CreateTheme::class, + 'October\Rain\Scaffold\Console\CreateComponent' => Cms\Console\CreateComponent::class, ]; diff --git a/modules/system/console/CreateCommand.php b/modules/system/console/CreateCommand.php new file mode 100644 index 0000000000..d4510218df --- /dev/null +++ b/modules/system/console/CreateCommand.php @@ -0,0 +1,67 @@ +(eg: Winter.Blog)} + {name : The name of the command to generate. (eg: create)} + {--force : Overwrite existing files with generated files.}'; + + /** + * The console command description. + * + * @var string + */ + protected $description = 'Creates a new console command.'; + + /** + * The type of class being generated. + * + * @var string + */ + protected $type = 'Command'; + + /** + * A mapping of stub to generated file. + * + * @var array + */ + protected $stubs = [ + 'scaffold/command/command.stub' => 'console/{{studly_name}}.php', + ]; + + /** + * Prepare variables for stubs. + * + * return @array + */ + protected function prepareVars() + { + $pluginCode = $this->argument('plugin'); + + $parts = explode('.', $pluginCode); + $plugin = array_pop($parts); + $author = array_pop($parts); + $command = $this->argument('name'); + + return [ + 'name' => $command, + 'author' => $author, + 'plugin' => $plugin + ]; + } +} diff --git a/modules/system/console/CreateModel.php b/modules/system/console/CreateModel.php new file mode 100644 index 0000000000..c8f2e993fc --- /dev/null +++ b/modules/system/console/CreateModel.php @@ -0,0 +1,71 @@ +(eg: Winter.Blog)} + {model : The name of the model to generate. (eg: Post)} + {--force : Overwrite existing files with generated files.}'; + + /** + * The console command description. + * + * @var string + */ + protected $description = 'Creates a new model.'; + + /** + * The type of class being generated. + * + * @var string + */ + protected $type = 'Model'; + + /** + * A mapping of stub to generated file. + * + * @var array + */ + protected $stubs = [ + '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. + * + * return @array + */ + protected function prepareVars() + { + $pluginCode = $this->argument('plugin'); + + $parts = explode('.', $pluginCode); + $plugin = array_pop($parts); + $author = array_pop($parts); + + $model = $this->argument('model'); + + return [ + 'name' => $model, + 'author' => $author, + 'plugin' => $plugin + ]; + } +} diff --git a/modules/system/console/CreatePlugin.php b/modules/system/console/CreatePlugin.php new file mode 100644 index 0000000000..79a2008472 --- /dev/null +++ b/modules/system/console/CreatePlugin.php @@ -0,0 +1,75 @@ +(eg: Winter.Blog)} + {--force : Overwrite existing files with generated files.}'; + + /** + * The console command description. + * + * @var string + */ + protected $description = 'Creates a new plugin.'; + + /** + * The type of class being generated. + * + * @var string + */ + protected $type = 'Plugin'; + + /** + * A mapping of stub to generated file. + * + * @var array + */ + protected $stubs = [ + 'scaffold/plugin/plugin.stub' => 'Plugin.php', + 'scaffold/plugin/version.stub' => 'updates/version.yaml', + ]; + + /** + * Prepare variables for stubs. + * + * return @array + */ + protected function prepareVars() + { + /* + * Extract the author and name from the plugin code + */ + $pluginCode = $this->argument('plugin'); + $parts = explode('.', $pluginCode); + + 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); + + return [ + 'name' => $pluginName, + 'author' => $authorName, + ]; + } +} diff --git a/modules/system/console/CreateSettings.php b/modules/system/console/CreateSettings.php new file mode 100644 index 0000000000..83d53d7dc4 --- /dev/null +++ b/modules/system/console/CreateSettings.php @@ -0,0 +1,68 @@ +(eg: Winter.Blog)} + {settings : The name of the settings model to generate. (eg: BlogSettings)} + {--force : Overwrite existing files with generated files.}'; + + /** + * The console command description. + * + * @var string + */ + protected $description = 'Creates a new settings model.'; + + /** + * The type of class being generated. + * + * @var string + */ + protected $type = 'Settings Model'; + + /** + * A mapping of stubs to generated files. + * + * @var array + */ + protected $stubs = [ + 'scaffold/settings/model.stub' => 'models/{{studly_name}}.php', + 'scaffold/settings/fields.stub' => 'models/{{lower_name}}/fields.yaml' + ]; + + /** + * Prepare variables for stubs. + * + * return @array + */ + protected function prepareVars() + { + $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 + ]; + } +} diff --git a/modules/system/console/scaffold/command/command.stub b/modules/system/console/scaffold/command/command.stub new file mode 100644 index 0000000000..bf65b244bd --- /dev/null +++ b/modules/system/console/scaffold/command/command.stub @@ -0,0 +1,63 @@ +output->writeln('Hello world!'); + } + + /** + * Get the console command arguments. + * @return array + */ + protected function getArguments() + { + return []; + } + + /** + * Get the console command options. + * @return array + */ + protected function getOptions() + { + return []; + } + + /** + * Provide autocompletion for this command's input + */ + public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void + { + // Suggest values for arguments provided by this command + // if ($input->mustSuggestArgumentValuesFor('nameOfArgument')) { + // $suggestions->suggestValues(['valid', 'argument', 'values', 'here']]); + // } + + // Suggest values for options provided by this command + // if ($input->mustSuggestOptionValuesFor('nameOfOption')) { + // $suggestions->suggestValues(['valid', 'option', 'values', 'here']); + // } + } +} diff --git a/modules/system/console/scaffold/model/columns.stub b/modules/system/console/scaffold/model/columns.stub new file mode 100644 index 0000000000..b11160b422 --- /dev/null +++ b/modules/system/console/scaffold/model/columns.stub @@ -0,0 +1,8 @@ +# =================================== +# List Column Definitions +# =================================== + +columns: + id: + label: ID + searchable: true diff --git a/modules/system/console/scaffold/model/create_table.stub b/modules/system/console/scaffold/model/create_table.stub new file mode 100644 index 0000000000..b2a280c091 --- /dev/null +++ b/modules/system/console/scaffold/model/create_table.stub @@ -0,0 +1,21 @@ +engine = 'InnoDB'; + $table->increments('id'); + $table->timestamps(); + }); + } + + public function down() + { + Schema::dropIfExists('{{lower_author}}_{{lower_plugin}}_{{snake_plural_name}}'); + } +}; diff --git a/modules/system/console/scaffold/model/fields.stub b/modules/system/console/scaffold/model/fields.stub new file mode 100644 index 0000000000..c611f31c78 --- /dev/null +++ b/modules/system/console/scaffold/model/fields.stub @@ -0,0 +1,8 @@ +# =================================== +# Form Field Definitions +# =================================== + +fields: + id: + label: ID + disabled: true diff --git a/modules/system/console/scaffold/model/model.stub b/modules/system/console/scaffold/model/model.stub new file mode 100644 index 0000000000..0816de62b0 --- /dev/null +++ b/modules/system/console/scaffold/model/model.stub @@ -0,0 +1,74 @@ + '{{name}}', + 'description' => 'No description provided yet...', + 'author' => '{{author}}', + 'icon' => 'icon-leaf' + ]; + } + + /** + * Register method, called when the plugin is first registered. + * + * @return void + */ + public function register() + { + + } + + /** + * Boot method, called right before the request route. + * + * @return array + */ + public function boot() + { + + } + + /** + * Registers any front-end components implemented in this plugin. + * + * @return array + */ + public function registerComponents() + { + return []; // Remove this line to activate + + return [ + '{{studly_author}}\{{studly_name}}\Components\MyComponent' => 'myComponent', + ]; + } + + /** + * Registers any back-end permissions used by this plugin. + * + * @return array + */ + public function registerPermissions() + { + return []; // Remove this line to activate + + return [ + '{{lower_author}}.{{lower_name}}.some_permission' => [ + 'tab' => '{{name}}', + 'label' => 'Some permission', + 'roles' => [UserRole::CODE_DEVELOPER, UserRole::CODE_PUBLISHER], + ], + ]; + } + + /** + * Registers back-end navigation items for this plugin. + * + * @return array + */ + public function registerNavigation() + { + return []; // Remove this line to activate + + return [ + '{{lower_name}}' => [ + 'label' => '{{name}}', + 'url' => Backend::url('{{lower_author}}/{{lower_name}}/mycontroller'), + 'icon' => 'icon-leaf', + 'permissions' => ['{{lower_author}}.{{lower_name}}.*'], + 'order' => 500, + ], + ]; + } +} diff --git a/modules/system/console/scaffold/plugin/version.stub b/modules/system/console/scaffold/plugin/version.stub new file mode 100644 index 0000000000..34b2bc0f97 --- /dev/null +++ b/modules/system/console/scaffold/plugin/version.stub @@ -0,0 +1 @@ +1.0.0: First version of {{name}} diff --git a/modules/system/console/scaffold/settings/fields.stub b/modules/system/console/scaffold/settings/fields.stub new file mode 100644 index 0000000000..7a890bd717 --- /dev/null +++ b/modules/system/console/scaffold/settings/fields.stub @@ -0,0 +1,7 @@ +# =================================== +# Form Field Definitions +# =================================== + +fields: + settings_option: + label: This is a sample settings field used by {{author}}.{{plugin}} diff --git a/modules/system/console/scaffold/settings/model.stub b/modules/system/console/scaffold/settings/model.stub new file mode 100644 index 0000000000..740e775a93 --- /dev/null +++ b/modules/system/console/scaffold/settings/model.stub @@ -0,0 +1,31 @@ +