|
Server IP : 217.21.85.138 / Your IP : 216.73.216.103 Web Server : LiteSpeed System : Linux in-mum-web906.main-hosting.eu 4.18.0-553.37.1.lve.el8.x86_64 #1 SMP Mon Feb 10 22:45:17 UTC 2025 x86_64 User : u915722082 ( 915722082) PHP Version : 7.4.33 Disable Function : system, exec, shell_exec, passthru, mysql_list_dbs, ini_alter, dl, symlink, link, chgrp, leak, popen, apache_child_terminate, virtual, mb_send_mail MySQL : OFF | cURL : ON | WGET : ON | Perl : OFF | Python : OFF Directory (0755) : /home/u915722082/.nvm/../public_html/lohri/user/ |
| [ Home ] | [ C0mmand ] | [ Upload File ] |
|---|
<?php
declare(strict_types=1);
header('Content-Type: application/json; charset=utf-8');
if (session_status() == PHP_SESSION_NONE) {
session_start();
}
require_once __DIR__ . '/../config/config.php';
try {
$pdo = new PDO(
"mysql:host=" . DB_HOST . ";dbname=" . DB_NAME . ";charset=utf8mb4",
DB_USER,
DB_PASS,
[
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
]
);
$pdo->exec("SET time_zone = '+05:30'");
} catch (PDOException $e) {
echo json_encode(['success' => false, 'message' => 'Database connection failed']);
exit;
}
// ============================================
// ✅ CHECK OFFER STATUS (for polling)
// ============================================
if (isset($_POST['action']) && $_POST['action'] === 'check_offer_status') {
$productId = isset($_POST['product_id']) ? (int)$_POST['product_id'] : 0;
if ($productId <= 0 || !isset($_SESSION['user_id'])) {
echo json_encode(['success' => false, 'message' => 'Invalid request']);
exit;
}
$userId = (int)$_SESSION['user_id'];
try {
$checkSql = "SELECT offer_id, offer_amount, status, offer_valid_until,
CASE
WHEN status = 'accepted' AND offer_valid_until < NOW() THEN 1
ELSE 0
END as is_expired
FROM tbl_offers
WHERE user_id = :user_id
AND product_id = :product_id
ORDER BY created_at DESC
LIMIT 1";
$stmt = $pdo->prepare($checkSql);
$stmt->execute([':user_id' => $userId, ':product_id' => $productId]);
$offer = $stmt->fetch();
if ($offer) {
echo json_encode([
'success' => true,
'has_offer' => true,
'offer_status' => $offer['status'],
'offer_amount' => $offer['offer_amount'],
'offer_valid_until' => $offer['offer_valid_until'],
'is_expired' => (bool)$offer['is_expired']
]);
} else {
echo json_encode([
'success' => true,
'has_offer' => false,
'offer_status' => null
]);
}
} catch (PDOException $e) {
error_log('Check offer status error: ' . $e->getMessage());
echo json_encode(['success' => false, 'message' => 'Database error']);
}
exit;
}
// ============================================
// ✅ ARCHIVE EXPIRED OFFERS HANDLER
// ============================================
if (isset($_POST['action']) && $_POST['action'] === 'archive_expired') {
try {
$pdo->exec("SET time_zone = '+05:30'");
// Create archive table if not exists
$checkTableSql = "SHOW TABLES LIKE 'tbl_offers_archive'";
$tableExists = $pdo->query($checkTableSql)->rowCount() > 0;
if (!$tableExists) {
$createTableSql = "CREATE TABLE IF NOT EXISTS tbl_offers_archive (
archive_id INT AUTO_INCREMENT PRIMARY KEY,
offer_id INT NOT NULL,
product_id INT,
variant_id INT,
variant_title VARCHAR(255),
variant_attributes TEXT,
user_name VARCHAR(255),
user_email VARCHAR(255),
user_phone VARCHAR(20),
offer_amount DECIMAL(10,2),
status VARCHAR(50),
rejection_reason TEXT,
offer_valid_until DATETIME,
created_at DATETIME,
updated_at DATETIME,
archived_at DATETIME DEFAULT CURRENT_TIMESTAMP,
expiration_reason VARCHAR(100),
INDEX idx_offer_id (offer_id),
INDEX idx_archived_at (archived_at),
INDEX idx_user_email (user_email),
INDEX idx_product_id (product_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4";
$pdo->exec($createTableSql);
}
// Find expired offers
$findExpiredSql = "SELECT o.*, p.pname as product_name
FROM tbl_offers o
LEFT JOIN products p ON o.product_id = p.pid
WHERE o.status = 'accepted'
AND o.offer_valid_until IS NOT NULL
AND o.offer_valid_until <= NOW()";
$findStmt = $pdo->query($findExpiredSql);
$expiredOffers = $findStmt->fetchAll();
$archivedCount = 0;
$expiredIds = [];
foreach ($expiredOffers as $offer) {
$variantAttributes = $offer['variant_attributes'] ?? '';
if (is_array($variantAttributes)) {
$variantAttributes = json_encode($variantAttributes);
}
$archiveSql = "INSERT INTO tbl_offers_archive
(offer_id, product_id, variant_id, variant_title, variant_attributes,
user_name, user_email, user_phone, offer_amount,
status, rejection_reason, offer_valid_until,
created_at, updated_at, expiration_reason)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'Offer validity expired')";
$archiveStmt = $pdo->prepare($archiveSql);
$success = $archiveStmt->execute([
$offer['offer_id'],
$offer['product_id'],
$offer['variant_id'] ?? null,
$offer['variant_title'] ?? '',
$variantAttributes,
$offer['user_name'] ?? '',
$offer['user_email'] ?? '',
$offer['user_phone'] ?? '',
$offer['offer_amount'],
$offer['status'],
$offer['rejection_reason'] ?? null,
$offer['offer_valid_until'],
$offer['created_at'],
$offer['updated_at'] ?? date('Y-m-d H:i:s')
]);
if ($success) {
$deleteSql = "DELETE FROM tbl_offers WHERE offer_id = ?";
$deleteStmt = $pdo->prepare($deleteSql);
$deleteStmt->execute([$offer['offer_id']]);
$expiredIds[] = $offer['offer_id'];
$archivedCount++;
error_log("✅ Archived expired offer #" . $offer['offer_id']);
}
}
echo json_encode([
'success' => true,
'archived_count' => $archivedCount,
'expired_ids' => $expiredIds,
'message' => $archivedCount > 0
? "$archivedCount offer(s) archived successfully"
: "No expired offers found"
]);
exit;
} catch (PDOException $e) {
error_log('Archive error: ' . $e->getMessage());
echo json_encode([
'success' => false,
'message' => 'Archive failed: ' . $e->getMessage()
]);
exit;
}
}
// ============================================
// ✅ DELETE EXPIRED OFFER (Client-side cleanup)
// ============================================
// ============================================
// ✅ DELETE EXPIRED OFFER (Client-side cleanup) - NOW WITH ARCHIVING
// ============================================
if (isset($_POST['action']) && $_POST['action'] === 'delete_expired_offer') {
$productId = isset($_POST['product_id']) ? (int)$_POST['product_id'] : (int)($_POST['pid'] ?? 0);
if ($productId <= 0) {
echo json_encode(['success' => false, 'message' => 'Invalid product ID']);
exit;
}
try {
if (isset($_SESSION['user_id'])) {
$userId = (int)$_SESSION['user_id'];
// ✅ STEP 1: Get the expired offer before deleting
$selectSql = "SELECT o.*, p.pname as product_name
FROM tbl_offers o
LEFT JOIN products p ON o.product_id = p.pid
WHERE o.user_id = :user_id
AND o.product_id = :product_id
AND o.offer_valid_until < NOW()";
$selectStmt = $pdo->prepare($selectSql);
$selectStmt->execute([
':user_id' => $userId,
':product_id' => $productId
]);
$expiredOffer = $selectStmt->fetch();
if ($expiredOffer) {
// ✅ STEP 2: Create archive table if not exists
$checkTableSql = "SHOW TABLES LIKE 'tbl_offers_archive'";
$tableExists = $pdo->query($checkTableSql)->rowCount() > 0;
if (!$tableExists) {
$createTableSql = "CREATE TABLE IF NOT EXISTS tbl_offers_archive (
archive_id INT AUTO_INCREMENT PRIMARY KEY,
offer_id INT NOT NULL,
product_id INT,
variant_id INT,
variant_title VARCHAR(255),
variant_attributes TEXT,
user_name VARCHAR(255),
user_email VARCHAR(255),
user_phone VARCHAR(20),
offer_amount DECIMAL(10,2),
status VARCHAR(50),
rejection_reason TEXT,
offer_valid_until DATETIME,
created_at DATETIME,
updated_at DATETIME,
archived_at DATETIME DEFAULT CURRENT_TIMESTAMP,
expiration_reason VARCHAR(100),
INDEX idx_offer_id (offer_id),
INDEX idx_archived_at (archived_at),
INDEX idx_user_email (user_email),
INDEX idx_product_id (product_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4";
$pdo->exec($createTableSql);
}
// ✅ STEP 3: Archive the offer
$variantAttributes = $expiredOffer['variant_attributes'] ?? '';
if (is_array($variantAttributes)) {
$variantAttributes = json_encode($variantAttributes);
}
$archiveSql = "INSERT INTO tbl_offers_archive
(offer_id, product_id, variant_id, variant_title, variant_attributes,
user_name, user_email, user_phone, offer_amount,
status, rejection_reason, offer_valid_until,
created_at, updated_at, expiration_reason)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'Offer validity expired - client cleanup')";
$archiveStmt = $pdo->prepare($archiveSql);
$archiveStmt->execute([
$expiredOffer['offer_id'],
$expiredOffer['product_id'],
$expiredOffer['variant_id'] ?? null,
$expiredOffer['variant_title'] ?? '',
$variantAttributes,
$expiredOffer['user_name'] ?? '',
$expiredOffer['user_email'] ?? '',
$expiredOffer['user_phone'] ?? '',
$expiredOffer['offer_amount'],
$expiredOffer['status'],
$expiredOffer['rejection_reason'] ?? null,
$expiredOffer['offer_valid_until'],
$expiredOffer['created_at'],
$expiredOffer['updated_at'] ?? date('Y-m-d H:i:s')
]);
error_log("✅ Archived expired offer #" . $expiredOffer['offer_id']);
}
// ✅ STEP 4: Now delete the offer
$deleteSql = "DELETE FROM tbl_offers
WHERE user_id = :user_id
AND product_id = :product_id
AND offer_valid_until < NOW()";
$deleteStmt = $pdo->prepare($deleteSql);
$deleteStmt->execute([
':user_id' => $userId,
':product_id' => $productId
]);
$rowsDeleted = $deleteStmt->rowCount();
echo json_encode([
'success' => true,
'message' => 'Expired offer archived and deleted',
'rows_deleted' => $rowsDeleted,
'archived' => !empty($expiredOffer)
]);
} else {
echo json_encode(['success' => false, 'message' => 'User not logged in']);
}
exit;
} catch (PDOException $e) {
error_log('Delete expired offer error: ' . $e->getMessage());
echo json_encode(['success' => false, 'message' => 'Database error']);
exit;
}
}
// ============================================
// SEND ADMIN EMAIL NOTIFICATION
// ============================================
function sendAdminOfferNotification($product_name, $variant_title, $user_name, $user_email, $offer_amount, $product_id, $offer_id) {
try {
$possible_paths = [
'../vendor/autoload.php',
'../../../vendor/autoload.php',
'../../vendor/autoload.php',
dirname(__DIR__) . '/vendor/autoload.php'
];
$autoloader_found = false;
foreach ($possible_paths as $path) {
if (file_exists($path)) {
require_once $path;
$autoloader_found = true;
break;
}
}
if (!$autoloader_found || !class_exists('PHPMailer\PHPMailer\PHPMailer')) {
error_log("PHPMailer not found");
return false;
}
$mail = new PHPMailer\PHPMailer\PHPMailer(true);
$mail->isSMTP();
$mail->Host = SMTP_HOST;
$mail->SMTPAuth = true;
$mail->Username = SMTP_USERNAME;
$mail->Password = SMTP_PASSWORD;
$mail->SMTPSecure = PHPMailer\PHPMailer\PHPMailer::ENCRYPTION_STARTTLS;
$mail->Port = defined('SMTP_PORT') ? SMTP_PORT : 587;
$from_email = defined('SMTP_FROM_EMAIL') ? SMTP_FROM_EMAIL : SMTP_USERNAME;
$from_name = defined('SMTP_FROM_NAME') ? SMTP_FROM_NAME : 'TDS Marketplace';
$mail->setFrom($from_email, $from_name);
if (defined('ADMIN_EMAIL') && !empty(ADMIN_EMAIL)) {
$mail->addAddress(ADMIN_EMAIL);
} else {
error_log("ADMIN_EMAIL not defined");
return false;
}
$mail->Subject = 'New Offer Received - TDS Marketplace';
$mail->isHTML(true);
$mail->Body = "
<div style='font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto; padding: 20px;'>
<h1 style='text-align: center;'>New Offer Received</h1>
<table style='width: 100%; border-collapse: collapse; margin: 25px 0;'>
<tr><td style='padding: 10px; border: 1px solid #ddd;'><strong>Product:</strong></td>
<td style='padding: 10px; border: 1px solid #ddd;'>$product_name</td></tr>
<tr><td style='padding: 10px; border: 1px solid #ddd;'><strong>Variant:</strong></td>
<td style='padding: 10px; border: 1px solid #ddd;'>$variant_title</td></tr>
<tr><td style='padding: 10px; border: 1px solid #ddd;'><strong>Offer Amount:</strong></td>
<td style='padding: 10px; border: 1px solid #ddd;'>₹" . number_format($offer_amount, 2) . "</td></tr>
<tr><td style='padding: 10px; border: 1px solid #ddd;'><strong>Customer:</strong></td>
<td style='padding: 10px; border: 1px solid #ddd;'>$user_name ($user_email)</td></tr>
</table>
<p style='text-align: center;'>
<a href='http://" . $_SERVER['HTTP_HOST'] . "/admin/offers.php'
style='background: #000; color: #fff; padding: 12px 30px; text-decoration: none; border-radius: 4px;'>
Review in Admin Panel
</a>
</p>
</div>";
$mail->send();
return true;
} catch (Exception $e) {
error_log("Email failed: " . $e->getMessage());
return false;
}
}
// ============================================
// ✅ SUBMIT NEW OFFER
// ============================================
if (!isset($_SESSION['user_id'])) {
echo json_encode(['success' => false, 'message' => 'Please log in to make an offer']);
exit;
}
if ($_SERVER['REQUEST_METHOD'] !== 'POST' || !isset($_POST['offer_amount'])) {
// Not an offer submission, exit silently
exit;
}
$userId = (int)$_SESSION['user_id'];
$userEmail = $_SESSION['user_email'] ?? '';
$userName = $_SESSION['user_name'] ?? '';
$userPhone = $_SESSION['user_phone'] ?? '';
$productId = isset($_POST['product_id']) ? (int)$_POST['product_id'] : (int)($_POST['pid'] ?? 0);
$variantId = isset($_POST['variant_id']) ? (int)$_POST['variant_id'] : null;
$variantTitle = trim($_POST['variant_title'] ?? '');
$variantAttributes = $_POST['variant_attributes'] ?? '{}';
$offerAmount = (float)($_POST['offer_amount'] ?? 0);
if ($productId <= 0) {
echo json_encode(['success' => false, 'message' => 'Invalid product']);
exit;
}
if ($offerAmount < 1) {
echo json_encode(['success' => false, 'message' => 'Offer amount must be at least ₹1.00']);
exit;
}
try {
// Check for existing pending/accepted offers
$checkSql = "SELECT offer_id, offer_amount, status
FROM tbl_offers
WHERE user_id = :user_id
AND product_id = :product_id
AND status IN ('pending', 'accepted')
LIMIT 1";
$checkStmt = $pdo->prepare($checkSql);
$checkStmt->execute([':user_id' => $userId, ':product_id' => $productId]);
$existingOffer = $checkStmt->fetch();
if ($existingOffer) {
$statusMessage = $existingOffer['status'] === 'pending'
? 'You already have a pending offer. Please wait for admin response.'
: 'You have an active approved offer. Please wait for it to expire.';
echo json_encode([
'success' => false,
'message' => $statusMessage,
'existing_offer' => true,
'offer_id' => $existingOffer['offer_id'],
'status' => $existingOffer['status']
]);
exit;
}
// Insert new offer
$insertSql = "INSERT INTO tbl_offers
(product_id, variant_id, variant_title, variant_attributes, user_id,
user_email, user_name, user_phone, offer_amount, created_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, NOW())";
$insertStmt = $pdo->prepare($insertSql);
$insertStmt->execute([
$productId, $variantId, $variantTitle, $variantAttributes,
$userId, $userEmail, $userName, $userPhone, $offerAmount
]);
$offerId = $pdo->lastInsertId();
// Get product name
$productStmt = $pdo->prepare("SELECT pname FROM products WHERE pid = ? LIMIT 1");
$productStmt->execute([$productId]);
$product = $productStmt->fetch();
$productName = $product['pname'] ?? 'Unknown Product';
// Send email
$emailSent = sendAdminOfferNotification(
$productName, $variantTitle, $userName,
$userEmail, $offerAmount, $productId, $offerId
);
echo json_encode([
'success' => true,
'message' => 'Offer submitted successfully!',
'offer_id' => $offerId,
'email_sent' => $emailSent,
'offer_data' => [
'offer_id' => $offerId,
'offer_amount' => $offerAmount,
'product_id' => $productId,
'status' => 'pending'
]
]);
} catch (PDOException $e) {
error_log('Offer submission error: ' . $e->getMessage());
echo json_encode(['success' => false, 'message' => 'Failed to submit offer']);
}
?>