From 02b43035f3375d2e222c4a0163ef0ff318500b62 Mon Sep 17 00:00:00 2001 From: Aaron van Geffen Date: Sat, 11 Mar 2023 15:32:07 +0100 Subject: [PATCH] AccountSettings: allow users to change their personal details --- controllers/AccountSettings.php | 130 ++++++++++++++++++++++++++++++++ models/Member.php | 5 +- models/Router.php | 1 + 3 files changed, 135 insertions(+), 1 deletion(-) create mode 100644 controllers/AccountSettings.php diff --git a/controllers/AccountSettings.php b/controllers/AccountSettings.php new file mode 100644 index 0000000..4bbb056 --- /dev/null +++ b/controllers/AccountSettings.php @@ -0,0 +1,130 @@ +isLoggedIn()) + throw new NotAllowedException('You need to be logged in to view this page.'); + + parent::__construct('Account settings'); + $form_title = 'Account settings'; + + // Session checking! + if (empty($_POST)) + Session::resetSessionToken(); + else + Session::validateSession(); + + $fields = [ + 'first_name' => [ + 'type' => 'text', + 'label' => 'First name', + 'size' => 50, + 'maxlength' => 255, + ], + 'surname' => [ + 'type' => 'text', + 'label' => 'Family name', + 'size' => 50, + 'maxlength' => 255, + ], + 'emailaddress' => [ + 'type' => 'text', + 'label' => 'Email address', + 'size' => 50, + 'maxlength' => 255, + ], + 'password1' => [ + 'before_html' => '

To change your password, please fill out the fields below.

', + 'type' => 'password', + 'label' => 'Password', + 'size' => 50, + 'maxlength' => 255, + 'is_optional' => true, + ], + 'password2' => [ + 'type' => 'password', + 'label' => 'Password (repeat)', + 'size' => 50, + 'maxlength' => 255, + 'is_optional' => true, + ], + ]; + + $form = new Form([ + 'request_url' => BASEURL . '/' . $_GET['action'] . '/', + 'fields' => $fields, + 'submit_caption' => 'Save details', + ]); + + $user = Registry::get('user'); + + // Create the form, add in default values. + $form->setData(empty($_POST) ? $user->getProps() : $_POST); + $formview = new FormView($form, $form_title); + $this->page->adopt($formview); + + // Left a message? + if (isset($_SESSION['account_msg'])) + { + $alert = $_SESSION['account_msg']; + $formview->adopt(new Alert($alert[0], $alert[1], $alert[2])); + unset($_SESSION['account_msg']); + } + + // Just updating account settings? + if (!empty($_POST)) + { + $form->verify($_POST); + + // Anything missing? + if (!empty($form->getMissing())) + { + $missingFields = array_intersect_key($fields, array_flip($form->getMissing())); + $missingFields = array_map(function($field) { return strtolower($field['label']); }, $missingFields); + return $formview->adopt(new Alert('Some data missing', 'Please fill out the following fields: ' . implode(', ', $missingFields), 'danger')); + } + + $data = $form->getData(); + + // Just to be on the safe side. + $data['first_name'] = htmlspecialchars(trim($data['first_name'])); + $data['surname'] = htmlspecialchars(trim($data['surname'])); + $data['emailaddress'] = trim($data['emailaddress']); + + // If it looks like an e-mail address... + if (!empty($data['emailaddress']) && !preg_match('~^[^ ]+@[^ ]+\.[a-z]+$~', $data['emailaddress'])) + return $formview->adopt(new Alert('Email addresses invalid', 'The email address you entered is not a valid email address.', 'danger')); + // Check whether email address is already linked to an account in the database -- just not to the account we happen to be editing, of course. + elseif (!empty($data['emailaddress']) && $user->getEmailAddress() !== $data['emailaddress'] && Member::exists($data['emailaddress'])) + return $formview->adopt(new Alert('Email address already in use', 'Another account is already using this e-mail address.', 'danger')); + + // Changing passwords? + if (!empty($data['password1']) && !empty($data['password2'])) + { + if (strlen($data['password1']) < 6 || !preg_match('~[^A-z]~', $data['password1'])) + return $formview->adopt(new Alert('Password not acceptable', 'Please use a password that is at least six characters long and contains at least one non-alphabetic character (e.g. a number or symbol).', 'danger')); + elseif ($data['password1'] !== $data['password2']) + return $formview->adopt(new Alert('Passwords do not match', 'The passwords you entered do not match. Please try again.', 'danger')); + + // Keep just the one. + $data['password'] = $data['password1']; + unset($data['password1'], $data['password2']); + $formview->adopt(new Alert('Your password has been changed', 'Next time you log in, you can use your new password to authenticate yourself.', 'success')); + } + else + $formview->adopt(new Alert('Your account settings have been saved', 'Thank you for keeping your information current.', 'success')); + + $user->update($data); + } + } +} diff --git a/models/Member.php b/models/Member.php index 9fc21f7..6675dac 100644 --- a/models/Member.php +++ b/models/Member.php @@ -110,6 +110,9 @@ class Member extends User $this->is_admin = $value == 1 ? 1 : 0; } + $params = get_object_vars($this); + $params['is_admin'] = $this->is_admin ? 1 : 0; + return Registry::get('db')->query(' UPDATE users SET @@ -120,7 +123,7 @@ class Member extends User password_hash = {string:password_hash}, is_admin = {int:is_admin} WHERE id_user = {int:id_user}', - get_object_vars($this)); + $params); } /** diff --git a/models/Router.php b/models/Router.php index ba54a61..da37499 100644 --- a/models/Router.php +++ b/models/Router.php @@ -11,6 +11,7 @@ class Router public static function route() { $possibleActions = [ + 'accountsettings' => 'AccountSettings', 'addalbum' => 'EditAlbum', 'albums' => 'ViewPhotoAlbums', 'editalbum' => 'EditAlbum',