コード例 #1
0
 /**
  * Generates a CSV for contest report
  *
  * @param Request $r
  * @return array
  */
 public static function apiCsvReport(Request $r)
 {
     self::authenticateRequest($r);
     self::validateStats($r);
     // Get full Report API of the contest
     $reportRequest = new Request(array("contest_alias" => $r["contest_alias"], "auth_token" => $r["auth_token"]));
     $contestReport = self::apiReport($reportRequest);
     // Get problem stats for each contest problem so we can
     // have the full list of cases
     $problemStats = array();
     $i = 0;
     foreach ($contestReport["problems"] as $entry) {
         $problem_alias = $entry["alias"];
         $problemStatsRequest = new Request(array("problem_alias" => $problem_alias, "auth_token" => $r["auth_token"]));
         $problemStats[$i] = ProblemController::apiStats($problemStatsRequest);
         $problemStats[$problem_alias] = $problemStats[$i];
         $i++;
     }
     // Build a csv
     $csvData = array();
     // Build titles
     $csvRow = array();
     $csvRow[] = "username";
     foreach ($contestReport["problems"] as $entry) {
         foreach ($problemStats[$entry["alias"]]["cases_stats"] as $caseName => $counts) {
             $csvRow[] = $caseName;
         }
         $csvRow[] = $entry["alias"] . " total";
     }
     $csvRow[] = "total";
     $csvData[] = $csvRow;
     foreach ($contestReport["ranking"] as $userData) {
         if ($userData === "ok") {
             continue;
         }
         $csvRow = array();
         $csvRow[] = $userData["username"];
         foreach ($userData["problems"] as $key => $problemData) {
             // If the user don't have these details then he didn't submit,
             // we need to fill the report with 0s for completeness
             if (!isset($problemData["run_details"]["cases"]) || count($problemData["run_details"]["cases"]) === 0) {
                 for ($i = 0; $i < count($problemStats[$key]["cases_stats"]); $i++) {
                     $csvRow[] = '0';
                 }
                 // And adding the total for this problem
                 $csvRow[] = '0';
             } else {
                 // for each case
                 foreach ($problemData["run_details"]["cases"] as $caseData) {
                     // If case is correct
                     if (strcmp($caseData["meta"]["status"], "OK") === 0 && strcmp($caseData["out_diff"], "") === 0) {
                         $csvRow[] = '1';
                     } else {
                         $csvRow[] = '0';
                     }
                 }
                 $csvRow[] = $problemData["points"];
             }
         }
         $csvRow[] = $userData["total"]["points"];
         $csvData[] = $csvRow;
     }
     // Set headers to auto-download file
     header("Pragma: public");
     header("Expires: 0");
     header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
     header("Content-Type: application/force-download");
     header("Content-Type: application/octet-stream");
     header("Content-Type: application/download");
     header("Content-Disposition: attachment;filename=" . $r["contest_alias"] . "_report.csv");
     header("Content-Transfer-Encoding: binary");
     // Write contents to a csv raw string
     // TODO(https://github.com/omegaup/omegaup/issues/628): Escape = to prevent applications from inadvertently executing code
     // http://contextis.co.uk/blog/comma-separated-vulnerabilities/
     $out = fopen('php://output', 'w');
     foreach ($csvData as $csvRow) {
         fputcsv($out, ContestController::escapeCsv($csvRow));
     }
     fclose($out);
     // X_X
     die;
 }