From fb69ca4470e634e8c82ead6068bd631d4379870f Mon Sep 17 00:00:00 2001
From: Greg Sarjeant <1686767+gsarjeant@users.noreply.github.com>
Date: Wed, 4 Jun 2025 21:06:29 -0400
Subject: [PATCH] Get setup working again.
---
.gitignore | 2 ++
config/init.php | 7 +++++
docker-compose.yml | 3 +-
{configs => http_config}/nginx/folder.conf | 0
{configs => http_config}/nginx/root.conf | 0
public/index.php | 8 ++---
.../AdminController/AdminController.php | 30 ++++++++++++------
src/Framework/Session/Session.php | 2 ++
src/Framework/Util/Util.php | 28 ++++++++++-------
src/Model/Config/Config.php | 31 ++++++++++++++-----
src/Model/User/User.php | 19 +++++++-----
templates/admin.php | 1 +
12 files changed, 91 insertions(+), 40 deletions(-)
create mode 100644 config/init.php
rename {configs => http_config}/nginx/folder.conf (100%)
rename {configs => http_config}/nginx/root.conf (100%)
diff --git a/.gitignore b/.gitignore
index ba19952..a8d3ba8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,5 @@
*.sqlite
*.txt
+
+init_complete
diff --git a/config/init.php b/config/init.php
new file mode 100644
index 0000000..1b4e9b5
--- /dev/null
+++ b/config/init.php
@@ -0,0 +1,7 @@
+ 'http://localhost',
+ 'base_path' => '/tkr/',
+];
diff --git a/docker-compose.yml b/docker-compose.yml
index f1b9afd..9694866 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -6,7 +6,7 @@ services:
- "80:80"
volumes:
- ./public:/var/www/html/tkr/public
- - ./configs/nginx/folder.conf:/etc/nginx/conf.d/default.conf
+ - ./http_config/nginx/folder.conf:/etc/nginx/conf.d/default.conf
depends_on:
- php
restart: unless-stopped
@@ -15,6 +15,7 @@ services:
image: php:8.2-fpm-alpine
container_name: php-fpm
volumes:
+ - ./config:/var/www/html/tkr/config
- ./public:/var/www/html/tkr/public
- ./src:/var/www/html/tkr/src
- ./storage:/var/www/html/tkr/storage
diff --git a/configs/nginx/folder.conf b/http_config/nginx/folder.conf
similarity index 100%
rename from configs/nginx/folder.conf
rename to http_config/nginx/folder.conf
diff --git a/configs/nginx/root.conf b/http_config/nginx/root.conf
similarity index 100%
rename from configs/nginx/root.conf
rename to http_config/nginx/root.conf
diff --git a/public/index.php b/public/index.php
index 07670b0..8a54d00 100644
--- a/public/index.php
+++ b/public/index.php
@@ -11,10 +11,10 @@ if (preg_match('/\.php$/', $path)) {
exit;
}
-// Define all the important paths
define('APP_ROOT', dirname(dirname(__FILE__)));
-define('SRC_DIR', APP_ROOT . '/src');
+// Define all the important paths
+define('SRC_DIR', APP_ROOT . '/src');
define('STORAGE_DIR', APP_ROOT . '/storage');
define('TEMPLATES_DIR', APP_ROOT . '/templates');
define('TICKS_DIR', STORAGE_DIR . '/ticks');
@@ -42,9 +42,9 @@ loadClasses();
// Everything's loaded. Now we can start ticking.
Util::confirm_setup();
+$config = Config::load();
Session::start();
Session::generateCsrfToken();
-$config = Config::load();
// Remove the base path from the URL
// and strip the trailing slash from the resulting route
@@ -92,7 +92,7 @@ $routeHandlers = [
['', 'HomeController'],
['', 'HomeController@handleTick', ['POST']],
['admin', 'AdminController'],
- ['admin', 'AdminController@save', ['POST']],
+ ['admin', 'AdminController@handleSave', ['POST']],
['login', 'AuthController@showLogin'],
['login', 'AuthController@handleLogin', ['POST']],
['logout', 'AuthController@handleLogout', ['GET', 'POST']],
diff --git a/src/Controller/AdminController/AdminController.php b/src/Controller/AdminController/AdminController.php
index 1c8dc84..9db62af 100644
--- a/src/Controller/AdminController/AdminController.php
+++ b/src/Controller/AdminController/AdminController.php
@@ -4,7 +4,7 @@ class AdminController extends Controller {
// render the admin page
public function index(){
$config = Config::load();
- $user = USER::load();
+ $user = User::load();
$vars = [
'user' => $user,
@@ -17,13 +17,15 @@ class AdminController extends Controller {
// POST handler
// save updated settings
public function handleSave(){
- //$isLoggedIn = isset($_SESSION['user_id']);
- if (!Session::isLoggedIn()){
- header('Location: ' . $config->basePath . 'login.php');
- exit;
+ $config = Config::load();
+
+ if (!Config::isFirstSetup()) {
+ if (!Session::isLoggedIn()){
+ header('Location: ' . $config->basePath . '/login');
+ exit;
+ }
}
- $config = Config::load();
$user = User::load();
// handle form submission
@@ -39,11 +41,11 @@ class AdminController extends Controller {
// Site settings
$siteTitle = trim($_POST['site_title']) ?? '';
$siteDescription = trim($_POST['site_description']) ?? '';
+ $baseUrl = trim($_POST['base_url'] ?? '');
$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'] ?? '';
@@ -54,6 +56,9 @@ class AdminController extends Controller {
if (!$displayName) {
$errors[] = "Display name is required.";
}
+ if (!$baseUrl) {
+ $errors[] = "Base URL is required.";
+ }
// Make sure the website looks like a URL and starts with a protocol
if ($website) {
if (!filter_var($website, FILTER_VALIDATE_URL)) {
@@ -63,7 +68,6 @@ class AdminController extends Controller {
}
}
-
// Validate site settings
if (!$siteTitle) {
$errors[] = "Site title is required.";
@@ -85,6 +89,7 @@ class AdminController extends Controller {
// Update site settings
$config->siteTitle = $siteTitle;
$config->siteDescription = $siteDescription;
+ $config->baseUrl = $baseUrl;
$config->basePath = $basePath;
$config->itemsPerPage = $itemsPerPage;
@@ -104,9 +109,16 @@ class AdminController extends Controller {
if($password){
$user->set_password($password);
}
+ } else {
+ echo implode(",", $errors);
+ exit;
}
}
+ if (Config::isFirstSetup()){
+ Config::completeSetup();
+ }
+
header('Location: ' . $config->basePath . '/admin');
exit;
}
diff --git a/src/Framework/Session/Session.php b/src/Framework/Session/Session.php
index 251aebf..bc02995 100644
--- a/src/Framework/Session/Session.php
+++ b/src/Framework/Session/Session.php
@@ -25,6 +25,8 @@ class Session {
}
public static function isLoggedIn(): bool {
+ //echo "User ID set: ". isset($_SESSION['user_id']). "
";
+ //exit;
return isset($_SESSION['user_id']);
}
diff --git a/src/Framework/Util/Util.php b/src/Framework/Util/Util.php
index fa8c3fe..8e1d9bf 100644
--- a/src/Framework/Util/Util.php
+++ b/src/Framework/Util/Util.php
@@ -68,10 +68,10 @@ class Util {
// Ensure required tables exist
$db->exec("CREATE TABLE IF NOT EXISTS user (
- id INTEGER PRIMARY KEY AUTOINCREMENT,
+ id INTEGER PRIMARY KEY,
username TEXT NOT NULL,
display_name TEXT NOT NULL,
- password_hash TEXT NOT NULL,
+ password_hash TEXT NULL,
about TEXT NULL,
website TEXT NULL,
mood TEXT NULL
@@ -81,6 +81,7 @@ class Util {
id INTEGER PRIMARY KEY,
site_title TEXT NOT NULL,
site_description TEXT NULL,
+ base_url TEXT NOT NULL,
base_path TEXT NOT NULL,
items_per_page INTEGER NOT NULL
)");
@@ -88,20 +89,24 @@ class Util {
// See if there's any data in the tables
$user_count = (int) $db->query("SELECT COUNT(*) FROM user")->fetchColumn();
$settings_count = (int) $db->query("SELECT COUNT(*) FROM settings")->fetchColumn();
+ $config = Config::load();
- // If either table has no records and we aren't on setup.php, redirect to setup.php
+ // If either table has no records and we aren't on /admin
if ($user_count === 0 || $settings_count === 0){
- if (basename($_SERVER['PHP_SELF']) !== 'setup.php'){
- header('Location: setup.php');
- exit;
- }
- } else {
- // If setup is complete and we are on setup.php, redirect to index.php.
- if (basename($_SERVER['PHP_SELF']) === 'setup.php'){
- header('Location: index.php');
+ if (basename($_SERVER['PHP_SELF']) !== 'admin'){
+ header('Location: ' . $config->basePath . 'admin');
exit;
}
};
+ /*
+ else {
+ // If setup is complete and we are on setup.php, redirect to index.php.
+ if (basename($_SERVER['PHP_SELF']) === 'admin'){
+ header('Location: ' . $config->basePath);
+ exit;
+ }
+ };
+ */
}
public static function tick_time_to_tick_path($tickTime){
@@ -115,7 +120,6 @@ class Util {
return "$year/$month/$day/$hour/$minute/$second";
}
- // TODO: Move to model base class?
public static function get_db(): PDO {
Util::verify_data_dir(DATA_DIR, true);
diff --git a/src/Model/Config/Config.php b/src/Model/Config/Config.php
index 9ad9e19..57cf594 100644
--- a/src/Model/Config/Config.php
+++ b/src/Model/Config/Config.php
@@ -3,21 +3,34 @@ class Config {
// properties and default values
public string $siteTitle = 'My tkr';
public string $siteDescription = '';
- public string $baseUrl = 'http://localhost'; //TODO - make this work
- public string $basePath = '/';
+ public string $baseUrl = '';
+ public string $basePath = '';
public int $itemsPerPage = 25;
public string $timezone = 'relative';
+ public static function isFirstSetup(): bool {
+ return !file_exists(STORAGE_DIR . '/init_complete');
+ }
+
+ public static function completeSetup(): void {
+ touch(STORAGE_DIR . '/init_complete');
+ }
+
// load config from sqlite database
public static function load(): self {
- $db = Util::get_db();
- $stmt = $db->query("SELECT site_title, site_description, base_path, items_per_page FROM settings WHERE id=1");
- $row = $stmt->fetch(PDO::FETCH_ASSOC);
+ $init = require APP_ROOT . '/config/init.php';
$c = new self();
+ $c->baseUrl = ($c->baseUrl === '') ? $init['base_url'] : $c->baseUrl;
+ $c->basePath = ($c->basePath === '') ? $init['base_path'] : $c->basePath;
+
+ $db = Util::get_db();
+ $stmt = $db->query("SELECT site_title, site_description, base_url, base_path, items_per_page FROM settings WHERE id=1");
+ $row = $stmt->fetch(PDO::FETCH_ASSOC);
if ($row) {
$c->siteTitle = $row['site_title'];
$c->siteDescription = $row['site_description'];
+ $c->baseUrl = $row['base_url'];
$c->basePath = $row['base_path'];
$c->itemsPerPage = (int) $row['items_per_page'];
}
@@ -28,8 +41,12 @@ class Config {
public function save(): self {
$db = Util::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]);
+ if (!Config::isFirstSetup()){
+ $stmt = $db->prepare("UPDATE settings SET site_title=?, site_description=?, base_url=?, base_path=?, items_per_page=? WHERE id=1");
+ } else {
+ $stmt = $db->prepare("INSERT INTO settings (id, site_title, site_description, base_url, base_path, items_per_page) VALUES (1, ?, ?, ?, ?, ?)");
+ }
+ $stmt->execute([$this->siteTitle, $this->siteDescription, $this->baseUrl, $this->basePath, $this->itemsPerPage]);
return self::load();
}
diff --git a/src/Model/User/User.php b/src/Model/User/User.php
index 59b31e9..e351ee0 100644
--- a/src/Model/User/User.php
+++ b/src/Model/User/User.php
@@ -1,11 +1,11 @@
displayName = $row['display_name'];
$u->about = $row['about'] ?? '';
$u->website = $row['website'] ?? '';
- $u->mood = $row['mood'];
+ $u->mood = $row['mood'] ?? '';
}
return $u;
@@ -30,7 +30,12 @@ class User {
public function save(): self {
$db = Util::get_db();
- $stmt = $db->prepare("UPDATE user SET username=?, display_name=?, about=?, website=?, mood=? WHERE id=1");
+ if (!Config::isFirstSetup()){
+ $stmt = $db->prepare("UPDATE user SET username=?, display_name=?, about=?, website=?, mood=? WHERE id=1");
+ } else {
+ $stmt = $db->prepare("INSERT INTO user (id, username, display_name, about, website, mood) VALUES (1, ?, ?, ?, ?, ?)");
+ }
+
$stmt->execute([$this->username, $this->displayName, $this->about, $this->website, $this->mood]);
return self::load();
diff --git a/templates/admin.php b/templates/admin.php
index 0ae2da5..71d12f8 100644
--- a/templates/admin.php
+++ b/templates/admin.php
@@ -23,6 +23,7 @@
+