/** * Returns a report with all user activity for a contest. * * @param Request $r * @return array * @throws InvalidDatabaseOperationException */ public static function apiActivityReport(Request $r) { self::validateDetails($r); if (!$r['contest_admin']) { throw new ForbiddenAccessException(); } $accesses = ContestAccessLogDAO::GetAccessForContest($r['contest']); $submissions = SubmissionLogDAO::GetSubmissionsForContest($r['contest']); // Merge both logs. $result['events'] = array(); $lenAccesses = count($accesses); $lenSubmissions = count($submissions); $iAccesses = 0; $iSubmissions = 0; while ($iAccesses < $lenAccesses && $iSubmissions < $lenSubmissions) { if ($accesses[$iAccesses]['time'] < $submissions[$iSubmissions]['time']) { array_push($result['events'], ContestController::processAccess($accesses[$iAccesses++])); } else { array_push($result['events'], ContestController::processSubmission($submissions[$iSubmissions++])); } } while ($iAccesses < $lenAccesses) { array_push($result['events'], ContestController::processAccess($accesses[$iAccesses++])); } while ($iSubmissions < $lenSubmissions) { array_push($result['events'], ContestController::processSubmission($submissions[$iSubmissions++])); } // Anonimize data. $ipMapping = array(); foreach ($result['events'] as &$entry) { if (!array_key_exists($entry['ip'], $ipMapping)) { $ipMapping[$entry['ip']] = count($ipMapping); } $entry['ip'] = $ipMapping[$entry['ip']]; } $result['status'] = 'ok'; return $result; }