From 97ce346ebe5cb644eed909212df21d3ec8b8defc Mon Sep 17 00:00:00 2001 From: Mexion Date: Thu, 11 Apr 2019 19:48:46 +0200 Subject: [PATCH 1/7] added multipage support --- composer.json | 2 +- src/SavesSettings.php | 10 +++++++--- src/Setting/AppSettings.php | 14 ++++++++------ src/config/app_settings.php | 2 +- src/resources/views/_settings.blade.php | 4 ++-- 5 files changed, 19 insertions(+), 13 deletions(-) diff --git a/composer.json b/composer.json index 2011277..4e46aa5 100644 --- a/composer.json +++ b/composer.json @@ -21,7 +21,7 @@ } ], "require": { - "php": ">=5.6.0", + "php": ">= 7.1.0", "laravel/framework": "~5.4.0|~5.5.0|~5.6.0|~5.7.0|~5.8.0", "qcod/laravel-settings": "~1.0" }, diff --git a/src/SavesSettings.php b/src/SavesSettings.php index f58ece4..b01a3a0 100644 --- a/src/SavesSettings.php +++ b/src/SavesSettings.php @@ -16,12 +16,16 @@ trait SavesSettings * @return \Illuminate\View\View * @param AppSettings $appSettings */ - public function index(AppSettings $appSettings) + public function index(AppSettings $appSettings, string $page) { $settingsUI = $appSettings->loadConfig(config('app_settings', [])); $settingViewName = config('app_settings.setting_page_view'); - return view($settingViewName, compact('settingsUI')); + $settingsPage = preg_replace("/[^A-Za-z0-9 ]/", '', $page); + return view($settingViewName, [ + 'settingsUI' => $settingsUI, + 'settingsPage' => $settingsPage, + ]); } /** @@ -39,7 +43,7 @@ public function store(Request $request, AppSettings $appSettings) // save settings $appSettings->save($request); - return redirect(config('app_settings.url', '/')) + return redirect()->route('settings.index', config('app_settings.default_page')) ->with([ 'status' => config('app_settings.submit_success_message', 'Settings Saved.') ]); diff --git a/src/Setting/AppSettings.php b/src/Setting/AppSettings.php index 6a6f03d..34261dc 100644 --- a/src/Setting/AppSettings.php +++ b/src/Setting/AppSettings.php @@ -102,8 +102,10 @@ public function remove($name) */ public function save($request) { + $settingsPage = preg_replace("/[^A-Za-z0-9 ]/", '', $request->page); + // get all defined settings from config - $allDefinedSettings = $this->getAllSettingFields(); + $allDefinedSettings = $this->getAllSettingFields($settingsPage); // set all the fields with updated values $allDefinedSettings->each(function ($setting) use ($request) { @@ -151,19 +153,19 @@ public function loadConfig($config) * * @return \Illuminate\Support\Collection */ - protected function getSettingUISections() + protected function getSettingUISections(string $settingsPage) { - return collect(config('app_settings.sections', [])); + return collect(config('app_settings.sections.'.$settingsPage , [])); } /** * Get all the setting fields defined from all sections - * + * @param $settingsPage string : the name of the page of settings to use * @return \Illuminate\Support\Collection */ - public function getAllSettingFields() + public function getAllSettingFields(string $settingsPage = '' ) { - return $this->getSettingUISections()->flatMap(function ($field) { + return $this->getSettingUISections($settingsPage)->flatMap(function ($field) { return array_get($field, 'inputs', []); }); } diff --git a/src/config/app_settings.php b/src/config/app_settings.php index ab8046a..5dfd3eb 100644 --- a/src/config/app_settings.php +++ b/src/config/app_settings.php @@ -59,7 +59,7 @@ ], // Setting page url, will be used for get and post request - 'url' => 'settings', + 'url' => 'settings/general', // Any middleware you want to run on above route 'middleware' => [], diff --git a/src/resources/views/_settings.blade.php b/src/resources/views/_settings.blade.php index 7aa62cc..17c6c8f 100644 --- a/src/resources/views/_settings.blade.php +++ b/src/resources/views/_settings.blade.php @@ -6,10 +6,10 @@
{!! csrf_field() !!} - + @if( isset($settingsUI) && count($settingsUI) ) - @foreach(array_get($settingsUI, 'sections', []) as $section => $fields) + @foreach(array_get($settingsUI, 'sections'. $settingsPage, []) as $section => $fields) @component('app_settings::section', compact('fields'))
@foreach(array_get($fields, 'inputs', []) as $field) From bd1078db7bd829b537af8dbf202b71f373598a11 Mon Sep 17 00:00:00 2001 From: Mexion Date: Thu, 11 Apr 2019 19:51:28 +0200 Subject: [PATCH 2/7] split sections in to separate files --- src/AppSettingsServiceProvider.php | 2 + src/config/app_settings.php | 54 +---------------------- src/config/app_settings_page_branding.php | 35 +++++++++++++++ src/config/app_settings_page_email.php | 25 +++++++++++ 4 files changed, 64 insertions(+), 52 deletions(-) create mode 100644 src/config/app_settings_page_branding.php create mode 100644 src/config/app_settings_page_email.php diff --git a/src/AppSettingsServiceProvider.php b/src/AppSettingsServiceProvider.php index 0bdadee..e3bfa43 100644 --- a/src/AppSettingsServiceProvider.php +++ b/src/AppSettingsServiceProvider.php @@ -30,6 +30,8 @@ public function boot() $this->publishes([ __DIR__ . '/config/app_settings.php' => config_path('app_settings.php'), + __DIR__ . '/config/app_settings_page_branding.php' => config_path('app_settings_page_branding.php'), + __DIR__ . '/config/app_settings_page_email.php' => config_path('app_settings_page_email.php'), ], 'config'); $this->loadRoutesFrom(__DIR__ . '/routes/web.php'); diff --git a/src/config/app_settings.php b/src/config/app_settings.php index 5dfd3eb..2330068 100644 --- a/src/config/app_settings.php +++ b/src/config/app_settings.php @@ -4,58 +4,8 @@ // All the sections for the settings page 'sections' => [ - 'app' => [ - 'title' => 'General Settings', - 'descriptions' => 'Application general settings.', // (optional) - 'icon' => 'fa fa-cog', // (optional) - - 'inputs' => [ - [ - 'name' => 'app_name', // unique key for setting - 'type' => 'text', // type of input can be text, number, textarea, select, boolean, checkbox etc. - 'label' => 'App Name', // label for input - // optional properties - 'placeholder' => 'Application Name', // placeholder for input - 'class' => 'form-control', // override global input_class - 'style' => '', // any inline styles - 'rules' => 'required|min:2|max:20', // validation rules for this input - 'value' => 'QCode', // any default value - 'hint' => 'You can set the app name here' // help block text for input - ], - [ - 'name' => 'logo', - 'type' => 'image', - 'label' => 'Upload logo', - 'hint' => 'Must be an image and cropped in desired size', - 'rules' => 'image|max:500', - 'disk' => 'public', // which disk you want to upload - 'path' => 'app', // path on the disk, - 'preview_class' => 'thumbnail', - 'preview_style' => 'height:40px' - ] - ] - ], - 'email' => [ - 'title' => 'Email Settings', - 'descriptions' => 'How app email will be sent.', - 'icon' => 'fa fa-envelope', - - 'inputs' => [ - [ - 'name' => 'from_email', - 'type' => 'email', - 'label' => 'From Email', - 'placeholder' => 'Application from email', - 'rules' => 'required|email', - ], - [ - 'name' => 'from_name', - 'type' => 'text', - 'label' => 'Email from Name', - 'placeholder' => 'Email from Name', - ] - ] - ] + 'branding' => require(__DIR__ . '/app_settings_page_branding.php'), + 'email' => require(__DIR__ . '/app_settings_page_email.php'), ], // Setting page url, will be used for get and post request diff --git a/src/config/app_settings_page_branding.php b/src/config/app_settings_page_branding.php new file mode 100644 index 0000000..17dc705 --- /dev/null +++ b/src/config/app_settings_page_branding.php @@ -0,0 +1,35 @@ + [ + 'title' => 'General Settings', + 'descriptions' => 'Application general settings.', // (optional) + 'icon' => 'fa fa-cog', // (optional) + + 'inputs' => [ + [ + 'name' => 'app_name', // unique key for setting + 'type' => 'text', // type of input can be text, number, textarea, select, boolean, checkbox etc. + 'label' => 'App Name', // label for input + // optional properties + 'placeholder' => 'Application Name', // placeholder for input + 'class' => 'form-control', // override global input_class + 'style' => '', // any inline styles + 'rules' => 'required|min:2|max:20', // validation rules for this input + 'value' => config('app.name'), + 'hint' => 'You can set the app name here' // help block text for input + ], + [ + 'name' => 'logo', + 'type' => 'image', + 'label' => 'Upload logo', + 'hint' => 'Must be an image and cropped in desired size', + 'rules' => 'image|max:500', + 'disk' => 'public', // which disk you want to upload + 'path' => 'app', // path on the disk, + 'preview_class' => 'thumbnail', + 'preview_style' => 'height:40px' + ] + ] + ], +]; \ No newline at end of file diff --git a/src/config/app_settings_page_email.php b/src/config/app_settings_page_email.php new file mode 100644 index 0000000..793c5a0 --- /dev/null +++ b/src/config/app_settings_page_email.php @@ -0,0 +1,25 @@ + [ + 'title' => 'Email Settings', + 'descriptions' => 'How app email will be sent.', + 'icon' => 'fa fa-envelope', + + 'inputs' => [ + [ + 'name' => 'from_email', + 'type' => 'email', + 'label' => 'From Email', + 'placeholder' => 'Application from email', + 'rules' => 'required|email', + ], + [ + 'name' => 'from_name', + 'type' => 'text', + 'label' => 'Email from Name', + 'placeholder' => 'Email from Name', + ] + ] + ] +]; \ No newline at end of file From 98d967dbb0757a3a3bb3edbe86845bddebb8aef5 Mon Sep 17 00:00:00 2001 From: Mexion Date: Thu, 11 Apr 2019 19:54:44 +0200 Subject: [PATCH 3/7] fix: routes --- src/routes/web.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/routes/web.php b/src/routes/web.php index d1c3b7d..a3983a9 100644 --- a/src/routes/web.php +++ b/src/routes/web.php @@ -3,6 +3,6 @@ Route::group([ 'middleware' => array_merge(['web'], config('app_settings.middleware', [])) ], function () { - Route::get(config('app_settings.url'), config('app_settings.controller').'@index'); - Route::post(config('app_settings.url'), config('app_settings.controller').'@store'); + Route::get(config('app_settings.url'). '/{page}', config('app_settings.controller').'@index'); + Route::post(config('app_settings.url'). '/{page}', config('app_settings.controller').'@store'); }); From 618c585bc8179a6c1a25a00ed19a7973bd0fd4c8 Mon Sep 17 00:00:00 2001 From: Mexion Date: Thu, 11 Apr 2019 20:01:32 +0200 Subject: [PATCH 4/7] fix: setting redirect to default page if pagename was invalid --- src/SavesSettings.php | 5 +++++ src/config/app_settings.php | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/SavesSettings.php b/src/SavesSettings.php index b01a3a0..87d9f9a 100644 --- a/src/SavesSettings.php +++ b/src/SavesSettings.php @@ -22,6 +22,11 @@ public function index(AppSettings $appSettings, string $page) $settingViewName = config('app_settings.setting_page_view'); $settingsPage = preg_replace("/[^A-Za-z0-9 ]/", '', $page); + + if ( !is_array( config('app_settings.sections.'.$settingsPage) ) ) { + $settingsPage = config('app_settings.default_page'); + } + return view($settingViewName, [ 'settingsUI' => $settingsUI, 'settingsPage' => $settingsPage, diff --git a/src/config/app_settings.php b/src/config/app_settings.php index 2330068..a70bf36 100644 --- a/src/config/app_settings.php +++ b/src/config/app_settings.php @@ -9,7 +9,8 @@ ], // Setting page url, will be used for get and post request - 'url' => 'settings/general', + 'url' => '/settings', + 'default_page' => 'email', // Any middleware you want to run on above route 'middleware' => [], From e158b4dbdf2e4569a2c8701713e04cf39769e54d Mon Sep 17 00:00:00 2001 From: Mexion Date: Fri, 12 Apr 2019 18:03:06 +0200 Subject: [PATCH 5/7] Make view of item customizable and independent of type. This way there can be multiple different views defined for 1 type. ie 3 different views to show a checkbox --- src/config/app_settings_page_branding.php | 1 + src/config/app_settings_page_email.php | 1 + src/resources/views/_settings.blade.php | 6 +++++- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/config/app_settings_page_branding.php b/src/config/app_settings_page_branding.php index 17dc705..23e7cf1 100644 --- a/src/config/app_settings_page_branding.php +++ b/src/config/app_settings_page_branding.php @@ -10,6 +10,7 @@ [ 'name' => 'app_name', // unique key for setting 'type' => 'text', // type of input can be text, number, textarea, select, boolean, checkbox etc. + 'view' => 'text', // the name of the view blade file , if left out, the type is the name of the view 'label' => 'App Name', // label for input // optional properties 'placeholder' => 'Application Name', // placeholder for input diff --git a/src/config/app_settings_page_email.php b/src/config/app_settings_page_email.php index 793c5a0..ee65893 100644 --- a/src/config/app_settings_page_email.php +++ b/src/config/app_settings_page_email.php @@ -10,6 +10,7 @@ [ 'name' => 'from_email', 'type' => 'email', + 'view' => 'email', // the name of the view, if left out, the type is the name of the view 'label' => 'From Email', 'placeholder' => 'Application from email', 'rules' => 'required|email', diff --git a/src/resources/views/_settings.blade.php b/src/resources/views/_settings.blade.php index 17c6c8f..5a31716 100644 --- a/src/resources/views/_settings.blade.php +++ b/src/resources/views/_settings.blade.php @@ -20,7 +20,11 @@ You can create a fields/{{ $field['type'] }}.balde.php to render this input however you want.
@endif - @includeIf('app_settings::fields.' . $field['type'] ) + @if (isset($field['view'])) + @includeIf('app_settings::fields.' . $field['view']) + @else + @includeIf('app_settings::fields.' . $field['type']) + @endif @endforeach @endcomponent From 04733a369940ab25ec91f9f65c191b42a6f3cb81 Mon Sep 17 00:00:00 2001 From: Mexion Date: Fri, 12 Apr 2019 19:04:03 +0200 Subject: [PATCH 6/7] Allow for passthrough config and exception in getting missing config key --- src/config/app_settings.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/config/app_settings.php b/src/config/app_settings.php index a70bf36..0cb9e65 100644 --- a/src/config/app_settings.php +++ b/src/config/app_settings.php @@ -39,6 +39,13 @@ // Remove any setting which declaration removed later from sections 'remove_abandoned_settings' => false, + // when the setting is not found, can we try to get the config setting for this key + 'allow_passthrough_config' => true, + + // Should we throw and exception if we cannot find the setting after we checked the config files + // only in addition to 'allow_passthrough_config' + 'exception_on_nodefined_config' => true, + // Controller to show and handle save setting 'controller' => '\QCod\AppSettings\Controllers\AppSettingController', ]; From 85d40293309cdcba7f072a268c876c5d0accc1e7 Mon Sep 17 00:00:00 2001 From: Mexion Date: Fri, 12 Apr 2019 19:05:53 +0200 Subject: [PATCH 7/7] Using the dot notation for keys allows us to use transparant settings-config handling. If the settings does not exist get the config. This allows for fixed settings in the config files which are overridable by the settings database --- src/config/app_settings_page_branding.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/config/app_settings_page_branding.php b/src/config/app_settings_page_branding.php index 23e7cf1..f73d1ed 100644 --- a/src/config/app_settings_page_branding.php +++ b/src/config/app_settings_page_branding.php @@ -8,12 +8,12 @@ 'inputs' => [ [ - 'name' => 'app_name', // unique key for setting + 'name' => 'app.name', // unique key for setting 'type' => 'text', // type of input can be text, number, textarea, select, boolean, checkbox etc. 'view' => 'text', // the name of the view blade file , if left out, the type is the name of the view 'label' => 'App Name', // label for input // optional properties - 'placeholder' => 'Application Name', // placeholder for input + 'placeholder' => config('app.name'), // placeholder for input 'class' => 'form-control', // override global input_class 'style' => '', // any inline styles 'rules' => 'required|min:2|max:20', // validation rules for this input