root('content') . '/analytics/visits.yml'; } private static function ensureFileExists(): void { $filePath = self::getFilePath(); $dirPath = dirname($filePath); if (!is_dir($dirPath)) { F::mkdir($dirPath, true); } if (!F::exists($filePath)) { F::write($filePath, Yaml::encode(['visits' => []])); } } public static function addVisit(Visit $visit): void { self::ensureFileExists(); $filePath = self::getFilePath(); $data = Yaml::decode(F::read($filePath)); $visits = $data['visits'] ?? []; $visits[] = $visit->toArray(); // Limiter à 10000 visites max if (count($visits) > 10000) { $visits = array_slice($visits, -10000); } $data['visits'] = $visits; F::write($filePath, Yaml::encode($data)); } public static function getVisits(array $filters = []): array { self::ensureFileExists(); $filePath = self::getFilePath(); $data = Yaml::decode(F::read($filePath)); $visits = $data['visits'] ?? []; // Convertir en objets Visit $visits = array_map(fn($v) => Visit::fromArray($v), $visits); // Filtrer par daterange if (!empty($filters['startDate']) || !empty($filters['endDate'])) { $visits = array_filter($visits, function($visit) use ($filters) { $timestamp = strtotime($visit->timestamp); if (!empty($filters['startDate'])) { $startDate = strtotime($filters['startDate'] . ' 00:00:00'); if ($timestamp < $startDate) { return false; } } if (!empty($filters['endDate'])) { $endDate = strtotime($filters['endDate'] . ' 23:59:59'); if ($timestamp > $endDate) { return false; } } return true; }); } // Filtrer par projet if (!empty($filters['project'])) { $projectId = $filters['project']; $visits = array_filter($visits, function($visit) use ($projectId) { return str_contains($visit->pageUrl, "/projects/{$projectId}"); }); } // Filtrer par email (permissions) if (!empty($filters['emails'])) { $allowedEmails = $filters['emails']; $visits = array_filter($visits, function($visit) use ($allowedEmails) { return in_array($visit->email, $allowedEmails); }); } return array_values($visits); } public static function getAggregatedData(array $filters = []): array { self::ensureFileExists(); $visits = self::getVisits($filters); // Visites par jour $visitsByDay = []; foreach ($visits as $visit) { $day = date('Y-m-d', strtotime($visit->timestamp)); $visitsByDay[$day] = ($visitsByDay[$day] ?? 0) + 1; } ksort($visitsByDay); // Visites par page $visitsByPage = []; foreach ($visits as $visit) { $page = $visit->pageName ?: $visit->pageUrl; $visitsByPage[$page] = ($visitsByPage[$page] ?? 0) + 1; } arsort($visitsByPage); // Visites par utilisateur $visitsByUser = []; foreach ($visits as $visit) { $visitsByUser[$visit->email] = ($visitsByUser[$visit->email] ?? 0) + 1; } arsort($visitsByUser); // Nombre de sessions uniques $uniqueSessions = count(array_unique(array_map(fn($v) => $v->sessionId, $visits))); // Visites par type de page $visitsByType = []; foreach ($visits as $visit) { $visitsByType[$visit->pageType] = ($visitsByType[$visit->pageType] ?? 0) + 1; } arsort($visitsByType); return [ 'totalVisits' => count($visits), 'uniqueSessions' => $uniqueSessions, 'visitsByDay' => $visitsByDay, 'visitsByPage' => array_slice($visitsByPage, 0, 10), 'visitsByUser' => $visitsByUser, 'visitsByType' => $visitsByType, ]; } }