From a622f2f295ee8fe66a95170d27ce28d77d9d53c1 Mon Sep 17 00:00:00 2001 From: alextselegidis Date: Mon, 22 Nov 2021 07:36:05 +0100 Subject: [PATCH] Ported the current user settings functionality to a new standalone page --- .../controllers/settings/Current_user.php | 110 ++++++++++ .../current_user/current_user_page.php | 191 ++++++++++++++++++ assets/js/backend_settings_current_user.js | 94 +++++++++ .../backend_settings_current_user_helper.js | 131 ++++++++++++ 4 files changed, 526 insertions(+) create mode 100644 application/controllers/settings/Current_user.php create mode 100644 application/views/pages/settings/current_user/current_user_page.php create mode 100644 assets/js/backend_settings_current_user.js create mode 100644 assets/js/backend_settings_current_user_helper.js diff --git a/application/controllers/settings/Current_user.php b/application/controllers/settings/Current_user.php new file mode 100644 index 00000000..10af7573 --- /dev/null +++ b/application/controllers/settings/Current_user.php @@ -0,0 +1,110 @@ + + * @copyright Copyright (c) 2013 - 2020, Alex Tselegidis + * @license https://opensource.org/licenses/GPL-3.0 - GPLv3 + * @link https://easyappointments.org + * @since v1.5.0 + * ---------------------------------------------------------------------------- */ + +/** + * Current user controller. + * + * Handles current user settings related operations. + * + * @package Controllers + */ +class Current_user extends EA_Controller { + /** + * @var array + */ + protected array $permissions; + + /** + * Current_user constructor. + */ + public function __construct() + { + parent::__construct(); + + $this->load->model('appointments_model'); + $this->load->model('customers_model'); + $this->load->model('services_model'); + $this->load->model('providers_model'); + $this->load->model('roles_model'); + $this->load->model('settings_model'); + + $this->load->library('accounts'); + $this->load->library('google_sync'); + $this->load->library('notifications'); + $this->load->library('synchronization'); + $this->load->library('timezones'); + + $role_slug = session('role_slug'); + + if ($role_slug) + { + $this->permissions = $this->roles_model->get_permissions_by_slug($role_slug); + } + } + + /** + * Render the settings page. + */ + public function index() + { + session(['dest_url' => site_url('services')]); + + if (cannot('view', 'services')) + { + show_error('Forbidden', 403); + } + + $user_id = session('user_id'); + + $role_slug = session('role_slug'); + + $this->load->view('pages/settings/current_user/current_user_page', [ + 'page_title' => lang('settings'), + 'active_menu' => PRIV_SYSTEM_SETTINGS, + 'user_display_name' => $this->accounts->get_user_display_name($user_id), + 'timezones' => $this->timezones->to_array(), + 'privileges' => $this->roles_model->get_permissions_by_slug($role_slug), + 'user_settings' => $this->users_model->find($user_id), + ]); + } + + /** + * Save general settings. + */ + public function save() + { + try + { + if ($this->permissions[PRIV_USER_SETTINGS]['edit'] == FALSE) + { + throw new Exception('You do not have the required permissions for this task.'); + } + + $settings = json_decode(request('settings'), TRUE); + + $this->users_model->save($settings); + + session([ + 'user_email' => $settings['email'], + 'username' => $settings['settings']['username'], + 'timezone' => $settings['timezone'], + ]); + + response(); + } + catch (Throwable $e) + { + json_exception($e); + } + } +} diff --git a/application/views/pages/settings/current_user/current_user_page.php b/application/views/pages/settings/current_user/current_user_page.php new file mode 100644 index 00000000..5f676c6a --- /dev/null +++ b/application/views/pages/settings/current_user/current_user_page.php @@ -0,0 +1,191 @@ + + + + + + + + + + +
+
+
+
+
+ + + + + + + + + +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+
+ +
+ + + + +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+
+
+
+
+
+ + diff --git a/assets/js/backend_settings_current_user.js b/assets/js/backend_settings_current_user.js new file mode 100644 index 00000000..bab8fd35 --- /dev/null +++ b/assets/js/backend_settings_current_user.js @@ -0,0 +1,94 @@ +/* ---------------------------------------------------------------------------- + * Easy!Appointments - Open Source Web Scheduler + * + * @package EasyAppointments + * @author A.Tselegidis + * @copyright Copyright (c) 2013 - 2020, Alex Tselegidis + * @license http://opensource.org/licenses/GPL-3.0 - GPLv3 + * @link http://easyappointments.org + * @since v1.0.0 + * ---------------------------------------------------------------------------- */ + +window.BackendSettingsCurrentUser = window.BackendSettingsCurrentUser || {}; + +/** + * Backend Settings + * + * Contains the functionality of the backend settings page. Can either work for system or user settings, + * but the actions allowed to the user are restricted to his role (only admin has full privileges). + * + * @module BackendSettingsCurrentUser + */ +(function (exports) { + 'use strict'; + + // Constants + exports.SETTINGS_USER = 'SETTINGS_USER'; + + /** + * Use this WorkingPlan class instance to perform actions on the page's working plan tables. + * + * @type {WorkingPlan} + */ + exports.wp = {}; + + /** + * Tab settings object. + * + * @type {Object} + */ + var settings = {}; + + /** + * Initialize Page + * + * @param {bool} defaultEventHandlers Optional (true), determines whether to bind the default event handlers. + */ + exports.initialize = function (defaultEventHandlers) { + defaultEventHandlers = defaultEventHandlers || true; + + // Load user settings into form + $('#user-id').val(GlobalVariables.settings.user.id); + $('#first-name').val(GlobalVariables.settings.user.first_name); + $('#last-name').val(GlobalVariables.settings.user.last_name); + $('#email').val(GlobalVariables.settings.user.email); + $('#mobile-number').val(GlobalVariables.settings.user.mobile_number); + $('#phone-number').val(GlobalVariables.settings.user.phone_number); + $('#address').val(GlobalVariables.settings.user.address); + $('#city').val(GlobalVariables.settings.user.city); + $('#state').val(GlobalVariables.settings.user.state); + $('#zip-code').val(GlobalVariables.settings.user.zip_code); + $('#notes').val(GlobalVariables.settings.user.notes); + $('#timezone').val(GlobalVariables.settings.user.timezone); + $('#username').val(GlobalVariables.settings.user.settings.username); + $('#password, #retype-password').val(''); + $('#calendar-view').val(GlobalVariables.settings.user.settings.calendar_view); + $('#user-notifications').prop('checked', Boolean(Number(GlobalVariables.settings.user.settings.notifications))); + + // Set default settings helper. + settings = new SystemSettingsCurrentUserHelper(); + + if (defaultEventHandlers) { + bindEventHandlers(); + } + + Backend.placeFooterToBottom(); + }; + + /** + * Bind the backend/settings default event handlers. + * + * This method depends on the backend/settings html, so do not use this method on a different page. + */ + function bindEventHandlers() { + /** + * Event: Save Settings Button "Click" + * + * Store the setting changes into the database. + */ + $('.save-settings').on('click', function () { + var data = settings.get(); + settings.save(data); + }); + } +})(window.BackendSettingsCurrentUser); diff --git a/assets/js/backend_settings_current_user_helper.js b/assets/js/backend_settings_current_user_helper.js new file mode 100644 index 00000000..7a73f729 --- /dev/null +++ b/assets/js/backend_settings_current_user_helper.js @@ -0,0 +1,131 @@ +/* ---------------------------------------------------------------------------- + * Easy!Appointments - Open Source Web Scheduler + * + * @package EasyAppointments + * @author A.Tselegidis + * @copyright Copyright (c) 2013 - 2020, Alex Tselegidis + * @license http://opensource.org/licenses/GPL-3.0 - GPLv3 + * @link http://easyappointments.org + * @since v1.0.0 + * ---------------------------------------------------------------------------- */ + +(function () { + 'use strict'; + + /** + * "User Settings" Tab Helper Class + * + * @class SystemSettingsCurrentUserHelper + */ + var SystemSettingsCurrentUserHelper = function () {}; + + /** + * Get the settings data for the user settings. + * + * @return {Object} Returns the user settings array. + */ + SystemSettingsCurrentUserHelper.prototype.get = function () { + var user = { + id: $('#user-id').val(), + first_name: $('#first-name').val(), + last_name: $('#last-name').val(), + email: $('#email').val(), + mobile_number: $('#mobile-number').val(), + phone_number: $('#phone-number').val(), + address: $('#address').val(), + city: $('#city').val(), + state: $('#state').val(), + zip_code: $('#zip-code').val(), + notes: $('#notes').val(), + timezone: $('#timezone').val(), + settings: { + username: $('#username').val(), + notifications: $('#user-notifications').prop('checked'), + calendar_view: $('#calendar-view').val() + } + }; + + if ($('#password').val()) { + user.settings.password = $('#password').val(); + } + + return user; + }; + + /** + * Store the user settings into the database. + * + * @param {Array} settings Contains the user settings. + */ + SystemSettingsCurrentUserHelper.prototype.save = function (settings) { + if (!this.validate(settings)) { + Backend.displayNotification(EALang.user_settings_are_invalid); + return; // Validation failed, do not proceed. + } + + var url = GlobalVariables.baseUrl + '/index.php/settings/current_user/save'; + + var data = { + csrfToken: GlobalVariables.csrfToken, + type: BackendSettingsCurrentUser.SETTINGS_USER, + settings: JSON.stringify(settings) + }; + + $.post(url, data).done(function () { + Backend.displayNotification(EALang.settings_saved); + + // Update footer greetings. + $('#footer-user-display-name').text('Hello, ' + $('#first-name').val() + ' ' + $('#last-name').val() + '!'); + }); + }; + + /** + * Validate the settings data. + * + * If the validation fails then display a message to the user. + * + * @return {Boolean} Returns the validation result. + */ + SystemSettingsCurrentUserHelper.prototype.validate = function () { + $('#current-user .has-error').removeClass('has-error'); + + try { + // Validate required fields. + var missingRequired = false; + $('#current-user .required').each(function (index, requiredField) { + if (!$(requiredField).val()) { + $(requiredField).closest('.form-group').addClass('has-error'); + missingRequired = true; + } + }); + + if (missingRequired) { + throw new Error(EALang.fields_are_required); + } + + // Validate passwords (if provided). + if ($('#password').val() !== $('#retype-password').val()) { + $('#password, #retype-password').closest('.form-group').addClass('has-error'); + throw new Error(EALang.passwords_mismatch); + } + + // Validate user email. + if (!GeneralFunctions.validateEmail($('#email').val())) { + $('#email').closest('.form-group').addClass('has-error'); + throw new Error(EALang.invalid_email); + } + + if ($('#username').attr('already-exists') === 'true') { + $('#username').closest('.form-group').addClass('has-error'); + throw new Error(EALang.username_already_exists); + } + + return true; + } catch (error) { + Backend.displayNotification(error.message); + return false; + } + }; + + window.SystemSettingsCurrentUserHelper = SystemSettingsCurrentUserHelper; +})();