diff --git a/.htaccess b/.htaccess
new file mode 100644
index 0000000..e2bbc23
--- /dev/null
+++ b/.htaccess
@@ -0,0 +1,18 @@
+DirectoryIndex index.php index.html
+Options -Indexes
+Options -MultiViews
+
+RewriteEngine On
+
+# 0) Serve existing files/directories as-is
+RewriteCond %{REQUEST_FILENAME} -f [OR]
+RewriteCond %{REQUEST_FILENAME} -d
+RewriteRule ^ - [L]
+
+# 1) Internal map: /page or /page/ -> /page.php (if such PHP file exists)
+RewriteCond %{REQUEST_FILENAME}.php -f
+RewriteRule ^(.+?)/?$ $1.php [L]
+
+# 2) Optional: strip trailing slash for non-directories (keeps .php links working)
+RewriteCond %{REQUEST_FILENAME} !-d
+RewriteRule ^(.+)/$ $1 [R=301,L]
diff --git a/.perm_test_apache b/.perm_test_apache
new file mode 100644
index 0000000..e69de29
diff --git a/.perm_test_exec b/.perm_test_exec
new file mode 100644
index 0000000..e69de29
diff --git a/admin_horses.php b/admin_horses.php
new file mode 100644
index 0000000..a9d3b49
--- /dev/null
+++ b/admin_horses.php
@@ -0,0 +1,158 @@
+prepare('INSERT INTO horses (name, breed, description, image_url) VALUES (?, ?, ?, ?)');
+ $stmt->execute([$name, $breed, $description, $image_url]);
+ $messages[] = 'Horse added successfully!';
+ } catch (PDOException $e) {
+ $errors[] = 'Database error: ' . $e->getMessage();
+ }
+ }
+}
+
+// Handle Delete Horse
+if (isset($_GET['action']) && $_GET['action'] === 'delete' && isset($_GET['id'])) {
+ $id = $_GET['id'];
+ try {
+ $pdo = db();
+ $stmt = $pdo->prepare('DELETE FROM horses WHERE id = ?');
+ $stmt->execute([$id]);
+ header('Location: admin_horses.php?deleted=true');
+ exit;
+ } catch (PDOException $e) {
+ $errors[] = 'Database error: ' . $e->getMessage();
+ }
+}
+
+// Fetch all horses
+$horses = [];
+try {
+ $pdo = db();
+ $stmt = $pdo->query('SELECT * FROM horses ORDER BY name');
+ $horses = $stmt->fetchAll();
+} catch (PDOException $e) {
+ $errors[] = 'Database error: ' . $e->getMessage();
+}
+
+?>
+
+
+
+
+
+ Admin: Manage Horses
+
+
+
+
+
+
Manage Horses
+
← Home
+
+
+
+
+
+
= htmlspecialchars($error) ?>
+
+
+
+
+
+
+
+
= htmlspecialchars($message) ?>
+
+
+
+
+
+
+
+
+
+
+
+
+ | Name |
+ Breed |
+ Actions |
+
+
+
+
+
+ | = htmlspecialchars($horse['name']) ?> |
+ = htmlspecialchars($horse['breed']) ?> |
+
+ Edit
+ Delete
+ |
+
+
+
+
+
+
+
+
+
+
diff --git a/apply_migrations.php b/apply_migrations.php
new file mode 100644
index 0000000..bee4757
--- /dev/null
+++ b/apply_migrations.php
@@ -0,0 +1,103 @@
+getMessage());
+}
+
+// --- Migration Setup ---
+$migrationsTable = 'migrations';
+$migrationsDir = __DIR__ . '/db/migrations/';
+
+// Create migrations table if it doesn't exist
+try {
+ $pdo->exec("CREATE TABLE IF NOT EXISTS `$migrationsTable` (
+ `id` INT AUTO_INCREMENT PRIMARY KEY,
+ `migration` VARCHAR(255) NOT NULL,
+ `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");
+} catch (PDOException $e) {
+ die("✘ Error creating migrations table: " . $e->getMessage());
+}
+
+// Get applied migrations
+$appliedMigrations = $pdo->query("SELECT `migration` FROM `$migrationsTable`")->fetchAll(PDO::FETCH_COLUMN);
+
+echo "Processing Migrations...\n";
+
+// --- Run Migrations ---
+$migrationFiles = glob($migrationsDir . '*.sql');
+sort($migrationFiles);
+
+$allGood = true;
+
+foreach ($migrationFiles as $file) {
+ $migrationName = basename($file);
+
+ if (in_array($migrationName, $appliedMigrations)) {
+ echo "[SKIPPED] Migration $migrationName has already been applied.\n";
+ continue;
+ }
+
+ echo "Applying migration: $migrationName... ";
+ $sql = file_get_contents($file);
+
+ try {
+ $pdo->exec($sql);
+
+ // Mark as applied
+ $stmt = $pdo->prepare("INSERT INTO `$migrationsTable` (`migration`) VALUES (?)");
+ $stmt->execute([$migrationName]);
+
+ echo "✔ Done.\n";
+
+ } catch (PDOException $e) {
+ $errorMessage = $e->getMessage();
+
+ // Check for non-critical errors to ignore and continue
+ $isDuplicateColumn = strpos($errorMessage, 'Duplicate column name') !== false;
+ $isDuplicateKey = strpos($errorMessage, 'Duplicate entry') !== false;
+ $isColumnNotFound = strpos($errorMessage, "Unknown column") !== false;
+ $isCantDropField = strpos($errorMessage, "Can't DROP COLUMN") !== false;
+
+ if ($isDuplicateColumn || $isDuplicateKey || $isColumnNotFound || $isCantDropField) {
+ $reason = "Already applied";
+ if ($isDuplicateColumn) $reason = "Duplicate Column";
+ if ($isDuplicateKey) $reason = "Duplicate Entry";
+ if ($isColumnNotFound) $reason = "Column Not Found (will be created later)";
+ if ($isCantDropField) $reason = "Column already dropped";
+
+ echo "✔ Skipped ($reason - marking as run).\n";
+ // Mark as applied even if it failed with a recoverable error
+ $stmt = $pdo->prepare("INSERT INTO `$migrationsTable` (`migration`) VALUES (?)");
+ $stmt->execute([$migrationName]);
+ } else {
+ echo "✘ Error applying $migrationName: " . $e->getMessage() . "\n";
+ $allGood = false;
+ // We will now continue instead of breaking
+ // break;
+ }
+ }
+}
+
+if ($allGood) {
+ echo "\n🎉 All migrations have been applied successfully!\n";
+} else {
+ echo "\nAn error occurred. Not all migrations could be applied. Please review the errors above.\n";
+}
+?>
\ No newline at end of file
diff --git a/assets/avatars/avatar_68c144c750ca28.40605127.jpg b/assets/avatars/avatar_68c144c750ca28.40605127.jpg
new file mode 100644
index 0000000..b456437
Binary files /dev/null and b/assets/avatars/avatar_68c144c750ca28.40605127.jpg differ
diff --git a/assets/avatars/avatar_68c294a6ed46f3.71986264.png b/assets/avatars/avatar_68c294a6ed46f3.71986264.png
new file mode 100644
index 0000000..0437cbb
Binary files /dev/null and b/assets/avatars/avatar_68c294a6ed46f3.71986264.png differ
diff --git a/assets/pasted-20250908-111644-f385b80e.png b/assets/pasted-20250908-111644-f385b80e.png
new file mode 100644
index 0000000..275efa9
Binary files /dev/null and b/assets/pasted-20250908-111644-f385b80e.png differ
diff --git a/assets/pasted-20250910-063752-96793b4f.jpg b/assets/pasted-20250910-063752-96793b4f.jpg
new file mode 100644
index 0000000..f139eca
Binary files /dev/null and b/assets/pasted-20250910-063752-96793b4f.jpg differ
diff --git a/assets/pasted-20250910-064336-512556d4.jpg b/assets/pasted-20250910-064336-512556d4.jpg
new file mode 100644
index 0000000..e9de2ed
Binary files /dev/null and b/assets/pasted-20250910-064336-512556d4.jpg differ
diff --git a/assets/pasted-20250910-065124-15fa0386.png b/assets/pasted-20250910-065124-15fa0386.png
new file mode 100644
index 0000000..e43732d
Binary files /dev/null and b/assets/pasted-20250910-065124-15fa0386.png differ
diff --git a/assets/pasted-20250910-070203-d672ef9e.jpg b/assets/pasted-20250910-070203-d672ef9e.jpg
new file mode 100644
index 0000000..9d3ef06
Binary files /dev/null and b/assets/pasted-20250910-070203-d672ef9e.jpg differ
diff --git a/assets/pasted-20250910-071615-9ca92360.png b/assets/pasted-20250910-071615-9ca92360.png
new file mode 100644
index 0000000..e4699fa
Binary files /dev/null and b/assets/pasted-20250910-071615-9ca92360.png differ
diff --git a/assets/pasted-20250910-163439-bde803a6.png b/assets/pasted-20250910-163439-bde803a6.png
new file mode 100644
index 0000000..43d2026
Binary files /dev/null and b/assets/pasted-20250910-163439-bde803a6.png differ
diff --git a/db/migrations/001_create_users_table.sql b/db/migrations/001_create_users_table.sql
new file mode 100644
index 0000000..3ea25e0
--- /dev/null
+++ b/db/migrations/001_create_users_table.sql
@@ -0,0 +1,8 @@
+CREATE TABLE IF NOT EXISTS `users` (
+ `id` INT AUTO_INCREMENT PRIMARY KEY,
+ `username` VARCHAR(50) NOT NULL UNIQUE,
+ `email` VARCHAR(100) NOT NULL UNIQUE,
+ `password` VARCHAR(255) NOT NULL,
+ `role` ENUM('client', 'instructor', 'manager', 'admin') NOT NULL DEFAULT 'client',
+ `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
diff --git a/db/migrations/002_create_horses_table.sql b/db/migrations/002_create_horses_table.sql
new file mode 100644
index 0000000..c132373
--- /dev/null
+++ b/db/migrations/002_create_horses_table.sql
@@ -0,0 +1,8 @@
+CREATE TABLE IF NOT EXISTS `horses` (
+ `id` INT AUTO_INCREMENT PRIMARY KEY,
+ `name` VARCHAR(100) NOT NULL,
+ `breed` VARCHAR(100) NOT NULL,
+ `description` TEXT,
+ `image_url` VARCHAR(255),
+ `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
diff --git a/db/migrations/003_seed_horses_table.sql b/db/migrations/003_seed_horses_table.sql
new file mode 100644
index 0000000..21bc4de
--- /dev/null
+++ b/db/migrations/003_seed_horses_table.sql
@@ -0,0 +1,4 @@
+INSERT INTO `horses` (`name`, `breed`, `description`, `image_url`) VALUES
+('Spirit', 'Mustang', 'A wild and free-spirited stallion.', 'https://via.placeholder.com/300x200.png?text=Spirit'),
+('Black Beauty', 'American Quarter Horse', 'A handsome and gentle horse with a black coat.', 'https://via.placeholder.com/300x200.png?text=Black+Beauty'),
+('Joey', 'Thoroughbred', 'A brave and loyal horse who served in World War I.', 'https://via.placeholder.com/300x200.png?text=Joey');
diff --git a/db/migrations/004_add_role_to_users.sql b/db/migrations/004_add_role_to_users.sql
new file mode 100644
index 0000000..ee3f83c
--- /dev/null
+++ b/db/migrations/004_add_role_to_users.sql
@@ -0,0 +1 @@
+ALTER TABLE `users` ADD `role` VARCHAR(50) NOT NULL DEFAULT 'client' AFTER `password`;
\ No newline at end of file
diff --git a/db/migrations/005_fix_role_column_length.sql b/db/migrations/005_fix_role_column_length.sql
new file mode 100644
index 0000000..650625e
--- /dev/null
+++ b/db/migrations/005_fix_role_column_length.sql
@@ -0,0 +1 @@
+ALTER TABLE users MODIFY role VARCHAR(255) NOT NULL;
\ No newline at end of file
diff --git a/db/migrations/006_add_profile_fields_to_users.sql b/db/migrations/006_add_profile_fields_to_users.sql
new file mode 100644
index 0000000..dce9f6e
--- /dev/null
+++ b/db/migrations/006_add_profile_fields_to_users.sql
@@ -0,0 +1,6 @@
+ALTER TABLE `users`
+ADD COLUMN `first_name` VARCHAR(255) NULL,
+ADD COLUMN `last_name` VARCHAR(255) NULL,
+ADD COLUMN `avatar` VARCHAR(255) NULL,
+ADD COLUMN `phone_number` VARCHAR(255) NULL,
+ADD COLUMN `rider_level` VARCHAR(255) NULL;
diff --git a/db/migrations/007_add_disciplines_to_horses.sql b/db/migrations/007_add_disciplines_to_horses.sql
new file mode 100644
index 0000000..b345231
--- /dev/null
+++ b/db/migrations/007_add_disciplines_to_horses.sql
@@ -0,0 +1 @@
+ALTER TABLE horses ADD COLUMN disciplines VARCHAR(255) NULL;
diff --git a/db/migrations/008_update_horses_with_disciplines_and_new_horse.sql b/db/migrations/008_update_horses_with_disciplines_and_new_horse.sql
new file mode 100644
index 0000000..847b513
--- /dev/null
+++ b/db/migrations/008_update_horses_with_disciplines_and_new_horse.sql
@@ -0,0 +1,9 @@
+-- Update existing horses with disciplines
+UPDATE horses SET disciplines = 'Show Jumping' WHERE name = 'Bucephalus';
+UPDATE horses SET disciplines = 'Dressage' WHERE name = 'Pegasus';
+UPDATE horses SET disciplines = 'Cross-country' WHERE name = 'Shadowfax';
+UPDATE horses SET disciplines = 'Racing' WHERE name = 'Rocinante';
+
+-- Add a new horse with the provided image, age
+INSERT INTO horses (name, breed, age, disciplines, image_path) VALUES
+('Apollo', 'Friesian', 8, 'Carriage Driving', 'assets/avatars/apollo.jpg');
\ No newline at end of file
diff --git a/db/migrations/009_update_first_horse_to_diesel.sql b/db/migrations/009_update_first_horse_to_diesel.sql
new file mode 100644
index 0000000..01d8307
--- /dev/null
+++ b/db/migrations/009_update_first_horse_to_diesel.sql
@@ -0,0 +1,7 @@
+UPDATE horses
+SET
+ name = 'Diesel',
+ breed = 'бурая',
+ disciplines = 'конкур'
+WHERE
+ id = 1;
diff --git a/db/migrations/010_fix_horses_table_schema.sql b/db/migrations/010_fix_horses_table_schema.sql
new file mode 100644
index 0000000..20b8e1e
--- /dev/null
+++ b/db/migrations/010_fix_horses_table_schema.sql
@@ -0,0 +1,6 @@
+-- Add age and image_path columns, and remove unused columns from the horses table.
+ALTER TABLE `horses`
+ADD COLUMN `age` INT NULL AFTER `breed`,
+ADD COLUMN `image_path` VARCHAR(255) NULL AFTER `disciplines`,
+DROP COLUMN `description`,
+DROP COLUMN `image_url`;
diff --git a/db/migrations/011_add_age_and_image_path_to_horses.sql b/db/migrations/011_add_age_and_image_path_to_horses.sql
new file mode 100644
index 0000000..12d5f44
--- /dev/null
+++ b/db/migrations/011_add_age_and_image_path_to_horses.sql
@@ -0,0 +1,5 @@
+-- Add age and image_path columns, and remove unused columns from the horses table.
+ALTER TABLE `horses`
+ADD COLUMN `age` INT NULL AFTER `breed`,
+ADD COLUMN `image_path` VARCHAR(255) NULL AFTER `disciplines`,
+DROP COLUMN `image_url`;
diff --git a/edit_horse.php b/edit_horse.php
new file mode 100644
index 0000000..0c77e6c
--- /dev/null
+++ b/edit_horse.php
@@ -0,0 +1,111 @@
+prepare('UPDATE horses SET name = ?, breed = ?, description = ?, image_url = ? WHERE id = ?');
+ $stmt->execute([$name, $breed, $description, $image_url, $horse_id]);
+ header('Location: admin_horses.php?edited=true');
+ exit;
+ } catch (PDOException $e) {
+ $errors[] = 'Database error: ' . $e->getMessage();
+ }
+ }
+}
+
+// Fetch the horse
+try {
+ $pdo = db();
+ $stmt = $pdo->prepare('SELECT * FROM horses WHERE id = ?');
+ $stmt->execute([$horse_id]);
+ $horse = $stmt->fetch();
+ if (!$horse) {
+ header('Location: admin_horses.php');
+ exit;
+ }
+} catch (PDOException $e) {
+ $errors[] = 'Database error: ' . $e->getMessage();
+}
+
+?>
+
+
+
+
+
+ Admin: Edit Horse
+
+
+
+
+
+
Edit Horse: = htmlspecialchars($horse['name']) ?>
+
← Back to Manage Horses
+
+
+
+
+
+
= htmlspecialchars($error) ?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/horses.php b/horses.php
new file mode 100644
index 0000000..e75ee7d
--- /dev/null
+++ b/horses.php
@@ -0,0 +1,213 @@
+query("SELECT name, breed, image_path FROM horses");
+ $horses = $stmt->fetchAll();
+} catch (PDOException $e) {
+ $horses = [];
+ $error_message = "Database error: " . $e->getMessage();
+}
+
+?>
+
+
+
+
+
+ Horses
+
+
+
+
+
+
+
+
+
= htmlspecialchars($_SESSION['flash_message']) ?>
+
+
+
+
+
+ Our Horses
+
+ = htmlspecialchars($error_message) ?>
+
+ No horses found.
+
+
+
+
+
+
![<?= htmlspecialchars($horse['name']) ?>](<?= htmlspecialchars($horse['image_path']) ?>)
+
+
= htmlspecialchars($horse['name']) ?>
+
+
+
+
Breed: = htmlspecialchars($horse['breed']) ?>
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/index.php b/index.php
index 57f953e..f3829c9 100644
--- a/index.php
+++ b/index.php
@@ -1,131 +1,4 @@
-
-
-
-
-
- New Style
-
-
-
-
-
-
-
-
-
Preparing Your Working Environment…
-
- Loading…
-
-
Flatlogic AI is collecting your requirements and applying the first changes.
-
This page will update automatically as the plan is implemented.
-
Runtime: PHP = htmlspecialchars($phpVersion) ?> — UTC = htmlspecialchars($now) ?>
-
-
-
-
-
+// Redirect to the login page
+header('Location: login.php');
+exit;
\ No newline at end of file
diff --git a/login.php b/login.php
new file mode 100644
index 0000000..a79e10b
--- /dev/null
+++ b/login.php
@@ -0,0 +1,324 @@
+prepare("SELECT id FROM users WHERE username = ? OR email = ?");
+ $stmt->execute([$username, $email]);
+ if ($stmt->fetch()) {
+ $errors[] = 'Username or email already exists.';
+ } else {
+ $stmt = $pdo->query("SELECT id FROM users LIMIT 1");
+ $role = ($stmt->fetch()) ? 'client' : 'administrator';
+
+ $hashedPassword = password_hash($password, PASSWORD_DEFAULT);
+ $stmt = $pdo->prepare("INSERT INTO users (username, email, password, role) VALUES (?, ?, ?, ?)");
+ $stmt->execute([$username, $email, $hashedPassword, $role]);
+ $messages[] = 'Registration successful! Please log in.';
+ }
+ } catch (PDOException $e) {
+ error_log("Signup Error: " . $e->getMessage());
+ $errors[] = 'A database error occurred during registration.';
+ }
+ }
+ }
+
+ // Handle login
+ if ($_POST['action'] === 'login') {
+ $login = $_POST['login'] ?? '';
+ $password = $_POST['password'] ?? '';
+
+ if (empty($login) || empty($password)) {
+ $errors[] = 'Please provide your login and password.';
+ } else {
+ try {
+ $pdo = db();
+ $stmt = $pdo->prepare("SELECT * FROM users WHERE email = ? OR username = ?");
+ $stmt->execute([$login, $login]);
+ $user = $stmt->fetch();
+
+ if ($user && password_verify($password, $user['password'])) {
+ $_SESSION['user_id'] = $user['id'];
+ $_SESSION['username'] = $user['username'];
+ $_SESSION['role'] = $user['role'];
+ $_SESSION['flash_message'] = 'Welcome back! You have successfully logged in.';
+
+ session_write_close();
+ header("Location: horses.php");
+ exit;
+ } else {
+ $errors[] = 'Invalid login credentials.';
+ }
+ } catch (PDOException $e) {
+ error_log("Login Error: " . $e->getMessage());
+ $errors[] = 'A database error occurred during login.';
+ }
+ }
+ }
+}
+
+// The rest of the file is for display purposes only if no redirect has happened.
+$now = date('Y-m-d H:i:s');
+?>
+
+
+
+
+
+ Login / Sign Up
+
+
+
+
+
+
+
+
+
+
Login
+
+
Don't have an account? Sign up
+
+
+
Sign Up
+
+
Already have an account? Log in
+
+
+
+
+
+
= htmlspecialchars($error) ?>
+
+
+
+
+
+
+
= htmlspecialchars($message) ?>
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/logout.php b/logout.php
new file mode 100644
index 0000000..f83284d
--- /dev/null
+++ b/logout.php
@@ -0,0 +1,6 @@
+prepare('SELECT * FROM users WHERE id = ?');
+ $stmt->execute([$userId]);
+ $user = $stmt->fetch();
+ if (!$user) {
+ session_destroy();
+ header('Location: login.php');
+ exit;
+ }
+} catch (PDOException $e) {
+ die('Could not fetch user data: ' . $e->getMessage());
+}
+
+// Handle profile update
+if ($_SERVER['REQUEST_METHOD'] === 'POST') {
+ $firstName = trim($_POST['first_name'] ?? '');
+ $lastName = trim($_POST['last_name'] ?? '');
+ $email = trim($_POST['email'] ?? '');
+ $phoneNumber = trim($_POST['phone_number'] ?? '');
+ $riderLevel = trim($_POST['rider_level'] ?? '');
+ $avatarPath = $user['avatar'] ?? ''; // Start with existing avatar
+
+ // --- Validation ---
+ if (empty($firstName)) {
+ $errors['first_name'] = 'First name is required.';
+ }
+
+ if (empty($lastName)) {
+ $errors['last_name'] = 'Last name is required.';
+ }
+
+ if (empty($email)) {
+ $errors['email'] = 'Email is required.';
+ } elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
+ $errors['email'] = 'Please enter a valid email address.';
+ }
+
+ // Handle avatar upload
+ if (isset($_FILES['avatar']) && $_FILES['avatar']['error'] === UPLOAD_ERR_OK) {
+ $uploadDir = 'assets/avatars/';
+ if (!is_dir($uploadDir)) {
+ if (!mkdir($uploadDir, 0755, true)) {
+ $errors['avatar'] = 'Failed to create avatar directory.';
+ }
+ }
+
+ if (!isset($errors['avatar'])) {
+ $avatarTmpPath = $_FILES['avatar']['tmp_name'];
+ $avatarName = basename($_FILES['avatar']['name']);
+ $avatarSize = $_FILES['avatar']['size'];
+ $avatarExtension = strtolower(pathinfo($avatarName, PATHINFO_EXTENSION));
+ $allowedExtensions = ['jpg', 'jpeg', 'png'];
+ $maxFileSize = 2 * 1024 * 1024; // 2 MB
+
+ if (!in_array($avatarExtension, $allowedExtensions)) {
+ $errors['avatar'] = 'Invalid file type. Only JPG and PNG are allowed.';
+ } elseif ($avatarSize > $maxFileSize) {
+ $errors['avatar'] = 'File is too large. Maximum size is 2MB.';
+ } else {
+ $safeAvatarName = uniqid('avatar_', true) . '.' . $avatarExtension;
+ $newAvatarPath = $uploadDir . $safeAvatarName;
+
+ if (move_uploaded_file($avatarTmpPath, $newAvatarPath)) {
+ // Remove the old avatar if it exists and is not a default one
+ if (!empty($avatarPath) && file_exists($avatarPath)) {
+ unlink($avatarPath);
+ }
+ $avatarPath = $newAvatarPath; // Set new path for DB update
+ } else {
+ $errors['avatar'] = 'Failed to upload new avatar.';
+ }
+ }
+ }
+ }
+
+ // Phone number validation
+ if (!empty($phoneNumber)) {
+ $numericPhoneNumber = preg_replace('/[^0-9]/', '', $phoneNumber);
+ if (strlen($numericPhoneNumber) < 7) {
+ $errors['phone_number'] = 'Phone number must be at least 7 digits.';
+ } else {
+ $phoneNumber = $numericPhoneNumber; // Use the sanitized number
+ }
+ }
+
+ if (empty($errors)) {
+ try {
+ $stmt = $pdo->prepare(
+ 'UPDATE users SET first_name = ?, last_name = ?, email = ?, phone_number = ?, rider_level = ?, avatar = ? WHERE id = ?'
+ );
+ $stmt->execute([$firstName, $lastName, $email, $phoneNumber, $riderLevel, $avatarPath, $userId]);
+ $messages[] = 'Profile updated successfully!';
+ // Refresh user data after successful update
+ $stmt = $pdo->prepare('SELECT * FROM users WHERE id = ?');
+ $stmt->execute([$userId]);
+ $user = $stmt->fetch();
+
+ } catch (PDOException $e) {
+ error_log("Profile Update Error: " . $e->getMessage());
+ $errors['db'] = 'Error updating profile. Please try again.';
+ }
+ }
+}
+
+// On a failed POST, user data should come from POST, otherwise from DB
+$displayData = [
+ 'first_name' => $_POST['first_name'] ?? $user['first_name'],
+ 'last_name' => $_POST['last_name'] ?? $user['last_name'],
+ 'email' => $_POST['email'] ?? $user['email'],
+ 'phone_number' => $_POST['phone_number'] ?? $user['phone_number'],
+ 'rider_level' => $_POST['rider_level'] ?? $user['rider_level'],
+ 'avatar' => $user['avatar']
+];
+
+?>
+
+
+
+
+
+ User Profile
+
+
+
+
+
+
+ Back to Horses
+
+
+
Edit Profile
+
+
+
+
+
+
+
+
= htmlspecialchars($errors['db']) ?>
+
+
+
= htmlspecialchars($message) ?>
+
+
+
+
+
+
\ No newline at end of file