This commit is contained in:
Flatlogic Bot 2026-01-22 07:43:24 +00:00
parent 73e14b3353
commit cdb0630e5e
4 changed files with 151 additions and 86 deletions

View File

@ -1,17 +1,51 @@
<?php <?php
// Generated by setup_mariadb_project.sh — edit as needed. // db/config.php
define('DB_HOST', '127.0.0.1'); // Database configuration with fallback for XAMPP/Localhost
define('DB_NAME', 'app_37650');
define('DB_USER', 'app_37650'); // 1. Try environment variables (for Cloud/VM environments)
define('DB_PASS', '4edb6fac-49c4-44d0-9b3e-6c6f933a7200'); $db_host = getenv('DB_HOST');
$db_name = getenv('DB_NAME');
$db_user = getenv('DB_USER');
$db_pass = getenv('DB_PASS');
// 2. Fallback to XAMPP defaults if not set
if ($db_host === false) $db_host = 'localhost';
if ($db_name === false) $db_name = 'car_dealership';
if ($db_user === false) $db_user = 'root';
if ($db_pass === false) $db_pass = ''; // Default XAMPP password is empty
// Define constants if not already defined
if (!defined('DB_HOST')) define('DB_HOST', $db_host);
if (!defined('DB_NAME')) define('DB_NAME', $db_name);
if (!defined('DB_USER')) define('DB_USER', $db_user);
if (!defined('DB_PASS')) define('DB_PASS', $db_pass);
function db() { function db() {
static $pdo; static $pdo;
if (!$pdo) { if (!$pdo) {
$pdo = new PDO('mysql:host='.DB_HOST.';dbname='.DB_NAME.';charset=utf8mb4', DB_USER, DB_PASS, [ try {
$dsn = 'mysql:host='.DB_HOST.';dbname='.DB_NAME.';charset=utf8mb4';
$pdo = new PDO($dsn, DB_USER, DB_PASS, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
]); ]);
} catch (PDOException $e) {
// Special handling: If database not found, try connecting without DB name
// This is useful for the installer script to create the DB
if ($e->getCode() == 1049) { // Unknown database
$dsn_no_db = 'mysql:host='.DB_HOST.';charset=utf8mb4';
try {
$pdo = new PDO($dsn_no_db, DB_USER, DB_PASS, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
]);
} catch (PDOException $ex) {
die("Database connection failed: " . $ex->getMessage());
}
} else {
die("Database connection failed: " . $e->getMessage());
}
}
} }
return $pdo; return $pdo;
} }

View File

@ -1,40 +1,65 @@
<?php <?php
// setup_project.php // install.php
// This script sets up the database tables and data as per the requirements. // Single installation file to set up the project on Windows (XAMPP) or Linux.
require_once 'includes/functions.php'; require_once 'db/config.php';
try { // Disable output buffering to show progress in real-time
$pdo = db(); if (function_exists('apache_setenv')) {
echo "Database connection established.\n"; @apache_setenv('no-gzip', 1);
} catch (PDOException $e) {
die("Database connection failed: " . $e->getMessage() . "\n");
} }
@ini_set('zlib.output_compression', 0);
@ini_set('implicit_flush', 1);
for ($i = 0; $i < ob_get_level(); $i++) { ob_end_flush(); }
ob_implicit_flush(1);
echo "<!DOCTYPE html><html><head><title>Installation</title><style>body{font-family: sans-serif; padding: 20px; line-height: 1.6;} .success{color: green;} .error{color: red;} .step{margin-bottom: 10px;}</style></head><body>";
echo "<h1>Car Sells in Afghanistan - Installation</h1>";
try { try {
// 2. Drop existing tables to ensure a clean state // 1. Connect to Database Server
$pdo->exec("SET FOREIGN_KEY_CHECKS=0"); $pdo = db();
$pdo->exec("DROP TABLE IF EXISTS reviews"); echo "<div class='step success'>✅ Connected to Database Server.</div>";
$pdo->exec("DROP TABLE IF EXISTS bookings");
$pdo->exec("DROP TABLE IF EXISTS cars");
$pdo->exec("DROP TABLE IF EXISTS users");
$pdo->exec("SET FOREIGN_KEY_CHECKS=1");
echo "Existing tables dropped.\n";
// 3. Create tables // 2. Create Database (if it doesn't exist)
// Note: On some hosting/VMs, the user might not have permission to create databases, only tables.
// We try to create it if we are 'root' or similar, but otherwise assume it exists if connection worked.
$dbName = DB_NAME;
try {
$pdo->exec("CREATE DATABASE IF NOT EXISTS `$dbName` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci");
echo "<div class='step success'>✅ Database `$dbName` checked/created.</div>";
} catch (PDOException $e) {
// Ignore if we can't create DB (might already be connected to it)
echo "<div class='step'> Note: Could not create database (might already exist or permission denied). Proceeding...</div>";
}
// Select the database
$pdo->exec("USE `$dbName`");
// 3. Drop existing tables (Clean Install)
$pdo->exec("SET FOREIGN_KEY_CHECKS=0");
$tables = ['reviews', 'bookings', 'cars', 'users'];
foreach ($tables as $table) {
$pdo->exec("DROP TABLE IF EXISTS `$table`");
}
$pdo->exec("SET FOREIGN_KEY_CHECKS=1");
echo "<div class='step success'>✅ Existing tables dropped (Clean Install).</div>";
// 4. Create Tables
// Users Table // Users Table
$pdo->exec(" CREATE TABLE users ( $pdo->exec("CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY, id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) UNIQUE NOT NULL, username VARCHAR(50) UNIQUE NOT NULL,
email VARCHAR(100) UNIQUE NOT NULL,
password VARCHAR(255) NOT NULL, password VARCHAR(255) NOT NULL,
role VARCHAR(20) DEFAULT 'user', role VARCHAR(20) DEFAULT 'user',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)"); )");
echo "Users table ready.\n"; echo "<div class='step success'>✅ Table `users` created.</div>";
// Cars Table // Cars Table
$pdo->exec(" CREATE TABLE cars ( $pdo->exec("CREATE TABLE cars (
id INT AUTO_INCREMENT PRIMARY KEY, id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NULL, user_id INT NULL,
title VARCHAR(255) NULL, title VARCHAR(255) NULL,
@ -52,10 +77,10 @@ try {
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE SET NULL FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE SET NULL
)"); )");
echo "Cars table ready.\n"; echo "<div class='step success'>✅ Table `cars` created.</div>";
// Bookings Table // Bookings Table
$pdo->exec(" CREATE TABLE bookings ( $pdo->exec("CREATE TABLE bookings (
id INT AUTO_INCREMENT PRIMARY KEY, id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL, user_id INT NOT NULL,
car_id INT NOT NULL, car_id INT NOT NULL,
@ -67,10 +92,10 @@ try {
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE, FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
FOREIGN KEY (car_id) REFERENCES cars(id) ON DELETE CASCADE FOREIGN KEY (car_id) REFERENCES cars(id) ON DELETE CASCADE
)"); )");
echo "Bookings table ready.\n"; echo "<div class='step success'>✅ Table `bookings` created.</div>";
// Reviews Table // Reviews Table
$pdo->exec(" CREATE TABLE reviews ( $pdo->exec("CREATE TABLE reviews (
id INT AUTO_INCREMENT PRIMARY KEY, id INT AUTO_INCREMENT PRIMARY KEY,
car_id INT NOT NULL, car_id INT NOT NULL,
user_id INT NOT NULL, user_id INT NOT NULL,
@ -81,30 +106,20 @@ try {
FOREIGN KEY (car_id) REFERENCES cars(id) ON DELETE CASCADE, FOREIGN KEY (car_id) REFERENCES cars(id) ON DELETE CASCADE,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
)"); )");
echo "Reviews table ready.\n"; echo "<div class='step success'>✅ Table `reviews` created.</div>";
// 4. Add default admin user // 5. Create Default Admin User
$adminUsername = 'admin@gmail.com'; $adminUser = 'admin';
$adminPassword = '12345678'; $adminEmail = 'admin@gmail.com';
$adminHash = password_hash($adminPassword, PASSWORD_DEFAULT); $adminPass = '123'; // As requested
$adminHash = password_hash($adminPass, PASSWORD_DEFAULT);
// Check if admin exists (though we dropped tables, good practice) $stmt = $pdo->prepare("INSERT INTO users (username, email, password, role) VALUES (?, ?, ?, 'admin')");
$stmt = $pdo->prepare("SELECT COUNT(*) FROM users WHERE username = ?"); $stmt->execute([$adminUser, $adminEmail, $adminHash]);
$stmt->execute([$adminUsername]);
if ($stmt->fetchColumn() == 0) {
$insertAdmin = $pdo->prepare("INSERT INTO users (username, password, role) VALUES (?, ?, 'admin')");
$insertAdmin->execute([$adminUsername, $adminHash]);
$adminId = $pdo->lastInsertId(); $adminId = $pdo->lastInsertId();
echo "Admin user created (User: $adminUsername, Pass: $adminPassword).\n"; echo "<div class='step success'>✅ Admin user created.<br> &nbsp;&nbsp; Username: <b>$adminUser</b><br> &nbsp;&nbsp; Email: <b>$adminEmail</b><br> &nbsp;&nbsp; Password: <b>$adminPass</b></div>";
} else {
echo "Admin user already exists.\n";
$stmt = $pdo->prepare("SELECT id FROM users WHERE username = ?");
$stmt->execute([$adminUsername]);
$adminId = $stmt->fetchColumn();
}
// 5. Insert sample data (15 Cars) // 6. Insert Sample Data (Cars)
$carsData = [ $carsData = [
[ [
'title' => 'Toyota Corolla 2020 Clean', 'title' => 'Toyota Corolla 2020 Clean',
@ -286,7 +301,7 @@ try {
'color' => 'Red', 'color' => 'Red',
'province' => 'Mazar-i-Sharif', 'province' => 'Mazar-i-Sharif',
'city' => 'Mazar', 'city' => 'Mazar',
'image_url' => 'https://images.pexels.com/photos/35967/mini-cooper-auto-model-vehicle.jpg?auto=compress&cs=tinysrgb&w=600' // Placeholder for small car 'image_url' => 'https://images.pexels.com/photos/35967/mini-cooper-auto-model-vehicle.jpg?auto=compress&cs=tinysrgb&w=600'
], ],
[ [
'title' => 'Mazda 6 2019', 'title' => 'Mazda 6 2019',
@ -324,10 +339,14 @@ try {
$car['user_id'] = $adminId; $car['user_id'] = $adminId;
$insertCar->execute($car); $insertCar->execute($car);
} }
echo "Seed data inserted (" . count($carsData) . " cars).\n"; echo "<div class='step success'>✅ Seed data inserted (" . count($carsData) . " cars).</div>";
echo "Setup complete. The application is ready to use.\n"; echo "<hr><h2>🎉 Installation Complete!</h2>";
echo "<p>You can now <a href='login.php'>Login here</a>.</p>";
echo "<p><b>Credentials:</b><br>Username: <code>admin</code> or <code>admin@gmail.com</code><br>Password: <code>123</code></p>";
} catch (PDOException $e) { } catch (PDOException $e) {
die("Setup failed: " . $e->getMessage() . "\n"); echo "<div class='step error'>❌ Installation Failed: " . htmlspecialchars($e->getMessage()) . "</div>";
} }
echo "</body></html>";
?>

View File

@ -14,12 +14,14 @@ if (isset($_SESSION['user_id'])) {
} }
$errors = []; $errors = [];
$login_input = ''; // Store input to repopulate form
if ($_SERVER['REQUEST_METHOD'] === 'POST') { if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$username = trim($_POST['username'] ?? ''); $login_input = trim($_POST['username'] ?? ''); // This field now accepts user OR email
$password = $_POST['password'] ?? ''; $password = $_POST['password'] ?? '';
if (empty($username)) { if (empty($login_input)) {
$errors[] = 'Username is required.'; $errors[] = 'Username or Email is required.';
} }
if (empty($password)) { if (empty($password)) {
$errors[] = 'Password is required.'; $errors[] = 'Password is required.';
@ -28,20 +30,14 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (empty($errors)) { if (empty($errors)) {
try { try {
$pdo = db(); $pdo = db();
// Allow login by username only per new schema // Allow login by username OR email
$stmt = $pdo->prepare("SELECT * FROM users WHERE username = :username LIMIT 1"); $stmt = $pdo->prepare("SELECT * FROM users WHERE username = :input OR email = :input LIMIT 1");
$stmt->execute(['username' => $username]); $stmt->execute(['input' => $login_input]);
$user = $stmt->fetch(); $user = $stmt->fetch();
// Note: The 'password' column stores the hash // Note: The 'password' column stores the hash
if ($user && password_verify($password, $user['password'])) { if ($user && password_verify($password, $user['password'])) {
if (isset($user['status']) && $user['status'] !== 'active') { // Login Success
// Kept specific status check logic if status column existed, but since schema is simple, this block is mostly for safety if schema evolves.
// Current schema doesn't have status, but if it did, we'd check it.
// The setup_project.php removed the status column from users table to fit the simple requirements.
// So we proceed.
}
$_SESSION['user_id'] = $user['id']; $_SESSION['user_id'] = $user['id'];
$_SESSION['username'] = $user['username']; $_SESSION['username'] = $user['username'];
$_SESSION['role'] = $user['role']; $_SESSION['role'] = $user['role'];
@ -94,7 +90,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
<form action="login.php" method="POST"> <form action="login.php" method="POST">
<div class="mb-4"> <div class="mb-4">
<label for="username" class="form-label fw-semibold">Username or Email</label> <label for="username" class="form-label fw-semibold">Username or Email</label>
<input type="text" id="username" name="username" class="form-control form-control-lg" placeholder="admin@gmail.com" required value="<?php echo isset($username) ? htmlspecialchars($username) : ''; ?>"> <input type="text" id="username" name="username" class="form-control form-control-lg" placeholder="admin or admin@gmail.com" required value="<?php echo htmlspecialchars($login_input); ?>">
</div> </div>
<div class="mb-4"> <div class="mb-4">
<label for="password" class="form-label fw-semibold">Password</label> <label for="password" class="form-label fw-semibold">Password</label>

View File

@ -9,14 +9,23 @@ if (isset($_SESSION['user_id'])) {
} }
$errors = []; $errors = [];
$username = '';
$email = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') { if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$username = trim($_POST['username'] ?? ''); $username = trim($_POST['username'] ?? '');
$email = trim($_POST['email'] ?? '');
$password = $_POST['password'] ?? ''; $password = $_POST['password'] ?? '';
// Validation // Validation
if (empty($username)) { if (empty($username)) {
$errors[] = 'Username is required.'; $errors[] = 'Username is required.';
} }
if (empty($email)) {
$errors[] = 'Email is required.';
} elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$errors[] = 'Invalid email format.';
}
if (empty($password)) { if (empty($password)) {
$errors[] = 'Password is required.'; $errors[] = 'Password is required.';
} elseif (strlen($password) < 8) { } elseif (strlen($password) < 8) {
@ -26,18 +35,21 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (empty($errors)) { if (empty($errors)) {
try { try {
$pdo = db(); $pdo = db();
// Check if username already exists // Check if username OR email already exists
$stmt = $pdo->prepare("SELECT COUNT(*) FROM users WHERE username = :username"); $stmt = $pdo->prepare("SELECT COUNT(*) FROM users WHERE username = :username OR email = :email");
$stmt->execute(['username' => $username]); $stmt->execute(['username' => $username, 'email' => $email]);
if ($stmt->fetchColumn() > 0) { if ($stmt->fetchColumn() > 0) {
$errors[] = 'Username is already taken.'; // Determine which one exists for better error message (optional but nice)
// For simplicity:
$errors[] = 'Username or Email is already taken.';
} else { } else {
// Hash password and insert new user // Hash password and insert new user
$password_hash = password_hash($password, PASSWORD_DEFAULT); $password_hash = password_hash($password, PASSWORD_DEFAULT);
// Schema: id, username, password, role, created_at // Schema: id, username, email, password, role, created_at
$insert_stmt = $pdo->prepare("INSERT INTO users (username, password, role) VALUES (:username, :password, 'user')"); $insert_stmt = $pdo->prepare("INSERT INTO users (username, email, password, role) VALUES (:username, :email, :password, 'user')");
$insert_stmt->execute([ $insert_stmt->execute([
':username' => $username, ':username' => $username,
':email' => $email,
':password' => $password_hash ':password' => $password_hash
]); ]);
@ -85,7 +97,11 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
<form action="register.php" method="POST"> <form action="register.php" method="POST">
<div class="mb-3"> <div class="mb-3">
<label for="username" class="form-label">Username</label> <label for="username" class="form-label">Username</label>
<input type="text" id="username" name="username" class="form-control" placeholder="e.g., ahmadwali" required value="<?php echo isset($username) ? htmlspecialchars($username) : ''; ?>"> <input type="text" id="username" name="username" class="form-control" placeholder="e.g., ahmadwali" required value="<?php echo htmlspecialchars($username); ?>">
</div>
<div class="mb-3">
<label for="email" class="form-label">Email Address</label>
<input type="email" id="email" name="email" class="form-control" placeholder="e.g., ahmad@example.com" required value="<?php echo htmlspecialchars($email); ?>">
</div> </div>
<div class="mb-3"> <div class="mb-3">
<label for="password" class="form-label">Password</label> <label for="password" class="form-label">Password</label>