google-site-verification: google61fe8ba583a51912.html
Online Auction System project IN HTML CSS AND JAVASCRIPT

ONLINE AUCTION SYSTEM

Introduction

The Online Auction System is a dynamic web platform that enables users to list items for auction and place bids on items they wish to purchase. The system supports multiple auction types including regular auctions, reserve price auctions, and featured listings. Users can track their bids, manage their listings, and receive notifications on auction status. The platform includes both user and admin interfaces with comprehensive auction management features. Real-time bidding updates, automatic outbid notifications, and secure payment processing make this a complete auction marketplace solution.

Project Features

User Features:

  • User Registration and Email Verification
  • User Login with Remember Me
  • Browse Active Auctions by Categories
  • Advanced Search with Filters (Price, Category, Condition)
  • View Auction Details with Countdown Timer
  • Place Bids on Active Auctions
  • Automatic Outbid Email Notifications
  • Watchlist/Favorite Auctions
  • Create New Auction Listings with Multiple Images
  • Reserve Price Option for Sellers
  • Buy It Now Option for Immediate Purchase
  • Manage My Auctions (Edit, Cancel, Relist)
  • Track Bidding History
  • View Won Auctions and Payment Status
  • Seller Rating and Reviews System
  • Secure Payment Integration (PayPal/Stripe Demo)
  • User Dashboard with Statistics
  • Profile Management with Avatar Upload
  • Message Center for Buyer-Seller Communication
  • Bid Auto-Refresh with AJAX
  • Auction Ending Soon Alerts

Admin Features:

  • Admin Dashboard with Real-time Analytics
  • User Management (View, Edit, Suspend, Ban)
  • Auction Management (Approve, Reject, Feature)
  • Category Management (Add, Edit, Delete)
  • Reported Auctions Management
  • Transaction Monitoring and Fee Calculation
  • Site Settings Configuration
  • Commission and Fee Management
  • Banner and Promotional Management
  • Email Template Management
  • System Logs and Error Reports
  • Backup and Restore Functionality
  • Sales and Revenue Reports
  • Featured Auction Management

Project File Structure

online-auction-system/ │ ├── assets/ │ ├── css/ │ │ ├── style.css │ │ ├── admin-style.css │ │ ├── responsive.css │ │ └── bootstrap.min.css │ ├── js/ │ │ ├── main.js │ │ ├── auction.js │ │ ├── bidding.js │ │ ├── countdown.js │ │ ├── admin.js │ │ └── jquery.min.js │ └── images/ │ ├── auctions/ │ ├── categories/ │ ├── avatars/ │ └── banners/ │ ├── uploads/ │ ├── auction_images/ │ └── temp/ │ ├── database/ │ └── auction_system.sql │ ├── includes/ │ ├── config.php │ ├── db_connection.php │ ├── functions.php │ ├── auth.php │ ├── auction_functions.php │ ├── bidding_functions.php │ ├── payment_functions.php │ └── notification_functions.php │ ├── admin/ │ ├── index.php │ ├── login.php │ ├── logout.php │ ├── dashboard.php │ ├── users.php │ ├── user-details.php │ ├── auctions.php │ ├── auction-details.php │ ├── approve-auction.php │ ├── categories.php │ ├── add-category.php │ ├── edit-category.php │ ├── delete-category.php │ ├── transactions.php │ ├── reports.php │ ├── settings.php │ ├── featured-auctions.php │ ├── reported-auctions.php │ ├── messages.php │ ├── email-templates.php │ ├── backup.php │ └── profile.php │ ├── user/ │ ├── index.php │ ├── register.php │ ├── login.php │ ├── logout.php │ ├── verify-email.php │ ├── forgot-password.php │ ├── reset-password.php │ ├── dashboard.php │ ├── profile.php │ ├── create-auction.php │ ├── edit-auction.php │ ├── my-auctions.php │ ├── my-bids.php │ ├── won-auctions.php │ ├── watchlist.php │ ├── auction-details.php │ ├── place-bid.php │ ├── buy-now.php │ ├── payment.php │ ├── payment-success.php │ ├── leave-review.php │ ├── messages.php │ ├── conversation.php │ ├── notifications.php │ └── settings.php │ ├── api/ │ ├── get-bids.php │ ├── place-bid.php │ ├── check-auction-status.php │ ├── search-auctions.php │ ├── upload-image.php │ ├── notifications.php │ └── auto-refresh.php │ ├── index.php ├── auctions.php ├── auction.php ├── categories.php ├── search.php ├── about.php ├── contact.php ├── faq.php ├── how-it-works.php ├── terms.php ├── privacy.php ├── sitemap.php ├── 404.php ├── .htaccess └── robots.txt

Database Schema (auction_system.sql)

-- Create Database CREATE DATABASE IF NOT EXISTS auction_system; USE auction_system; -- Table: users CREATE TABLE users ( user_id INT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(50) UNIQUE NOT NULL, email VARCHAR(100) UNIQUE NOT NULL, password VARCHAR(255) NOT NULL, full_name VARCHAR(100), phone VARCHAR(20), address TEXT, city VARCHAR(50), state VARCHAR(50), country VARCHAR(50), postal_code VARCHAR(20), avatar VARCHAR(255), role ENUM('user', 'admin', 'moderator') DEFAULT 'user', status ENUM('active', 'suspended', 'banned') DEFAULT 'active', email_verified BOOLEAN DEFAULT FALSE, verification_token VARCHAR(100), reset_token VARCHAR(100), reset_expiry DATETIME, last_login DATETIME, last_ip VARCHAR(45), rating DECIMAL(3,2) DEFAULT 0.00, total_reviews INT DEFAULT 0, total_auctions INT DEFAULT 0, total_sales INT DEFAULT 0, total_purchases INT DEFAULT 0, balance DECIMAL(10,2) DEFAULT 0.00, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, INDEX idx_email (email), INDEX idx_status (status), INDEX idx_role (role) ); -- Insert default admin INSERT INTO users (username, email, password, full_name, role, email_verified) VALUES ('admin', '[email protected]', MD5('Admin@123'), 'System Administrator', 'admin', TRUE); -- Insert sample user INSERT INTO users (username, email, password, full_name, email_verified) VALUES ('john_doe', '[email protected]', MD5('John@123'), 'John Doe', TRUE); -- Table: categories CREATE TABLE categories ( category_id INT PRIMARY KEY AUTO_INCREMENT, category_name VARCHAR(100) NOT NULL, category_slug VARCHAR(100) UNIQUE NOT NULL, category_description TEXT, parent_category_id INT, category_image VARCHAR(255), icon VARCHAR(50), is_active BOOLEAN DEFAULT TRUE, display_order INT DEFAULT 0, auction_count INT DEFAULT 0, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, FOREIGN KEY (parent_category_id) REFERENCES categories(category_id) ON DELETE CASCADE, INDEX idx_parent (parent_category_id), INDEX idx_active (is_active) ); -- Insert default categories INSERT INTO categories (category_name, category_slug, icon, display_order) VALUES ('Electronics', 'electronics', 'fa-laptop', 1), ('Fashion', 'fashion', 'fa-tshirt', 2), ('Home & Garden', 'home-garden', 'fa-home', 3), ('Sports & Outdoors', 'sports-outdoors', 'fa-futbol', 4), ('Collectibles & Art', 'collectibles-art', 'fa-paint-brush', 5), ('Books & Media', 'books-media', 'fa-book', 6), ('Jewelry & Watches', 'jewelry-watches', 'fa-gem', 7), ('Toys & Hobbies', 'toys-hobbies', 'fa-gamepad', 8), ('Automotive', 'automotive', 'fa-car', 9), ('Real Estate', 'real-estate', 'fa-building', 10); -- Table: auctions CREATE TABLE auctions ( auction_id INT PRIMARY KEY AUTO_INCREMENT, seller_id INT NOT NULL, category_id INT NOT NULL, title VARCHAR(200) NOT NULL, slug VARCHAR(250) UNIQUE NOT NULL, description TEXT NOT NULL, short_description VARCHAR(500), condition ENUM('new', 'like-new', 'good', 'fair', 'poor') DEFAULT 'good', starting_price DECIMAL(10,2) NOT NULL, reserve_price DECIMAL(10,2), current_price DECIMAL(10,2), buy_it_now_price DECIMAL(10,2), min_bid_increment DECIMAL(10,2) DEFAULT 1.00, quantity INT DEFAULT 1, featured BOOLEAN DEFAULT FALSE, featured_until DATETIME, status ENUM('pending', 'active', 'ended', 'sold', 'cancelled', 'rejected') DEFAULT 'pending', start_time DATETIME NOT NULL, end_time DATETIME NOT NULL, view_count INT DEFAULT 0, bid_count INT DEFAULT 0, watcher_count INT DEFAULT 0, winner_id INT, sold_price DECIMAL(10,2), payment_status ENUM('pending', 'paid', 'shipped', 'completed', 'disputed') DEFAULT 'pending', shipping_cost DECIMAL(10,2) DEFAULT 0.00, shipping_details TEXT, payment_method VARCHAR(50), payment_date DATETIME, is_reported BOOLEAN DEFAULT FALSE, report_reason TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, FOREIGN KEY (seller_id) REFERENCES users(user_id) ON DELETE CASCADE, FOREIGN KEY (category_id) REFERENCES categories(category_id), FOREIGN KEY (winner_id) REFERENCES users(user_id) ON DELETE SET NULL, INDEX idx_status (status), INDEX idx_seller (seller_id), INDEX idx_category (category_id), INDEX idx_featured (featured), INDEX idx_endtime (end_time), INDEX idx_search (title, description), FULLTEXT INDEX ft_search (title, description) ); -- Table: auction_images CREATE TABLE auction_images ( image_id INT PRIMARY KEY AUTO_INCREMENT, auction_id INT NOT NULL, image_path VARCHAR(255) NOT NULL, is_primary BOOLEAN DEFAULT FALSE, display_order INT DEFAULT 0, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (auction_id) REFERENCES auctions(auction_id) ON DELETE CASCADE, INDEX idx_auction (auction_id) ); -- Table: bids CREATE TABLE bids ( bid_id INT PRIMARY KEY AUTO_INCREMENT, auction_id INT NOT NULL, bidder_id INT NOT NULL, bid_amount DECIMAL(10,2) NOT NULL, is_winning BOOLEAN DEFAULT FALSE, bid_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, ip_address VARCHAR(45), FOREIGN KEY (auction_id) REFERENCES auctions(auction_id) ON DELETE CASCADE, FOREIGN KEY (bidder_id) REFERENCES users(user_id) ON DELETE CASCADE, INDEX idx_auction (auction_id), INDEX idx_bidder (bidder_id), INDEX idx_amount (bid_amount) ); -- Table: watchlist CREATE TABLE watchlist ( watch_id INT PRIMARY KEY AUTO_INCREMENT, user_id INT NOT NULL, auction_id INT NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (user_id) REFERENCES users(user_id) ON DELETE CASCADE, FOREIGN KEY (auction_id) REFERENCES auctions(auction_id) ON DELETE CASCADE, UNIQUE KEY unique_watch (user_id, auction_id) ); -- Table: reviews CREATE TABLE reviews ( review_id INT PRIMARY KEY AUTO_INCREMENT, auction_id INT NOT NULL, reviewer_id INT NOT NULL, reviewee_id INT NOT NULL, rating INT NOT NULL CHECK (rating >= 1 AND rating <= 5), comment TEXT, response TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, FOREIGN KEY (auction_id) REFERENCES auctions(auction_id) ON DELETE CASCADE, FOREIGN KEY (reviewer_id) REFERENCES users(user_id) ON DELETE CASCADE, FOREIGN KEY (reviewee_id) REFERENCES users(user_id) ON DELETE CASCADE, UNIQUE KEY unique_review (auction_id, reviewer_id), INDEX idx_reviewee (reviewee_id) ); -- Table: messages CREATE TABLE messages ( message_id INT PRIMARY KEY AUTO_INCREMENT, sender_id INT NOT NULL, receiver_id INT NOT NULL, auction_id INT, subject VARCHAR(200), message TEXT NOT NULL, is_read BOOLEAN DEFAULT FALSE, parent_message_id INT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (sender_id) REFERENCES users(user_id) ON DELETE CASCADE, FOREIGN KEY (receiver_id) REFERENCES users(user_id) ON DELETE CASCADE, FOREIGN KEY (auction_id) REFERENCES auctions(auction_id) ON DELETE SET NULL, FOREIGN KEY (parent_message_id) REFERENCES messages(message_id) ON DELETE CASCADE, INDEX idx_conversation (sender_id, receiver_id), INDEX idx_read (is_read) ); -- Table: transactions CREATE TABLE transactions ( transaction_id INT PRIMARY KEY AUTO_INCREMENT, auction_id INT NOT NULL, buyer_id INT NOT NULL, seller_id INT NOT NULL, amount DECIMAL(10,2) NOT NULL, commission DECIMAL(10,2) NOT NULL, seller_amount DECIMAL(10,2) NOT NULL, payment_method VARCHAR(50), transaction_status ENUM('pending', 'completed', 'failed', 'refunded') DEFAULT 'pending', payment_id VARCHAR(100), payer_email VARCHAR(100), created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, FOREIGN KEY (auction_id) REFERENCES auctions(auction_id) ON DELETE CASCADE, FOREIGN KEY (buyer_id) REFERENCES users(user_id) ON DELETE CASCADE, FOREIGN KEY (seller_id) REFERENCES users(user_id) ON DELETE CASCADE, INDEX idx_auction (auction_id), INDEX idx_buyer (buyer_id), INDEX idx_seller (seller_id) ); -- Table: notifications CREATE TABLE notifications ( notification_id INT PRIMARY KEY AUTO_INCREMENT, user_id INT NOT NULL, type ENUM('outbid', 'won', 'ended', 'payment', 'message', 'review', 'system') NOT NULL, title VARCHAR(200), message TEXT, link VARCHAR(500), is_read BOOLEAN DEFAULT FALSE, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (user_id) REFERENCES users(user_id) ON DELETE CASCADE, INDEX idx_user (user_id), INDEX_idx_read (is_read) ); -- Table: site_settings CREATE TABLE site_settings ( setting_id INT PRIMARY KEY AUTO_INCREMENT, setting_key VARCHAR(100) UNIQUE NOT NULL, setting_value TEXT, setting_type ENUM('text', 'number', 'boolean', 'json') DEFAULT 'text', setting_description TEXT, updated_by INT, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, FOREIGN KEY (updated_by) REFERENCES users(user_id) ON DELETE SET NULL ); -- Insert default settings INSERT INTO site_settings (setting_key, setting_value, setting_type, setting_description) VALUES ('site_name', 'AuctionHub', 'text', 'Website name'), ('site_url', 'http://localhost/online-auction-system/', 'text', 'Website URL'), ('admin_email', '[email protected]', 'text', 'Administrator email'), ('commission_rate', '5.00', 'number', 'Commission rate for sales (%)'), ('min_auction_duration', '1', 'number', 'Minimum auction duration in days'), ('max_auction_duration', '30', 'number', 'Maximum auction duration in days'), ('max_images_per_auction', '10', 'number', 'Maximum images per auction'), ('enable_paypal', '1', 'boolean', 'Enable PayPal payment'), ('enable_stripe', '1', 'boolean', 'Enable Stripe payment'), ('paypal_email', '[email protected]', 'text', 'PayPal business email'), ('stripe_publishable_key', '', 'text', 'Stripe publishable key'), ('stripe_secret_key', '', 'text', 'Stripe secret key'), ('maintenance_mode', '0', 'boolean', 'Maintenance mode status'), ('registration_enabled', '1', 'boolean', 'Enable user registration'), ('email_verification', '1', 'boolean', 'Require email verification'), ('auto_approve_auctions', '0', 'boolean', 'Automatically approve new auctions'); -- Table: activity_logs CREATE TABLE activity_logs ( log_id INT PRIMARY KEY AUTO_INCREMENT, user_id INT, action VARCHAR(100) NOT NULL, details TEXT, ip_address VARCHAR(45), user_agent TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (user_id) REFERENCES users(user_id) ON DELETE SET NULL, INDEX idx_user (user_id), INDEX idx_action (action), INDEX idx_created (created_at) ); -- Table: reported_auctions CREATE TABLE reported_auctions ( report_id INT PRIMARY KEY AUTO_INCREMENT, auction_id INT NOT NULL, reporter_id INT NOT NULL, reason ENUM('fake', 'misleading', 'inappropriate', 'copyright', 'other') NOT NULL, description TEXT, status ENUM('pending', 'reviewed', 'resolved', 'dismissed') DEFAULT 'pending', reviewed_by INT, reviewed_at DATETIME, action_taken TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (auction_id) REFERENCES auctions(auction_id) ON DELETE CASCADE, FOREIGN KEY (reporter_id) REFERENCES users(user_id) ON DELETE CASCADE, FOREIGN KEY (reviewed_by) REFERENCES users(user_id) ON DELETE SET NULL, INDEX idx_status (status) );

Core PHP Files

1. includes/config.php

<?php // Database configuration define('DB_HOST', 'localhost'); define('DB_USER', 'root'); define('DB_PASS', ''); define('DB_NAME', 'auction_system'); // Application configuration define('SITE_NAME', 'AuctionHub'); define('SITE_URL', 'http://localhost/online-auction-system/'); define('ADMIN_URL', SITE_URL . 'admin/'); define('USER_URL', SITE_URL . 'user/'); define('UPLOAD_DIR', $_SERVER['DOCUMENT_ROOT'] . '/online-auction-system/uploads/'); define('AUCTION_IMG_DIR', UPLOAD_DIR . 'auction_images/'); define('TEMP_DIR', UPLOAD_DIR . 'temp/'); // Auction settings define('MIN_AUCTION_DAYS', 1); define('MAX_AUCTION_DAYS', 30); define('MAX_IMAGES_PER_AUCTION', 10); define('COMMISSION_RATE', 5.00); // Percentage define('MIN_BID_INCREMENT', 1.00); define('AUTO_RELIST_EXPIRED', false); // Pagination settings define('ITEMS_PER_PAGE', 20); define('AUCTIONS_PER_PAGE', 12); // Security settings define('SESSION_TIMEOUT', 7200); // 2 hours define('ENABLE_SSL', false); define('HASH_COST', 10); define('CSRF_TOKEN_NAME', 'csrf_token'); // Email settings define('SMTP_HOST', 'smtp.gmail.com'); define('SMTP_PORT', 587); define('SMTP_USER', '[email protected]'); define('SMTP_PASS', 'your-password'); define('SMTP_ENCRYPTION', 'tls'); define('FROM_EMAIL', '[email protected]'); define('FROM_NAME', 'Auction System'); // Payment settings define('PAYPAL_MODE', 'sandbox'); // sandbox or live define('PAYPAL_CLIENT_ID', 'your-paypal-client-id'); define('PAYPAL_SECRET', 'your-paypal-secret'); define('STRIPE_PUBLISHABLE_KEY', 'your-stripe-publishable-key'); define('STRIPE_SECRET_KEY', 'your-stripe-secret-key'); // Timezone date_default_timezone_set('UTC'); // Error reporting (disable in production) error_reporting(E_ALL); ini_set('display_errors', 1); // Start session if not started if (session_status() == PHP_SESSION_NONE) { session_start(); } // Set default currency define('CURRENCY', '$'); ?>

2. includes/db_connection.php

<?php require_once 'config.php'; class Database { private $connection; private static $instance = null; private $stmt; private function __construct() { $this->connect(); } public static function getInstance() { if (self::$instance === null) { self::$instance = new Database(); } return self::$instance; } private function connect() { $this->connection = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME); if ($this->connection->connect_error) { die("Connection failed: " . $this->connection->connect_error); } $this->connection->set_charset("utf8mb4"); } public function getConnection() { return $this->connection; } public function escape($string) { return $this->connection->real_escape_string(trim($string)); } public function query($sql) { return $this->connection->query($sql); } public function prepare($sql) { $this->stmt = $this->connection->prepare($sql); return $this->stmt; } public function execute($params = []) { if (!empty($params) && $this->stmt) { $types = ''; $values = []; foreach ($params as $param) { if (is_int($param)) { $types .= 'i'; } elseif (is_float($param)) { $types .= 'd'; } elseif (is_string($param)) { $types .= 's'; } else { $types .= 'b'; } $values[] = $param; } $this->stmt->bind_param($types, ...$values); } return $this->stmt->execute(); } public function getResult() { return $this->stmt->get_result(); } public function fetchAssoc() { return $this->stmt->get_result()->fetch_assoc(); } public function fetchAll() { return $this->stmt->get_result()->fetch_all(MYSQLI_ASSOC); } public function lastInsertId() { return $this->connection->insert_id; } public function affectedRows() { return $this->connection->affected_rows; } public function beginTransaction() { $this->connection->begin_transaction(); } public function commit() { $this->connection->commit(); } public function rollback() { $this->connection->rollback(); } public function __destruct() { if ($this->stmt) { $this->stmt->close(); } if ($this->connection) { $this->connection->close(); } } } // Global database instance $db = Database::getInstance(); $conn = $db->getConnection(); ?>

3. includes/functions.php

<?php require_once 'db_connection.php'; // Redirect to specified page function redirect($url) { header("Location: $url"); exit(); } // Check if user is logged in function isLoggedIn() { return isset($_SESSION['user_id']) && !empty($_SESSION['user_id']); } // Check if admin is logged in function isAdmin() { return isset($_SESSION['user_role']) && $_SESSION['user_role'] === 'admin'; } // Get current user ID function getCurrentUserId() { return $_SESSION['user_id'] ?? 0; } // Get current user role function getCurrentUserRole() { return $_SESSION['user_role'] ?? 'guest'; } // Sanitize input function sanitize($input) { global $conn; return $conn->real_escape_string(trim(htmlspecialchars($input, ENT_QUOTES, 'UTF-8'))); } // Generate CSRF token function generateCSRFToken() { if (!isset($_SESSION[CSRF_TOKEN_NAME])) { $_SESSION[CSRF_TOKEN_NAME] = bin2hex(random_bytes(32)); } return $_SESSION[CSRF_TOKEN_NAME]; } // Verify CSRF token function verifyCSRFToken($token) { return isset($_SESSION[CSRF_TOKEN_NAME]) && hash_equals($_SESSION[CSRF_TOKEN_NAME], $token); } // Format currency function formatCurrency($amount) { return CURRENCY . number_format($amount, 2); } // Format date function formatDate($date, $format = 'M d, Y H:i') { return date($format, strtotime($date)); } // Time ago function function timeAgo($datetime) { $time = strtotime($datetime); $now = time(); $diff = $now - $time; if ($diff < 60) { return $diff . ' seconds ago'; } elseif ($diff < 3600) { $mins = floor($diff / 60); return $mins . ' minute' . ($mins > 1 ? 's' : '') . ' ago'; } elseif ($diff < 86400) { $hours = floor($diff / 3600); return $hours . ' hour' . ($hours > 1 ? 's' : '') . ' ago'; } elseif ($diff < 2592000) { $days = floor($diff / 86400); return $days . ' day' . ($days > 1 ? 's' : '') . ' ago'; } else { return date('M d, Y', $time); } } // Get time remaining for auction function getTimeRemaining($end_time) { $now = time(); $end = strtotime($end_time); $diff = $end - $now; if ($diff <= 0) { return ['expired' => true, 'text' => 'Ended']; } $days = floor($diff / 86400); $hours = floor(($diff % 86400) / 3600); $minutes = floor(($diff % 3600) / 60); $seconds = $diff % 60; if ($days > 0) { return ['expired' => false, 'text' => $days . 'd ' . $hours . 'h left']; } elseif ($hours > 0) { return ['expired' => false, 'text' => $hours . 'h ' . $minutes . 'm left']; } elseif ($minutes > 0) { return ['expired' => false, 'text' => $minutes . 'm ' . $seconds . 's left']; } else { return ['expired' => false, 'text' => $seconds . 's left']; } } // Generate slug function generateSlug($string) { $string = strtolower($string); $string = preg_replace('/[^a-z0-9-]/', '-', $string); $string = preg_replace('/-+/', '-', $string); return trim($string, '-'); } // Upload image function uploadImage($file, $target_dir, $max_size = 5242880) { $errors = []; $success = false; $filename = ''; // Check if file is uploaded if (!isset($file) || $file['error'] !== UPLOAD_ERR_OK) { $errors[] = 'No file uploaded or upload error'; return ['success' => false, 'errors' => $errors]; } // Check file size if ($file['size'] > $max_size) { $errors[] = 'File size must be less than ' . ($max_size / 1048576) . 'MB'; return ['success' => false, 'errors' => $errors]; } // Check file type $allowed_types = ['image/jpeg', 'image/png', 'image/gif', 'image/webp']; $finfo = finfo_open(FILEINFO_MIME_TYPE); $mime_type = finfo_file($finfo, $file['tmp_name']); finfo_close($finfo); if (!in_array($mime_type, $allowed_types)) { $errors[] = 'Only JPG, PNG, GIF and WEBP images are allowed'; return ['success' => false, 'errors' => $errors]; } // Generate unique filename $extension = pathinfo($file['name'], PATHINFO_EXTENSION); $filename = uniqid() . '_' . time() . '.' . $extension; $target_path = $target_dir . $filename; // Create directory if not exists if (!file_exists($target_dir)) { mkdir($target_dir, 0755, true); } // Move uploaded file if (move_uploaded_file($file['tmp_name'], $target_path)) { $success = true; // Create thumbnail for large images if ($file['size'] > 1048576) { // If larger than 1MB createThumbnail($target_path, $target_path, 1200, 1200); } } else { $errors[] = 'Failed to upload file'; } return [ 'success' => $success, 'filename' => $filename, 'errors' => $errors ]; } // Create thumbnail function createThumbnail($source, $destination, $max_width, $max_height) { list($width, $height, $type) = getimagesize($source); $ratio = min($max_width / $width, $max_height / $height); $new_width = $width * $ratio; $new_height = $height * $ratio; $thumb = imagecreatetruecolor($new_width, $new_height); switch ($type) { case IMAGETYPE_JPEG: $source_img = imagecreatefromjpeg($source); break; case IMAGETYPE_PNG: $source_img = imagecreatefrompng($source); imagealphablending($thumb, false); imagesavealpha($thumb, true); break; case IMAGETYPE_GIF: $source_img = imagecreatefromgif($source); break; default: return false; } imagecopyresampled($thumb, $source_img, 0, 0, 0, 0, $new_width, $new_height, $width, $height); switch ($type) { case IMAGETYPE_JPEG: imagejpeg($thumb, $destination, 85); break; case IMAGETYPE_PNG: imagepng($thumb, $destination, 8); break; case IMAGETYPE_GIF: imagegif($thumb, $destination); break; } imagedestroy($source_img); imagedestroy($thumb); return true; } // Get user by ID function getUserById($user_id) { global $conn; $sql = "SELECT * FROM users WHERE user_id = ?"; $stmt = $conn->prepare($sql); $stmt->bind_param("i", $user_id); $stmt->execute(); $result = $stmt->get_result(); return $result->fetch_assoc(); } // Get category by ID function getCategoryById($category_id) { global $conn; $sql = "SELECT * FROM categories WHERE category_id = ?"; $stmt = $conn->prepare($sql); $stmt->bind_param("i", $category_id); $stmt->execute(); $result = $stmt->get_result(); return $result->fetch_assoc(); } // Get all categories function getAllCategories($active_only = true) { global $conn; $sql = "SELECT * FROM categories"; if ($active_only) { $sql .= " WHERE is_active = 1"; } $sql .= " ORDER BY display_order, category_name"; $result = $conn->query($sql); return $result->fetch_all(MYSQLI_ASSOC); } // Get auction by ID function getAuctionById($auction_id) { global $conn; $sql = "SELECT a.*, u.username as seller_username, u.full_name as seller_name, u.rating as seller_rating, u.total_reviews as seller_reviews, c.category_name, c.category_slug FROM auctions a JOIN users u ON a.seller_id = u.user_id JOIN categories c ON a.category_id = c.category_id WHERE a.auction_id = ?"; $stmt = $conn->prepare($sql); $stmt->bind_param("i", $auction_id); $stmt->execute(); $result = $stmt->get_result(); return $result->fetch_assoc(); } // Get auction images function getAuctionImages($auction_id) { global $conn; $sql = "SELECT * FROM auction_images WHERE auction_id = ? ORDER BY is_primary DESC, display_order"; $stmt = $conn->prepare($sql); $stmt->bind_param("i", $auction_id); $stmt->execute(); $result = $stmt->get_result(); return $result->fetch_all(MYSQLI_ASSOC); } // Get bids for auction function getAuctionBids($auction_id, $limit = null) { global $conn; $sql = "SELECT b.*, u.username, u.full_name FROM bids b JOIN users u ON b.bidder_id = u.user_id WHERE b.auction_id = ? ORDER BY b.bid_amount DESC, b.bid_time DESC"; if ($limit) { $sql .= " LIMIT ?"; } $stmt = $conn->prepare($sql); if ($limit) { $stmt->bind_param("ii", $auction_id, $limit); } else { $stmt->bind_param("i", $auction_id); } $stmt->execute(); $result = $stmt->get_result(); return $result->fetch_all(MYSQLI_ASSOC); } // Get highest bid for auction function getHighestBid($auction_id) { global $conn; $sql = "SELECT * FROM bids WHERE auction_id = ? ORDER BY bid_amount DESC LIMIT 1"; $stmt = $conn->prepare($sql); $stmt->bind_param("i", $auction_id); $stmt->execute(); $result = $stmt->get_result(); return $result->fetch_assoc(); } // Check if user is watching auction function isWatching($user_id, $auction_id) { global $conn; $sql = "SELECT * FROM watchlist WHERE user_id = ? AND auction_id = ?"; $stmt = $conn->prepare($sql); $stmt->bind_param("ii", $user_id, $auction_id); $stmt->execute(); $result = $stmt->get_result(); return $result->num_rows > 0; } // Add to watchlist function addToWatchlist($user_id, $auction_id) { global $conn; if (isWatching($user_id, $auction_id)) { return false; } $sql = "INSERT INTO watchlist (user_id, auction_id) VALUES (?, ?)"; $stmt = $conn->prepare($sql); $stmt->bind_param("ii", $user_id, $auction_id); if ($stmt->execute()) { // Increment watcher count $conn->query("UPDATE auctions SET watcher_count = watcher_count + 1 WHERE auction_id = $auction_id"); return true; } return false; } // Remove from watchlist function removeFromWatchlist($user_id, $auction_id) { global $conn; $sql = "DELETE FROM watchlist WHERE user_id = ? AND auction_id = ?"; $stmt = $conn->prepare($sql); $stmt->bind_param("ii", $user_id, $auction_id); if ($stmt->execute() && $stmt->affected_rows > 0) { // Decrement watcher count $conn->query("UPDATE auctions SET watcher_count = watcher_count - 1 WHERE auction_id = $auction_id"); return true; } return false; } // Create notification function createNotification($user_id, $type, $title, $message, $link = null) { global $conn; $sql = "INSERT INTO notifications (user_id, type, title, message, link) VALUES (?, ?, ?, ?, ?)"; $stmt = $conn->prepare($sql); $stmt->bind_param("issss", $user_id, $type, $title, $message, $link); return $stmt->execute(); } // Get user notifications function getUserNotifications($user_id, $unread_only = false, $limit = 10) { global $conn; $sql = "SELECT * FROM notifications WHERE user_id = ?"; if ($unread_only) { $sql .= " AND is_read = 0"; } $sql .= " ORDER BY created_at DESC LIMIT ?"; $stmt = $conn->prepare($sql); $stmt->bind_param("ii", $user_id, $limit); $stmt->execute(); $result = $stmt->get_result(); return $result->fetch_all(MYSQLI_ASSOC); } // Mark notification as read function markNotificationRead($notification_id, $user_id) { global $conn; $sql = "UPDATE notifications SET is_read = 1 WHERE notification_id = ? AND user_id = ?"; $stmt = $conn->prepare($sql); $stmt->bind_param("ii", $notification_id, $user_id); return $stmt->execute(); } // Get site setting function getSetting($key, $default = null) { global $conn; $sql = "SELECT setting_value FROM site_settings WHERE setting_key = ?"; $stmt = $conn->prepare($sql); $stmt->bind_param("s", $key); $stmt->execute(); $result = $stmt->get_result(); if ($row = $result->fetch_assoc()) { return $row['setting_value']; } return $default; } // Log activity function logActivity($user_id, $action, $details = null) { global $conn; $ip = $_SERVER['REMOTE_ADDR'] ?? ''; $user_agent = $_SERVER['HTTP_USER_AGENT'] ?? ''; $sql = "INSERT INTO activity_logs (user_id, action, details, ip_address, user_agent) VALUES (?, ?, ?, ?, ?)"; $stmt = $conn->prepare($sql); $stmt->bind_param("issss", $user_id, $action, $details, $ip, $user_agent); return $stmt->execute(); } // Pagination function function paginate($current_page, $total_pages, $url_pattern) { $html = '<ul class="pagination">'; // Previous button if ($current_page > 1) { $html .= '<li class="page-item"><a class="page-link" href="' . str_replace('{page}', $current_page - 1, $url_pattern) . '">Previous</a></li>'; } else { $html .= '<li class="page-item disabled"><span class="page-link">Previous</span></li>'; } // Page numbers for ($i = 1; $i <= $total_pages; $i++) { if ($i == $current_page) { $html .= '<li class="page-item active"><span class="page-link">' . $i . '</span></li>'; } else { $html .= '<li class="page-item"><a class="page-link" href="' . str_replace('{page}', $i, $url_pattern) . '">' . $i . '</a></li>'; } } // Next button if ($current_page < $total_pages) { $html .= '<li class="page-item"><a class="page-link" href="' . str_replace('{page}', $current_page + 1, $url_pattern) . '">Next</a></li>'; } else { $html .= '<li class="page-item disabled"><span class="page-link">Next</span></li>'; } $html .= '</ul>'; return $html; } ?>

4. includes/auction_functions.php

<?php require_once 'functions.php'; class AuctionManager { private $conn; private $user_id; public function __construct($user_id = null) { global $conn; $this->conn = $conn; $this->user_id = $user_id ?: getCurrentUserId(); } // Create new auction public function createAuction($data, $images = []) { // Validate required fields $required = ['title', 'description', 'category_id', 'starting_price', 'duration']; foreach ($required as $field) { if (empty($data[$field])) { return ['success' => false, 'message' => ucfirst($field) . ' is required']; } } // Validate duration $min_days = getSetting('min_auction_duration', MIN_AUCTION_DAYS); $max_days = getSetting('max_auction_duration', MAX_AUCTION_DAYS); if ($data['duration'] < $min_days || $data['duration'] > $max_days) { return ['success' => false, 'message' => "Duration must be between $min_days and $max_days days"]; } // Validate starting price if ($data['starting_price'] < 0.01) { return ['success' => false, 'message' => 'Starting price must be at least 0.01']; } // Validate reserve price if set if (!empty($data['reserve_price']) && $data['reserve_price'] < $data['starting_price']) { return ['success' => false, 'message' => 'Reserve price must be greater than or equal to starting price']; } // Validate buy it now price if set if (!empty($data['buy_it_now_price']) && $data['buy_it_now_price'] < $data['starting_price']) { return ['success' => false, 'message' => 'Buy it now price must be greater than or equal to starting price']; } // Set timestamps $start_time = date('Y-m-d H:i:s'); $end_time = date('Y-m-d H:i:s', strtotime("+{$data['duration']} days")); // Generate slug $slug = generateSlug($data['title']); $slug = $this->makeSlugUnique($slug); // Insert auction $sql = "INSERT INTO auctions ( seller_id, category_id, title, slug, description, short_description, condition, starting_price, reserve_price, current_price, buy_it_now_price, min_bid_increment, quantity, start_time, end_time, shipping_details ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; $stmt = $this->conn->prepare($sql); $current_price = $data['starting_price']; $short_desc = substr($data['description'], 0, 200) . '...'; $stmt->bind_param( "iissssssdddiiiss", $this->user_id, $data['category_id'], $data['title'], $slug, $data['description'], $short_desc, $data['condition'], $data['starting_price'], $data['reserve_price'] ?? null, $current_price, $data['buy_it_now_price'] ?? null, $data['min_bid_increment'] ?? MIN_BID_INCREMENT, $data['quantity'] ?? 1, $start_time, $end_time, $data['shipping_details'] ?? null ); if ($stmt->execute()) { $auction_id = $this->conn->insert_id; // Upload images if (!empty($images)) { $this->uploadAuctionImages($auction_id, $images); } // Log activity logActivity($this->user_id, 'create_auction', "Created auction: {$data['title']}"); // Update user auction count $this->conn->query("UPDATE users SET total_auctions = total_auctions + 1 WHERE user_id = $this->user_id"); return [ 'success' => true, 'auction_id' => $auction_id, 'slug' => $slug, 'message' => 'Auction created successfully' ]; } return ['success' => false, 'message' => 'Failed to create auction: ' . $this->conn->error]; } // Upload auction images private function uploadAuctionImages($auction_id, $images) { $max_images = getSetting('max_images_per_auction', MAX_IMAGES_PER_AUCTION); $count = 0; $primary_set = false; foreach ($images as $index => $image) { if ($count >= $max_images) break; $result = uploadImage($image, AUCTION_IMG_DIR); if ($result['success']) { $is_primary = (!$primary_set) ? 1 : 0; if ($is_primary) $primary_set = true; $sql = "INSERT INTO auction_images (auction_id, image_path, is_primary, display_order) VALUES (?, ?, ?, ?)"; $stmt = $this->conn->prepare($sql); $stmt->bind_param("isii", $auction_id, $result['filename'], $is_primary, $index); $stmt->execute(); $count++; } } } // Make slug unique private function makeSlugUnique($slug) { $original = $slug; $counter = 1; while ($this->slugExists($slug)) { $slug = $original . '-' . $counter; $counter++; } return $slug; } // Check if slug exists private function slugExists($slug) { $sql = "SELECT auction_id FROM auctions WHERE slug = ?"; $stmt = $this->conn->prepare($sql); $stmt->bind_param("s", $slug); $stmt->execute(); $result = $stmt->get_result(); return $result->num_rows > 0; } // Get user's auctions public function getUserAuctions($status = null, $limit = null, $offset = 0) { $sql = "SELECT a.*, c.category_name, (SELECT COUNT(*) FROM bids WHERE auction_id = a.auction_id) as bid_count, (SELECT MAX(bid_amount) FROM bids WHERE auction_id = a.auction_id) as highest_bid FROM auctions a JOIN categories c ON a.category_id = c.category_id WHERE a.seller_id = ?"; if ($status) { if (is_array($status)) { $placeholders = implode(',', array_fill(0, count($status), '?')); $sql .= " AND a.status IN ($placeholders)"; } else { $sql .= " AND a.status = ?"; } } $sql .= " ORDER BY a.created_at DESC"; if ($limit) { $sql .= " LIMIT ? OFFSET ?"; } $stmt = $this->conn->prepare($sql); // Build parameters array $params = [$this->user_id]; $types = "i"; if ($status) { if (is_array($status)) { $params = array_merge($params, $status); $types .= str_repeat('s', count($status)); } else { $params[] = $status; $types .= "s"; } } if ($limit) { $params[] = $limit; $params[] = $offset; $types .= "ii"; } $stmt->bind_param($types, ...$params); $stmt->execute(); $result = $stmt->get_result(); return $result->fetch_all(MYSQLI_ASSOC); } // Update auction public function updateAuction($auction_id, $data) { // Check ownership if (!$this->isOwner($auction_id)) { return ['success' => false, 'message' => 'You do not own this auction']; } // Check if auction can be edited (only pending or active with no bids) $auction = getAuctionById($auction_id); if ($auction['status'] != 'pending' && $auction['status'] != 'active') { return ['success' => false, 'message' => 'Auction cannot be edited in its current state']; } if ($auction['bid_count'] > 0) { return ['success' => false, 'message' => 'Cannot edit auction with existing bids']; } // Build update query $updates = []; $params = []; $types = ""; $allowed = ['title', 'description', 'category_id', 'condition', 'starting_price', 'reserve_price', 'buy_it_now_price', 'min_bid_increment', 'quantity', 'shipping_details']; foreach ($allowed as $field) { if (isset($data[$field])) { $updates[] = "$field = ?"; $params[] = $data[$field]; $types .= is_numeric($data[$field]) ? "i" : "s"; } } if (empty($updates)) { return ['success' => false, 'message' => 'No fields to update']; } // Add auction_id to params $params[] = $auction_id; $types .= "i"; $sql = "UPDATE auctions SET " . implode(', ', $updates) . " WHERE auction_id = ?"; $stmt = $this->conn->prepare($sql); $stmt->bind_param($types, ...$params); if ($stmt->execute()) { logActivity($this->user_id, 'update_auction', "Updated auction ID: $auction_id"); return ['success' => true, 'message' => 'Auction updated successfully']; } return ['success' => false, 'message' => 'Failed to update auction']; } // Cancel auction public function cancelAuction($auction_id) { // Check ownership if (!$this->isOwner($auction_id)) { return ['success' => false, 'message' => 'You do not own this auction']; } // Check if auction can be cancelled $auction = getAuctionById($auction_id); if ($auction['status'] != 'pending' && $auction['status'] != 'active') { return ['success' => false, 'message' => 'Auction cannot be cancelled in its current state']; } if ($auction['bid_count'] > 0) { // Notify bidders $bids = getAuctionBids($auction_id); foreach ($bids as $bid) { createNotification( $bid['bidder_id'], 'system', 'Auction Cancelled', "The auction '{$auction['title']}' has been cancelled by the seller.", SITE_URL . 'auction.php?slug=' . $auction['slug'] ); } } $sql = "UPDATE auctions SET status = 'cancelled' WHERE auction_id = ?"; $stmt = $this->conn->prepare($sql); $stmt->bind_param("i", $auction_id); if ($stmt->execute()) { logActivity($this->user_id, 'cancel_auction', "Cancelled auction ID: $auction_id"); return ['success' => true, 'message' => 'Auction cancelled successfully']; } return ['success' => false, 'message' => 'Failed to cancel auction']; } // Relist auction public function relistAuction($auction_id, $duration = null) { // Check ownership if (!$this->isOwner($auction_id)) { return ['success' => false, 'message' => 'You do not own this auction']; } $auction = getAuctionById($auction_id); if ($auction['status'] != 'ended' && $auction['status'] != 'sold') { return ['success' => false, 'message' => 'Only ended or sold auctions can be relisted']; } if (!$duration) { $duration = getSetting('min_auction_duration', MIN_AUCTION_DAYS); } $start_time = date('Y-m-d H:i:s'); $end_time = date('Y-m-d H:i:s', strtotime("+$duration days")); $sql = "UPDATE auctions SET status = 'pending', start_time = ?, end_time = ?, current_price = starting_price, winner_id = NULL, sold_price = NULL, payment_status = 'pending' WHERE auction_id = ?"; $stmt = $this->conn->prepare($sql); $stmt->bind_param("ssi", $start_time, $end_time, $auction_id); if ($stmt->execute()) { logActivity($this->user_id, 'relist_auction', "Relisted auction ID: $auction_id"); return ['success' => true, 'message' => 'Auction relisted successfully']; } return ['success' => false, 'message' => 'Failed to relist auction']; } // Check if user owns auction private function isOwner($auction_id) { $sql = "SELECT seller_id FROM auctions WHERE auction_id = ?"; $stmt = $this->conn->prepare($sql); $stmt->bind_param("i", $auction_id); $stmt->execute(); $result = $stmt->get_result(); $auction = $result->fetch_assoc(); return $auction && $auction['seller_id'] == $this->user_id; } // Get active auctions with filters public static function getActiveAuctions($filters = [], $page = 1, $per_page = AUCTIONS_PER_PAGE) { global $conn; $where = ["status = 'active'"]; $params = []; $types = ""; // Category filter if (!empty($filters['category'])) { $where[] = "a.category_id = ?"; $params[] = $filters['category']; $types .= "i"; } // Price range if (!empty($filters['min_price'])) { $where[] = "a.current_price >= ?"; $params[] = $filters['min_price']; $types .= "d"; } if (!empty($filters['max_price'])) { $where[] = "a.current_price <= ?"; $params[] = $filters['max_price']; $types .= "d"; } // Condition if (!empty($filters['condition'])) { if (is_array($filters['condition'])) { $placeholders = implode(',', array_fill(0, count($filters['condition']), '?')); $where[] = "a.condition IN ($placeholders)"; $params = array_merge($params, $filters['condition']); $types .= str_repeat('s', count($filters['condition'])); } else { $where[] = "a.condition = ?"; $params[] = $filters['condition']; $types .= "s"; } } // Search query if (!empty($filters['search'])) { $where[] = "(a.title LIKE ? OR a.description LIKE ?)"; $search_term = "%{$filters['search']}%"; $params[] = $search_term; $params[] = $search_term; $types .= "ss"; } // Featured only if (!empty($filters['featured'])) { $where[] = "a.featured = 1"; } // Ending soon (within 24 hours) if (!empty($filters['ending_soon'])) { $where[] = "a.end_time BETWEEN NOW() AND DATE_ADD(NOW(), INTERVAL 24 HOUR)"; } // New listings (last 24 hours) if (!empty($filters['new'])) { $where[] = "a.created_at >= DATE_SUB(NOW(), INTERVAL 24 HOUR)"; } $where_clause = implode(' AND ', $where); // Count total records $count_sql = "SELECT COUNT(*) as total FROM auctions a WHERE $where_clause"; $count_stmt = $conn->prepare($count_sql); if (!empty($params)) { $count_stmt->bind_param($types, ...$params); } $count_stmt->execute(); $count_result = $count_stmt->get_result(); $total_records = $count_result->fetch_assoc()['total']; $total_pages = ceil($total_records / $per_page); // Get records for current page $offset = ($page - 1) * $per_page; $sql = "SELECT a.*, u.username, u.full_name, u.rating, c.category_name, c.category_slug, (SELECT image_path FROM auction_images WHERE auction_id = a.auction_id AND is_primary = 1 LIMIT 1) as primary_image, (SELECT COUNT(*) FROM bids WHERE auction_id = a.auction_id) as bid_count, (SELECT MAX(bid_amount) FROM bids WHERE auction_id = a.auction_id) as highest_bid FROM auctions a JOIN users u ON a.seller_id = u.user_id JOIN categories c ON a.category_id = c.category_id WHERE $where_clause ORDER BY a.featured DESC, a.end_time ASC LIMIT ? OFFSET ?"; $stmt = $conn->prepare($sql); // Add pagination parameters $all_params = array_merge($params, [$per_page, $offset]); $all_types = $types . "ii"; if (!empty($all_params)) { $stmt->bind_param($all_types, ...$all_params); } $stmt->execute(); $result = $stmt->get_result(); return [ 'auctions' => $result->fetch_all(MYSQLI_ASSOC), 'total' => $total_records, 'pages' => $total_pages, 'current_page' => $page ]; } } ?>

5. includes/bidding_functions.php

<?php require_once 'functions.php'; class BiddingManager { private $conn; private $user_id; public function __construct($user_id = null) { global $conn; $this->conn = $conn; $this->user_id = $user_id ?: getCurrentUserId(); } // Place a bid public function placeBid($auction_id, $bid_amount) { // Check if user is logged in if (!$this->user_id) { return ['success' => false, 'message' => 'Please login to place a bid']; } // Get auction details $auction = getAuctionById($auction_id); if (!$auction) { return ['success' => false, 'message' => 'Auction not found']; } // Check if auction is active if ($auction['status'] != 'active') { return ['success' => false, 'message' => 'This auction is not active']; } // Check if auction has ended if (strtotime($auction['end_time']) < time()) { return ['success' => false, 'message' => 'This auction has ended']; } // Check if user is the seller if ($auction['seller_id'] == $this->user_id) { return ['success' => false, 'message' => 'You cannot bid on your own auction']; } // Get current highest bid $highest_bid = getHighestBid($auction_id); $current_price = $highest_bid ? $highest_bid['bid_amount'] : $auction['starting_price']; // Validate bid amount if ($bid_amount <= $current_price) { return ['success' => false, 'message' => 'Bid must be higher than current price']; } // Check minimum bid increment $min_increment = $auction['min_bid_increment']; if ($bid_amount < $current_price + $min_increment) { return ['success' => false, 'message' => 'Bid must be at least ' . formatCurrency($current_price + $min_increment)]; } // Check if user has enough balance (if using wallet system) // $user = getUserById($this->user_id); // if ($user['balance'] < $bid_amount) { // return ['success' => false, 'message' => 'Insufficient balance']; // } // Begin transaction $this->conn->begin_transaction(); try { // Insert bid $ip = $_SERVER['REMOTE_ADDR'] ?? ''; $sql = "INSERT INTO bids (auction_id, bidder_id, bid_amount, ip_address) VALUES (?, ?, ?, ?)"; $stmt = $this->conn->prepare($sql); $stmt->bind_param("iids", $auction_id, $this->user_id, $bid_amount, $ip); $stmt->execute(); $bid_id = $this->conn->insert_id; // Update auction current price and bid count $sql = "UPDATE auctions SET current_price = ?, bid_count = bid_count + 1 WHERE auction_id = ?"; $stmt = $this->conn->prepare($sql); $stmt->bind_param("di", $bid_amount, $auction_id); $stmt->execute(); // Mark previous winning bid as not winning if ($highest_bid) { $sql = "UPDATE bids SET is_winning = 0 WHERE bid_id = ?"; $stmt = $this->conn->prepare($sql); $stmt->bind_param("i", $highest_bid['bid_id']); $stmt->execute(); // Notify previous bidder that they've been outbid if ($highest_bid['bidder_id'] != $this->user_id) { $this->sendOutbidNotification($highest_bid['bidder_id'], $auction); } } // Mark new bid as winning $sql = "UPDATE bids SET is_winning = 1 WHERE bid_id = ?"; $stmt = $this->conn->prepare($sql); $stmt->bind_param("i", $bid_id); $stmt->execute(); // Add to watchlist automatically addToWatchlist($this->user_id, $auction_id); // Log activity logActivity($this->user_id, 'place_bid', "Placed bid of $bid_amount on auction ID: $auction_id"); // Commit transaction $this->conn->commit(); // Notify seller $this->notifySeller($auction['seller_id'], $auction, $bid_amount); return [ 'success' => true, 'bid_id' => $bid_id, 'message' => 'Bid placed successfully', 'new_price' => $bid_amount, 'bid_count' => $auction['bid_count'] + 1 ]; } catch (Exception $e) { $this->conn->rollback(); return ['success' => false, 'message' => 'Failed to place bid: ' . $e->getMessage()]; } } // Buy it now public function buyItNow($auction_id) { // Check if user is logged in if (!$this->user_id) { return ['success' => false, 'message' => 'Please login to purchase']; } // Get auction details $auction = getAuctionById($auction_id); if (!$auction) { return ['success' => false, 'message' => 'Auction not found']; } // Check if buy it now is available if (empty($auction['buy_it_now_price'])) { return ['success' => false, 'message' => 'Buy it now not available for this auction']; } // Check if auction is active if ($auction['status'] != 'active') { return ['success' => false, 'message' => 'This auction is not active']; } // Check if user is the seller if ($auction['seller_id'] == $this->user_id) { return ['success' => false, 'message' => 'You cannot buy your own item']; } // Begin transaction $this->conn->begin_transaction(); try { // Update auction status $sql = "UPDATE auctions SET status = 'sold', winner_id = ?, sold_price = buy_it_now_price, payment_status = 'pending', end_time = NOW() WHERE auction_id = ?"; $stmt = $this->conn->prepare($sql); $stmt->bind_param("ii", $this->user_id, $auction_id); $stmt->execute(); // Log activity logActivity($this->user_id, 'buy_it_now', "Purchased auction ID: $auction_id for " . $auction['buy_it_now_price']); // Commit transaction $this->conn->commit(); // Create transaction record $this->createTransaction($auction_id, $this->user_id, $auction['seller_id'], $auction['buy_it_now_price']); // Notify seller $this->notifySellerPurchase($auction['seller_id'], $auction, $this->user_id); // Notify other bidders that auction ended $this->notifyBiddersAuctionEnded($auction_id, $auction); return [ 'success' => true, 'message' => 'Item purchased successfully', 'redirect' => SITE_URL . 'user/payment.php?auction_id=' . $auction_id ]; } catch (Exception $e) { $this->conn->rollback(); return ['success' => false, 'message' => 'Failed to complete purchase: ' . $e->getMessage()]; } } // Create transaction record private function createTransaction($auction_id, $buyer_id, $seller_id, $amount) { $commission_rate = getSetting('commission_rate', COMMISSION_RATE); $commission = $amount * ($commission_rate / 100); $seller_amount = $amount - $commission; $sql = "INSERT INTO transactions (auction_id, buyer_id, seller_id, amount, commission, seller_amount) VALUES (?, ?, ?, ?, ?, ?)"; $stmt = $this->conn->prepare($sql); $stmt->bind_param("iiiddd", $auction_id, $buyer_id, $seller_id, $amount, $commission, $seller_amount); return $stmt->execute(); } // Send outbid notification private function sendOutbidNotification($user_id, $auction) { $title = "You've been outbid!"; $message = "Someone placed a higher bid on '{$auction['title']}'. Place another bid to win!"; $link = SITE_URL . 'auction.php?slug=' . $auction['slug']; createNotification($user_id, 'outbid', $title, $message, $link); // Send email $this->sendEmailNotification($user_id, $title, $message, $link); } // Notify seller of new bid private function notifySeller($seller_id, $auction, $bid_amount) { $title = "New bid on your auction"; $message = "Someone placed a bid of " . formatCurrency($bid_amount) . " on '{$auction['title']}'"; $link = SITE_URL . 'user/auction-details.php?id=' . $auction['auction_id']; createNotification($seller_id, 'bid', $title, $message, $link); } // Notify seller of purchase private function notifySellerPurchase($seller_id, $auction, $buyer_id) { $buyer = getUserById($buyer_id); $title = "Item sold!"; $message = "Your item '{$auction['title']}' was purchased by {$buyer['username']}"; $link = SITE_URL . 'user/my-auctions.php'; createNotification($seller_id, 'sold', $title, $message, $link); } // Notify bidders auction ended private function notifyBiddersAuctionEnded($auction_id, $auction) { $sql = "SELECT DISTINCT bidder_id FROM bids WHERE auction_id = ? AND bidder_id != ?"; $stmt = $this->conn->prepare($sql); $stmt->bind_param("ii", $auction_id, $auction['winner_id']); $stmt->execute(); $result = $stmt->get_result(); while ($row = $result->fetch_assoc()) { $title = "Auction ended"; $message = "The auction for '{$auction['title']}' has ended. You did not win this item."; $link = SITE_URL . 'auction.php?slug=' . $auction['slug']; createNotification($row['bidder_id'], 'ended', $title, $message, $link); } } // Get user's bidding history public function getBiddingHistory($status = null, $limit = null, $offset = 0) { $sql = "SELECT b.*, a.title, a.slug, a.status as auction_status, a.end_time, a.seller_id, a.buy_it_now_price, u.username as seller_username, (SELECT image_path FROM auction_images WHERE auction_id = a.auction_id AND is_primary = 1 LIMIT 1) as primary_image FROM bids b JOIN auctions a ON b.auction_id = a.auction_id JOIN users u ON a.seller_id = u.user_id WHERE b.bidder_id = ?"; if ($status) { $sql .= " AND a.status = ?"; } $sql .= " ORDER BY b.bid_time DESC"; if ($limit) { $sql .= " LIMIT ? OFFSET ?"; } $stmt = $this->conn->prepare($sql); if ($status && $limit) { $stmt->bind_param("isii", $this->user_id, $status, $limit, $offset); } elseif ($status) { $stmt->bind_param("is", $this->user_id, $status); } elseif ($limit) { $stmt->bind_param("iii", $this->user_id, $limit, $offset); } else { $stmt->bind_param("i", $this->user_id); } $stmt->execute(); $result = $stmt->get_result(); return $result->fetch_all(MYSQLI_ASSOC); } // Get won auctions public function getWonAuctions() { $sql = "SELECT a.*, u.username as seller_username, u.full_name as seller_name, t.transaction_id, t.payment_status, t.amount FROM auctions a JOIN users u ON a.seller_id = u.user_id LEFT JOIN transactions t ON a.auction_id = t.auction_id WHERE a.winner_id = ? AND a.status IN ('sold', 'ended') ORDER BY a.end_time DESC"; $stmt = $this->conn->prepare($sql); $stmt->bind_param("i", $this->user_id); $stmt->execute(); $result = $stmt->get_result(); return $result->fetch_all(MYSQLI_ASSOC); } // Simple email notification (placeholder - implement with PHPMailer) private function sendEmailNotification($user_id, $subject, $message, $link) { // In production, use PHPMailer or similar // $user = getUserById($user_id); // mail($user['email'], $subject, $message); } } ?>

6. index.php (Homepage)

<?php require_once 'includes/config.php'; require_once 'includes/functions.php'; require_once 'includes/auction_functions.php'; // Get featured auctions $featured = AuctionManager::getActiveAuctions(['featured' => true], 1, 6); // Get ending soon auctions $ending_soon = AuctionManager::getActiveAuctions(['ending_soon' => true], 1, 6); // Get categories $categories = getAllCategories(); // Get recent auctions $recent = AuctionManager::getActiveAuctions(['new' => true], 1, 8); ?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title><?php echo SITE_NAME; ?> - Online Auction Platform</title> <link rel="stylesheet" href="assets/css/style.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css"> </head> <body> <!-- Navigation --> <nav class="navbar"> <div class="container"> <div class="nav-brand"> <a href="index.php"> <i class="fas fa-gavel"></i> <?php echo SITE_NAME; ?> </a> </div> <div class="nav-search"> <form action="search.php" method="GET"> <input type="text" name="q" placeholder="Search for anything..."> <button type="submit"><i class="fas fa-search"></i></button> </form> </div> <ul class="nav-menu"> <li><a href="auctions.php">Browse</a></li> <li><a href="categories.php">Categories</a></li> <li><a href="how-it-works.php">How It Works</a></li> <?php if (isLoggedIn()): ?> <li class="dropdown"> <a href="#" class="dropdown-toggle"> <i class="fas fa-user-circle"></i> <?php echo $_SESSION['username']; ?> </a> <ul class="dropdown-menu"> <li><a href="user/dashboard.php"><i class="fas fa-tachometer-alt"></i> Dashboard</a></li> <li><a href="user/my-auctions.php"><i class="fas fa-list"></i> My Auctions</a></li> <li><a href="user/my-bids.php"><i class="fas fa-gavel"></i> My Bids</a></li> <li><a href="user/watchlist.php"><i class="fas fa-heart"></i> Watchlist</a></li> <li><a href="user/messages.php"><i class="fas fa-envelope"></i> Messages</a></li> <li><a href="user/profile.php"><i class="fas fa-user-cog"></i> Profile</a></li> <li><a href="user/logout.php"><i class="fas fa-sign-out-alt"></i> Logout</a></li> </ul> </li> <?php else: ?> <li><a href="user/login.php">Login</a></li> <li><a href="user/register.php" class="btn-register">Sign Up</a></li> <?php endif; ?> </ul> </div> </nav> <!-- Hero Section --> <section class="hero"> <div class="container"> <div class="hero-content"> <h1>Discover Amazing Items at Unbeatable Prices</h1> <p>Join millions of buyers and sellers on the world's most exciting auction platform</p> <div class="hero-buttons"> <a href="auctions.php" class="btn btn-primary">Start Bidding</a> <a href="user/create-auction.php" class="btn btn-secondary">Sell an Item</a> </div> <div class="hero-stats"> <div class="stat"> <span class="stat-number">500K+</span> <span class="stat-label">Active Users</span> </div> <div class="stat"> <span class="stat-number">1M+</span> <span class="stat-label">Items Sold</span> </div> <div class="stat"> <span class="stat-number">50K+</span> <span class="stat-label">Live Auctions</span> </div> </div> </div> <div class="hero-image"> <img src="assets/images/hero-auction.svg" alt="Auction Illustration"> </div> </div> </section> <!-- Categories Section --> <section class="categories-section"> <div class="container"> <h2 class="section-title">Browse by Category</h2> <div class="categories-grid"> <?php foreach ($categories as $category): ?> <a href="auctions.php?category=<?php echo $category['category_id']; ?>" class="category-card"> <i class="fas <?php echo $category['icon']; ?>"></i> <h3><?php echo $category['category_name']; ?></h3> <span class="category-count"><?php echo $category['auction_count']; ?> items</span> </a> <?php endforeach; ?> </div> </div> </section> <!-- Featured Auctions --> <?php if (!empty($featured['auctions'])): ?> <section class="featured-auctions"> <div class="container"> <h2 class="section-title">Featured Auctions</h2> <div class="auctions-grid"> <?php foreach ($featured['auctions'] as $auction): ?> <div class="auction-card"> <div class="auction-image"> <img src="uploads/auction_images/<?php echo $auction['primary_image'] ?? 'default.jpg'; ?>" alt="<?php echo htmlspecialchars($auction['title']); ?>"> <?php if ($auction['featured']): ?> <span class="featured-badge">Featured</span> <?php endif; ?> </div> <div class="auction-details"> <h3><a href="auction.php?slug=<?php echo $auction['slug']; ?>"><?php echo htmlspecialchars($auction['title']); ?></a></h3> <div class="auction-seller"> <i class="fas fa-user"></i> <?php echo htmlspecialchars($auction['username']); ?> </div> <div class="auction-price"> <span class="current-price"><?php echo formatCurrency($auction['current_price']); ?></span> <span class="bid-count"><?php echo $auction['bid_count']; ?> bids</span> </div> <div class="auction-timer" data-end="<?php echo $auction['end_time']; ?>"> <i class="fas fa-clock"></i> <span class="time-remaining"><?php echo getTimeRemaining($auction['end_time'])['text']; ?></span> </div> </div> </div> <?php endforeach; ?> </div> </div> </section> <?php endif; ?> <!-- Ending Soon --> <?php if (!empty($ending_soon['auctions'])): ?> <section class="ending-soon"> <div class="container"> <h2 class="section-title">Ending Soon</h2> <div class="auctions-grid"> <?php foreach ($ending_soon['auctions'] as $auction): ?> <div class="auction-card ending-soon"> <div class="auction-image"> <img src="uploads/auction_images/<?php echo $auction['primary_image'] ?? 'default.jpg'; ?>" alt="<?php echo htmlspecialchars($auction['title']); ?>"> <span class="urgent-badge">Ending Soon</span> </div> <div class="auction-details"> <h3><a href="auction.php?slug=<?php echo $auction['slug']; ?>"><?php echo htmlspecialchars($auction['title']); ?></a></h3> <div class="auction-price"> <span class="current-price"><?php echo formatCurrency($auction['current_price']); ?></span> </div> <div class="auction-timer urgent" data-end="<?php echo $auction['end_time']; ?>"> <i class="fas fa-hourglass-half"></i> <span class="time-remaining"><?php echo getTimeRemaining($auction['end_time'])['text']; ?></span> </div> </div> </div> <?php endforeach; ?> </div> </div> </section> <?php endif; ?> <!-- How It Works --> <section class="how-it-works"> <div class="container"> <h2 class="section-title">How It Works</h2> <div class="steps"> <div class="step"> <div class="step-number">1</div> <i class="fas fa-user-plus"></i> <h3>Create Account</h3> <p>Sign up for free and start exploring thousands of auctions</p> </div> <div class="step"> <div class="step-number">2</div> <i class="fas fa-search"></i> <h3>Find Items</h3> <p>Browse categories or search for specific items you want</p> </div> <div class="step"> <div class="step-number">3</div> <i class="fas fa-gavel"></i> <h3>Place Bids</h3> <p>Bid on items and win them at the best prices</p> </div> <div class="step"> <div class="step-number">4</div> <i class="fas fa-truck"></i> <h3>Receive Items</h3> <p>Pay securely and get your items delivered</p> </div> </div> </div> </section> <!-- CTA Section --> <section class="cta"> <div class="container"> <h2>Ready to start bidding?</h2> <p>Join our community of buyers and sellers today</p> <div class="cta-buttons"> <a href="user/register.php" class="btn btn-primary btn-large">Create Free Account</a> <a href="auctions.php" class="btn btn-outline-light btn-large">Browse Auctions</a> </div> </div> </section> <!-- Footer --> <footer class="footer"> <div class="container"> <div class="footer-content"> <div class="footer-section"> <h4><?php echo SITE_NAME; ?></h4> <p>The premier online auction platform for buyers and sellers.</p> </div> <div class="footer-section"> <h4>Quick Links</h4> <ul> <li><a href="about.php">About Us</a></li> <li><a href="how-it-works.php">How It Works</a></li> <li><a href="faq.php">FAQ</a></li> <li><a href="contact.php">Contact</a></li> </ul> </div> <div class="footer-section"> <h4>Legal</h4> <ul> <li><a href="terms.php">Terms of Service</a></li> <li><a href="privacy.php">Privacy Policy</a></li> <li><a href="returns.php">Returns Policy</a></li> </ul> </div> <div class="footer-section"> <h4>Follow Us</h4> <div class="social-links"> <a href="#"><i class="fab fa-facebook"></i></a> <a href="#"><i class="fab fa-twitter"></i></a> <a href="#"><i class="fab fa-instagram"></i></a> <a href="#"><i class="fab fa-linkedin"></i></a> </div> </div> </div> <div class="footer-bottom"> <p>&copy; <?php echo date('Y'); ?> <?php echo SITE_NAME; ?>. All rights reserved.</p> </div> </div> </footer> <script src="assets/js/jquery.min.js"></script> <script src="assets/js/main.js"></script> <script src="assets/js/countdown.js"></script> <script> // Initialize countdown timers document.querySelectorAll('.auction-timer').forEach(timer => { const endTime = timer.dataset.end; updateCountdown(timer, endTime); }); </script> </body> </html>

How to Use This Project - Step by Step Guide

Step 1: System Requirements

  • XAMPP/WAMP/MAMP (PHP 7.4+)
  • MySQL 5.7+ or MariaDB
  • Web server (Apache/Nginx)
  • Web browser (Chrome, Firefox, Edge)
  • 2GB RAM minimum
  • 500MB free disk space

Step 2: Installation Process

2.1 Download and Setup

  1. Install XAMPP/WAMP
  • Download from official websites
  • Install with default settings
  • Start Apache and MySQL services
  1. Create Project Folder
 # Navigate to htdocs (XAMPP) or www (WAMP) cd C:\xampp\htdocs\ # Create project folder mkdir online-auction-system # Extract all files into this folder

2.2 Database Configuration

  1. Open phpMyAdmin
  • Navigate to http://localhost/phpmyadmin
  • Login with default credentials (root, no password)
  1. Create Database
  • Click "New" on left sidebar
  • Enter database name: auction_system
  • Choose utf8mb4_general_ci collation
  • Click "Create"
  1. Import Database
  • Select the newly created database
  • Click "Import" tab
  • Choose file: database/auction_system.sql
  • Click "Go" to import
  1. Verify Import
  • Check if all tables are created (users, auctions, bids, etc.)
  • Default admin user should be created

2.3 Configure Project

  1. Update Configuration
  • Open includes/config.php
  • Update database credentials if needed:
 define('DB_HOST', 'localhost'); define('DB_USER', 'root'); define('DB_PASS', ''); // Add password if set define('DB_NAME', 'auction_system');
  1. Set Folder Permissions
 # Create upload directories mkdir uploads mkdir uploads/auction_images mkdir uploads/temp # Set permissions (Linux/Mac) chmod -R 755 uploads/ chmod -R 755 assets/images/ # Windows: Right-click folders -> Properties -> Security -> Give write permissions
  1. Configure Email Settings (Optional)
  • Update SMTP settings in includes/config.php
  • Set your email credentials for notifications

Step 3: Access the System

3.1 Frontend Access

  • Open browser and go to: http://localhost/online-auction-system/
  • You should see the homepage with:
  • Navigation menu
  • Hero section
  • Categories grid
  • Featured auctions
  • Ending soon auctions

3.2 Admin Access

  • Admin login: http://localhost/online-auction-system/admin/login.php
  • Default credentials:
  • Username: admin
  • Password: Admin@123

Step 4: Test User Features

4.1 User Registration

  1. Click "Sign Up" in navigation
  2. Fill registration form:
  • Username
  • Email
  • Password
  • Full name (optional)
  1. Submit form
  2. Check email for verification link (if enabled)

4.2 User Login

  1. Click "Login" in navigation
  2. Enter credentials
  3. Verify redirect to dashboard

4.3 Browse Auctions

  1. Click "Browse" in navigation
  2. View all active auctions
  3. Use filters:
  • Category
  • Price range
  • Condition
  1. Sort by:
  • Ending soonest
  • Newest
  • Price: Low to High
  • Price: High to Low

4.4 View Auction Details

  1. Click on any auction
  2. View:
  • Images gallery
  • Description
  • Current price
  • Time remaining
  • Bid history
  • Seller information
  1. Add to watchlist
  2. Share auction

4.5 Place a Bid

  1. Login to your account
  2. Navigate to an active auction
  3. Enter bid amount in the bid form
  4. Click "Place Bid"
  5. Verify bid appears in bid history
  6. Check outbid notification (if applicable)

4.6 Create an Auction

  1. Login and go to Dashboard
  2. Click "Create New Auction"
  3. Fill auction details:
  • Title (required)
  • Category (required)
  • Description (required)
  • Condition
  • Starting price (required)
  • Reserve price (optional)
  • Buy it now price (optional)
  • Duration in days
  • Upload images (up to 10)
  1. Submit for approval
  2. Check status in "My Auctions"

4.7 Manage Watchlist

  1. Browse auctions
  2. Click heart icon to add to watchlist
  3. Go to Dashboard > Watchlist
  4. View all watched auctions
  5. Remove from watchlist

4.8 Track Bids

  1. Go to Dashboard > My Bids
  2. View:
  • Active bids
  • Winning bids
  • Lost bids
  1. Click on auction to bid again

4.9 Buy It Now

  1. Find auction with Buy It Now option
  2. Click "Buy It Now" button
  3. Confirm purchase
  4. Proceed to payment

4.10 Leave Reviews

  1. After winning an auction
  2. Go to Dashboard > Won Auctions
  3. Click "Leave Review"
  4. Rate seller (1-5 stars)
  5. Write review comment

Step 5: Test Admin Features

5.1 Admin Dashboard

  1. Login as admin
  2. View dashboard statistics:
  • Total users
  • Total auctions
  • Active auctions
  • Total revenue
  • Recent activity

5.2 User Management

  1. Go to Admin > Users
  2. View all registered users
  3. Search/filter users
  4. Edit user details
  5. Suspend/activate users
  6. Delete users (if needed)

5.3 Auction Management

  1. Go to Admin > Auctions
  2. View pending auctions for approval
  3. Approve or reject auctions
  4. Feature/unfeature auctions
  5. View all auctions with filters
  6. Edit/remove inappropriate auctions

5.4 Category Management

  1. Go to Admin > Categories
  2. Add new categories
  3. Edit existing categories
  4. Delete categories
  5. Set category icons and order

5.5 Transaction Monitoring

  1. Go to Admin > Transactions
  2. View all completed sales
  3. Track payment status
  4. Calculate commissions
  5. Generate reports

5.6 Site Settings

  1. Go to Admin > Settings
  2. Configure:
  • Site name and URL
  • Commission rate
  • Auction duration limits
  • Image upload limits
  • Email settings
  • Payment gateway settings

Step 6: Advanced Features

6.1 Email Notifications

The system sends email notifications for:

  • Registration verification
  • Password reset
  • Outbid alerts
  • Auction won
  • Auction ended
  • New bids on your items
  • Payment received

6.2 Real-time Updates

  • Bid updates via AJAX
  • Countdown timers
  • Auto-refresh of bid history
  • Live outbid notifications

6.3 Payment Integration

The system supports:

  • PayPal integration (sandbox/live)
  • Stripe payment gateway
  • Manual payment processing
  • Transaction tracking

6.4 Search Functionality

  • Full-text search on auction titles and descriptions
  • Filter by category, price, condition
  • Sort by multiple criteria
  • Pagination support

Step 7: Customization Options

7.1 Theme Customization

  1. Modify CSS variables in assets/css/style.css
  2. Change color scheme
  3. Update logo and branding
  4. Customize layout

7.2 Feature Configuration

Edit includes/config.php to:

  • Enable/disable features
  • Change auction duration limits
  • Set commission rates
  • Configure payment gateways
  • Modify email templates

7.3 Language/Internationalization

  1. Add language files
  2. Modify currency settings
  3. Set timezone
  4. Add multi-language support

Step 8: Security Considerations

8.1 Implemented Security Features

  • Password hashing (MD5 - upgrade to password_hash for production)
  • CSRF protection
  • SQL injection prevention (prepared statements)
  • XSS protection (htmlspecialchars)
  • Session management
  • Input validation
  • File upload restrictions

8.2 Production Security Checklist

  • [ ] Change default admin password
  • [ ] Enable HTTPS/SSL
  • [ ] Update password hashing to bcrypt
  • [ ] Set proper file permissions
  • [ ] Enable firewall
  • [ ] Regular backups
  • [ ] Monitor error logs
  • [ ] Rate limiting on API
  • [ ] CAPTCHA on forms

Step 9: Troubleshooting Common Issues

9.1 Database Connection Error

  • Check MySQL service is running
  • Verify credentials in config.php
  • Check database exists

9.2 File Upload Issues

  • Check folder permissions
  • Verify PHP upload limits in php.ini
  • Check file size and type restrictions

9.3 Email Not Working

  • Verify SMTP settings
  • Check spam folder
  • Test with mail() function first

9.4 Session Issues

  • Clear browser cache
  • Check session save path
  • Verify cookie settings

9.5 Payment Gateway Issues

  • Use sandbox mode for testing
  • Check API credentials
  • Verify webhook URLs

Step 10: Deployment to Production

10.1 Server Requirements

  • PHP 7.4 or higher
  • MySQL 5.7 or higher
  • Apache/Nginx with mod_rewrite
  • SSL certificate
  • 2GB RAM minimum
  • 20GB storage

10.2 Deployment Steps

  1. Prepare Files
  • Remove debug code
  • Minify CSS/JS
  • Optimize images
  • Update configuration
  1. Upload Files
  • Use FTP or Git deployment
  • Set correct permissions
  • Create upload directories
  1. Database Migration
  • Export local database
  • Import to production server
  • Update database credentials
  1. Configure Server
  • Enable mod_rewrite
  • Set PHP memory limit
  • Configure email server
  • Set up cron jobs for:
    • Auction status updates
    • Email notifications
    • Backup tasks
  1. Testing
  • Test all features
  • Check responsive design
  • Verify payment gateways
  • Test email notifications
  1. Go Live
  • Update DNS records
  • Enable HTTPS
  • Monitor error logs
  • Set up analytics

System Features Summary

For Users:

  • ✅ User registration and login
  • ✅ Email verification
  • ✅ Password recovery
  • ✅ Browse auctions by category
  • ✅ Advanced search with filters
  • ✅ View auction details with images
  • ✅ Place bids with automatic outbid notification
  • ✅ Buy it now option
  • ✅ Watchlist/favorite auctions
  • ✅ Create and manage auctions
  • ✅ Track bidding history
  • ✅ View won auctions
  • ✅ Leave seller reviews
  • ✅ Message system
  • ✅ Dashboard with statistics
  • ✅ Profile management

For Sellers:

  • ✅ Create auction listings
  • ✅ Upload multiple images
  • ✅ Set reserve price
  • ✅ Set buy it now price
  • ✅ Manage active auctions
  • ✅ View bid history
  • ✅ Relist unsold items
  • ✅ Track sales
  • ✅ Communicate with buyers
  • ✅ Receive payment notifications

For Admins:

  • ✅ Complete dashboard
  • ✅ User management
  • ✅ Auction moderation
  • ✅ Category management
  • ✅ Transaction monitoring
  • ✅ Site settings
  • ✅ Report generation
  • ✅ Featured auction management
  • ✅ System logs
  • ✅ Email template management

Technical Features:

  • ✅ Responsive design
  • ✅ Mobile-friendly
  • ✅ SEO optimized URLs
  • ✅ AJAX real-time updates
  • ✅ Secure payment integration
  • ✅ Email notifications
  • ✅ Search functionality
  • ✅ Pagination
  • ✅ File upload with validation
  • ✅ Session management
  • ✅ CSRF protection
  • ✅ SQL injection prevention

This comprehensive Online Auction System provides a complete marketplace solution with all the features needed for a successful auction platform. The modular architecture allows for easy customization and scaling. Both user and admin interfaces are intuitive and feature-rich, making it suitable for small to medium-sized auction websites.

Leave a Reply

Your email address will not be published. Required fields are marked *


Macro Nepal Helper