diff --git a/app/Http/Controllers/SettingController.php b/app/Http/Controllers/SettingController.php new file mode 100644 index 0000000..619e111 --- /dev/null +++ b/app/Http/Controllers/SettingController.php @@ -0,0 +1,391 @@ +user(); + } + /** + * Display the settings page. + * + * @return \Illuminate\View\View + */ + public function index() + { + // Check if the authenticated user has the required permission to view settings + $user = $this->getUser(); + if (is_null($user) || !$user->can('basic-data.read')) { + abort(403, 'Sorry! You are not allowed to view settings.'); + } + // Get all settings or group them by category + $emailSettings = [ + 'mail_from_address' => Settings::get('mail_from_address', config('mail.from.address')), + 'mail_from_name' => Settings::get('mail_from_name', config('mail.from.name')), + 'mail_host' => Settings::get('mail_host', config('mail.mailers.smtp.host')), + 'mail_port' => Settings::get('mail_port', config('mail.mailers.smtp.port')), + 'mail_username' => Settings::get('mail_username', config('mail.mailers.smtp.username')), + 'mail_encryption' => Settings::get('mail_encryption', config('mail.mailers.smtp.encryption')), + ]; + + $appSettings = [ + 'app_name' => Settings::get('app_name', config('app.name')), + 'app_url' => Settings::get('app_url', config('app.url')), + 'app_timezone' => Settings::get('app_timezone', config('app.timezone')), + 'app_debug' => Settings::get('app_debug', config('app.debug')), + ]; + + $statementSettings = [ + 'statement_email_subject' => Settings::get('statement_email_subject', 'Your Account Statement'), + 'statement_email_body' => Settings::get('statement_email_body', 'Please find attached your account statement.'), + 'statement_footer_text' => Settings::get('statement_footer_text', '© ' . date('Y') . ' Bank. All rights reserved.'), + ]; + + return view('basicdata::settings.index', compact('emailSettings', 'appSettings', 'statementSettings')); + } + + /** + * Update the specified settings. + * + * @param \Illuminate\Http\Request $request + * + * @return \Illuminate\Http\RedirectResponse + */ + public function update(Request $request) + { + // Check if the authenticated user has the required permission to update settings + $user = $this->getUser(); + if (is_null($user) || !$user->can('basic-data.update')) { + abort(403, 'Sorry! You are not allowed to update settings.'); + } + // Validate settings based on category + $category = $request->input('category', 'general'); + + switch ($category) { + case 'email': + $validator = Validator::make($request->all(), [ + 'mail_from_address' => 'required|email', + 'mail_from_name' => 'required|string|max:255', + 'mail_host' => 'required|string|max:255', + 'mail_port' => 'required|numeric', + 'mail_username' => 'required|string|max:255', + 'mail_password' => 'nullable|string', + 'mail_encryption' => 'nullable|string|in:tls,ssl,', + ]); + break; + + case 'app': + $validator = Validator::make($request->all(), [ + 'app_name' => 'required|string|max:255', + 'app_url' => 'required|url', + 'app_timezone' => 'required|string|max:255', + 'app_debug' => 'required|string|in:true,false', + ]); + break; + + case 'statement': + $validator = Validator::make($request->all(), [ + 'statement_email_subject' => 'required|string|max:255', + 'statement_email_body' => 'required|string', + 'statement_footer_text' => 'required|string', + ]); + break; + + default: + $validator = Validator::make($request->all(), []); + } + + if ($validator->fails()) { + return redirect()->back() + ->withErrors($validator) + ->withInput(); + } + + // Save settings + foreach ($request->except(['_token', 'category']) as $key => $value) { + // Special handling for boolean values + if ($key === 'app_debug') { + $value = $value === 'true'; + } + + // Don't save empty password + if ($key === 'mail_password' && empty($value)) { + continue; + } + + // Encrypt password + if ($key === 'mail_password') { + $value = encrypt($value); + } + + Settings::set($key, $value); + } + + // Update environment configuration + $this->updateEnvironmentConfig($category, $request); + + // If mail settings were updated, update the config at runtime + if ($category === 'email') { + config([ + 'mail.from.address' => $request->input('mail_from_address'), + 'mail.from.name' => $request->input('mail_from_name'), + 'mail.mailers.smtp.host' => $request->input('mail_host'), + 'mail.mailers.smtp.port' => $request->input('mail_port'), + 'mail.mailers.smtp.username' => $request->input('mail_username'), + 'mail.mailers.smtp.encryption' => $request->input('mail_encryption'), + ]); + + // If password was updated, update it in the config + if ($request->filled('mail_password')) { + config(['mail.mailers.smtp.password' => decrypt(Settings::get('mail_password'))]); + } + } + + // If app settings were updated, update the config at runtime + if ($category === 'app') { + config([ + 'app.name' => $request->input('app_name'), + 'app.url' => $request->input('app_url'), + 'app.timezone' => $request->input('app_timezone'), + 'app.debug' => $request->input('app_debug') === 'true', + ]); + } + + return redirect()->back() + ->with('success', ucfirst($category) . ' settings updated successfully') + ->withFragment('#' . $category); + } + + /** + * Update environment configuration in .env file. + * + * @param string $category + * @param \Illuminate\Http\Request $request + * + * @return void + */ + protected function updateEnvironmentConfig($category, Request $request) + { + // Map settings keys to .env keys + $envMappings = [ + 'app' => [ + 'app_name' => 'APP_NAME', + 'app_url' => 'APP_URL', + 'app_timezone' => 'APP_TIMEZONE', + 'app_debug' => 'APP_DEBUG', + ], + 'email' => [ + 'mail_from_address' => 'MAIL_FROM_ADDRESS', + 'mail_from_name' => 'MAIL_FROM_NAME', + 'mail_host' => 'MAIL_HOST', + 'mail_port' => 'MAIL_PORT', + 'mail_username' => 'MAIL_USERNAME', + 'mail_encryption' => 'MAIL_ENCRYPTION', + ], + ]; + + // Only update .env for app and email settings + if (!isset($envMappings[$category])) { + return; + } + + $envFile = base_path('.env'); + $envContent = file_get_contents($envFile); + + foreach ($envMappings[$category] as $settingKey => $envKey) { + if ($request->has($settingKey)) { + $value = $request->input($settingKey); + + // Format value for .env file + if ($settingKey === 'app_debug') { + $value = $value === 'true' ? 'true' : 'false'; + } else if (is_string($value) && str_contains($value, ' ')) { + $value = '"' . $value . '"'; + } + + // Update .env file + if (preg_match("/^{$envKey}=.*/m", $envContent)) { + $envContent = preg_replace("/^{$envKey}=.*/m", "{$envKey}={$value}", $envContent); + } else { + $envContent .= "\n{$envKey}={$value}"; + } + } + } + + // Handle mail password separately + if ($category === 'email' && $request->filled('mail_password')) { + $value = $request->input('mail_password'); + if (preg_match("/^MAIL_PASSWORD=.*/m", $envContent)) { + $envContent = preg_replace("/^MAIL_PASSWORD=.*/m", "MAIL_PASSWORD={$value}", $envContent); + } else { + $envContent .= "\nMAIL_PASSWORD={$value}"; + } + } + + file_put_contents($envFile, $envContent); + + // Clear config cache + Artisan::call('config:clear'); + } + + /** + * Reset settings to their default values. + * + * @param \Illuminate\Http\Request $request + * + * @return \Illuminate\Http\RedirectResponse + */ + public function reset(Request $request) + { + // Check if the authenticated user has the required permission to update settings + $user = $this->getUser(); + if (is_null($user) || !$user->can('basic-data.update')) { + abort(403, 'Sorry! You are not allowed to reset settings.'); + } + $category = $request->input('category', 'general'); + + switch ($category) { + case 'email': + $keys = [ + 'mail_from_address', + 'mail_from_name', + 'mail_host', + 'mail_port', + 'mail_username', + 'mail_password', + 'mail_encryption' + ]; + break; + + case 'app': + $keys = [ + 'app_name', + 'app_url', + 'app_timezone', + 'app_debug' + ]; + break; + + case 'statement': + $keys = [ + 'statement_email_subject', + 'statement_email_body', + 'statement_footer_text' + ]; + break; + + default: + $keys = []; + } + + // Delete settings + foreach ($keys as $key) { + Settings::forget($key); + } + + // Reset environment configuration to original values from .env file + $this->resetEnvironmentConfig($category); + + return redirect()->back() + ->with('success', ucfirst($category) . ' settings have been reset to default values') + ->withFragment('#' . $category); + } + + /** + * Reset environment configuration to original values from .env file. + * + * @param string $category + * + * @return void + */ + protected function resetEnvironmentConfig($category) + { + // Only reset .env for app and email settings + if (!in_array($category, ['app', 'email'])) { + return; + } + + // Clear config cache to reload from .env + Artisan::call('config:clear'); + } + + /** + * Send a test email. + * + * @param \Illuminate\Http\Request $request + * + * @return \Illuminate\Http\JsonResponse + */ + public function testEmail(Request $request) + { + // Check if the authenticated user has the required permission to update settings + $user = $this->getUser(); + if (is_null($user) || !$user->can('basic-data.update')) { + return response()->json([ + 'success' => false, + 'message' => 'Sorry! You are not allowed to test email settings.', + ], 403); + } + $validator = Validator::make($request->all(), [ + 'test_email' => 'required|email', + ]); + + if ($validator->fails()) { + return response()->json([ + 'success' => false, + 'message' => 'Please enter a valid email address.', + ]); + } + + try { + // Get current mail settings + $config = [ + 'from' => [ + 'address' => Settings::get('mail_from_address', config('mail.from.address')), + 'name' => Settings::get('mail_from_name', config('mail.from.name')), + ], + 'host' => Settings::get('mail_host', config('mail.mailers.smtp.host')), + 'port' => Settings::get('mail_port', config('mail.mailers.smtp.port')), + 'username' => Settings::get('mail_username', config('mail.mailers.smtp.username')), + 'encryption' => Settings::get('mail_encryption', config('mail.mailers.smtp.encryption')), + ]; + + // Get password if it exists + if (Settings::has('mail_password')) { + $config['password'] = decrypt(Settings::get('mail_password')); + } else { + $config['password'] = config('mail.mailers.smtp.password'); + } + + // Send test email + Mail::mailer('smtp') + ->send(new TestEmail($request->input('test_email'), $config)); + + return response()->json([ + 'success' => true, + 'message' => 'Test email sent successfully! Please check your inbox.', + ]); + } catch (Exception $e) { + return response()->json([ + 'success' => false, + 'message' => 'Failed to send test email: ' . $e->getMessage(), + ]); + } + } + }