File manager - Edit - /home/webapp69.cm.in.th/u69319090046/02_shop/config.php
Back
<?php // Session initialization for authentication if (session_status() === PHP_SESSION_NONE) { session_start(); } // Configuration & Store Setup define('STORE_NAME', 'APEX STUDIO'); define('PRODUCT_NAME', 'Apex Heavyweight Oversized Tee'); define('PRODUCT_PRICE', 390); // THB define('SHIPPING_FEE', 50); // THB define('FREE_SHIPPING_MIN_QTY', 2); define('TOTAL_STOCK_LIMIT', 350); // Total Campaign Limit define('INITIAL_ORDER_OFFSET', 284); // Initial reserved count define('ADMIN_PASSWORD', '1234'); // Admin login password define('DATA_DIR', __DIR__ . '/data'); define('UPLOADS_DIR', __DIR__ . '/uploads'); define('ORDERS_FILE', DATA_DIR . '/orders.json'); define('CUSTOM_PRODUCTS_FILE', DATA_DIR . '/custom_products.json'); define('DB_FILE', DATA_DIR . '/database.sqlite'); // Database Type: 'sqlite' or 'mysql' define('DB_TYPE', 'sqlite'); define('DB_HOST', '127.0.0.1'); define('DB_NAME', 'apex_studio'); define('DB_USER', 'root'); define('DB_PASS', ''); // Ensure data & upload directories exist if (!file_exists(DATA_DIR)) { mkdir(DATA_DIR, 0777, true); } if (!file_exists(UPLOADS_DIR)) { mkdir(UPLOADS_DIR, 0777, true); } if (!file_exists(UPLOADS_DIR . '/avatars')) { mkdir(UPLOADS_DIR . '/avatars', 0777, true); } if (!file_exists(UPLOADS_DIR . '/products')) { mkdir(UPLOADS_DIR . '/products', 0777, true); } if (!file_exists(UPLOADS_DIR . '/slips')) { mkdir(UPLOADS_DIR . '/slips', 0777, true); } // Ensure orders.json & custom_products.json exist if (!file_exists(ORDERS_FILE)) { file_put_contents(ORDERS_FILE, json_encode([], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)); } if (!file_exists(CUSTOM_PRODUCTS_FILE)) { file_put_contents(CUSTOM_PRODUCTS_FILE, json_encode([], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)); } // --- SHOPEE MEMBERSHIP TIERS CONFIGURATION --- $SHOPEE_TIERS = [ 'classic' => [ 'id' => 'classic', 'name' => 'Classic Member (คลาสสิก)', 'badge' => 'Shopee Classic', 'color' => 'from-slate-700 via-slate-800 to-slate-900', 'border' => 'border-slate-600', 'textColor' => 'text-slate-300', 'minSpent' => 0, 'minOrders' => 0, 'coinCashback' => 1, // 1% 'freeShippingVouchers' => 1, 'discountPercent' => 0, 'icon' => 'shield', 'gradientGlow' => 'shadow-slate-500/20', 'nextTier' => 'silver', 'nextRequirement' => ['spent' => 1000, 'orders' => 2] ], 'silver' => [ 'id' => 'silver', 'name' => 'Silver Member (ซิลเวอร์)', 'badge' => 'Shopee Silver', 'color' => 'from-slate-400 via-zinc-300 to-slate-500', 'border' => 'border-slate-400', 'textColor' => 'text-slate-100', 'minSpent' => 1000, 'minOrders' => 2, 'coinCashback' => 3, // 3% 'freeShippingVouchers' => 2, 'discountPercent' => 5, 'icon' => 'medal', 'gradientGlow' => 'shadow-slate-300/30', 'nextTier' => 'gold', 'nextRequirement' => ['spent' => 3000, 'orders' => 5] ], 'gold' => [ 'id' => 'gold', 'name' => 'Gold Member (โกลด์ VIP)', 'badge' => 'Shopee Gold VIP', 'color' => 'from-amber-400 via-yellow-500 to-amber-600', 'border' => 'border-amber-400', 'textColor' => 'text-amber-100', 'minSpent' => 3000, 'minOrders' => 5, 'coinCashback' => 5, // 5% 'freeShippingVouchers' => 4, 'discountPercent' => 10, 'icon' => 'crown', 'gradientGlow' => 'shadow-amber-500/40', 'nextTier' => 'platinum', 'nextRequirement' => ['spent' => 8000, 'orders' => 10] ], 'platinum' => [ 'id' => 'platinum', 'name' => 'Platinum Member (แพลตตินัม Super VIP)', 'badge' => 'Shopee Platinum Super VIP', 'color' => 'from-violet-600 via-purple-600 to-indigo-700', 'border' => 'border-purple-400', 'textColor' => 'text-purple-100', 'minSpent' => 8000, 'minOrders' => 10, 'coinCashback' => 10, // 10% 'freeShippingVouchers' => 8, 'discountPercent' => 15, 'icon' => 'sparkles', 'gradientGlow' => 'shadow-purple-500/50', 'nextTier' => null, 'nextRequirement' => null ] ]; // --- 7-DAY DAILY CHECK-IN STREAK REWARDS --- $DAILY_STREAK_REWARDS = [ 1 => ['day' => 1, 'coins' => 5, 'label' => '+5 Coins', 'tag' => 'วันที่ 1'], 2 => ['day' => 2, 'coins' => 10, 'label' => '+10 Coins', 'tag' => 'วันที่ 2'], 3 => ['day' => 3, 'coins' => 15, 'label' => '+15 Coins', 'tag' => 'วันที่ 3'], 4 => ['day' => 4, 'coins' => 20, 'label' => '+20 Coins', 'tag' => 'วันที่ 4'], 5 => ['day' => 5, 'coins' => 25, 'label' => '+25 Coins', 'tag' => 'วันที่ 5'], 6 => ['day' => 6, 'coins' => 30, 'label' => '+30 Coins', 'tag' => 'วันที่ 6'], 7 => ['day' => 7, 'coins' => 50, 'label' => '+50 Coins + กล่องเซอร์ไพรส์ 🎁', 'tag' => 'วันที่ 7 (Super Box)'] ]; // --- SHOPEE MISSIONS REWARDS --- $SHOPEE_MISSIONS = [ [ 'id' => 'profile_complete', 'title' => 'ตั้งค่าข้อมูลโปรไฟล์และรูปภาพ', 'subtitle' => 'กรอกชื่อ เบอร์โทร ที่อยู่ และอัปโหลดรูปประจำตัว', 'rewardCoins' => 30, 'icon' => 'user', 'category' => 'profile' ], [ 'id' => 'checkin_3days', 'title' => 'เช็คอินรายวันสะสมครบ 3 วัน', 'subtitle' => 'เข้ามารับเหรียญ Shopee Coins ต่อเนื่อง 3 วัน', 'rewardCoins' => 50, 'icon' => 'calendar', 'category' => 'checkin' ], [ 'id' => 'lucky_spin_play', 'title' => 'หมุนวงล้อเสี่ยงโชค Shopee Rewards', 'subtitle' => 'เล่น Lucky Wheel ลุ้นรับเหรียญและคูปองฟรี', 'rewardCoins' => 20, 'icon' => 'sparkles', 'category' => 'game' ], [ 'id' => 'collect_3vouchers', 'title' => 'เก็บโค้ดส่วนลด 3 โค้ดเข้ากระเป๋า', 'subtitle' => 'สะสมคูปองส่งฟรีและส่วนลด Shopee Mall', 'rewardCoins' => 25, 'icon' => 'tag', 'category' => 'voucher' ], [ 'id' => 'first_order', 'title' => 'สั่งซื้อสินค้าชิ้นแรกในร้าน APEX STUDIO', 'subtitle' => 'ช้อปสินค้าแฟชั่นสตรีทรับ Coins คืนสูงสุด 10%', 'rewardCoins' => 100, 'icon' => 'bag', 'category' => 'shopping' ] ]; // --- AVAILABLE SHOPEE VOUCHERS LIST --- $AVAILABLE_VOUCHERS = [ [ 'code' => 'SHOPEEFREE', 'title' => 'โค้ดส่งฟรี ขั้นต่ำ 0.-', 'subtitle' => 'ใช้ได้กับทุกสินค้าในร้าน APEX STUDIO ไม่มีขั้นต่ำ', 'discountType' => 'freeship', 'discountAmount' => 50, 'minSpend' => 0, 'tag' => 'ส่งฟรี', 'color' => 'bg-emerald-600', 'icon' => 'truck' ], [ 'code' => 'MALL10', 'title' => 'ส่วนลด 10% Shopee Mall', 'subtitle' => 'ลดสูงสุด 200.- เมื่อซื้อครบ 500.- สิทธิพิเศษ Mall', 'discountType' => 'percent', 'discountAmount' => 10, 'minSpend' => 500, 'tag' => 'Shopee Mall', 'color' => 'bg-rose-600', 'icon' => 'tag' ], [ 'code' => 'COINBACK20', 'title' => 'เงินคืน 20% Shopee Coins', 'subtitle' => 'รับเหรียญคืนสูงสุด 150 Coins เมื่อซื้อครบ 300.-', 'discountType' => 'coinback', 'discountAmount' => 20, 'minSpend' => 300, 'tag' => 'Coins Cashback', 'color' => 'bg-amber-600', 'icon' => 'coins' ], [ 'code' => 'NEWUSER50', 'title' => 'ลดทันที 50.- ลูกค้าใหม่', 'subtitle' => 'ไม่มีขั้นต่ำ สำหรับการสั่งซื้อออเดอร์แรก', 'discountType' => 'fixed', 'discountAmount' => 50, 'minSpend' => 0, 'tag' => 'สมาชิกใหม่', 'color' => 'bg-orange-600', 'icon' => 'sparkles' ], [ 'code' => 'BDAY100', 'title' => 'ของขวัญวันเกิด ลดทันที 100.-', 'subtitle' => 'สำหรับสมาชิก Shopee VIP ในเดือนเกิด (ขั้นต่ำ 400.-)', 'discountType' => 'fixed', 'discountAmount' => 100, 'minSpend' => 400, 'tag' => 'วันเกิด VIP', 'color' => 'bg-purple-600', 'icon' => 'gift' ] ]; // --- DATABASE CONNECTION & SETUP --- function getDbConnection() { static $pdo = null; if ($pdo !== null) return $pdo; try { if (DB_TYPE === 'sqlite') { $pdo = new PDO('sqlite:' . DB_FILE); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); } else { try { $rootPdo = new PDO("mysql:host=" . DB_HOST . ";charset=utf8mb4", DB_USER, DB_PASS); $rootPdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $rootPdo->exec("CREATE DATABASE IF NOT EXISTS `" . DB_NAME . "` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci"); } catch (PDOException $e) { // Ignore if user has no grant to CREATE DATABASE } $dsn = "mysql:host=" . DB_HOST . ";dbname=" . DB_NAME . ";charset=utf8mb4"; $pdo = new PDO($dsn, DB_USER, DB_PASS); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); } initDbTables($pdo); } catch (PDOException $e) { error_log("Database Connection Error: " . $e->getMessage()); if (DB_TYPE === 'mysql') { try { $pdo = new PDO('sqlite:' . DB_FILE); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); initDbTables($pdo); return $pdo; } catch (PDOException $sqle) { error_log("Fallback SQLite Error: " . $sqle->getMessage()); } } return null; } return $pdo; } function initDbTables($pdo) { if (!$pdo) return; $driver = $pdo->getAttribute(PDO::ATTR_DRIVER_NAME); $intPrimary = ($driver === 'sqlite') ? "INTEGER PRIMARY KEY AUTOINCREMENT" : "INT AUTO_INCREMENT PRIMARY KEY"; // 1. Create Users Table with complete Shopee membership attributes $usersSql = "CREATE TABLE IF NOT EXISTS users ( id $intPrimary, username VARCHAR(50) NOT NULL UNIQUE, email VARCHAR(100) NOT NULL UNIQUE, password_hash VARCHAR(255) NOT NULL, full_name VARCHAR(100) NOT NULL, phone VARCHAR(20) NOT NULL, address TEXT NOT NULL, role VARCHAR(20) DEFAULT 'member', badge VARCHAR(50) DEFAULT 'Shopee Classic', membership_tier VARCHAR(20) DEFAULT 'classic', total_spent DECIMAL(10,2) DEFAULT 0, orders_count INTEGER DEFAULT 0, points INTEGER DEFAULT 100, coins INTEGER DEFAULT 100, daily_checkin VARCHAR(20) DEFAULT '', checkin_streak INTEGER DEFAULT 0, last_spin_date VARCHAR(20) DEFAULT '', missions_json TEXT DEFAULT '[]', vouchers_json TEXT DEFAULT '[]', avatar VARCHAR(255) DEFAULT '', gender VARCHAR(10) DEFAULT 'other', birthday VARCHAR(20) DEFAULT '', created_at DATETIME DEFAULT CURRENT_TIMESTAMP )"; $pdo->exec($usersSql); // Auto-migrate missing columns $missingCols = [ 'membership_tier' => "VARCHAR(20) DEFAULT 'classic'", 'total_spent' => "DECIMAL(10,2) DEFAULT 0", 'orders_count' => "INTEGER DEFAULT 0", 'points' => "INTEGER DEFAULT 100", 'coins' => "INTEGER DEFAULT 100", 'daily_checkin' => "VARCHAR(20) DEFAULT ''", 'checkin_streak' => "INTEGER DEFAULT 0", 'last_spin_date' => "VARCHAR(20) DEFAULT ''", 'missions_json' => "TEXT DEFAULT '[]'", 'vouchers_json' => "TEXT DEFAULT '[]'", 'avatar' => "VARCHAR(255) DEFAULT ''", 'gender' => "VARCHAR(10) DEFAULT 'other'", 'birthday' => "VARCHAR(20) DEFAULT ''" ]; if ($driver === 'sqlite') { $cols = []; $stmt = $pdo->query("PRAGMA table_info(users)"); while ($row = $stmt->fetch()) { $cols[] = $row['name']; } foreach ($missingCols as $colName => $colDef) { if (!in_array($colName, $cols)) { try { $pdo->exec("ALTER TABLE users ADD COLUMN $colName $colDef"); } catch (Exception $e) {} } } } // 2. Create Orders Table $ordersSql = "CREATE TABLE IF NOT EXISTS orders ( id $intPrimary, order_id VARCHAR(50) NOT NULL UNIQUE, user_id INTEGER NULL, customer_name VARCHAR(100) NOT NULL, customer_phone VARCHAR(20) NOT NULL, customer_address TEXT NOT NULL, payment_method VARCHAR(50) NOT NULL, subtotal DECIMAL(10,2) NOT NULL, shipping DECIMAL(10,2) NOT NULL, discount DECIMAL(10,2) DEFAULT 0, coins_used INTEGER DEFAULT 0, coins_earned INTEGER DEFAULT 0, grand_total DECIMAL(10,2) NOT NULL, status VARCHAR(50) DEFAULT 'Pending Payment', items_json TEXT NOT NULL, slip_image VARCHAR(255) DEFAULT '', tracking_number VARCHAR(50) DEFAULT '', created_at DATETIME DEFAULT CURRENT_TIMESTAMP )"; $pdo->exec($ordersSql); // 3. Create Coin Logs Table $coinLogsSql = "CREATE TABLE IF NOT EXISTS coin_logs ( id $intPrimary, user_id INTEGER NOT NULL, type VARCHAR(30) NOT NULL, amount INTEGER NOT NULL, balance_after INTEGER NOT NULL, order_code VARCHAR(50) DEFAULT NULL, description VARCHAR(255) NOT NULL, created_at DATETIME DEFAULT CURRENT_TIMESTAMP )"; $pdo->exec($coinLogsSql); // Seed default demo accounts if table has fewer than 2 users $userCountStmt = $pdo->query("SELECT COUNT(*) FROM users"); if ($userCountStmt && $userCountStmt->fetchColumn() < 2) { seedDemoUsers($pdo); } } function seedDemoUsers($pdo) { $defaultPassHash = password_hash('123456', PASSWORD_BCRYPT); $users = [ [ 'username' => 'admin', 'email' => 'admin@apexstudio.com', 'password_hash' => $defaultPassHash, 'full_name' => 'ผู้ดูแลระบบ APEX STUDIO', 'phone' => '081-999-8888', 'address' => 'APEX Studio Flagship Store สยามสแควร์ กรุงเทพมหานคร 10330', 'role' => 'admin', 'badge' => 'Shopee Platinum Super VIP', 'membership_tier' => 'platinum', 'total_spent' => 15900.00, 'orders_count' => 18, 'points' => 1590, 'coins' => 500, 'checkin_streak' => 5, 'vouchers_json' => json_encode(['SHOPEEFREE', 'MALL10', 'COINBACK20', 'NEWUSER50', 'BDAY100'], JSON_UNESCAPED_UNICODE), 'avatar' => 'https://images.unsplash.com/photo-1534528741775-53994a69daeb?w=400&auto=format&fit=crop&q=80', 'gender' => 'other', 'birthday' => '1995-08-17' ], [ 'username' => 'member_vip', 'email' => 'vip@apexstudio.com', 'password_hash' => $defaultPassHash, 'full_name' => 'คุณพงศกร สมาชิกแพลตตินัม (Platinum VIP)', 'phone' => '089-123-4567', 'address' => '88/12 อาคารสยามทาวเวอร์ แขวงปทุมวัน เขตปทุมวัน กรุงเทพมหานคร 10330', 'role' => 'member', 'badge' => 'Shopee Platinum Super VIP', 'membership_tier' => 'platinum', 'total_spent' => 9450.00, 'orders_count' => 12, 'points' => 945, 'coins' => 350, 'checkin_streak' => 4, 'vouchers_json' => json_encode(['SHOPEEFREE', 'MALL10', 'COINBACK20', 'BDAY100'], JSON_UNESCAPED_UNICODE), 'avatar' => 'https://images.unsplash.com/photo-1539571696357-5a69c17a67c6?w=400&auto=format&fit=crop&q=80', 'gender' => 'male', 'birthday' => '1998-05-15' ], [ 'username' => 'somchai', 'email' => 'somchai@gmail.com', 'password_hash' => $defaultPassHash, 'full_name' => 'สมชาย สายสตรีท (Gold VIP)', 'phone' => '086-555-1234', 'address' => '123/45 ถนนสุขุมวิท แขวงคลองเตย เขตคลองเตย กรุงเทพมหานคร 10110', 'role' => 'member', 'badge' => 'Shopee Gold VIP', 'membership_tier' => 'gold', 'total_spent' => 3890.00, 'orders_count' => 6, 'points' => 389, 'coins' => 180, 'checkin_streak' => 2, 'vouchers_json' => json_encode(['SHOPEEFREE', 'MALL10', 'NEWUSER50'], JSON_UNESCAPED_UNICODE), 'avatar' => 'https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=400&auto=format&fit=crop&q=80', 'gender' => 'male', 'birthday' => '2000-08-20' ], [ 'username' => 'nicha', 'email' => 'nicha@gmail.com', 'password_hash' => $defaultPassHash, 'full_name' => 'ณิชา แฟชั่นนิสต้า (Silver)', 'phone' => '081-444-9988', 'address' => '55/9 ถนนพหลโยธิน แขวงจตุจักร เขตจตุจักร กรุงเทพมหานคร 10900', 'role' => 'member', 'badge' => 'Shopee Silver', 'membership_tier' => 'silver', 'total_spent' => 1490.00, 'orders_count' => 2, 'points' => 149, 'coins' => 120, 'checkin_streak' => 1, 'vouchers_json' => json_encode(['SHOPEEFREE', 'NEWUSER50'], JSON_UNESCAPED_UNICODE), 'avatar' => 'https://images.unsplash.com/photo-1494790108377-be9c29b29330?w=400&auto=format&fit=crop&q=80', 'gender' => 'female', 'birthday' => '2001-11-10' ], [ 'username' => 'new_user', 'email' => 'newuser@gmail.com', 'password_hash' => $defaultPassHash, 'full_name' => 'สมาชิกใหม่ Shopee Classic', 'phone' => '089-777-6655', 'address' => '99/1 ซอยอารีย์ แขวงสามเสนใน เขตพญาไท กรุงเทพมหานคร 10400', 'role' => 'member', 'badge' => 'Shopee Classic', 'membership_tier' => 'classic', 'total_spent' => 0.00, 'orders_count' => 0, 'points' => 100, 'coins' => 100, 'checkin_streak' => 0, 'vouchers_json' => json_encode(['SHOPEEFREE', 'NEWUSER50'], JSON_UNESCAPED_UNICODE), 'avatar' => 'https://images.unsplash.com/photo-1535713875002-d1d0cf377fde?w=400&auto=format&fit=crop&q=80', 'gender' => 'other', 'birthday' => '2002-03-25' ] ]; foreach ($users as $u) { try { $stmt = $pdo->prepare("INSERT INTO users (username, email, password_hash, full_name, phone, address, role, badge, membership_tier, total_spent, orders_count, points, coins, checkin_streak, vouchers_json, avatar, gender, birthday) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); $stmt->execute([ $u['username'], $u['email'], $u['password_hash'], $u['full_name'], $u['phone'], $u['address'], $u['role'], $u['badge'], $u['membership_tier'], $u['total_spent'], $u['orders_count'], $u['points'], $u['coins'], $u['checkin_streak'], $u['vouchers_json'], $u['avatar'], $u['gender'], $u['birthday'] ]); $insertedId = $pdo->lastInsertId(); logCoinTransaction($insertedId, 'welcome_bonus', $u['coins'], $u['coins'], null, 'โบนัสต้อนรับสมาชิกใหม่ Shopee Member Club'); } catch (Exception $e) {} } } // Ensure DB is initialized getDbConnection(); // --- COIN TRANSACTION LOGGER --- function logCoinTransaction($userId, $type, $amount, $balanceAfter, $orderCode = null, $description = '') { $pdo = getDbConnection(); if (!$pdo) return false; try { $stmt = $pdo->prepare("INSERT INTO coin_logs (user_id, type, amount, balance_after, order_code, description) VALUES (?, ?, ?, ?, ?, ?)"); return $stmt->execute([$userId, $type, $amount, $balanceAfter, $orderCode, $description]); } catch (Exception $e) { return false; } } function getCoinLogs($userId, $limit = 20) { $pdo = getDbConnection(); if (!$pdo) return []; try { $stmt = $pdo->prepare("SELECT * FROM coin_logs WHERE user_id = ? ORDER BY id DESC LIMIT ?"); $stmt->bindValue(1, $userId, PDO::PARAM_INT); $stmt->bindValue(2, $limit, PDO::PARAM_INT); $stmt->execute(); return $stmt->fetchAll(); } catch (Exception $e) { return []; } } // --- TIER CALCULATION HELPER --- function calculateMembershipTier($totalSpent, $ordersCount) { global $SHOPEE_TIERS; if ($totalSpent >= 8000 || $ordersCount >= 10) return 'platinum'; if ($totalSpent >= 3000 || $ordersCount >= 5) return 'gold'; if ($totalSpent >= 1000 || $ordersCount >= 2) return 'silver'; return 'classic'; } function formatUserData($user) { global $SHOPEE_TIERS; if (!$user) return null; unset($user['password_hash']); $totalSpent = floatval($user['total_spent'] ?? 0); $ordersCount = intval($user['orders_count'] ?? 0); $tierKey = calculateMembershipTier($totalSpent, $ordersCount); $tierInfo = $SHOPEE_TIERS[$tierKey] ?? $SHOPEE_TIERS['classic']; $user['membership_tier'] = $tierKey; $user['tier_info'] = $tierInfo; $user['badge'] = $tierInfo['badge']; $user['coins'] = intval($user['coins'] ?? 100); $user['checkin_streak'] = intval($user['checkin_streak'] ?? 0); $user['total_spent'] = $totalSpent; $user['orders_count'] = $ordersCount; $user['missions_completed'] = json_decode($user['missions_json'] ?? '[]', true) ?: []; $user['vouchers'] = json_decode($user['vouchers_json'] ?? '[]', true) ?: ['SHOPEEFREE', 'NEWUSER50']; $user['avatar'] = $user['avatar'] ?? ''; return $user; } // --- 7-DAY STREAK DAILY CHECK-IN --- function claimDailyCoinsWithStreak($userId) { global $DAILY_STREAK_REWARDS; $pdo = getDbConnection(); if (!$pdo) return ['success' => false, 'message' => 'Database error']; $today = date('Y-m-d'); $yesterday = date('Y-m-d', strtotime('-1 day')); $stmt = $pdo->prepare("SELECT daily_checkin, checkin_streak, coins FROM users WHERE id = ?"); $stmt->execute([$userId]); $u = $stmt->fetch(); if (!$u) return ['success' => false, 'message' => 'User not found']; if ($u['daily_checkin'] === $today) { return ['success' => false, 'message' => 'คุณได้กดรับเหรียญประจำวันนี้ไปแล้ว เจอกันใหม่พรุ่งนี้นะ!']; } $currentStreak = intval($u['checkin_streak'] ?? 0); if ($u['daily_checkin'] === $yesterday) { $newStreak = ($currentStreak % 7) + 1; } else { $newStreak = 1; } $rewardInfo = $DAILY_STREAK_REWARDS[$newStreak] ?? $DAILY_STREAK_REWARDS[1]; $coinsReward = $rewardInfo['coins']; $newCoins = intval($u['coins'] ?? 0) + $coinsReward; $stmtUp = $pdo->prepare("UPDATE users SET daily_checkin = ?, checkin_streak = ?, coins = ? WHERE id = ?"); $stmtUp->execute([$today, $newStreak, $newCoins, $userId]); logCoinTransaction($userId, 'daily_checkin', $coinsReward, $newCoins, null, "เช็คอินวันที่ {$newStreak} (+{$coinsReward} Coins)"); $stmtFresh = $pdo->prepare("SELECT * FROM users WHERE id = ?"); $stmtFresh->execute([$userId]); $updatedUser = formatUserData($stmtFresh->fetch()); $_SESSION['user'] = $updatedUser; return [ 'success' => true, 'message' => "เช็คอินสำเร็จ! คุณได้รับ +{$coinsReward} Shopee Coins (สะสมวันที่ {$newStreak}/7)", 'user' => $updatedUser, 'earnedCoins' => $coinsReward, 'streak' => $newStreak, 'rewardInfo' => $rewardInfo ]; } // --- SHOPEE LUCKY SPIN WHEEL --- function spinLuckyWheel($userId) { $pdo = getDbConnection(); if (!$pdo) return ['success' => false, 'message' => 'Database error']; $today = date('Y-m-d'); $stmt = $pdo->prepare("SELECT last_spin_date, coins, vouchers_json FROM users WHERE id = ?"); $stmt->execute([$userId]); $u = $stmt->fetch(); if (!$u) return ['success' => false, 'message' => 'User not found']; // Possible prizes $prizes = [ ['id' => 1, 'name' => '10 Shopee Coins', 'type' => 'coins', 'amount' => 10, 'icon' => '🪙', 'color' => '#f59e0b'], ['id' => 2, 'name' => '20 Shopee Coins', 'type' => 'coins', 'amount' => 20, 'icon' => '🪙', 'color' => '#d97706'], ['id' => 3, 'name' => 'โค้ดส่งฟรี 0.-', 'type' => 'voucher', 'voucherCode' => 'SHOPEEFREE', 'amount' => 0, 'icon' => '🚚', 'color' => '#10b981'], ['id' => 4, 'name' => '50 Shopee Coins', 'type' => 'coins', 'amount' => 50, 'icon' => '✨', 'color' => '#ea580c'], ['id' => 5, 'name' => 'ส่วนลด 10% Mall', 'type' => 'voucher', 'voucherCode' => 'MALL10', 'amount' => 0, 'icon' => '🏷️', 'color' => '#e11d48'], ['id' => 6, 'name' => '100 Shopee Coins (BIG WIN!)', 'type' => 'coins', 'amount' => 100, 'icon' => '👑', 'color' => '#8b5cf6'] ]; $wonPrize = $prizes[array_rand($prizes)]; $newCoins = intval($u['coins'] ?? 0); $vouchers = json_decode($u['vouchers_json'] ?? '[]', true) ?: []; if ($wonPrize['type'] === 'coins') { $newCoins += $wonPrize['amount']; logCoinTransaction($userId, 'lucky_spin', $wonPrize['amount'], $newCoins, null, "รางวัลจาก Lucky Spin: +{$wonPrize['amount']} Coins"); } elseif ($wonPrize['type'] === 'voucher' && !in_array($wonPrize['voucherCode'], $vouchers)) { $vouchers[] = $wonPrize['voucherCode']; } $stmtUp = $pdo->prepare("UPDATE users SET last_spin_date = ?, coins = ?, vouchers_json = ? WHERE id = ?"); $stmtUp->execute([$today, $newCoins, json_encode($vouchers, JSON_UNESCAPED_UNICODE), $userId]); $stmtFresh = $pdo->prepare("SELECT * FROM users WHERE id = ?"); $stmtFresh->execute([$userId]); $updatedUser = formatUserData($stmtFresh->fetch()); $_SESSION['user'] = $updatedUser; return [ 'success' => true, 'message' => "ยินดีด้วย! คุณได้รับรางวัล: {$wonPrize['name']} 🎉", 'prize' => $wonPrize, 'user' => $updatedUser ]; } // --- CLAIM MISSION REWARD --- function claimMissionReward($userId, $missionId) { global $SHOPEE_MISSIONS; $pdo = getDbConnection(); if (!$pdo) return ['success' => false, 'message' => 'Database error']; $targetMission = null; foreach ($SHOPEE_MISSIONS as $m) { if ($m['id'] === $missionId) { $targetMission = $m; break; } } if (!$targetMission) return ['success' => false, 'message' => 'ไม่พบภารกิจนี้']; $stmt = $pdo->prepare("SELECT missions_json, coins FROM users WHERE id = ?"); $stmt->execute([$userId]); $u = $stmt->fetch(); if (!$u) return ['success' => false, 'message' => 'User not found']; $completedMissions = json_decode($u['missions_json'] ?? '[]', true) ?: []; if (in_array($missionId, $completedMissions)) { return ['success' => false, 'message' => 'คุณเคยกดรับรางวัลภารกิจนี้ไปแล้ว']; } $rewardCoins = $targetMission['rewardCoins']; $newCoins = intval($u['coins'] ?? 0) + $rewardCoins; $completedMissions[] = $missionId; $stmtUp = $pdo->prepare("UPDATE users SET missions_json = ?, coins = ? WHERE id = ?"); $stmtUp->execute([json_encode($completedMissions, JSON_UNESCAPED_UNICODE), $newCoins, $userId]); logCoinTransaction($userId, 'mission_reward', $rewardCoins, $newCoins, null, "รางวัลภารกิจ: {$targetMission['title']} (+{$rewardCoins} Coins)"); $stmtFresh = $pdo->prepare("SELECT * FROM users WHERE id = ?"); $stmtFresh->execute([$userId]); $updatedUser = formatUserData($stmtFresh->fetch()); $_SESSION['user'] = $updatedUser; return [ 'success' => true, 'message' => "สำเร็จ! คุณได้รับ +{$rewardCoins} Shopee Coins จากภารกิจ '{$targetMission['title']}' 🎉", 'user' => $updatedUser, 'earnedCoins' => $rewardCoins ]; } // --- QUICK DEMO LOGIN AS TIER --- function quickLoginAsTier($tierKey) { $pdo = getDbConnection(); if (!$pdo) return ['success' => false, 'message' => 'Database error']; $map = [ 'platinum' => 'member_vip', 'gold' => 'somchai', 'silver' => 'nicha', 'classic' => 'new_user', 'admin' => 'admin' ]; $targetUsername = $map[$tierKey] ?? 'new_user'; $stmt = $pdo->prepare("SELECT * FROM users WHERE username = ?"); $stmt->execute([$targetUsername]); $rawUser = $stmt->fetch(); if ($rawUser) { $user = formatUserData($rawUser); $_SESSION['user'] = $user; return [ 'success' => true, 'message' => "สลับเข้าใช้งานในฐานะ {$user['full_name']} ({$user['badge']}) สำเร็จ!", 'user' => $user ]; } return ['success' => false, 'message' => 'ไม่พบบัญชีทดสอบ']; } // --- MEMBER / AUTHENTICATION FUNCTIONS --- function registerUser($username, $email, $password, $fullName, $phone, $address) { $pdo = getDbConnection(); if (!$pdo) { return ['success' => false, 'message' => 'ไม่สามารถเชื่อมต่อฐานข้อมูลได้']; } $username = trim($username); $email = trim(strtolower($email)); $fullName = trim($fullName); $phone = trim($phone); $address = trim($address); if (empty($username) || empty($email) || empty($password) || empty($fullName) || empty($phone)) { return ['success' => false, 'message' => 'กรุณากรอกข้อมูลให้ครบถ้วนทุกช่อง']; } if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { return ['success' => false, 'message' => 'รูปแบบอีเมลไม่ถูกต้อง']; } if (strlen($password) < 6) { return ['success' => false, 'message' => 'รหัสผ่านต้องมีความยาวอย่างน้อย 6 ตัวอักษร']; } // Check if username or email exists $stmt = $pdo->prepare("SELECT id FROM users WHERE username = ? OR email = ?"); $stmt->execute([$username, $email]); if ($stmt->fetch()) { return ['success' => false, 'message' => 'ชื่อผู้ใช้หรืออีเมลนี้มีอยู่ในระบบแล้ว']; } $passwordHash = password_hash($password, PASSWORD_BCRYPT); $initialVouchers = json_encode(['SHOPEEFREE', 'NEWUSER50', 'MALL10'], JSON_UNESCAPED_UNICODE); $stmt = $pdo->prepare("INSERT INTO users (username, email, password_hash, full_name, phone, address, role, badge, membership_tier, total_spent, orders_count, coins, points, vouchers_json, avatar) VALUES (?, ?, ?, ?, ?, ?, 'member', 'Shopee Classic', 'classic', 0, 0, 100, 100, ?, '')"); if ($stmt->execute([$username, $email, $passwordHash, $fullName, $phone, $address, $initialVouchers])) { $userId = $pdo->lastInsertId(); logCoinTransaction($userId, 'welcome_bonus', 100, 100, null, 'โบนัสต้อนรับสมาชิกใหม่ Shopee Member Club'); $stmtUser = $pdo->prepare("SELECT * FROM users WHERE id = ?"); $stmtUser->execute([$userId]); $userData = formatUserData($stmtUser->fetch()); $_SESSION['user'] = $userData; return ['success' => true, 'message' => 'สมัครสมาชิก Shopee Member Club สำเร็จ! รับฟรี 100 Shopee Coins & คูปองต้อนรับ', 'user' => $userData]; } return ['success' => false, 'message' => 'เกิดข้อผิดพลาดในการบันทึกข้อมูลสมาชิก']; } function loginUser($usernameOrEmail, $password) { $pdo = getDbConnection(); if (!$pdo) { return ['success' => false, 'message' => 'ไม่สามารถเชื่อมต่อฐานข้อมูลได้']; } $input = trim($usernameOrEmail); if (empty($input) || empty($password)) { return ['success' => false, 'message' => 'กรุณากรอกชื่อผู้ใช้/อีเมล และรหัสผ่าน']; } $stmt = $pdo->prepare("SELECT * FROM users WHERE username = ? OR email = ?"); $stmt->execute([$input, strtolower($input)]); $rawUser = $stmt->fetch(); if ($rawUser && password_verify($password, $rawUser['password_hash'])) { $user = formatUserData($rawUser); $_SESSION['user'] = $user; return ['success' => true, 'message' => 'เข้าสู่ระบบ Shopee Member Club สำเร็จ! ยินดีต้อนรับ ' . $user['full_name'], 'user' => $user]; } return ['success' => false, 'message' => 'ชื่อผู้ใช้/อีเมล หรือรหัสผ่านไม่ถูกต้อง']; } function getLoggedInUser() { if (!isset($_SESSION['user']) || empty($_SESSION['user']['id'])) { return null; } $pdo = getDbConnection(); if ($pdo) { $stmt = $pdo->prepare("SELECT * FROM users WHERE id = ?"); $stmt->execute([$_SESSION['user']['id']]); $fresh = $stmt->fetch(); if ($fresh) { $_SESSION['user'] = formatUserData($fresh); } } return $_SESSION['user'] ?? null; } function collectVoucher($userId, $voucherCode) { $pdo = getDbConnection(); if (!$pdo) return ['success' => false, 'message' => 'Database error']; $stmt = $pdo->prepare("SELECT vouchers_json FROM users WHERE id = ?"); $stmt->execute([$userId]); $u = $stmt->fetch(); if (!$u) return ['success' => false, 'message' => 'User not found']; $vouchers = json_decode($u['vouchers_json'] ?? '[]', true) ?: []; if (in_array($voucherCode, $vouchers)) { return ['success' => false, 'message' => 'คุณเก็บโค้ดนี้ไปแล้วในกระเป๋าคูปอง']; } $vouchers[] = $voucherCode; $stmtUp = $pdo->prepare("UPDATE users SET vouchers_json = ? WHERE id = ?"); $stmtUp->execute([json_encode($vouchers, JSON_UNESCAPED_UNICODE), $userId]); $stmtFresh = $pdo->prepare("SELECT * FROM users WHERE id = ?"); $stmtFresh->execute([$userId]); $updatedUser = formatUserData($stmtFresh->fetch()); $_SESSION['user'] = $updatedUser; return ['success' => true, 'message' => 'เก็บโค้ดส่วนลดเข้ากระเป๋าเรียบร้อยแล้ว!', 'user' => $updatedUser]; } function getUserOrdersFromDb($userId) { $pdo = getDbConnection(); if (!$pdo) return []; $stmt = $pdo->prepare("SELECT * FROM orders WHERE user_id = ? ORDER BY id DESC"); $stmt->execute([$userId]); $rows = $stmt->fetchAll(); $result = []; foreach ($rows as $row) { $result[] = [ 'orderId' => $row['order_id'], 'customer' => [ 'fullName' => $row['customer_name'], 'phone' => $row['customer_phone'], 'address' => $row['customer_address'], 'paymentMethod' => $row['payment_method'] ], 'subtotal' => floatval($row['subtotal']), 'shipping' => floatval($row['shipping']), 'discount' => floatval($row['discount'] ?? 0), 'coinsUsed' => intval($row['coins_used'] ?? 0), 'coinsEarned' => intval($row['coins_earned'] ?? 0), 'grandTotal' => floatval($row['grand_total']), 'status' => $row['status'], 'slipImage' => $row['slip_image'] ?? '', 'trackingNumber' => $row['tracking_number'] ?? '', 'createdAt' => $row['created_at'], 'items' => json_decode($row['items_json'], true) ?: [] ]; } return $result; } function saveOrderToDb($newOrder, $userId = null) { $pdo = getDbConnection(); if (!$pdo) return false; try { $stmt = $pdo->prepare("INSERT INTO orders (order_id, user_id, customer_name, customer_phone, customer_address, payment_method, subtotal, shipping, discount, coins_used, coins_earned, grand_total, status, items_json, slip_image) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); $stmt->execute([ $newOrder['orderId'], $userId, $newOrder['customer']['fullName'] ?? '', $newOrder['customer']['phone'] ?? '', $newOrder['customer']['address'] ?? '', $newOrder['customer']['paymentMethod'] ?? 'promptpay', $newOrder['subtotal'] ?? 0, $newOrder['shipping'] ?? 0, $newOrder['discount'] ?? 0, $newOrder['coinsUsed'] ?? 0, $newOrder['coinsEarned'] ?? 0, $newOrder['grandTotal'] ?? 0, $newOrder['status'] ?? 'Pending Payment', json_encode($newOrder['items'] ?? [], JSON_UNESCAPED_UNICODE), $newOrder['slipImage'] ?? '' ]); // If logged in user, update user spending & tier & deduct coins used & add coins earned if ($userId) { $stmtUser = $pdo->prepare("SELECT total_spent, orders_count, coins FROM users WHERE id = ?"); $stmtUser->execute([$userId]); $u = $stmtUser->fetch(); if ($u) { $newSpent = floatval($u['total_spent'] ?? 0) + floatval($newOrder['grandTotal']); $newOrdersCount = intval($u['orders_count'] ?? 0) + 1; $newCoins = max(0, intval($u['coins'] ?? 0) - intval($newOrder['coinsUsed'] ?? 0)) + intval($newOrder['coinsEarned'] ?? 0); $newTier = calculateMembershipTier($newSpent, $newOrdersCount); $stmtUp = $pdo->prepare("UPDATE users SET total_spent = ?, orders_count = ?, coins = ?, membership_tier = ? WHERE id = ?"); $stmtUp->execute([$newSpent, $newOrdersCount, $newCoins, $newTier, $userId]); if (intval($newOrder['coinsUsed'] ?? 0) > 0) { logCoinTransaction($userId, 'spend', -intval($newOrder['coinsUsed']), $newCoins - intval($newOrder['coinsEarned'] ?? 0), $newOrder['orderId'], "ใช้เหรียญเป็นส่วนลดออเดอร์ {$newOrder['orderId']}"); } if (intval($newOrder['coinsEarned'] ?? 0) > 0) { logCoinTransaction($userId, 'earn', intval($newOrder['coinsEarned']), $newCoins, $newOrder['orderId'], "เงินคืน Shopee Coins จากออเดอร์ {$newOrder['orderId']}"); } } } return true; } catch (PDOException $e) { error_log("Failed to save order to DB: " . $e->getMessage()); return false; } } // Colors configuration for SVG T-shirt customizer $COLOR_OPTIONS = [ [ 'id' => 'black', 'name' => 'Classic Black (ดำคลาสสิก)', 'hex' => '#18181b', 'collarHex' => '#09090b', 'textDark' => false, 'printColor' => '#f8fafc', 'accentColor' => '#10b981', 'shadow' => 'rgba(0,0,0,0.6)', 'tag' => 'Popular' ], [ 'id' => 'off-white', 'name' => 'Off-White Cream (ขาวครีม)', 'hex' => '#f5f5f4', 'collarHex' => '#e7e5e4', 'textDark' => true, 'printColor' => '#0f172a', 'accentColor' => '#059669', 'shadow' => 'rgba(0,0,0,0.15)', 'tag' => 'Trending' ], [ 'id' => 'navy', 'name' => 'Navy Blue (น้ำเงินกรมท่า)', 'hex' => '#1e293b', 'collarHex' => '#0f172a', 'textDark' => false, 'printColor' => '#38bdf8', 'accentColor' => '#38bdf8', 'shadow' => 'rgba(15,23,42,0.6)', 'tag' => '' ], [ 'id' => 'olive', 'name' => 'Olive Green (เขียวออลีฟ)', 'hex' => '#3f6212', 'collarHex' => '#1a2e05', 'textDark' => false, 'printColor' => '#fef08a', 'accentColor' => '#eab308', 'shadow' => 'rgba(26,46,5,0.6)', 'tag' => 'Limited' ], [ 'id' => 'crimson', 'name' => 'Vintage Crimson (แดงไวน์)', 'hex' => '#881337', 'collarHex' => '#4c0519', 'textDark' => false, 'printColor' => '#fecdd3', 'accentColor' => '#fb7185', 'shadow' => 'rgba(76,5,25,0.6)', 'tag' => '' ], [ 'id' => 'slate', 'name' => 'Slate Gray (เทาสเลท)', 'hex' => '#475569', 'collarHex' => '#334155', 'textDark' => false, 'printColor' => '#e2e8f0', 'accentColor' => '#818cf8', 'shadow' => 'rgba(51,65,85,0.6)', 'tag' => '' ] ]; // Sizes configuration $SIZE_OPTIONS = [ ['id' => 'S', 'label' => 'S', 'chest' => 38, 'length' => 27, 'shoulder' => 19], ['id' => 'M', 'label' => 'M', 'chest' => 40, 'length' => 28, 'shoulder' => 20], ['id' => 'L', 'label' => 'L', 'chest' => 44, 'length' => 29, 'shoulder' => 21], ['id' => 'XL', 'label' => 'XL', 'chest' => 48, 'length' => 30, 'shoulder' => 22], ['id' => '2XL', 'label' => '2XL', 'chest' => 52, 'length' => 31, 'shoulder' => 23], ['id' => '3XL', 'label' => '3XL', 'chest' => 56, 'length' => 32, 'shoulder' => 24] ]; // --- REAL SHOPEE MALL QUALITY FASHION CATALOG WITH MULTI-IMAGE GALLERIES --- $DEFAULT_CATALOG = [ [ 'id' => 'prod-oversized-tee', 'category' => 't-shirts', 'category_name' => 'เสื้อยืด (T-Shirts)', 'name' => 'Apex Heavyweight Oversized Tee 220 GSM', 'subtitle' => 'เสื้อยืดพรีออเดอร์ Oversized ผ้า Cotton Comb 100% สกรีนลายสตรีท HD', 'price' => 390, 'original_price' => 690, 'sold_count' => 1420, 'badge' => 'SHOPEE MALL', 'badge_color' => 'bg-rose-600', 'rating' => 4.9, 'reviews_count' => 842, 'image' => 'https://images.unsplash.com/photo-1521572267360-ee0c2909d518?w=800&auto=format&fit=crop&q=80', 'gallery' => [ 'https://images.unsplash.com/photo-1521572267360-ee0c2909d518?w=800&auto=format&fit=crop&q=80', 'https://images.unsplash.com/photo-1503342217505-b0a15ec3261c?w=800&auto=format&fit=crop&q=80', 'https://images.unsplash.com/photo-1583743814966-8936f5b7be1a?w=800&auto=format&fit=crop&q=80', 'https://images.unsplash.com/photo-1618354691373-d851c5c3a990?w=800&auto=format&fit=crop&q=80' ], 'colors' => $COLOR_OPTIONS, 'sizes' => ['S', 'M', 'L', 'XL', '2XL', '3XL'], 'description' => 'เสื้อยืดพรีเมียม Heavyweight 220 GSM ทรง Oversized เกาหลี นุ่ม ใส่สบาย ไหล่ตก คอไม่ย้วย สกรีนลายคมชัดระดับ HD พร้อมรับประกันแท้ 100% คืนเงิน 2 เท่า' ], [ 'id' => 'prod-vintage-graphic-tee', 'category' => 't-shirts', 'category_name' => 'เสื้อยืด (T-Shirts)', 'name' => 'Apex Vintage Washed Acid Graphic Tee', 'subtitle' => 'เสื้อยืดวินเทจกัดสี Washed Cotton ลายสกรีน Retro Streetwear 90s', 'price' => 450, 'original_price' => 790, 'sold_count' => 960, 'badge' => 'BEST SELLER', 'badge_color' => 'bg-amber-600', 'rating' => 4.9, 'reviews_count' => 489, 'image' => 'https://images.unsplash.com/photo-1503342217505-b0a15ec3261c?w=800&auto=format&fit=crop&q=80', 'gallery' => [ 'https://images.unsplash.com/photo-1503342217505-b0a15ec3261c?w=800&auto=format&fit=crop&q=80', 'https://images.unsplash.com/photo-1521572267360-ee0c2909d518?w=800&auto=format&fit=crop&q=80', 'https://images.unsplash.com/photo-1576566588028-4147f3842f27?w=800&auto=format&fit=crop&q=80' ], 'colors' => [ ['id' => 'vintage-black', 'name' => 'Washed Black (ดำวินเทจ)', 'hex' => '#27272a', 'collarHex' => '#18181b', 'textDark' => false, 'printColor' => '#fbbf24'], ['id' => 'vintage-grey', 'name' => 'Acid Grey (เทากรด)', 'hex' => '#52525b', 'collarHex' => '#3f3f46', 'textDark' => false, 'printColor' => '#f43f5e'] ], 'sizes' => ['S', 'M', 'L', 'XL', '2XL'], 'description' => 'เสื้อยืดวินเทจผ่านเทคนิคการซัก Acid Washed ทำให้ผ้าสัมผัสนุ่มและมีเท็กซ์เจอร์ย้อนยุค ลายสกรีนกราฟฟิกสตรีทแฟชั่นเฉพาะตัว สวมใส่ได้ทั้งชายและหญิง' ], [ 'id' => 'prod-tactical-hoodie', 'category' => 'hoodies', 'category_name' => 'เสื้อกันหนาว/ฮู้ดดี้ (Hoodies & Jackets)', 'name' => 'Apex Tactical Heavy Oversized Hoodie 400 GSM', 'subtitle' => 'เสื้อฮู้ดดี้เนื้อหนาพิเศษ 400 GSM ทรงสตรีทพรีเมียม ปักโลโก้นูน 3D', 'price' => 890, 'original_price' => 1490, 'sold_count' => 650, 'badge' => 'FLASH SALE', 'badge_color' => 'bg-orange-500', 'rating' => 5.0, 'reviews_count' => 312, 'image' => 'https://images.unsplash.com/photo-1556905055-8f358a7a47b2?w=800&auto=format&fit=crop&q=80', 'gallery' => [ 'https://images.unsplash.com/photo-1556905055-8f358a7a47b2?w=800&auto=format&fit=crop&q=80', 'https://images.unsplash.com/photo-1509967419530-da38b4704bc6?w=800&auto=format&fit=crop&q=80', 'https://images.unsplash.com/photo-1544441893-675973e31985?w=800&auto=format&fit=crop&q=80' ], 'colors' => [ ['id' => 'hoodie-black', 'name' => 'Jet Black (ดำเข้ม)', 'hex' => '#09090b', 'collarHex' => '#000000', 'textDark' => false, 'printColor' => '#ffffff'], ['id' => 'hoodie-cream', 'name' => 'Sand Beige (เบจทราย)', 'hex' => '#d6d3d1', 'collarHex' => '#a8a29e', 'textDark' => true, 'printColor' => '#1c1917'] ], 'sizes' => ['M', 'L', 'XL', '2XL'], 'description' => 'เสื้อฮู้ดดี้ผ้าสำลีหนานุ่ม 400 GSM ทรง Oversized หมวกสองชั้นตั้งทรงสวย กระเป๋าหน้าใบใหญ่ พร้อมสายปรับกระชับ กันหนาวได้ดีเยี่ยม' ], [ 'id' => 'prod-denim-jacket', 'category' => 'hoodies', 'category_name' => 'เสื้อแจ็คเก็ตยีนส์ (Denim Jacket)', 'name' => 'Apex Raw Denim Streetwear Jacket 14oz', 'subtitle' => 'แจ็คเก็ตยีนส์ทรงครอปสตรีท ตัดเย็บด้วยผ้ายีนส์ริมแดงพรีเมียม', 'price' => 1290, 'original_price' => 1990, 'sold_count' => 380, 'badge' => 'SHOPEE MALL', 'badge_color' => 'bg-rose-600', 'rating' => 4.9, 'reviews_count' => 174, 'image' => 'https://images.unsplash.com/photo-1576995853123-5a10305d93c0?w=800&auto=format&fit=crop&q=80', 'gallery' => [ 'https://images.unsplash.com/photo-1576995853123-5a10305d93c0?w=800&auto=format&fit=crop&q=80', 'https://images.unsplash.com/photo-1543076447-215ad9ba6923?w=800&auto=format&fit=crop&q=80' ], 'colors' => [ ['id' => 'denim-indigo', 'name' => 'Raw Indigo (ยีนส์เข้ม)', 'hex' => '#1e3a8a', 'collarHex' => '#172554', 'textDark' => false, 'printColor' => '#ffffff'], ['id' => 'denim-washed', 'name' => 'Light Vintage Blue (ยีนส์อ่อน)', 'hex' => '#60a5fa', 'collarHex' => '#3b82f6', 'textDark' => true, 'printColor' => '#0f172a'] ], 'sizes' => ['M', 'L', 'XL'], 'description' => 'แจ็คเก็ตยีนส์พรีเมียม 14oz ทรงคลาสสิกสตรีท ดีเทลปักโลโก้แบรนด์ด้านหลัง กระดุมโลหะแมทช์คัสตอม ใส่คลุมได้ทุกโอกาส' ], [ 'id' => 'prod-cargo-pants', 'category' => 'pants', 'category_name' => 'กางเกงคาร์โก้ (Pants)', 'name' => 'Apex Utility Streetwear Cargo Pants', 'subtitle' => 'กางเกงคาร์โก้ทรงกระบอกกว้าง กระเป๋าข้าง 6 ช่อง สายสตรีทสายลุย', 'price' => 790, 'original_price' => 1190, 'sold_count' => 1120, 'badge' => 'TOP 1', 'badge_color' => 'bg-emerald-600', 'rating' => 4.9, 'reviews_count' => 520, 'image' => 'https://images.unsplash.com/photo-1624378439575-d8705ad7ae80?w=800&auto=format&fit=crop&q=80', 'gallery' => [ 'https://images.unsplash.com/photo-1624378439575-d8705ad7ae80?w=800&auto=format&fit=crop&q=80', 'https://images.unsplash.com/photo-1552902865-b72c031ac5ea?w=800&auto=format&fit=crop&q=80' ], 'colors' => [ ['id' => 'cargo-black', 'name' => 'Matte Black (ดำด้าน)', 'hex' => '#18181b', 'collarHex' => '#09090b', 'textDark' => false, 'printColor' => '#ffffff'], ['id' => 'cargo-olive', 'name' => 'Military Green (เขียวทหาร)', 'hex' => '#3f6212', 'collarHex' => '#1a2e05', 'textDark' => false, 'printColor' => '#ffffff'] ], 'sizes' => ['S', 'M', 'L', 'XL'], 'description' => 'กางเกงคาร์โก้ผ้าคอตตอนทวิลหนาทนทาน ทรง Relaxed Straight ขอบเอวยางยืดพร้อมสายเชือกปรับระดับได้ กระเป๋าใหญ่ 6 ช่อง' ], [ 'id' => 'prod-streetwear-cap', 'category' => 'accessories', 'category_name' => 'แอคเซสเซอรี่ (Accessories)', 'name' => 'Apex 3D Embroidered Streetwear Cap', 'subtitle' => 'หมวกแก๊ปสตรีทปักโลโก้นูน APEX งานตัดเย็บระดับพรีเมียม', 'price' => 320, 'original_price' => 550, 'sold_count' => 740, 'badge' => 'HOT', 'badge_color' => 'bg-indigo-600', 'rating' => 4.9, 'reviews_count' => 310, 'image' => 'https://images.unsplash.com/photo-1588850561407-ed78c282e89b?w=800&auto=format&fit=crop&q=80', 'gallery' => [ 'https://images.unsplash.com/photo-1588850561407-ed78c282e89b?w=800&auto=format&fit=crop&q=80' ], 'colors' => [ ['id' => 'cap-black', 'name' => 'Stealth Black (ดำ)', 'hex' => '#18181b', 'collarHex' => '#09090b', 'textDark' => false, 'printColor' => '#ffffff'] ], 'sizes' => ['Free Size'], 'description' => 'หมวกแก๊ประดับสตรีทแฟชั่น ทรงสวยไม่เสียรูป สายปรับไซส์ด้านหลังแบบบัคเคิลโลหะลุคหรูหรา' ] ]; // Helper to get custom and default products combined function getAllProducts() { global $DEFAULT_CATALOG; $custom = []; if (file_exists(CUSTOM_PRODUCTS_FILE)) { $custom = json_decode(file_get_contents(CUSTOM_PRODUCTS_FILE), true) ?: []; } return array_merge($custom, $DEFAULT_CATALOG); } function saveCustomProduct($product) { $custom = []; if (file_exists(CUSTOM_PRODUCTS_FILE)) { $custom = json_decode(file_get_contents(CUSTOM_PRODUCTS_FILE), true) ?: []; } array_unshift($custom, $product); file_put_contents(CUSTOM_PRODUCTS_FILE, json_encode($custom, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)); return true; } // Helper to get total ordered count function getTotalOrderedCount() { if (!file_exists(ORDERS_FILE)) return INITIAL_ORDER_OFFSET; $orders = json_decode(file_get_contents(ORDERS_FILE), true) ?: []; $totalFromDb = 0; foreach ($orders as $order) { if (isset($order['items']) && is_array($order['items'])) { foreach ($order['items'] as $item) { $totalFromDb += intval($item['quantity'] ?? 0); } } } return INITIAL_ORDER_OFFSET + $totalFromDb; } // Helper to get remaining stock count function getRemainingStock() { $totalOrdered = getTotalOrderedCount(); return max(0, TOTAL_STOCK_LIMIT - $totalOrdered); } // Helper to get all orders function getAllOrders() { if (!file_exists(ORDERS_FILE)) return []; return json_decode(file_get_contents(ORDERS_FILE), true) ?: []; }
| ver. 1.4 |
Github
|
.
| PHP 7.4.33 | Generation time: 0.5 |
proxy
|
phpinfo
|
Settings