export_contest_standings_table.php 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. <?php
  2. if (!validateUInt($_GET['id']) || !($contest = queryContest($_GET['id']))) {
  3. become404Page();
  4. }
  5. genMoreContestInfo($contest);
  6. if (!hasContestPermission(Auth::user(), $contest)) {
  7. becomeMsgPage('您没有权限下载此比赛的排名。');
  8. }
  9. if ($contest['cur_progress'] < CONTEST_FINISHED) {
  10. becomeMsgPage('比赛尚未结束,无法下载排名。');
  11. }
  12. $contest_data = queryContestData($contest);
  13. calcStandings($contest, $contest_data, $score, $standings);
  14. function array2csv(array &$array) {
  15. if (count($array) == 0) {
  16. return null;
  17. }
  18. ob_start();
  19. $df = fopen("php://output", 'w');
  20. fputcsv($df, array_keys(reset($array)));
  21. foreach ($array as $row) {
  22. fputcsv($df, $row);
  23. }
  24. fclose($df);
  25. return ob_get_clean();
  26. }
  27. $export_data = [];
  28. $csv_header = ['Rank', 'Username', 'Score', 'Penalty'];
  29. $n_problems = count($contest_data['problems']);
  30. for ($i = 0; $i < $n_problems; $i++) {
  31. $csv_header[] = chr(ord('A') + $i);
  32. $csv_header[] = chr(ord('A') + $i) . '_penalty';
  33. $csv_header[] = chr(ord('A') + $i) . '_submission_id';
  34. }
  35. $export_data[] = $csv_header;
  36. // Convert data in $standings and $score to $export_data
  37. foreach ($standings as $rank => $row) {
  38. // $row: rank, username, score, penalty
  39. $res = [$rank + 1, $row[2][0], $row[0], $row[1]];
  40. for ($i = 0; $i < $n_problems; $i++) {
  41. // $score[$row[2][0]][$i]: score, penalty, submission_id
  42. $res[] = isset($score[$row[2][0]][$i][0]) ? $score[$row[2][0]][$i][0] : "";
  43. $res[] = isset($score[$row[2][0]][$i][1]) ? $score[$row[2][0]][$i][1] : "";
  44. $res[] = isset($score[$row[2][0]][$i][2]) ? $score[$row[2][0]][$i][2] : "";
  45. }
  46. $export_data[] = $res;
  47. }
  48. $csv = array2csv($export_data);
  49. header("Cache-Control: max-age=0, no-cache, must-revalidate, proxy-revalidate");
  50. header("Last-Modified: {$now} GMT");
  51. header("Content-Type: text/csv");
  52. header("Content-Disposition: attachment;filename={$contest['id']}_standings.csv");
  53. die($csv);