) function checkAchievements($userId) { global $pdo; // Get user stats $stmt = $pdo->prepare("SELECT * FROM users WHERE id = ?"); $stmt->execute([$userId]); $user = $stmt->fetch(); if (!$user) return; // Get user's earned achievements $stmt = $pdo->prepare("SELECT achievement_id FROM user_achievements WHERE user_id = ?"); $stmt->execute([$userId]); $earnedIds = array_column($stmt->fetchAll(), 'achievement_id'); // Get all achievements $stmt = $pdo->query("SELECT * FROM achievements"); $achievements = $stmt->fetchAll(); // Check each achievement foreach ($achievements as $achievement) { // Skip if already earned if (in_array($achievement['id'], $earnedIds)) { continue; } $earned = false; $current = 0; switch ($achievement['requirement_type']) { case 'surfs_completed': $stmt = $pdo->prepare("SELECT COUNT(*) as total FROM surf_sessions WHERE user_id = ? AND completed = 1"); $stmt->execute([$userId]); $current = $stmt->fetch()['total']; $earned = ($current >= $achievement['requirement_value']); break; case 'level': $current = $user['level']; $earned = ($current >= $achievement['requirement_value']); break; case 'sites_added': $stmt = $pdo->prepare("SELECT COUNT(*) as total FROM sites WHERE user_id = ?"); $stmt->execute([$userId]); $current = $stmt->fetch()['total']; $earned = ($current >= $achievement['requirement_value']); break; case 'credits_earned': $stmt = $pdo->prepare("SELECT SUM(amount) as total FROM transactions WHERE user_id = ? AND type = 'earn'"); $stmt->execute([$userId]); $current = $stmt->fetch()['total'] ?? 0; $earned = ($current >= $achievement['requirement_value']); break; case 'login_streak': $current = $user['login_streak']; $earned = ($current >= $achievement['requirement_value']); break; } // Award achievement if earned if ($earned) { try { // Insert achievement $stmt = $pdo->prepare("INSERT INTO user_achievements (user_id, achievement_id) VALUES (?, ?)"); $stmt->execute([$userId, $achievement['id']]); // Award credits if ($achievement['credits_reward'] > 0) { addCredits($userId, $achievement['credits_reward'], 'bonus', 'Achievement: ' . $achievement['name']); } // Store in session for notification if (!isset($_SESSION['new_achievements'])) { $_SESSION['new_achievements'] = []; } $_SESSION['new_achievements'][] = $achievement; } catch (Exception $e) { // Achievement already exists (race condition), ignore } } } } function updateLoginStreak($userId) { global $pdo; $stmt = $pdo->prepare("SELECT login_streak, last_streak_date FROM users WHERE id = ?"); $stmt->execute([$userId]); $user = $stmt->fetch(); $today = date('Y-m-d'); $lastDate = $user['last_streak_date']; if (!$lastDate) { // First login $stmt = $pdo->prepare("UPDATE users SET login_streak = 1, last_streak_date = ? WHERE id = ?"); $stmt->execute([$today, $userId]); } elseif ($lastDate == $today) { // Already logged in today, do nothing return; } elseif ($lastDate == date('Y-m-d', strtotime('-1 day'))) { // Consecutive day - increment streak $newStreak = $user['login_streak'] + 1; $stmt = $pdo->prepare("UPDATE users SET login_streak = ?, last_streak_date = ? WHERE id = ?"); $stmt->execute([$newStreak, $today, $userId]); // Check streak achievements checkAchievements($userId); } else { // Streak broken - reset to 1 $stmt = $pdo->prepare("UPDATE users SET login_streak = 1, last_streak_date = ? WHERE id = ?"); $stmt->execute([$today, $userId]); } } function getNewAchievementNotifications() { if (isset($_SESSION['new_achievements'])) { $achievements = $_SESSION['new_achievements']; unset($_SESSION['new_achievements']); return $achievements; } return []; } function trackAnalyticsEvent($siteId, $userId, $eventType, $duration = 0) { global $pdo; try { $stmt = $pdo->prepare("INSERT INTO analytics_events (site_id, user_id, event_type, duration) VALUES (?, ?, ?, ?)"); $stmt->execute([$siteId, $userId, $eventType, $duration]); // Update site aggregate stats updateSiteAnalytics($siteId); } catch (Exception $e) { // Log error but don't break the flow error_log("Analytics tracking error: " . $e->getMessage()); } } function updateSiteAnalytics($siteId) { global $pdo; // Calculate average duration $stmt = $pdo->prepare("SELECT AVG(duration) as avg_duration FROM surf_sessions WHERE site_id = ? AND completed = 1"); $stmt->execute([$siteId]); $avgDuration = $stmt->fetch()['avg_duration'] ?? 0; // Update site $stmt = $pdo->prepare("UPDATE sites SET avg_duration = ? WHERE id = ?"); $stmt->execute([$avgDuration, $siteId]); } // Achievement Helper Functions // ADD THESE FUNCTIONS TO THE END OF config.php (before the closing ?>) function checkAchievements($userId) { global $pdo; // Get user stats $stmt = $pdo->prepare("SELECT * FROM users WHERE id = ?"); $stmt->execute([$userId]); $user = $stmt->fetch(); if (!$user) return; // Get user's earned achievements $stmt = $pdo->prepare("SELECT achievement_id FROM user_achievements WHERE user_id = ?"); $stmt->execute([$userId]); $earnedIds = array_column($stmt->fetchAll(), 'achievement_id'); // Get all achievements $stmt = $pdo->query("SELECT * FROM achievements"); $achievements = $stmt->fetchAll(); // Check each achievement foreach ($achievements as $achievement) { // Skip if already earned if (in_array($achievement['id'], $earnedIds)) { continue; } $earned = false; $current = 0; switch ($achievement['requirement_type']) { case 'surfs_completed': $stmt = $pdo->prepare("SELECT COUNT(*) as total FROM surf_sessions WHERE user_id = ? AND completed = 1"); $stmt->execute([$userId]); $current = $stmt->fetch()['total']; $earned = ($current >= $achievement['requirement_value']); break; case 'level': $current = $user['level']; $earned = ($current >= $achievement['requirement_value']); break; case 'sites_added': $stmt = $pdo->prepare("SELECT COUNT(*) as total FROM sites WHERE user_id = ?"); $stmt->execute([$userId]); $current = $stmt->fetch()['total']; $earned = ($current >= $achievement['requirement_value']); break; case 'credits_earned': $stmt = $pdo->prepare("SELECT SUM(amount) as total FROM transactions WHERE user_id = ? AND type = 'earn'"); $stmt->execute([$userId]); $current = $stmt->fetch()['total'] ?? 0; $earned = ($current >= $achievement['requirement_value']); break; case 'login_streak': $current = $user['login_streak']; $earned = ($current >= $achievement['requirement_value']); break; } // Award achievement if earned if ($earned) { try { // Insert achievement $stmt = $pdo->prepare("INSERT INTO user_achievements (user_id, achievement_id) VALUES (?, ?)"); $stmt->execute([$userId, $achievement['id']]); // Award credits if ($achievement['credits_reward'] > 0) { addCredits($userId, $achievement['credits_reward'], 'bonus', 'Achievement: ' . $achievement['name']); } // Store in session for notification if (!isset($_SESSION['new_achievements'])) { $_SESSION['new_achievements'] = []; } $_SESSION['new_achievements'][] = $achievement; } catch (Exception $e) { // Achievement already exists (race condition), ignore } } } } function updateLoginStreak($userId) { global $pdo; $stmt = $pdo->prepare("SELECT login_streak, last_streak_date FROM users WHERE id = ?"); $stmt->execute([$userId]); $user = $stmt->fetch(); $today = date('Y-m-d'); $lastDate = $user['last_streak_date']; if (!$lastDate) { // First login $stmt = $pdo->prepare("UPDATE users SET login_streak = 1, last_streak_date = ? WHERE id = ?"); $stmt->execute([$today, $userId]); } elseif ($lastDate == $today) { // Already logged in today, do nothing return; } elseif ($lastDate == date('Y-m-d', strtotime('-1 day'))) { // Consecutive day - increment streak $newStreak = $user['login_streak'] + 1; $stmt = $pdo->prepare("UPDATE users SET login_streak = ?, last_streak_date = ? WHERE id = ?"); $stmt->execute([$newStreak, $today, $userId]); // Check streak achievements checkAchievements($userId); } else { // Streak broken - reset to 1 $stmt = $pdo->prepare("UPDATE users SET login_streak = 1, last_streak_date = ? WHERE id = ?"); $stmt->execute([$today, $userId]); } } function getNewAchievementNotifications() { if (isset($_SESSION['new_achievements'])) { $achievements = $_SESSION['new_achievements']; unset($_SESSION['new_achievements']); return $achievements; } return []; } function trackAnalyticsEvent($siteId, $userId, $eventType, $duration = 0) { global $pdo; try { $stmt = $pdo->prepare("INSERT INTO analytics_events (site_id, user_id, event_type, duration) VALUES (?, ?, ?, ?)"); $stmt->execute([$siteId, $userId, $eventType, $duration]); // Update site aggregate stats updateSiteAnalytics($siteId); } catch (Exception $e) { // Log error but don't break the flow error_log("Analytics tracking error: " . $e->getMessage()); } } function updateSiteAnalytics($siteId) { global $pdo; // Calculate average duration $stmt = $pdo->prepare("SELECT AVG(duration) as avg_duration FROM surf_sessions WHERE site_id = ? AND completed = 1"); $stmt->execute([$siteId]); $avgDuration = $stmt->fetch()['avg_duration'] ?? 0; // Update site $stmt = $pdo->prepare("UPDATE sites SET avg_duration = ? WHERE id = ?"); $stmt->execute([$avgDuration, $siteId]); } ?>
Start Your Traffic Adventure