'track-visit.json', 'method' => 'POST', 'action' => function () { $kirby = kirby(); $user = $kirby->user(); // Seuls les utilisateurs connectés peuvent tracker if (!$user) { return [ 'status' => 'error', 'message' => 'Unauthorized' ]; } $data = $kirby->request()->body()->toArray(); // Détection du pays $country = null; // 1. Header Cloudflare if (isset($_SERVER['HTTP_CF_IPCOUNTRY'])) { $country = $_SERVER['HTTP_CF_IPCOUNTRY']; } // 2. Fallback : API ipapi.co (optionnel, peut être désactivé) elseif (!empty($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] !== '127.0.0.1') { try { $ip = $_SERVER['REMOTE_ADDR']; $response = @file_get_contents("https://ipapi.co/{$ip}/country/", false, stream_context_create([ 'http' => ['timeout' => 1] ])); if ($response) { $country = trim($response); } } catch (Exception $e) { // Ignorer les erreurs de géolocalisation } } $visit = new Visit([ 'email' => $user->email()->value(), 'country' => $country, 'sessionId' => $data['sessionId'] ?? '', 'pageUrl' => $data['pageUrl'] ?? '', 'pageType' => $data['pageType'] ?? 'unknown', 'pageName' => $data['pageName'] ?? null, ]); AnalyticsStore::addVisit($visit); return [ 'status' => 'success', 'message' => 'Visit tracked' ]; } ];