From f3ac806c4bbcac904cd98153122af26552db0168 Mon Sep 17 00:00:00 2001 From: Greg Sarjeant <1686767+gsarjeant@users.noreply.github.com> Date: Thu, 29 May 2025 17:16:12 -0400 Subject: [PATCH] Add admin page --- tkr/lib/config.php | 16 +++++- tkr/lib/user.php | 50 ++++++++++++++++++ tkr/public/admin.php | 121 +++++++++++++++++++++++++++++++++++++++++++ tkr/public/index.php | 2 +- tkr/public/setup.php | 1 + 5 files changed, 188 insertions(+), 2 deletions(-) create mode 100644 tkr/lib/user.php create mode 100644 tkr/public/admin.php diff --git a/tkr/lib/config.php b/tkr/lib/config.php index 4d998f0..9aab040 100644 --- a/tkr/lib/config.php +++ b/tkr/lib/config.php @@ -28,4 +28,18 @@ class Config { return $c; } -} \ No newline at end of file + + public function save(): self { + $db = get_db(); + + $stmt = $db->prepare("UPDATE settings SET site_title=?, site_description=?, base_path=?, items_per_page=? WHERE id=1"); + $stmt->execute([$this->siteTitle, $this->siteDescription, $this->basePath, $this->itemsPerPage]); + + return self::load(); + } + + // I'm making this + public function setPassword(){ + + } +} diff --git a/tkr/lib/user.php b/tkr/lib/user.php new file mode 100644 index 0000000..cfa0379 --- /dev/null +++ b/tkr/lib/user.php @@ -0,0 +1,50 @@ +query("SELECT username, display_name, mood FROM user WHERE id=1"); + $row = $stmt->fetch(PDO::FETCH_ASSOC); + $u = new self(); + + if ($row) { + $u->username = $row['username']; + $u->displayName = $row['display_name']; + $u->mood = $row['mood']; + } + + return $u; + } + + public function save(): self { + $db = get_db(); + + $stmt = $db->prepare("UPDATE user SET username=?, display_name=?, mood=? WHERE id=1"); + $stmt->execute([$this->username, $this->displayName, $this->mood]); + + return self::load(); + } + + // Making this a separate function to avoid + // loading the password into memory + public function set_password(string $password): void { + $db = get_db(); + + $hash = password_hash($password, PASSWORD_DEFAULT); + $stmt = $db->prepare("UPDATE user SET password_hash=? WHERE id=1"); + $stmt->execute([$hash]); + } +} diff --git a/tkr/public/admin.php b/tkr/public/admin.php new file mode 100644 index 0000000..6ad61de --- /dev/null +++ b/tkr/public/admin.php @@ -0,0 +1,121 @@ +basePath . 'login.php'); +} + +require LIB_ROOT . '/user.php'; + +$config = Config::load(); +$user = User::load(); + +// handle form submission +if ($_SERVER['REQUEST_METHOD'] === 'POST') { + $errors = []; + + // User profile + $username = trim($_POST['username'] ?? ''); + $displayName = trim($_POST['display_name'] ?? ''); + // Site settings + $siteTitle = trim($_POST['site_title']) ?? ''; + $siteDescription = trim($_POST['site_description']) ?? ''; + $basePath = trim($_POST['base_path'] ?? '/'); + $itemsPerPage = (int) ($_POST['items_per_page'] ?? 25); + // Password + // TODO - Make sure I really shouldn't trim these + // (I'm assuming there may be people who end their password with a space character) + $password = $_POST['password'] ?? ''; + $confirmPassword = $_POST['confirm_password'] ?? ''; + + // Validate user profile + if (!$username) { + $errors[] = "Username is required."; + } + if (!$displayName) { + $errors[] = "Display name is required."; + } + + // Validate site settings + if (!$siteTitle) { + $errors[] = "Site title is required."; + } + if (!preg_match('#^/[^?<>:"|\\*]*$#', $basePath)) { + $errors[] = "Base path must look like a valid URL path (e.g. / or /tkr/)."; + } + if ($itemsPerPage < 1 || $itemsPerPage > 50) { + $errors[] = "Items per page must be a number between 1 and 50."; + } + + // If a password was sent, make sure it matches the confirmation + if ($password && !($password = $confirmPassword)){ + $errors[] = "Passwords do not match"; + } + + // TODO: Actually handle errors + if (empty($errors)) { + // Update site settings + $config->siteTitle = $siteTitle; + $config->siteDescription = $siteDescription; + $config->basePath = $basePath; + $config->itemsPerPage = $itemsPerPage; + + // Save site settings and reload config from database + $config = $config->save(); + + // Update user profile + $user->username = $username; + $user->displayName = $displayName; + + // Save user profile and reload user from database + $user = $user->save(); + + // Update the password if one was sent + if($password){ + $user->set_password($password); + } + } +} + +?> + + + + + <?= $config->siteTitle ?> + + + + + +

Admin

+
Back to home
+
+
+
+ User settings +
+
+
+
+ Site settings +
+
+
+
+
+
+ Change password +
+
+
+ +
+
+ + \ No newline at end of file diff --git a/tkr/public/index.php b/tkr/public/index.php index c7c7c56..735a943 100644 --- a/tkr/public/index.php +++ b/tkr/public/index.php @@ -53,7 +53,7 @@ $ticks = iterator_to_array(stream_ticks($limit, $offset));

Current mood: | Set your mood

-

Logout

+

Admin | Logout

diff --git a/tkr/public/setup.php b/tkr/public/setup.php index 479f91b..e6bb6a5 100644 --- a/tkr/public/setup.php +++ b/tkr/public/setup.php @@ -39,6 +39,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { $errors[] = "Items per page must be a number between 1 and 50."; } + // TODO: Actually handle errors if (empty($errors)) { $hash = password_hash($password, PASSWORD_DEFAULT);