fix: profile settings not being saved

This commit is contained in:
grandeljay 2023-09-20 15:33:20 +02:00
parent a7bf23154c
commit 7dbe413f77
9 changed files with 507 additions and 195 deletions

View file

@ -154,10 +154,13 @@ if ($options && $options->getOption('isInstalled')) {
if (!isset($page)) { if (!isset($page)) {
$page = isset($_GET['page']) ? $_GET['page'] : 'home'; $page = isset($_GET['page']) ? $_GET['page'] : 'home';
} }
$pagePath = 'src/pages/' . $page . '.php'; $pagePath = 'src/pages/' . $page . '.php';
$pagePathAlt = 'src/pages/' . $page . '/' . $page . '.php';
if (file_exists($pagePath)) { if (file_exists($pagePath)) {
require $pagePath; require $pagePath;
} elseif (\file_exists($pagePathAlt)) {
require $pagePathAlt;
} else { } else {
http_response_code(404); http_response_code(404);
?> ?>

View file

@ -4,11 +4,17 @@ namespace wishthis;
class Sanitiser class Sanitiser
{ {
/**
* @deprecated 1.1.0
*/
public static function render(string $text): string public static function render(string $text): string
{ {
return $text; return $text;
} }
/**
* @deprecated 1.1.0
*/
public static function getNumber(mixed $valueToSanitise): float|int public static function getNumber(mixed $valueToSanitise): float|int
{ {
$number = preg_replace('/[^0-9\.]+/', '', $valueToSanitise); $number = preg_replace('/[^0-9\.]+/', '', $valueToSanitise);
@ -16,6 +22,9 @@ class Sanitiser
return $number; return $number;
} }
/**
* @deprecated 1.1.0
*/
public static function getPage(mixed $valueToSanitise): string public static function getPage(mixed $valueToSanitise): string
{ {
$valueToSanitise = strtolower($valueToSanitise); $valueToSanitise = strtolower($valueToSanitise);
@ -23,6 +32,9 @@ class Sanitiser
return preg_replace('/[^a-z\-_]+/', '', $valueToSanitise); return preg_replace('/[^a-z\-_]+/', '', $valueToSanitise);
} }
/**
* @deprecated 1.1.0
*/
public static function getTable(mixed $valueToSanitise): string public static function getTable(mixed $valueToSanitise): string
{ {
$valueToSanitise = strtolower($valueToSanitise); $valueToSanitise = strtolower($valueToSanitise);
@ -30,6 +42,9 @@ class Sanitiser
return preg_replace('/[^a-z_]+/', '', $valueToSanitise); return preg_replace('/[^a-z_]+/', '', $valueToSanitise);
} }
/**
* @deprecated 1.1.0
*/
public static function getTitle(mixed $valueToSanitise): string public static function getTitle(mixed $valueToSanitise): string
{ {
$valueToSanitise = trim($valueToSanitise); $valueToSanitise = trim($valueToSanitise);
@ -37,6 +52,9 @@ class Sanitiser
return htmlentities($valueToSanitise, ENT_QUOTES | ENT_SUBSTITUTE | ENT_DISALLOWED | ENT_HTML5); return htmlentities($valueToSanitise, ENT_QUOTES | ENT_SUBSTITUTE | ENT_DISALLOWED | ENT_HTML5);
} }
/**
* @deprecated 1.1.0
*/
public static function getText(mixed $valueToSanitise): string public static function getText(mixed $valueToSanitise): string
{ {
$valueToSanitise = trim($valueToSanitise); $valueToSanitise = trim($valueToSanitise);
@ -44,11 +62,17 @@ class Sanitiser
return htmlentities($valueToSanitise, ENT_QUOTES | ENT_SUBSTITUTE | ENT_DISALLOWED | ENT_HTML5); return htmlentities($valueToSanitise, ENT_QUOTES | ENT_SUBSTITUTE | ENT_DISALLOWED | ENT_HTML5);
} }
/**
* @deprecated 1.1.0
*/
public static function getURL(mixed $valueToSanitise): string public static function getURL(mixed $valueToSanitise): string
{ {
return preg_replace('/[\s]+/', '', $valueToSanitise); return preg_replace('/[\s]+/', '', $valueToSanitise);
} }
/**
* @deprecated 1.1.0
*/
public static function getStatus(mixed $valueToSanitise): string public static function getStatus(mixed $valueToSanitise): string
{ {
$valueToSanitise = strtolower($valueToSanitise); $valueToSanitise = strtolower($valueToSanitise);
@ -56,11 +80,17 @@ class Sanitiser
return preg_replace('/[^a-z\-_]+/', '', $valueToSanitise); return preg_replace('/[^a-z\-_]+/', '', $valueToSanitise);
} }
/**
* @deprecated 1.1.0
*/
public static function getOption(mixed $valueToSanitise): string public static function getOption(mixed $valueToSanitise): string
{ {
return preg_replace('/[^a-zA-Z\_]+/', '', $valueToSanitise); return preg_replace('/[^a-zA-Z\_]+/', '', $valueToSanitise);
} }
/**
* @deprecated 1.1.0
*/
public static function getEmail(mixed $valueToSanitise): string public static function getEmail(mixed $valueToSanitise): string
{ {
$valueToSanitise = strtolower($valueToSanitise); $valueToSanitise = strtolower($valueToSanitise);
@ -68,10 +98,39 @@ class Sanitiser
return preg_replace('/[^a-z\-_0-9\.+@]+/', '', $valueToSanitise); return preg_replace('/[^a-z\-_0-9\.+@]+/', '', $valueToSanitise);
} }
/**
* @deprecated 1.1.0
*/
public static function getSHA1(mixed $valueToSanitise): string public static function getSHA1(mixed $valueToSanitise): string
{ {
$valueToSanitise = strtolower($valueToSanitise); $valueToSanitise = strtolower($valueToSanitise);
return preg_replace('/[^a-f0-9]+/', '', $valueToSanitise); return preg_replace('/[^a-f0-9]+/', '', $valueToSanitise);
} }
/**
* Sanitize a single line of text.
*
* @param string $text
*
* @return string
*/
public static function sanitiseText(string $text): string {
$sanitisedText = \trim(\addslashes(\filter_var($text, \FILTER_SANITIZE_SPECIAL_CHARS)));
return $sanitisedText;
}
/**
* Sanitise an email address.
*
* @param string $email
*
* @return string
*/
public static function sanitiseEmail(string $email): string {
$sanitisedEmail = \trim(\addslashes(\filter_var($email, \FILTER_SANITIZE_EMAIL)));
return $sanitisedEmail;
}
} }

View file

@ -103,7 +103,7 @@ class User
private int $power = 0; private int $power = 0;
/** /**
* A unix timestamp of the users birthdate. * The users birthdate, formatted as `YYYY-MM-DD`.
* *
* @var string * @var string
*/ */
@ -461,11 +461,46 @@ class User
return $this->id; return $this->id;
} }
public function getNameFirst(): string
{
return $this->name_first;
}
public function setNameFirst(string $nameFirst): void
{
$this->name_first = $nameFirst;
}
public function getNameLast(): string
{
return $this->name_last;
}
public function setNameLast(string $nameLast): void
{
$this->name_last = $nameLast;
}
public function getNameNick(): string
{
return $this->name_nick;
}
public function setNameNick(string $nameNick): void
{
$this->name_nick = $nameNick;
}
public function getEmail(): string public function getEmail(): string
{ {
return $this->email; return $this->email;
} }
public function setEmail(string $email): void
{
$this->email = $email;
}
public function getPassword(): string public function getPassword(): string
{ {
return $this->password; return $this->password;
@ -476,21 +511,6 @@ class User
return $this->power; return $this->power;
} }
public function getFirstName(): string
{
return $this->name_first;
}
public function getLastName(): string
{
return $this->name_last;
}
public function getNickName(): string
{
return $this->name_nick;
}
public function getBirthdate(): string public function getBirthdate(): string
{ {
return $this->birthdate; return $this->birthdate;

View file

@ -0,0 +1,17 @@
<?php
/**
* The "Account" section of the users profile.
*/
namespace wishthis;
/**
* Account
*/
if (isset($_POST['account-delete'])) {
$user->delete();
$user->logOut();
redirect(Page::PAGE_HOME);
}

View file

@ -0,0 +1,34 @@
<?php
/**
* The "Password" section of the users profile.
*/
namespace wishthis;
if (
isset($_POST['user-password'])
&& isset($_POST['user-password-repeat'])
&& \strlen($_POST['user-password']) >= 8
&& \strlen($_POST['user-password-repeat']) >= 8
&& $_POST['user-password'] === $_POST['user-password-repeat']
) {
$password = User::passwordToHash($_POST['user-password']);
$database->query(
'UPDATE `users`
SET `password` = :password
WHERE `id` = :user_id',
array(
'password' => $password,
'user_id' => $userId,
)
);
$loginRequired = true;
$page->messages[] = Page::success(
__('Password updated.'),
__('Success')
);
}

View file

@ -0,0 +1,152 @@
<?php
/**
* The "Personal" section of the users profile.
*/
namespace wishthis;
/**
* Name (First)
*/
if (isset($_POST['user-name-first'])) {
$nameFirst = Sanitiser::sanitiseText($_POST['user-name-first']);
if ($nameFirst !== $user->getNameFirst()) {
$database->query(
'UPDATE `users`
SET `name_first` = :name_first
WHERE `id` = :user_id',
array(
'name_first' => $nameFirst,
'user_id' => $userId,
)
);
$user->setNameFirst($nameFirst);
$page->messages[] = Page::success(
sprintf(
/** TRANSLATORS: %s: The users first name. */
__('First name updated to "%s".'),
'<strong>' . $nameFirst . '</strong>'
),
__('Success')
);
}
}
/**
* Name (Last)
*/
if (isset($_POST['user-name-last'])) {
$nameLast = Sanitiser::sanitiseText($_POST['user-name-last']);
if ($nameLast !== $user->getNameLast()) {
$database->query(
'UPDATE `users`
SET `name_last` = :name_last
WHERE `id` = :user_id',
array(
'name_last' => $nameLast,
'user_id' => $userId,
)
);
$user->setNameLast($nameLast);
$page->messages[] = Page::success(
sprintf(
/** TRANSLATORS: %s: The users last name. */
__('Last name updated to "%s".'),
'<strong>' . $nameLast . '</strong>'
),
__('Success')
);
}
}
/**
* Name (Nick)
*/
if (isset($_POST['user-name-nick'])) {
$nameNick = Sanitiser::sanitiseText($_POST['user-name-nick']);
if ($nameNick !== $user->getNameNick()) {
$database->query(
'UPDATE `users`
SET `name_nick` = :name_nick
WHERE `id` = :user_id',
array(
'name_nick' => $nameNick,
'user_id' => $userId,
)
);
$user->setNameNick($nameNick);
$page->messages[] = Page::success(
sprintf(
/** TRANSLATORS: %s: The users nick name. */
__('Nick name updated to "%s".'),
'<strong>' . $nameNick . '</strong>'
),
__('Success')
);
}
}
/**
* Email
*/
if (isset($_POST['user-email'])) {
$email = Sanitiser::sanitiseEmail($_POST['user-email']);
if ($email !== $user->getEmail()) {
$database->query(
'UPDATE `users`
SET `email` = :email
WHERE `id` = :user_id',
array(
'email' => $email,
'user_id' => $userId,
)
);
$user->setEmail($email);
$page->messages[] = Page::success(
sprintf(
/** TRANSLATORS: %s: The users email address. */
__('Email address updated to "%s".'),
'<strong>' . $email . '</strong>'
),
__('Success')
);
}
}
/**
* Birthdate
*/
if (isset($_POST['user-birthdate'])) {
$birthdateTimestamp = \strtotime($_POST['user-birthdate']);
if (\is_int($birthdateTimestamp)) {
$birthdate = \date('Y-m-d', $birthdateTimestamp);
if ($birthdate !== $user->getBirthdate()) {
$database->query(
'UPDATE `users`
SET `birthdate` = :birthdate
WHERE `id` = :user_id',
array(
'birthdate' => $birthdate,
'user_id' => $userId,
)
);
$user->setBirthdate($birthdate);
}
}
}

View file

@ -0,0 +1,177 @@
<?php
/**
* The "Preferences" section of the users profile.
*/
namespace wishthis;
/**
* Language
*/
if (isset($_POST['user-language'])) {
$userLocale = $_POST['user-language'];
/**
* To do
*
* Verify the submitted locale actually exists.
*/
/** */
if ($userLocale !== $user->getLocale()) {
$database->query(
'UPDATE `users`
SET `language` = :language
WHERE `id` = :user_id',
array(
'language' => $userLocale,
'user_id' => $userId,
)
);
$user->setLocale($userLocale);
$page->messages[] = Page::success(
sprintf(
/** TRANSLATORS: %s: The users locale. */
__('Locale updated to "%s".'),
'<strong>' . $userLocale . '</strong>'
),
__('Success')
);
}
}
/**
* Currency
*/
if (isset($_POST['user-currency'])) {
$userCurrency = $_POST['user-currency'];
/**
* To do
*
* Verify the submitted currency actually exists.
*/
/** */
if ($userCurrency !== $user->getCurrency()) {
$database->query(
'UPDATE `users`
SET `currency` = :currency
WHERE `id` = :user_id',
array(
'currency' => $userCurrency,
'user_id' => $userId,
)
);
$user->setCurrency($userCurrency);
$page->messages[] = Page::success(
sprintf(
/** TRANSLATORS: %s: The users currency. */
__('Currency updated to "%s".'),
'<strong>' . $userCurrency . '</strong>'
),
__('Success')
);
}
}
/**
* Channel
*/
if (isset($_POST['user-channel'])) {
$userChannel = $_POST['user-channel'];
$channels = \defined('CHANNELS') ? \array_map(
function ($channel) {
return $channel['branch'] ?? '';
},
CHANNELS
)
: array();
if (\in_array($userChannel, $channels, true) && $userChannel !== $user->getChannel()) {
$database->query(
'UPDATE `users`
SET `channel` = :channel
WHERE `id` = :user_id',
array(
'channel' => $userChannel,
'user_id' => $userId,
)
);
$user->setChannel($userChannel);
$page->messages[] = Page::success(
sprintf(
/** TRANSLATORS: %s: The users channel. */
__('Channel updated to "%s".'),
'<strong>' . $userChannel . '</strong>'
),
__('Success')
);
}
if ('' === $userChannel && '' !== $user->getChannel()) {
$database->query(
'UPDATE `users`
SET `channel` = :channel
WHERE `id` = :user_id',
array(
'channel' => null,
'user_id' => $userId,
)
);
$user->setChannel($userChannel);
$page->messages[] = Page::success(
__('Channel has been reset.'),
__('Success')
);
}
}
/**
* Advertisements
*/
$userAdvertisements = isset($_POST['enable-advertisements']);
if ($userAdvertisements !== $user->getAdvertisements()) {
$database->query(
'UPDATE `users`
SET `advertisements` = :advertisements
WHERE `id` = :user_id',
array(
'advertisements' => $userAdvertisements,
'user_id' => $userId,
)
);
$user->setAdvertisements($userAdvertisements);
$page->messages[] = Page::success(
sprintf(
/** TRANSLATORS: %s: The users advertisements. */
__('Advertisements updated to "%s".'),
'<strong>' . $userAdvertisements ? 'True' : 'False' . '</strong>'
),
__('Success')
);
}
if ($loginRequired) {
session_destroy();
unset($_SESSION);
$page->messages[] = Page::warning(
__('Your account credentials have changed and you have been logged out. Please log in again.'),
__('Account credentials changed')
);
}

View file

@ -0,0 +1,22 @@
<?php
namespace wishthis;
if (!isset($_POST['section'])) {
return;
}
$loginRequired = false;
$userId = $user->getId();
require \sprintf(__DIR__ . '/profile-handle-post-%s.php', $_POST['section']);
if ($loginRequired) {
session_destroy();
unset($_SESSION);
$page->messages[] = Page::warning(
__('Your account credentials have changed and you have been logged out. Please log in again.'),
__('Account credentials changed')
);
}

View file

@ -11,173 +11,7 @@ namespace wishthis;
$page = new Page(__FILE__, __('Profile'), 1); $page = new Page(__FILE__, __('Profile'), 1);
$user = User::getCurrent(); $user = User::getCurrent();
if (isset($_POST['user-id'], $_POST['section'])) { require __DIR__ . '/profile-handle-post.php';
$set = array();
$formFieldsString = array(
array(
'column' => 'name_first',
'key' => 'user-name-first',
'label' => __('First name'),
),
array(
'column' => 'name_last',
'key' => 'user-name-last',
'label' => __('Last name'),
),
array(
'column' => 'name_nick',
'key' => 'user-name-nick',
'label' => __('Nickname'),
),
array(
'column' => 'email',
'key' => 'user-email',
'label' => __('Email'),
),
);
$loginRequired = false;
foreach ($formFieldsString as $field) {
if (!empty($_POST[$field['key']]) && $_POST[$field['key']] !== $user->{$field['column']}) {
$set[] = '`' . $field['column'] . '` = "' . $_POST[$field['key']] . '"';
$user->{$field['column']} = $_POST[$field['key']];
$page->messages[] = Page::success(
sprintf(
__('%s successfully updated!'),
'<strong>' . $field['label'] . '</strong>'
),
__('Success')
);
}
}
if (!empty($_POST['user-email']) && $_POST['user-email'] !== $user->getEmail()) {
$loginRequired = true;
}
/**
* Personal
*/
if (isset($_POST['user-birthdate'])) {
if (empty($_POST['user-birthdate'])) {
$user->setBirthdate('');
$set[] = '`birthdate` = NULL';
} else {
$user->setBirthdate($_POST['user-birthdate']);
$set[] = '`birthdate` = "' . $_POST['user-birthdate'] . '"';
}
}
/**
* Password
*/
if (
!empty($_POST['user-password'])
&& !empty($_POST['user-password-repeat'])
&& $_POST['user-password'] === $_POST['user-password-repeat']
) {
$set[] = '`password` = "' . User::passwordToHash($_POST['user-password']) . '"';
$loginRequired = true;
}
/**
* Preferences
*/
/** Language */
if (isset($_POST['user-language']) && $_POST['user-language'] !== $user->getLocale()) {
$user->setLocale($_POST['user-language']);
$set[] = '`language` = "' . $user->getLocale() . '"';
$page->messages[] = Page::success(
sprintf(
/** TRANSLATORS: %s: The new locale */
__('Language set to %s.'),
'<strong>' . $user->getLocale() . '</strong>'
),
__('Success')
);
}
/** Currency */
if (isset($_POST['user-currency']) && $_POST['user-currency'] !== $user->getLocale() && $_POST['user-currency'] !== $user->getCurrency()) {
$user->setCurrency($_POST['user-currency']);
$set[] = '`currency` = "' . $user->getCurrency() . '"';
$page->messages[] = Page::success(
sprintf(
/** TRANSLATORS: %s: The new locale */
__('Currency set to %s.'),
'<strong>' . $user->getCurrency() . '</strong>'
),
__('Success')
);
}
/** Channel */
if (isset($_POST['user-channel']) && $_POST['user-channel'] !== $user->getChannel()) {
if (empty($_POST['user-channel'])) {
$user->setChannel('');
$set[] = '`channel` = NULL';
} else {
$user->setChannel($_POST['user-channel']);
$set[] = '`channel` = "' . $_POST['user-channel'] . '"';
}
}
/** Advertisements */
if (isset($_POST['enable-advertisements'])) {
$user->setAdvertisements(true);
$set[] = '`advertisements` = TRUE';
} else {
$user->setAdvertisements(false);
$set[] = '`advertisements` = FALSE';
}
/** Save */
if ($set) {
$database
->query(
'UPDATE `users`
SET ' . implode(',', $set) . '
WHERE `id` = :user_id',
array(
'user_id' => Sanitiser::getNumber($_POST['user-id']),
)
);
}
if ($loginRequired) {
session_destroy();
unset($_SESSION);
$page->messages[] = Page::warning(
__('It is required for you to login again.'),
__('Success')
);
}
/**
* Account
*/
if (isset($_POST['account-delete'])) {
$user->delete();
$user->logOut();
redirect(Page::PAGE_HOME);
}
}
$page->header(); $page->header();
$page->bodyStart(); $page->bodyStart();
@ -218,26 +52,25 @@ $page->navigation();
<div class="ui segment"> <div class="ui segment">
<form class="ui form" method="POST"> <form class="ui form" method="POST">
<input type="hidden" name="user-id" value="<?= $user->getId() ?>" />
<input type="hidden" name="section" value="personal" /> <input type="hidden" name="section" value="personal" />
<div class="three fields"> <div class="three fields">
<div class="field"> <div class="field">
<label><?= __('First name') ?></label> <label><?= __('First name') ?></label>
<input type="text" name="user-name-first" value="<?= $user->getFirstName() ?>" /> <input type="text" name="user-name-first" value="<?= $user->getNameFirst() ?>" />
</div> </div>
<div class="field"> <div class="field">
<label><?= __('Last name') ?></label> <label><?= __('Last name') ?></label>
<input type="text" name="user-name-last" value="<?= $user->getLastName() ?>" /> <input type="text" name="user-name-last" value="<?= $user->getNameLast() ?>" />
</div> </div>
<div class="field"> <div class="field">
<label><?= __('Nickname') ?></label> <label><?= __('Nickname') ?></label>
<input type="text" name="user-name-nick" value="<?= $user->getNickName() ?>" /> <input type="text" name="user-name-nick" value="<?= $user->getNameNick() ?>" />
</div> </div>
</div> </div>
@ -284,20 +117,19 @@ $page->navigation();
<div class="ui segment"> <div class="ui segment">
<form class="ui form" method="POST"> <form class="ui form" method="POST">
<input type="hidden" name="user-id" value="<?= $user->getId() ?>" />
<input type="hidden" name="section" value="password" /> <input type="hidden" name="section" value="password" />
<div class="two fields"> <div class="two fields">
<div class="field"> <div class="field">
<label><?= __('Password') ?></label> <label><?= __('Password') ?></label>
<input type="password" name="user-password" autocomplete="new-password" /> <input type="password" name="user-password" placeholder="1234isnotarealpassword" autocomplete="new-password" />
</div> </div>
<div class="field"> <div class="field">
<label><?= __('Password (repeat)') ?></label> <label><?= __('Password (repeat)') ?></label>
<input type="password" name="user-password-repeat" autocomplete="new-password" /> <input type="password" name="user-password-repeat" placeholder="1234isnotarealpassword" autocomplete="new-password" />
</div> </div>
</div> </div>
@ -347,7 +179,6 @@ $page->navigation();
<div class="ui segment"> <div class="ui segment">
<form class="ui form" method="POST"> <form class="ui form" method="POST">
<input type="hidden" name="user-id" value="<?= $user->getId() ?>" />
<input type="hidden" name="section" value="preferences" /> <input type="hidden" name="section" value="preferences" />
<div class="two fields"> <div class="two fields">
@ -447,7 +278,6 @@ $page->navigation();
<div class="ui segment"> <div class="ui segment">
<form class="ui form" method="POST"> <form class="ui form" method="POST">
<input type="hidden" name="user-id" value="<?= $user->getId() ?>" />
<input type="hidden" name="section" value="preferences" /> <input type="hidden" name="section" value="preferences" />
<?php if (defined('CHANNELS') && is_array(CHANNELS)) { ?> <?php if (defined('CHANNELS') && is_array(CHANNELS)) { ?>
@ -512,7 +342,6 @@ $page->navigation();
<div class="ui segment"> <div class="ui segment">
<form class="ui form" method="POST"> <form class="ui form" method="POST">
<input type="hidden" name="user-id" value="<?= $user->getId() ?>" />
<input type="hidden" name="section" value="preferences" /> <input type="hidden" name="section" value="preferences" />
<div class="field"> <div class="field">
@ -559,7 +388,6 @@ $page->navigation();
<div class="ui segment"> <div class="ui segment">
<form class="ui form" method="POST"> <form class="ui form" method="POST">
<input type="hidden" name="user-id" value="<?= $user->getId() ?>" />
<input type="hidden" name="section" value="account" /> <input type="hidden" name="section" value="account" />
<div class="field"> <div class="field">