File manager - Edit - /home/webapp69.cm.in.th/u69319090044/shop/admin.php
Back
<?php // admin.php - Product Management Panel for Admin Accounts require_once 'includes/helper.php'; require_once 'classes/Product.php'; start_secure_session(); // Check if user is logged in and is an admin if (!isset($_SESSION['user_id']) || $_SESSION['role'] !== 'admin') { header("Location: index.php"); exit(); } $productObj = new Product(); $error = ''; $success = ''; $csrfToken = generate_csrf_token(); $action = $_GET['action'] ?? 'list'; $editProduct = null; // Handle Product actions (Add, Edit, Delete) if ($_SERVER['REQUEST_METHOD'] === 'POST') { $token = $_POST['csrf_token'] ?? ''; if (!validate_csrf_token($token)) { $error = "ระบบความปลอดภัย: CSRF Token ไม่ถูกต้อง"; } else { $postAction = $_POST['action'] ?? ''; if ($postAction === 'create' || $postAction === 'update') { $name = trim($_POST['name'] ?? ''); $description = trim($_POST['description'] ?? ''); $price = (float)($_POST['price'] ?? 0); $stock = (int)($_POST['stock'] ?? 0); $size = trim($_POST['size'] ?? 'Free Size'); $imageUrl = trim($_POST['image_url'] ?? ''); // Handle file upload if (isset($_FILES['product_image']) && $_FILES['product_image']['error'] === UPLOAD_ERR_OK) { $fileTmpPath = $_FILES['product_image']['tmp_name']; $fileName = $_FILES['product_image']['name']; $fileSize = $_FILES['product_image']['size']; $fileType = $_FILES['product_image']['type']; $fileNameCmps = explode(".", $fileName); $fileExtension = strtolower(end($fileNameCmps)); $allowedExtensions = ['jpg', 'jpeg', 'png', 'gif', 'webp']; if (in_array($fileExtension, $allowedExtensions)) { $newFileName = md5(time() . $fileName) . '.' . $fileExtension; $uploadAssetsDir = __DIR__ . '/assets/products/'; $uploadThaiDir = __DIR__ . '/รูป/products/'; // Create directories if they do not exist if (!is_dir($uploadAssetsDir)) { mkdir($uploadAssetsDir, 0755, true); } if (!is_dir($uploadThaiDir)) { mkdir($uploadThaiDir, 0755, true); } $destAssets = $uploadAssetsDir . $newFileName; $destThai = $uploadThaiDir . $newFileName; if (move_uploaded_file($fileTmpPath, $destAssets)) { @copy($destAssets, $destThai); $imageUrl = 'assets/products/' . $newFileName; } else if (move_uploaded_file($fileTmpPath, $destThai)) { @copy($destThai, $destAssets); $imageUrl = 'assets/products/' . $newFileName; } else { $error = "เกิดข้อผิดพลาดในการบันทึกไฟล์รูปภาพ"; } } else { $error = "ประเภทไฟล์ไม่ได้รับอนุญาต (อนุญาตเฉพาะ JPG, PNG, GIF, WEBP)"; } } if (empty($name)) { $error = "กรุณากรอกชื่อสินค้า"; } else if ($price < 0) { $error = "ราคาสินค้าต้องไม่น้อยกว่า 0"; } else if ($stock < 0) { $error = "จำนวนสต็อกสินค้าต้องไม่น้อยกว่า 0"; } else if (empty($error)) { if ($postAction === 'create') { if ($productObj->create($name, $description, $price, $stock, $imageUrl, $size)) { $success = "เพิ่มสินค้าใหม่เรียบร้อยแล้ว!"; $action = 'list'; } else { $error = "ไม่สามารถบันทึกข้อมูลสินค้าได้"; } } else if ($postAction === 'update') { $id = (int)$_POST['id']; if ($productObj->update($id, $name, $description, $price, $stock, $imageUrl, $size)) { $success = "แก้ไขข้อมูลสินค้าสำเร็จ!"; $action = 'list'; } else { $error = "ไม่สามารถแก้ไขข้อมูลสินค้าได้"; } } } } else if ($postAction === 'delete') { $id = (int)$_POST['id']; if ($productObj->delete($id)) { $success = "ลบสินค้าสำเร็จ!"; $action = 'list'; } else { $error = "ไม่สามารถลบสินค้าได้"; } } } } // Fetch edit product if edit action requested if ($action === 'edit' && isset($_GET['id'])) { $editId = (int)$_GET['id']; $editProduct = $productObj->getById($editId); if (!$editProduct) { $error = "ไม่พบสินค้าที่ต้องการแก้ไข"; $action = 'list'; } } $products = $productObj->getAll(); require_once 'includes/header.php'; ?> <div class="max-w-7xl mx-auto my-4 sm:my-6 px-4"> <div class="flex flex-col sm:flex-row items-center justify-between gap-4 mb-8"> <div> <h2 class="text-2xl sm:text-3xl font-extrabold text-white tracking-tight flex items-center gap-3 justify-center sm:justify-start"> <span>🛠️</span> จัดการสินค้า (Admin Panel) </h2> <p class="text-slate-400 text-sm mt-1">เพิ่ม ลด แก้ไข และลบสินค้าคงคลังของ CMTC SHOP</p> </div> <?php if ($action === 'list'): ?> <a href="admin.php?action=add" class="px-5 py-2.5 bg-gradient-to-r from-violet-600 to-indigo-600 hover:from-violet-500 hover:to-indigo-500 text-white font-bold rounded-xl shadow-lg transition-all text-sm active:scale-95"> + เพิ่มสินค้าใหม่ </a> <?php else: ?> <a href="admin.php?action=list" class="px-5 py-2.5 bg-slate-900 border border-slate-800 text-slate-300 hover:text-white font-bold rounded-xl transition-all text-sm active:scale-95"> ← กลับรายการสินค้า </a> <?php endif; ?> </div> <?php if ($error): ?> <div class="bg-red-950/60 border border-red-800 text-red-300 p-4 rounded-2xl text-sm mb-6 animate-pulse"> ⚠️ <?= escape($error) ?> </div> <?php endif; ?> <?php if ($success): ?> <div class="bg-emerald-950/60 border border-emerald-800 text-emerald-300 p-4 rounded-2xl text-sm mb-6"> 🎉 <?= escape($success) ?> </div> <?php endif; ?> <!-- 1. ADD / EDIT PRODUCT FORM --> <?php if ($action === 'add' || $action === 'edit'): ?> <div class="glass p-6 sm:p-8 rounded-3xl max-w-2xl mx-auto shadow-2xl"> <h3 class="text-xl font-bold text-white mb-6 border-b border-slate-900 pb-3 flex items-center gap-2"> <span><?= $action === 'edit' ? '📝 แก้ไขข้อมูลสินค้า' : '✨ เพิ่มสินค้าใหม่' ?></span> </h3> <form action="admin.php?action=<?= $action ?><?= $action === 'edit' ? '&id=' . $editProduct['id'] : '' ?>" method="POST" enctype="multipart/form-data" class="space-y-5"> <input type="hidden" name="csrf_token" value="<?= escape($csrfToken) ?>"> <input type="hidden" name="action" value="<?= $action === 'edit' ? 'update' : 'create' ?>"> <?php if ($action === 'edit'): ?> <input type="hidden" name="id" value="<?= $editProduct['id'] ?>"> <?php endif; ?> <div> <label class="block text-xs font-bold text-slate-400 uppercase tracking-wider mb-2">ชื่อสินค้า <span class="text-red-500">*</span></label> <input type="text" name="name" required value="<?= escape($editProduct['name'] ?? '') ?>" class="w-full px-4 py-2.5 bg-slate-900 border border-slate-800 focus:border-violet-500 rounded-xl focus:ring-1 focus:ring-violet-500 outline-none text-slate-100 placeholder-slate-600 transition-all text-sm" placeholder="ระบุชื่อสินค้า เช่น เสื้อยืดลายพราง"> </div> <div> <label class="block text-xs font-bold text-slate-400 uppercase tracking-wider mb-2">รายละเอียดสินค้า</label> <textarea name="description" rows="4" class="w-full px-4 py-2.5 bg-slate-900 border border-slate-800 focus:border-violet-500 rounded-xl focus:ring-1 focus:ring-violet-500 outline-none text-slate-100 placeholder-slate-600 transition-all text-sm resize-none" placeholder="ระบุคำอธิบายเกี่ยวกับสินค้าคัดเลือก..."><?= escape($editProduct['description'] ?? '') ?></textarea> </div> <div class="grid grid-cols-1 sm:grid-cols-3 gap-4"> <div> <label class="block text-xs font-bold text-slate-400 uppercase tracking-wider mb-2">ราคาจำหน่าย (บาท) <span class="text-red-500">*</span></label> <input type="number" step="0.01" min="0" name="price" required value="<?= escape($editProduct['price'] ?? '0.00') ?>" class="w-full px-4 py-2.5 bg-slate-900 border border-slate-800 focus:border-violet-500 rounded-xl focus:ring-1 focus:ring-violet-500 outline-none text-slate-100 placeholder-slate-600 transition-all text-sm" placeholder="0.00"> </div> <div> <label class="block text-xs font-bold text-slate-400 uppercase tracking-wider mb-2">ขนาด (Size)</label> <select name="size" class="w-full px-4 py-2.5 bg-slate-900 border border-slate-800 focus:border-violet-500 rounded-xl focus:ring-1 focus:ring-violet-500 outline-none text-slate-100 transition-all text-sm"> <?php $sizes = ['Free Size', 'XS', 'S', 'M', 'L', 'XL', 'XXL', '38', '39', '40', '41', '42', '43', '44']; $currentSize = $editProduct['size'] ?? 'Free Size'; foreach ($sizes as $s): ?> <option value="<?= escape($s) ?>" <?= $currentSize === $s ? 'selected' : '' ?>><?= escape($s) ?></option> <?php endforeach; ?> </select> </div> <div> <label class="block text-xs font-bold text-slate-400 uppercase tracking-wider mb-2">สต็อกคงเหลือ <span class="text-red-500">*</span></label> <input type="number" min="0" name="stock" required value="<?= escape($editProduct['stock'] ?? '0') ?>" class="w-full px-4 py-2.5 bg-slate-900 border border-slate-800 focus:border-violet-500 rounded-xl focus:ring-1 focus:ring-violet-500 outline-none text-slate-100 placeholder-slate-600 transition-all text-sm" placeholder="0"> </div> </div> <div> <label class="block text-xs font-bold text-slate-400 uppercase tracking-wider mb-2">รูปภาพสินค้า</label> <?php if ($action === 'edit' && !empty($editProduct['image_url'])): ?> <?php $editImg = get_product_image_url($editProduct['image_url'] ?? '', $editProduct['name'] ?? ''); ?> <div class="flex items-center gap-3 mb-3 p-3 bg-slate-900/60 rounded-xl border border-slate-800"> <img src="<?= escape($editImg) ?>" class="w-12 h-12 object-cover rounded-lg border border-slate-800" onerror="if(!this.dataset.tried){ this.dataset.tried='1'; this.src=(this.src.indexOf('assets/')!==-1 ? this.src.replace('assets/','รูป/') : this.src.replace('รูป/','assets/')); } else { this.style.display='none'; }"> <div class="text-xs"> <p class="text-slate-300 font-bold">รูปภาพปัจจุบัน</p> <p class="text-slate-500"><?= escape($editProduct['image_url']) ?></p> </div> </div> <?php endif; ?> <div class="space-y-2"> <input type="file" name="product_image" accept="image/*" class="block w-full text-xs text-slate-400 file:mr-4 file:py-2 file:px-4 file:rounded-xl file:border-0 file:text-xs file:font-semibold file:bg-violet-600/20 file:text-violet-400 hover:file:bg-violet-600/30 file:cursor-pointer"> <p class="text-[10px] text-slate-500">หรือระบุลิงก์/เส้นทางไฟล์รูปภาพด้านล่าง:</p> <input type="text" name="image_url" value="<?= escape($editProduct['image_url'] ?? '') ?>" class="w-full px-4 py-2.5 bg-slate-900 border border-slate-800 focus:border-violet-500 rounded-xl focus:ring-1 focus:ring-violet-500 outline-none text-slate-100 placeholder-slate-600 transition-all text-sm" placeholder="assets/products/filename.png"> </div> </div> <div class="border-t border-slate-900 pt-5 mt-6"> <button type="submit" class="w-full py-3.5 bg-gradient-to-r from-violet-600 to-indigo-600 hover:from-violet-500 hover:to-indigo-500 text-white font-bold rounded-xl shadow-lg transition-all text-sm sm:text-base active:scale-95"> <?= $action === 'edit' ? 'บันทึกการแก้ไข' : 'บันทึกสินค้าใหม่' ?> </button> </div> </form> </div> <!-- 2. PRODUCTS LIST TABLE --> <?php else: ?> <div class="glass rounded-3xl overflow-hidden shadow-2xl border border-slate-800"> <div class="overflow-x-auto"> <table class="w-full text-left border-collapse text-sm"> <thead> <tr class="bg-slate-900/60 border-b border-slate-800 text-slate-300 font-bold"> <th class="p-4 sm:p-5">สินค้า</th> <th class="p-4 sm:p-5">รายละเอียด</th> <th class="p-4 sm:p-5 text-center">ขนาด</th> <th class="p-4 sm:p-5 text-right">ราคา</th> <th class="p-4 sm:p-5 text-center">สต็อก</th> <th class="p-4 sm:p-5 text-center">การจัดการ</th> </tr> </thead> <tbody class="divide-y divide-slate-900/60 text-slate-200"> <?php if (empty($products)): ?> <tr> <td colspan="6" class="p-8 text-center text-slate-500">ยังไม่มีสินค้าในระบบ</td> </tr> <?php else: ?> <?php foreach ($products as $product): ?> <tr class="hover:bg-slate-900/20 transition-colors"> <!-- Product Info & Image --> <td class="p-4 sm:p-5"> <div class="flex items-center gap-3"> <div class="w-12 h-12 bg-slate-900 border border-slate-800 rounded-lg flex items-center justify-center overflow-hidden flex-shrink-0"> <?php $adminImg = get_product_image_url($product['image_url'] ?? '', $product['name'] ?? ''); ?> <?php if (!empty($adminImg)): ?> <img src="<?= escape($adminImg) ?>" alt="<?= escape($product['name']) ?>" class="w-full h-full object-cover" onerror="if(!this.dataset.tried){ this.dataset.tried='1'; this.src=(this.src.indexOf('assets/')!==-1 ? this.src.replace('assets/','รูป/') : this.src.replace('รูป/','assets/')); } else { this.style.display='none'; if(this.nextElementSibling) this.nextElementSibling.style.display='inline'; }"> <span class="text-xl hidden">🛍️</span> <?php else: ?> <span class="text-xl">🛍️</span> <?php endif; ?> </div> <div> <h4 class="font-bold text-slate-100 leading-tight"><?= escape($product['name']) ?></h4> <span class="text-[10px] text-slate-500">ID: <?= $product['id'] ?></span> </div> </div> </td> <!-- Description --> <td class="p-4 sm:p-5 max-w-xs sm:max-w-sm truncate text-slate-400 text-xs"> <?= escape($product['description']) ?> </td> <!-- Size --> <td class="p-4 sm:p-5 text-center whitespace-nowrap"> <span class="px-2.5 py-0.5 rounded-full text-xs font-bold bg-indigo-950/80 text-indigo-400 border border-indigo-800"> <?= escape($product['size'] ?? 'Free Size') ?> </span> </td> <!-- Price --> <td class="p-4 sm:p-5 text-right font-bold text-violet-400 whitespace-nowrap"> <?= format_price($product['price']) ?> </td> <!-- Stock --> <td class="p-4 sm:p-5 text-center whitespace-nowrap"> <span class="px-2.5 py-0.5 rounded-full text-xs font-bold <?= $product['stock'] > 0 ? 'bg-emerald-950/80 text-emerald-400 border border-emerald-800' : 'bg-red-950/80 text-red-400 border border-red-800' ?>"> <?= $product['stock'] ?> ชิ้น </span> </td> <!-- Actions --> <td class="p-4 sm:p-5 text-center"> <div class="flex items-center justify-center gap-2"> <!-- Edit Button --> <a href="admin.php?action=edit&id=<?= $product['id'] ?>" class="px-3 py-1.5 bg-slate-900 border border-slate-800 text-slate-300 hover:bg-violet-600 hover:border-violet-500 hover:text-white text-xs font-bold rounded-lg transition-all active:scale-95"> แก้ไข </a> <!-- Delete Button --> <form action="admin.php" method="POST" onsubmit="return confirm('คุณแน่ใจหรือไม่ว่าต้องการลบสินค้านี้?');" class="inline"> <input type="hidden" name="csrf_token" value="<?= escape($csrfToken) ?>"> <input type="hidden" name="action" value="delete"> <input type="hidden" name="id" value="<?= $product['id'] ?>"> <button type="submit" class="px-3 py-1.5 bg-slate-900 border border-slate-800 text-red-400 hover:bg-red-950 hover:border-red-900/60 hover:text-red-300 text-xs font-bold rounded-lg transition-all active:scale-95"> ลบ </button> </form> </div> </td> </tr> <?php endforeach; ?> <?php endif; ?> </tbody> </table> </div> </div> <?php endif; ?> </div> <?php require_once 'includes/footer.php'; ?>
| ver. 1.4 |
Github
|
.
| PHP 7.4.33 | Generation time: 0.25 |
proxy
|
phpinfo
|
Settings