) 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]); } ?>
The only traffic exchange that rewards you for real engagement. Earn credits while discovering amazing websites, then drive quality visitors to yours.
We're not your typical traffic exchange. We've gamified the experience to make earning and spending traffic actually enjoyable.
Level up as you surf. Earn XP, unlock achievements, and climb leaderboards while building your traffic empire.
See your credits grow in real-time. No delays, no waiting. Surf, earn, and use your credits immediately.
Our AI matches your site with viewers actually interested in your niche. No more random, low-quality traffic.
30-second minimum surf time ensures real people see your content. No bots, no fake views, just genuine attention.
Track every view, click, and engagement. Make data-driven decisions to optimize your campaigns.
Bank-level security, verified users, and fraud protection. Your credits and data are always safe with us.
Three simple steps to start driving quality traffic to your website
Create your account in 30 seconds and receive 50 credits instantly. No credit card required.
Surf other members' websites for 30 seconds each. Earn 10 credits per site and level up your account.
Use your credits to drive targeted visitors to your own website. Watch your traffic grow automatically.
Start free or supercharge your growth with credit packages
Join thousands of smart marketers who are already growing their audience with TrafficQuest. Get started in less than a minute.
Start Free - Get 50 Credits Now