diff --git a/app/Console/Commands/DisableLDAP.php b/app/Console/Commands/DisableLDAP.php index 8e9d8c8d69..5522df37cc 100644 --- a/app/Console/Commands/DisableLDAP.php +++ b/app/Console/Commands/DisableLDAP.php @@ -41,7 +41,7 @@ class DisableLDAP extends Command if ($this->confirm("\n****************************************************\nThis will disable LDAP support. You will not be able \nto login with an account that does not exist \nlocally in the Snipe-IT local database. \n****************************************************\n\nDo you wish to continue? [y|N]")) { - $setting = Setting::first(); + $setting = Setting::getSettings(); $setting->ldap_enabled = 0; if ($setting->save()) { $this->info('LDAP has been set to disabled.'); diff --git a/app/Console/Commands/SendExpirationAlerts.php b/app/Console/Commands/SendExpirationAlerts.php index f78768ea5e..858f33b345 100644 --- a/app/Console/Commands/SendExpirationAlerts.php +++ b/app/Console/Commands/SendExpirationAlerts.php @@ -52,7 +52,7 @@ class SendExpirationAlerts extends Command }); // Expiring Assets - $assets = Asset::getExpiringWarrantee(Setting::getSettings()->alert_interval); + $assets = Asset::getExpiringWarrantee($threshold); if ($assets->count() > 0) { $this->info(trans_choice('mail.assets_warrantee_alert', $assets->count(), ['count' => $assets->count(), 'threshold' => $threshold])); Notification::send($recipients, new ExpiringAssetsNotification($assets, $threshold)); diff --git a/app/Events/SettingSaved.php b/app/Events/SettingSaved.php new file mode 100644 index 0000000000..e8423789b7 --- /dev/null +++ b/app/Events/SettingSaved.php @@ -0,0 +1,20 @@ +settings = $settings; + } +} \ No newline at end of file diff --git a/app/Http/Controllers/ReportsController.php b/app/Http/Controllers/ReportsController.php index 2c2e466c5f..0d8d79e5d3 100644 --- a/app/Http/Controllers/ReportsController.php +++ b/app/Http/Controllers/ReportsController.php @@ -173,7 +173,7 @@ class ReportsController extends Controller if ($asset->location) { $currency = e($asset->location->currency); } else { - $currency = e(Setting::first()->default_currency); + $currency = e(Setting::getSettings()->default_currency); } $row[] = $asset->purchase_date; diff --git a/app/Http/Controllers/SettingsController.php b/app/Http/Controllers/SettingsController.php index 19d2f4839b..c1f4c9cedf 100755 --- a/app/Http/Controllers/SettingsController.php +++ b/app/Http/Controllers/SettingsController.php @@ -267,7 +267,7 @@ class SettingsController extends Controller */ public function index() { - $settings = Setting::all(); + $settings = Setting::getSettings(); return view('settings/index', compact('settings')); } @@ -283,7 +283,7 @@ class SettingsController extends Controller */ public function getEdit() { - $setting = Setting::first(); + $setting = Setting::getSettings(); return view('settings/general', compact('setting')); } @@ -299,7 +299,7 @@ class SettingsController extends Controller */ public function getSettings() { - $setting = Setting::first(); + $setting = Setting::getSettings(); return view('settings/general', compact('setting')); } @@ -315,7 +315,7 @@ class SettingsController extends Controller */ public function postSettings(Request $request) { - if (is_null($setting = Setting::first())) { + if (is_null($setting = Setting::getSettings())) { return redirect()->to('admin')->with('error', trans('admin/settings/message.update.error')); } @@ -369,7 +369,7 @@ class SettingsController extends Controller */ public function getBranding() { - $setting = Setting::first(); + $setting = Setting::getSettings(); return view('settings.branding', compact('setting')); } @@ -385,7 +385,7 @@ class SettingsController extends Controller */ public function postBranding(ImageUploadRequest $request) { - if (is_null($setting = Setting::first())) { + if (is_null($setting = Setting::getSettings())) { return redirect()->to('admin')->with('error', trans('admin/settings/message.update.error')); } @@ -452,7 +452,7 @@ class SettingsController extends Controller */ public function getSecurity() { - $setting = Setting::first(); + $setting = Setting::getSettings(); return view('settings.security', compact('setting')); } @@ -468,7 +468,7 @@ class SettingsController extends Controller */ public function postSecurity(Request $request) { - if (is_null($setting = Setting::first())) { + if (is_null($setting = Setting::getSettings())) { return redirect()->to('admin')->with('error', trans('admin/settings/message.update.error')); } @@ -512,7 +512,7 @@ class SettingsController extends Controller */ public function getLocalization() { - $setting = Setting::first(); + $setting = Setting::getSettings(); return view('settings.localization', compact('setting')); } @@ -528,7 +528,7 @@ class SettingsController extends Controller */ public function postLocalization(Request $request) { - if (is_null($setting = Setting::first())) { + if (is_null($setting = Setting::getSettings())) { return redirect()->to('admin')->with('error', trans('admin/settings/message.update.error')); } @@ -558,7 +558,7 @@ class SettingsController extends Controller */ public function getAlerts() { - $setting = Setting::first(); + $setting = Setting::getSettings(); return view('settings.alerts', compact('setting')); } @@ -574,7 +574,7 @@ class SettingsController extends Controller */ public function postAlerts(Request $request) { - if (is_null($setting = Setting::first())) { + if (is_null($setting = Setting::getSettings())) { return redirect()->to('admin')->with('error', trans('admin/settings/message.update.error')); } @@ -611,7 +611,7 @@ class SettingsController extends Controller */ public function getSlack() { - $setting = Setting::first(); + $setting = Setting::getSettings(); return view('settings.slack', compact('setting')); } @@ -627,7 +627,7 @@ class SettingsController extends Controller */ public function postSlack(Request $request) { - if (is_null($setting = Setting::first())) { + if (is_null($setting = Setting::getSettings())) { return redirect()->to('admin')->with('error', trans('admin/settings/message.update.error')); } @@ -654,7 +654,7 @@ class SettingsController extends Controller */ public function getAssetTags() { - $setting = Setting::first(); + $setting = Setting::getSettings(); return view('settings.asset_tags', compact('setting')); } @@ -670,7 +670,7 @@ class SettingsController extends Controller */ public function postAssetTags(Request $request) { - if (is_null($setting = Setting::first())) { + if (is_null($setting = Setting::getSettings())) { return redirect()->to('admin')->with('error', trans('admin/settings/message.update.error')); } @@ -698,7 +698,7 @@ class SettingsController extends Controller */ public function getBarcodes() { - $setting = Setting::first(); + $setting = Setting::getSettings(); $is_gd_installed = extension_loaded('gd'); return view('settings.barcodes', compact('setting'))->with('is_gd_installed', $is_gd_installed); @@ -715,7 +715,7 @@ class SettingsController extends Controller */ public function postBarcodes(Request $request) { - if (is_null($setting = Setting::first())) { + if (is_null($setting = Setting::getSettings())) { return redirect()->to('admin')->with('error', trans('admin/settings/message.update.error')); } @@ -763,7 +763,7 @@ class SettingsController extends Controller */ public function getLabels() { - $setting = Setting::first(); + $setting = Setting::getSettings(); return view('settings.labels', compact('setting')); } @@ -779,7 +779,7 @@ class SettingsController extends Controller */ public function postLabels(Request $request) { - if (is_null($setting = Setting::first())) { + if (is_null($setting = Setting::getSettings())) { return redirect()->to('admin')->with('error', trans('admin/settings/message.update.error')); } $setting->labels_per_page = $request->input('labels_per_page'); @@ -845,7 +845,7 @@ class SettingsController extends Controller */ public function getLdapSettings() { - $setting = Setting::first(); + $setting = Setting::getSettings(); return view('settings.ldap', compact('setting')); } @@ -861,7 +861,7 @@ class SettingsController extends Controller */ public function postLdapSettings(Request $request) { - if (is_null($setting = Setting::first())) { + if (is_null($setting = Setting::getSettings())) { return redirect()->to('admin')->with('error', trans('admin/settings/message.update.error')); } diff --git a/app/Http/Middleware/CheckForSetup.php b/app/Http/Middleware/CheckForSetup.php index e161a912d2..fca16d110e 100644 --- a/app/Http/Middleware/CheckForSetup.php +++ b/app/Http/Middleware/CheckForSetup.php @@ -14,7 +14,10 @@ class CheckForSetup public function handle($request, Closure $next, $guard = null) { - // This is dumb + /** + * This is dumb + * @todo Check on removing this, not sure if it's still needed + */ if ($request->is('_debugbar*')) { return $next($request); } diff --git a/app/Http/Middleware/CheckForTwoFactor.php b/app/Http/Middleware/CheckForTwoFactor.php index 61dcf52690..60df26ad61 100644 --- a/app/Http/Middleware/CheckForTwoFactor.php +++ b/app/Http/Middleware/CheckForTwoFactor.php @@ -1,52 +1,55 @@ route()->getName()=='two-factor') || ($request->route()->getName()=='two-factor-enroll') || ($request->route()->getPrefix()=='setup') || ($request->route()->getName()=='logout')) { + if (in_array($request->route()->getName(), self::IGNORE_ROUTES)) { return $next($request); } // Two-factor is enabled (either optional or required) - if (Setting::getSettings()) { - if (Auth::check() && (Setting::getSettings()->two_factor_enabled!='')) { - + if ($settings = Setting::getSettings()) { + if (Auth::check() && ($settings->two_factor_enabled != '')) { // This user is already 2fa-authed if ($request->session()->get('2fa_authed')) { return $next($request); } // Two-factor is optional and the user has NOT opted in, let them through - if ((Setting::getSettings()->two_factor_enabled=='1') && (Auth::user()->two_factor_optin!='1')) { + if (($settings->two_factor_enabled == '1') && (Auth::user()->two_factor_optin != '1')) { return $next($request); } // Otherwise make sure they're enrolled and show them the 2FA code screen - if ((Auth::user()->two_factor_secret!='') && (Auth::user()->two_factor_enrolled=='1')) { + if ((Auth::user()->two_factor_secret != '') && (Auth::user()->two_factor_enrolled == '1')) { return redirect()->route('two-factor')->with('info', 'Please enter your two-factor authentication code.'); } return redirect()->route('two-factor-enroll')->with('success', 'Please enroll a device in two-factor authentication.'); } } - return $next($request); + return $next($request); } } diff --git a/app/Http/Middleware/CheckLocale.php b/app/Http/Middleware/CheckLocale.php index 2f925e3a0b..3e42a7a901 100644 --- a/app/Http/Middleware/CheckLocale.php +++ b/app/Http/Middleware/CheckLocale.php @@ -4,35 +4,31 @@ namespace App\Http\Middleware; use Closure; use Config; -use Route; -use Schema; use App\Models\Setting; class CheckLocale { - /** - * Handle the locale for the user, default to settings otherwise - * - * @param \Illuminate\Http\Request $request - * @param \Closure $next - * @param string|null $guard - * @return mixed - */ - + /** + * Handle the locale for the user, default to settings otherwise. + * + * @param \Illuminate\Http\Request $request + * @param \Closure $next + * @param string|null $guard + * + * @return mixed + */ public function handle($request, Closure $next, $guard = null) { - - - if (Setting::getSettings()) { + if ($settings = Setting::getSettings()) { // User's preference if (($request->user()) && ($request->user()->locale)) { \App::setLocale($request->user()->locale); - // App setting preference - } elseif ((Setting::getSettings()) && (Setting::getSettings()->locale!='')) { - \App::setLocale(Setting::getSettings()->locale); + // App setting preference + } elseif ($settings->locale != '') { + \App::setLocale($settings->locale); - // Default app setting + // Default app setting } else { \App::setLocale(config('app.locale')); } diff --git a/app/Http/Traits/UniqueSerialTrait.php b/app/Http/Traits/UniqueSerialTrait.php index be9a885c08..b5529d7cf8 100644 --- a/app/Http/Traits/UniqueSerialTrait.php +++ b/app/Http/Traits/UniqueSerialTrait.php @@ -1,21 +1,24 @@ unique_serial=='1') { - return 'unique_undeleted:'.$this->table.','. $this->getKey(); + if ($settings = Setting::getSettings()) { + if ($settings->unique_serial == '1') { + return 'unique_undeleted:'.$this->table.','.$this->getKey(); } } } diff --git a/app/Models/Depreciable.php b/app/Models/Depreciable.php index 1ed80fdcb2..b7769fd360 100644 --- a/app/Models/Depreciable.php +++ b/app/Models/Depreciable.php @@ -50,7 +50,7 @@ class Depreciable extends SnipeModel return $this->purchase_cost; } $depreciation = 0; - $setting = Setting::first(); + $setting = Setting::getSettings(); switch($setting->depreciation_method) { case 'half_1': $depreciation = $this->getHalfYearDepreciatedValue(true); diff --git a/app/Models/Setting.php b/app/Models/Setting.php index af8fafb7d3..89ca0feff5 100755 --- a/app/Models/Setting.php +++ b/app/Models/Setting.php @@ -1,201 +1,297 @@ 'required|min:1|numeric', - 'qr_text' => 'max:31|nullable', - 'logo_img' => 'mimes:jpeg,bmp,png,gif', - 'alert_email' => 'email_array|nullable', - 'admin_cc_email' => 'email|nullable', - 'default_currency' => 'required', - 'locale' => 'required', - 'slack_endpoint' => 'url|required_with:slack_channel|nullable', - 'slack_channel' => 'regex:/(? 'string|nullable', - 'labels_per_page' => 'numeric', - 'labels_width' => 'numeric', - 'labels_height' => 'numeric', - 'labels_pmargin_left' => 'numeric|nullable', - 'labels_pmargin_right' => 'numeric|nullable', - 'labels_pmargin_top' => 'numeric|nullable', - 'labels_pmargin_bottom' => 'numeric|nullable', - 'labels_display_bgutter' => 'numeric|nullable', - 'labels_display_sgutter' => 'numeric|nullable', - 'labels_fontsize' => 'numeric|min:5', - 'labels_pagewidth' => 'numeric|nullable', - 'labels_pageheight' => 'numeric|nullable', - 'login_remote_user_enabled' => 'numeric|nullable', - 'login_common_disabled' => 'numeric|nullable', - 'login_remote_user_custom_logout_url' => 'string|nullable', - 'thumbnail_max_h' => 'numeric|max:500|min:25', - 'pwd_secure_min' => 'numeric|required|min:5', - 'audit_warning_days' => 'numeric|nullable', - 'audit_interval' => 'numeric|nullable', - 'custom_forgot_pass_url' => 'url|nullable', - 'privacy_policy_link' => 'nullable|url' + /** + * The app settings cache key name. + * + * @var string + */ + const APP_SETTINGS_KEY = 'snipeit_app_settings'; + + /** + * The setup check cache key name. + * + * @var string + */ + const SETUP_CHECK_KEY = 'snipeit_setup_check'; + + /** + * Whether the model should inject it's identifier to the unique + * validation rules before attempting validation. If this property + * is not set in the model it will default to true. + * + * @var bool + */ + protected $injectUniqueIdentifier = true; + + /** + * The event map for the model. + * + * @var array + */ + protected $dispatchesEvents = [ + 'saved' => SettingSaved::class, ]; - protected $fillable = ['site_name','email_domain','email_format','username_format']; + /** + * Model rules. + * + * @var array + */ + protected $rules = [ + 'brand' => 'required|min:1|numeric', + 'qr_text' => 'max:31|nullable', + 'logo_img' => 'mimes:jpeg,bmp,png,gif', + 'alert_email' => 'email_array|nullable', + 'admin_cc_email' => 'email|nullable', + 'default_currency' => 'required', + 'locale' => 'required', + 'slack_endpoint' => 'url|required_with:slack_channel|nullable', + 'slack_channel' => 'regex:/(? 'string|nullable', + 'labels_per_page' => 'numeric', + 'labels_width' => 'numeric', + 'labels_height' => 'numeric', + 'labels_pmargin_left' => 'numeric|nullable', + 'labels_pmargin_right' => 'numeric|nullable', + 'labels_pmargin_top' => 'numeric|nullable', + 'labels_pmargin_bottom' => 'numeric|nullable', + 'labels_display_bgutter' => 'numeric|nullable', + 'labels_display_sgutter' => 'numeric|nullable', + 'labels_fontsize' => 'numeric|min:5', + 'labels_pagewidth' => 'numeric|nullable', + 'labels_pageheight' => 'numeric|nullable', + 'login_remote_user_enabled' => 'numeric|nullable', + 'login_common_disabled' => 'numeric|nullable', + 'login_remote_user_custom_logout_url' => 'string|nullable', + 'thumbnail_max_h' => 'numeric|max:500|min:25', + 'pwd_secure_min' => 'numeric|required|min:5', + 'audit_warning_days' => 'numeric|nullable', + 'audit_interval' => 'numeric|nullable', + 'custom_forgot_pass_url' => 'url|nullable', + 'privacy_policy_link' => 'nullable|url', + ]; + protected $fillable = [ + 'site_name', + 'email_domain', + 'email_format', + 'username_format', + ]; + + /** + * Get the app settings. + * Cache is expired on Setting model saved in EventServiceProvider. + * + * @author Wes Hulette + * + * @since 5.0.0 + * + * @return \App\Models\Setting + */ public static function getSettings() { - static $static_cache = null; + return Cache::rememberForever(self::APP_SETTINGS_KEY, function () { + return self::first(); + }); + } - if (!$static_cache) { - if (Schema::hasTable('settings')) { - $static_cache = Setting::first(); + /** + * Check to see if setup process is complete. + * Cache is expired on Setting model saved in EventServiceProvider. + * + * @return bool + */ + public static function setupCompleted(): bool + { + return Cache::rememberForever(self::SETUP_CHECK_KEY, function () { + try { + $usercount = User::withTrashed()->count(); + $settingsCount = self::count(); + + return $usercount > 0 && $settingsCount > 0; + } catch (\Throwable $th) { + // Catche the error if the tables dont exit } - } - - return $static_cache; + return false; + }); } - public static function setupCompleted() + /** + * Get the current Laravel version. + * + * @return string + */ + public function lar_ver(): string { + $app = App::getFacadeApplication(); - $users_table_exists = Schema::hasTable('users'); - $settings_table_exists = Schema::hasTable('settings'); - - if ($users_table_exists && $settings_table_exists) { - $usercount = User::withTrashed()->count(); - $settingsCount = Setting::count(); - return ($usercount > 0 && $settingsCount > 0); - } - - } - - public function lar_ver() - { - $app = \App::getFacadeApplication(); return $app::VERSION; } - public static function getDefaultEula() + /** + * Get the default EULA text. + * + * @return string|null + */ + public static function getDefaultEula(): ?string { - $Parsedown = new \Parsedown(); - if (Setting::getSettings()->default_eula_text) { - return $Parsedown->text(e(Setting::getSettings()->default_eula_text)); + if (self::getSettings()->default_eula_text) { + $parsedown = new Parsedown(); + + return $parsedown->text(e(self::getSettings()->default_eula_text)); } + return null; } - public function modellistCheckedValue ($element) { - + /** + * Check wether to show in model dropdowns. + * + * @param string $element + * + * @return bool + */ + public function modellistCheckedValue($element): bool + { + $settings = self::getSettings(); // If the value is blank for some reason - if ($this->modellist_displays=='') { + if ($settings->modellist_displays == '') { return false; } - $values = explode(',', $this->modellist_displays); + + $values = explode(',', $settings->modellist_displays); foreach ($values as $value) { if ($value == $element) { return true; } } - return false; + return false; } /** * Escapes the custom CSS, and then un-escapes the greater-than symbol * so it can work with direct descendant characters for bootstrap - * menu overrides like: - * + * menu overrides like:. + * * .skin-blue .sidebar-menu>li.active>a, .skin-blue .sidebar-menu>li:hover>a - * + * * Important: Do not remove the e() escaping here, as we output raw in the blade. * * @return string escaped CSS + * * @author A. Gianotto */ - public function show_custom_css() + public function show_custom_css(): string { - $custom_css = Setting::getSettings()->custom_css; + $custom_css = self::getSettings()->custom_css; $custom_css = e($custom_css); // Needed for modifying the bootstrap nav :( $custom_css = str_ireplace('script', 'SCRIPTS-NOT-ALLOWED-HERE', $custom_css); $custom_css = str_replace('>', '>', $custom_css); + return $custom_css; } /** - * Converts bytes into human readable file size. - * - * @param string $bytes - * @return string human readable file size (2,87 Мб) - * @author Mogilev Arseny - */ - public static function fileSizeConvert($bytes) + * Converts bytes into human readable file size. + * + * @param string $bytes + * + * @return string human readable file size (2,87 Мб) + * + * @author Mogilev Arseny + */ + public static function fileSizeConvert($bytes): string { $bytes = floatval($bytes); - $arBytes = array( - 0 => array( - "UNIT" => "TB", - "VALUE" => pow(1024, 4) - ), - 1 => array( - "UNIT" => "GB", - "VALUE" => pow(1024, 3) - ), - 2 => array( - "UNIT" => "MB", - "VALUE" => pow(1024, 2) - ), - 3 => array( - "UNIT" => "KB", - "VALUE" => 1024 - ), - 4 => array( - "UNIT" => "B", - "VALUE" => 1 - ), - ); + $arBytes = [ + 0 => [ + 'UNIT' => 'TB', + 'VALUE' => pow(1024, 4), + ], + 1 => [ + 'UNIT' => 'GB', + 'VALUE' => pow(1024, 3), + ], + 2 => [ + 'UNIT' => 'MB', + 'VALUE' => pow(1024, 2), + ], + 3 => [ + 'UNIT' => 'KB', + 'VALUE' => 1024, + ], + 4 => [ + 'UNIT' => 'B', + 'VALUE' => 1, + ], + ]; - foreach ($arBytes as $arItem) { - if ($bytes >= $arItem["VALUE"]) { - $result = $bytes / $arItem["VALUE"]; - $result = round($result, 2) .$arItem["UNIT"]; - break; - } + foreach ($arBytes as $arItem) { + if ($bytes >= $arItem['VALUE']) { + $result = $bytes / $arItem['VALUE']; + $result = round($result, 2).$arItem['UNIT']; + break; } - return $result; + } + + return $result; } /** * The url for slack notifications. - * Used by Notifiable trait. - * @return mixed + * Used by Notifiable trait. + * + * @return string */ - public function routeNotificationForSlack() + public function routeNotificationForSlack(): string { // At this point the endpoint is the same for everything. // In the future this may want to be adapted for individual notifications. - return $this->slack_endpoint; + return self::getSettings()->slack_endpoint; } - public function routeNotificationForMail() + /** + * Get the mail reply to address from configuration. + * + * @return string + */ + public function routeNotificationForMail(): string { // At this point the endpoint is the same for everything. // In the future this may want to be adapted for individual notifications. return config('mail.reply_to.address'); } - public static function passwordComplexityRulesSaving($action = 'update') + /** + * Get the password complexity rule. + * + * @return string + */ + public static function passwordComplexityRulesSaving($action = 'update'): string { $security_rules = ''; - $settings = Setting::getSettings(); + $settings = self::getSettings(); // Check if they have uncommon password enforcement selected in settings if ($settings->pwd_secure_uncommon == 1) { @@ -203,8 +299,8 @@ class Setting extends Model } // Check for any secure password complexity rules that may have been selected - if ($settings->pwd_secure_complexity!='') { - $security_rules .= '|'.$settings->pwd_secure_complexity; + if ($settings->pwd_secure_complexity != '') { + $security_rules .= '|'.$settings->pwd_secure_complexity; } if ($action == 'update') { @@ -212,9 +308,5 @@ class Setting extends Model } return 'required|min:'.$settings->pwd_secure_min.$security_rules; - } - - - } diff --git a/app/Observers/AssetObserver.php b/app/Observers/AssetObserver.php index df466d3753..2a42a26873 100644 --- a/app/Observers/AssetObserver.php +++ b/app/Observers/AssetObserver.php @@ -57,7 +57,7 @@ class AssetObserver */ public function created(Asset $asset) { - if ($settings = Setting::first()) { + if ($settings = Setting::getSettings()) { $settings->increment('next_auto_tag_base'); } diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php index 28c3aecf06..db9677d8a7 100644 --- a/app/Providers/EventServiceProvider.php +++ b/app/Providers/EventServiceProvider.php @@ -2,9 +2,12 @@ namespace App\Providers; +use App\Models\Setting; +use App\Events\SettingSaved; +use App\Listeners\LogListener; +use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Event; use App\Listeners\CheckoutableListener; -use App\Listeners\LogListener; use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider; class EventServiceProvider extends ServiceProvider @@ -44,6 +47,12 @@ class EventServiceProvider extends ServiceProvider { parent::boot(); - // + /** + * Clear the LDAP settings cache when the settings model is saved + */ + Event::listen(SettingSaved::class, function () { + Cache::forget(Setting::APP_SETTINGS_KEY); + Cache::forget(Setting::SETUP_CHECK_KEY); + }); } }