File manager - Edit - /home/webapp69.cm.in.th/u69319090036/Shop/Shop/cart.php
Back
<?php // cart.php - Shopping Cart and Checkout handler require_once 'db_connect.php'; // Enforce login if (!isLoggedIn()) { header("Location: login.php?redirect=cart.php&error=" . urlencode("Please log in to view your shopping cart.")); exit(); } $user = getLoggedInUser(); $action = $_GET['action'] ?? ''; // Handle Actions if ($_SERVER['REQUEST_METHOD'] === 'POST') { // ACTION: ADD TO CART if ($action === 'add') { $productId = intval($_POST['product_id'] ?? 0); $quantity = intval($_POST['quantity'] ?? 1); $size = trim($_POST['size'] ?? 'Standard'); $color = trim($_POST['color'] ?? 'Standard'); if (empty($size)) $size = 'Standard'; if (empty($color)) $color = 'Standard'; if ($productId <= 0 || $quantity <= 0) { header("Location: index.php?error=" . urlencode("Invalid product options selected.")); exit(); } // Validate stock $stmt = $pdo->prepare("SELECT stock, title FROM products WHERE id = ?"); $stmt->execute([$productId]); $product = $stmt->fetch(); if (!$product) { header("Location: index.php?error=" . urlencode("Product not found.")); exit(); } if ($product['stock'] < $quantity) { header("Location: index.php?error=" . urlencode("Insufficient stock. Only {$product['stock']} item(s) left.")); exit(); } // Check if item is already in the cart with the same parameters $stmt = $pdo->prepare("SELECT id, quantity FROM cart WHERE user_id = ? AND product_id = ? AND size = ? AND color = ?"); $stmt->execute([$user['id'], $productId, $size, $color]); $existing = $stmt->fetch(); if ($existing) { $newQty = $existing['quantity'] + $quantity; if ($product['stock'] < $newQty) { header("Location: index.php?error=" . urlencode("Cannot add more. Combined cart quantity exceeds stock.")); exit(); } $update = $pdo->prepare("UPDATE cart SET quantity = ? WHERE id = ?"); $update->execute([$newQty, $existing['id']]); } else { $insert = $pdo->prepare("INSERT INTO cart (user_id, product_id, quantity, size, color) VALUES (?, ?, ?, ?, ?)"); $insert->execute([$user['id'], $productId, $quantity, $size, $color]); } header("Location: cart.php?success=" . urlencode("Added to shopping cart successfully.")); exit(); } // ACTION: UPDATE QUANTITY if ($action === 'update') { $cartId = intval($_POST['cart_id'] ?? 0); $quantity = intval($_POST['quantity'] ?? 0); if ($cartId > 0 && $quantity > 0) { // Verify ownership and check stock $stmt = $pdo->prepare(" SELECT c.id, c.user_id, p.stock FROM cart c JOIN products p ON c.product_id = p.id WHERE c.id = ? "); $stmt->execute([$cartId]); $item = $stmt->fetch(); if ($item && intval($item['user_id']) === intval($user['id'])) { if ($item['stock'] >= $quantity) { $update = $pdo->prepare("UPDATE cart SET quantity = ? WHERE id = ?"); $update->execute([$quantity, $cartId]); } else { header("Location: cart.php?error=" . urlencode("Cannot update. Only {$item['stock']} items available.")); exit(); } } } header("Location: cart.php"); exit(); } // ACTION: SIMULATED CHECKOUT TRANSACTION if ($action === 'checkout') { $shipping_address = trim($_POST['shipping_address'] ?? ''); $payment_method = $_POST['payment_method'] ?? 'COD'; if (empty($shipping_address)) { header("Location: cart.php?error=" . urlencode("Shipping address is required for checkout.")); exit(); } // Get cart items to checkout $stmt = $pdo->prepare(" SELECT c.*, p.title, p.price, p.stock FROM cart c JOIN products p ON c.product_id = p.id WHERE c.user_id = ? "); $stmt->execute([$user['id']]); $items = $stmt->fetchAll(); if (empty($items)) { header("Location: cart.php?error=" . urlencode("Your cart is empty.")); exit(); } try { $pdo->beginTransaction(); $subtotal = 0; // Validate stock levels foreach ($items as $item) { if ($item['stock'] < $item['quantity']) { throw new Exception("Product '{$item['title']}' has insufficient stock. Only {$item['stock']} remaining."); } $subtotal += floatval($item['price']) * intval($item['quantity']); } $shippingFee = 5.00; $grandTotal = $subtotal + $shippingFee; // 1. Create order $orderStmt = $pdo->prepare(" INSERT INTO orders (buyer_id, total_amount, shipping_address, payment_method, status) VALUES (?, ?, ?, ?, 'Pending') "); $orderStmt->execute([$user['id'], $grandTotal, $shipping_address, $payment_method]); $orderId = $pdo->lastInsertId(); // 2. Insert items, deduct stock, remove from cart $itemInsert = $pdo->prepare(" INSERT INTO order_items (order_id, product_id, quantity, price, size, color) VALUES (?, ?, ?, ?, ?, ?) "); $stockDeduct = $pdo->prepare("UPDATE products SET stock = stock - ? WHERE id = ?"); $cartClear = $pdo->prepare("DELETE FROM cart WHERE id = ?"); foreach ($items as $item) { $itemInsert->execute([ $orderId, $item['product_id'], $item['quantity'], $item['price'], $item['size'], $item['color'] ]); $stockDeduct->execute([$item['quantity'], $item['product_id']]); $cartClear->execute([$item['id']]); } // Save default shipping address if not set if (empty($user['shipping_address'])) { $addrUpdate = $pdo->prepare("UPDATE users SET shipping_address = ? WHERE id = ?"); $addrUpdate->execute([$shipping_address, $user['id']]); } $pdo->commit(); header("Location: index.php?success=" . urlencode("Checkout successful! Order placed. Order ID is TV-{$orderId}.")); exit(); } catch (Exception $e) { if ($pdo->inTransaction()) { $pdo->rollBack(); } header("Location: cart.php?error=" . urlencode($e->getMessage())); exit(); } } } // Handle GET Action (Removal) if ($action === 'remove') { $cartId = intval($_GET['cart_id'] ?? 0); if ($cartId > 0) { $stmt = $pdo->prepare("SELECT user_id FROM cart WHERE id = ?"); $stmt->execute([$cartId]); $item = $stmt->fetch(); if ($item && intval($item['user_id']) === intval($user['id'])) { $delete = $pdo->prepare("DELETE FROM cart WHERE id = ?"); $delete->execute([$cartId]); } } header("Location: cart.php?success=" . urlencode("Item removed from cart.")); exit(); } // Fetch Cart items to display $stmt = $pdo->prepare(" SELECT c.*, p.title, p.price, p.stock, p.images, u.username as seller_name FROM cart c JOIN products p ON c.product_id = p.id JOIN users u ON p.seller_id = u.id WHERE c.user_id = ? "); $stmt->execute([$user['id']]); $cartItems = $stmt->fetchAll(); // Calculate subtotal $subtotal = 0; foreach ($cartItems as $item) { $subtotal += floatval($item['price']) * intval($item['quantity']); } $shippingFee = count($cartItems) > 0 ? 5.00 : 0.00; $grandTotal = $subtotal + $shippingFee; renderHeader(__('cart_page_title')); ?> <div class="grid grid-cols-1 lg:grid-cols-12 gap-8 items-start"> <!-- Left Side: Cart Items list --> <div class="lg:col-span-8 space-y-4"> <h2 class="text-2xl font-extrabold text-gray-900 tracking-tight mb-6"><?php echo __('cart_heading'); ?></h2> <?php if (empty($cartItems)): ?> <div class="text-center py-16 bg-white rounded-3xl border border-gray-100 shadow-sm space-y-4"> <div class="w-16 h-16 bg-orange-50 border border-orange-100 text-orange-500 rounded-2xl flex items-center justify-center mx-auto"> <svg class="w-8 h-8" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M3 3h2l.4 2M7 13h10l4-8H5.4M7 13L5.4 5M7 13l-2.293 2.293c-.63.63-.184 1.707.707 1.707H17m0 0a2 2 0 100 4 2 2 0 000-4zm-8 2a2 2 0 11-4 0 2 2 0 014 0z"/></svg> </div> <h3 class="text-xl font-bold text-gray-900"><?php echo __('cart_empty_title'); ?></h3> <p class="text-sm text-gray-500 max-w-xs mx-auto"><?php echo __('cart_empty_desc'); ?></p> <a href="index.php" class="inline-block px-6 py-2.5 bg-gradient-to-r from-orange-500 to-rose-500 text-white font-bold rounded-xl shadow-md hover:shadow-lg transition-all text-sm"><?php echo __('cart_start_shopping'); ?></a> </div> <?php else: ?> <div class="space-y-4"> <?php foreach ($cartItems as $item): $price = floatval($item['price']); $itemTotal = ($price * intval($item['quantity'])); $img = getProductImgUrl($item['product_id'], $item['images']); ?> <div class="bg-white p-5 rounded-2xl border border-gray-100 shadow-sm flex flex-col sm:flex-row items-start sm:items-center justify-between gap-4 relative"> <!-- Details --> <div class="flex items-center gap-4 flex-1"> <img src="<?php echo $img; ?>" alt="<?php echo sanitize($item['title']); ?>" class="w-16 h-16 rounded-xl object-cover border border-gray-100" onerror="this.onerror=null; this.src='https://images.unsplash.com/photo-1526170375885-4d8ecf77b99f?w=100';" > <div class="space-y-1"> <span class="text-[9px] font-bold text-gray-400 uppercase tracking-widest"><?php echo __('cart_store'); ?> <?php echo sanitize($item['seller_name']); ?></span> <h4 class="font-bold text-gray-900 text-sm sm:text-base"><?php echo sanitize($item['title']); ?></h4> <div class="flex items-center gap-3 text-xs font-semibold text-gray-400"> <?php if (!empty($item['size']) && $item['size'] !== 'Standard'): ?> <span><?php echo __('cart_option'); ?> <strong class="text-gray-700"><?php echo sanitize($item['size']); ?></strong></span> <?php endif; ?> <?php if (!empty($item['color']) && $item['color'] !== 'Standard'): ?> <span><?php echo __('cart_variant'); ?> <strong class="text-gray-700"><?php echo sanitize($item['color']); ?></strong></span> <?php endif; ?> </div> </div> </div> <!-- Controls --> <div class="flex items-center justify-between w-full sm:w-auto sm:justify-end gap-6 border-t border-gray-100 sm:border-0 pt-3 sm:pt-0"> <!-- Qty update form --> <form action="cart.php?action=update" method="POST" class="flex items-center border border-gray-200 rounded-lg overflow-hidden bg-gray-50 text-xs"> <input type="hidden" name="cart_id" value="<?php echo $item['id']; ?>"> <button type="submit" name="quantity" value="<?php echo $item['quantity'] - 1; ?>" class="px-2.5 py-1 text-gray-500 hover:bg-gray-100 font-bold" <?php echo $item['quantity'] <= 1 ? 'disabled' : ''; ?>>-</button> <span class="px-3.5 py-1 font-bold text-gray-900 bg-white border-x border-gray-100 w-8 text-center"><?php echo $item['quantity']; ?></span> <button type="submit" name="quantity" value="<?php echo $item['quantity'] + 1; ?>" class="px-2.5 py-1 text-gray-500 hover:bg-gray-100 font-bold" <?php echo $item['quantity'] >= $item['stock'] ? 'disabled' : ''; ?>>+</button> </form> <!-- Price info --> <div class="text-right"> <span class="block text-base font-black text-rose-600">$<?php echo number_format($itemTotal, 2); ?></span> <a href="cart.php?action=remove&cart_id=<?php echo $item['id']; ?>" class="text-xs font-semibold text-gray-400 hover:text-red-500 transition-colors"><?php echo __('cart_remove'); ?></a> </div> </div> </div> <?php endforeach; ?> </div> <?php endif; ?> </div> <!-- Right Side: Order summary & Checkout --> <?php if (!empty($cartItems)): ?> <div class="lg:col-span-4 bg-white p-6 rounded-3xl border border-gray-100 shadow-sm space-y-6 lg:sticky lg:top-24"> <h3 class="font-bold text-gray-900 text-lg border-b border-gray-100 pb-4"><?php echo __('cart_checkout_title'); ?></h3> <form action="cart.php?action=checkout" method="POST" class="space-y-6"> <!-- Shipping Address --> <div class="space-y-2"> <label for="shipping_address" class="block text-xs font-bold uppercase tracking-wider text-gray-500"><?php echo __('cart_shipping_label'); ?></label> <textarea name="shipping_address" id="shipping_address" rows="3" required placeholder="<?php echo __('cart_shipping_ph'); ?>" class="w-full p-3 bg-gray-50 border border-gray-200 rounded-xl text-sm focus:outline-none focus:bg-white focus:ring-2 focus:ring-orange-500/20 focus:border-orange-500 transition-all" ><?php echo sanitize($user['shipping_address']); ?></textarea> </div> <!-- Payment Method --> <div class="space-y-2"> <label class="block text-xs font-bold uppercase tracking-wider text-gray-500"><?php echo __('cart_payment_label'); ?></label> <div class="grid grid-cols-1 gap-2.5"> <label class="flex items-center gap-3 p-3 rounded-xl border border-gray-200 hover:border-orange-500 cursor-pointer bg-gray-50/50 text-xs"> <input type="radio" name="payment_method" value="COD" checked class="text-orange-500 focus:ring-orange-500"> <div> <strong class="block text-gray-900"><?php echo __('cart_cod_title'); ?></strong> <span class="text-gray-400"><?php echo __('cart_cod_desc'); ?></span> </div> </label> <label class="flex items-center gap-3 p-3 rounded-xl border border-gray-200 hover:border-orange-500 cursor-pointer bg-gray-50/50 text-xs"> <input type="radio" name="payment_method" value="Credit Card" class="text-orange-500 focus:ring-orange-500"> <div> <strong class="block text-gray-900"><?php echo __('cart_cc_title'); ?></strong> <span class="text-gray-400"><?php echo __('cart_cc_desc'); ?></span> </div> </label> </div> </div> <!-- Calculations --> <div class="space-y-3 text-xs border-t border-gray-100 pt-4"> <div class="flex justify-between text-gray-500"> <span><?php echo __('cart_subtotal'); ?></span> <span class="font-bold text-gray-900">$<?php echo number_format($subtotal, 2); ?></span> </div> <div class="flex justify-between text-gray-500"> <span><?php echo __('cart_shipping_fee'); ?></span> <span class="font-bold text-gray-900">$<?php echo number_format($shippingFee, 2); ?></span> </div> <div class="border-t border-gray-100 pt-3 flex justify-between text-sm font-black text-gray-900"> <span><?php echo __('cart_total'); ?></span> <span class="text-rose-600 text-base">$<?php echo number_format($grandTotal, 2); ?></span> </div> </div> <button type="submit" class="w-full py-3 bg-gradient-to-r from-orange-500 to-rose-500 text-white font-extrabold rounded-xl shadow-lg hover:shadow-xl transition-all hover:-translate-y-0.5 focus:outline-none"> <?php echo __('cart_place_order'); ?> </button> </form> </div> <?php endif; ?> </div> <?php renderFooter(); ?>
| ver. 1.4 |
Github
|
.
| PHP 7.4.33 | Generation time: 0.25 |
proxy
|
phpinfo
|
Settings