getJoinedMembersByUniqueNames($groups); $groupFilter = ["nickname", "IN", $nicknames]; // get IDs $tests = $testMgr->getResultsByGameId($gameid, $filter, $ordering, true, $groupFilter); $ids = array_map(fn($test) => $test["_id"], $tests); // generate stats return $testMgr->generateDetailedStats($gameid, $ids); } } class TeXUtils { static public function processCodeInserts(string $str) : string { $parts = explode("`", $str); $output = ""; for ($i = 0; $i < count($parts); $i++) { $output .= $parts[$i]; if ($i < count($parts) - 1) { if (($i % 2) === 0) { $output .= "\\texttt{"; } else { $output .= "}"; } } } return $output; } static public function escape(string $str) : string { return preg_replace("/([#%&])/", "\\\\$1", $str); } } class Answer { const CORRECT = "Correct"; const INCORRECT = "Incorrect"; private string $text; // Answer's text private string $type; // Answer's type private float $ratio; // Answer's ratio public function __construct(string $type, string $text, float $ratio) { $this->type = $type; $this->text = $text; $this->ratio = $ratio; } // Convert answer into TeX format. public function genTeX(): string { return "\\answer" . $this->type . "{" . $this->ratio . "}{" . $this->text . "}\n"; } } class Challenge { private string $question; private array $answers; function __construct(array $data) { $this->question = $data["question"]; // store question for ($i = 0; $i < count($data["answers"]); $i++) { $answer = $data["answers"][$i]; $ratio = $data["answer_ratio"][$i]; $type = $answer === $data["correct_answer"] ? Answer::CORRECT : Answer::INCORRECT; $this->answers[] = new Answer($type, $answer, $ratio); } } public function getQuestion(): string { return $this->question; } public function getAnswers(): array { return $this->answers; } // Generate TeX representation. public function genTeX(): string { $tex = "\\begin{question}{" . $this->question . "}\n"; foreach ($this->answers as &$answer) { $tex .= $answer->genTeX(); } $tex .= "\\end{question}\n"; return $tex; } } class ReportSection { private string $title; private array $challenges; function __construct(string $title, array $challenges) { $this->title = $title; $this->challenges = array_map(fn($ch) => new Challenge($ch), $challenges); } function getChallenges(): array { return $this->challenges; } function getTitle(): string { return $this->title; } // Generate TeX representation of this report. function genTeX(): string { $tex = "\\begin{quiz}{" . $this->title . "}\n"; foreach ($this->challenges as $challenge) { $tex .= $challenge->genTeX(); } $tex .= "\\end{quiz}\n"; return $tex; } } class Report { private string $title; private array $sections; function __construct(string $title) { $this->title = $title; $this->sections = []; } // Add a new section to the report. function addSection(ReportSection &$section): void { $this->sections[] = $section; } // Generate TeX representation. function genTeX(): string { $tex = ""; foreach ($this->sections as $section) { $tex .= $section->genTeX() . "\n\n"; } $tex = TeXUtils::processCodeInserts($tex); $tex = TeXUtils::escape($tex); return $tex; } const CONTENT_FILE = "content.tex"; const TITLE_FILE = "title.tex"; // Save TeX representation. function saveTeX(string $dir): void { file_put_contents($dir . DIRECTORY_SEPARATOR . self::CONTENT_FILE, $this->genTeX()); file_put_contents($dir . DIRECTORY_SEPARATOR . self::TITLE_FILE, $this->title); } }