Compare commits
No commits in common. "master" and "live_debug" have entirely different histories.
master
...
live_debug
@ -31,7 +31,7 @@ class Game extends AutoStoring
|
|||||||
|
|
||||||
// -------
|
// -------
|
||||||
|
|
||||||
static public function genPublicId(): string
|
static private function genPublicId(): string
|
||||||
{
|
{
|
||||||
return uniqid("p");
|
return uniqid("p");
|
||||||
}
|
}
|
||||||
@ -386,7 +386,7 @@ class GameMgr
|
|||||||
"game_file_present" => false,
|
"game_file_present" => false,
|
||||||
"properties" => $properties,
|
"properties" => $properties,
|
||||||
"public" => false,
|
"public" => false,
|
||||||
"public_id" => Game::genPublicId(),
|
"public_id" => self::genPublicId(),
|
||||||
"version" => Game::CURRENT_GAME_VERSION
|
"version" => Game::CURRENT_GAME_VERSION
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -430,34 +430,5 @@ class GameMgr
|
|||||||
return $games;
|
return $games;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sanitize games and return game IDs.
|
|
||||||
function sanitizeGames(array $games) : array {
|
|
||||||
$sanitized = [];
|
|
||||||
foreach ($games as $game) {
|
|
||||||
// explode game identifier
|
|
||||||
[$name, $id] = explode("#", $game);
|
|
||||||
|
|
||||||
// fetch game
|
|
||||||
if ($id !== null) {
|
|
||||||
$records = $this->db->findBy([["name", "=", $name], "AND", ["_id", "=", (int)$id]]);
|
|
||||||
} else {
|
|
||||||
$records = $this->db->findBy(["name", "=", $name]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// put game ID into sanitized list only if identifier is not ambiguous
|
|
||||||
if (count($records) === 1) {
|
|
||||||
$sanitized[] = $records[0]["_id"];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $sanitized;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Resolve group IDs to full group identifiers.
|
|
||||||
function resolveGames(array &$gameIds): void {
|
|
||||||
$a = $this->db->findBy([["_id", "IN", $gameIds]]); // no caching here...
|
|
||||||
$gameIds = array_map(fn($r) => $r["name"] . "#" . $r["_id"] ,$a);
|
|
||||||
}
|
|
||||||
|
|
||||||
// -------
|
// -------
|
||||||
}
|
}
|
@ -192,7 +192,7 @@ class Group extends AutoStoring
|
|||||||
alter_array_contents($this->games, $gameid, null);
|
alter_array_contents($this->games, $gameid, null);
|
||||||
}
|
}
|
||||||
foreach ($gameids_remove as $gameid) { // remove games
|
foreach ($gameids_remove as $gameid) { // remove games
|
||||||
alter_array_contents($this->games, null, $gameid);
|
alter_array_contents($this->members, null, $gameid);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->storeMods(); // store changes
|
$this->storeMods(); // store changes
|
||||||
|
@ -7,7 +7,7 @@ require_once "common_func.php";
|
|||||||
|
|
||||||
class ReportBuilder
|
class ReportBuilder
|
||||||
{
|
{
|
||||||
static public function getStatsByFilters(int $gameid, string $filter, string $groups, bool $bestOnly)
|
static public function getStatsByFilters(int $gameid, string $filter, string $groups, string $ordering)
|
||||||
{
|
{
|
||||||
$groupMgr = new GroupMgr();
|
$groupMgr = new GroupMgr();
|
||||||
$testMgr = new TestMgr();
|
$testMgr = new TestMgr();
|
||||||
@ -18,7 +18,7 @@ class ReportBuilder
|
|||||||
$groupFilter = ["nickname", "IN", $nicknames];
|
$groupFilter = ["nickname", "IN", $nicknames];
|
||||||
|
|
||||||
// get IDs
|
// get IDs
|
||||||
$tests = $testMgr->getResultsByGameId($gameid, $filter, "", true, $bestOnly, $groupFilter);
|
$tests = $testMgr->getResultsByGameId($gameid, $filter, $ordering, true, $groupFilter);
|
||||||
$ids = array_map(fn($test) => $test["_id"], $tests);
|
$ids = array_map(fn($test) => $test["_id"], $tests);
|
||||||
|
|
||||||
// generate stats
|
// generate stats
|
||||||
@ -71,25 +71,12 @@ class Answer
|
|||||||
{
|
{
|
||||||
return "\\answer" . $this->type . "{" . $this->ratio . "}{" . $this->text . "}\n";
|
return "\\answer" . $this->type . "{" . $this->ratio . "}{" . $this->text . "}\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get answer ratio.
|
|
||||||
public function getRatio(): float
|
|
||||||
{
|
|
||||||
return $this->ratio;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class Challenge
|
class Challenge
|
||||||
{
|
{
|
||||||
private string $question;
|
private string $question;
|
||||||
private array $answers;
|
private array $answers;
|
||||||
private int $fillCount;
|
|
||||||
private int $skipCount;
|
|
||||||
|
|
||||||
// Sort answers by ratio.
|
|
||||||
private function sortAnswers() : void {
|
|
||||||
usort($this->answers, function($a, $b) {return $a->getRatio() < $b->getRatio();});
|
|
||||||
}
|
|
||||||
|
|
||||||
function __construct(array $data)
|
function __construct(array $data)
|
||||||
{
|
{
|
||||||
@ -100,10 +87,6 @@ class Challenge
|
|||||||
$type = $answer === $data["correct_answer"] ? Answer::CORRECT : Answer::INCORRECT;
|
$type = $answer === $data["correct_answer"] ? Answer::CORRECT : Answer::INCORRECT;
|
||||||
$this->answers[] = new Answer($type, $answer, $ratio);
|
$this->answers[] = new Answer($type, $answer, $ratio);
|
||||||
}
|
}
|
||||||
$this->fillCount = array_sum($data["player_answers"]); // get fill count
|
|
||||||
$this->skipCount = $data["skipped"];
|
|
||||||
|
|
||||||
$this->sortAnswers(); // sort answers by fill ratio
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getQuestion(): string
|
public function getQuestion(): string
|
||||||
@ -116,22 +99,10 @@ class Challenge
|
|||||||
return $this->answers;
|
return $this->answers;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getFillCount(): int {
|
|
||||||
return $this->fillCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getSkipCount(): int {
|
|
||||||
return $this->skipCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getSubmissionCount() : int {
|
|
||||||
return $this->fillCount + $this->skipCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate TeX representation.
|
// Generate TeX representation.
|
||||||
public function genTeX(): string
|
public function genTeX(): string
|
||||||
{
|
{
|
||||||
$tex = "\\begin{question}{" . $this->question . "}{" . $this->fillCount . "}\n";
|
$tex = "\\begin{question}{" . $this->question . "}\n";
|
||||||
foreach ($this->answers as &$answer) {
|
foreach ($this->answers as &$answer) {
|
||||||
$tex .= $answer->genTeX();
|
$tex .= $answer->genTeX();
|
||||||
}
|
}
|
||||||
@ -145,10 +116,6 @@ class ReportSection
|
|||||||
private string $title;
|
private string $title;
|
||||||
private array $challenges;
|
private array $challenges;
|
||||||
|
|
||||||
private function getNumberOfSubmissions() : int {
|
|
||||||
return count($this->challenges) > 0 ? $this->challenges[0]->getSubmissionCount() : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
function __construct(string $title, array $challenges)
|
function __construct(string $title, array $challenges)
|
||||||
{
|
{
|
||||||
$this->title = $title;
|
$this->title = $title;
|
||||||
@ -168,7 +135,7 @@ class ReportSection
|
|||||||
// Generate TeX representation of this report.
|
// Generate TeX representation of this report.
|
||||||
function genTeX(): string
|
function genTeX(): string
|
||||||
{
|
{
|
||||||
$tex = "\\begin{quiz}{" . $this->title . "}{" . $this->getNumberOfSubmissions() . "}\n";
|
$tex = "\\begin{quiz}{" . $this->title . "}\n";
|
||||||
foreach ($this->challenges as $challenge) {
|
foreach ($this->challenges as $challenge) {
|
||||||
$tex .= $challenge->genTeX();
|
$tex .= $challenge->genTeX();
|
||||||
}
|
}
|
||||||
@ -181,13 +148,11 @@ class Report
|
|||||||
{
|
{
|
||||||
private string $title;
|
private string $title;
|
||||||
private array $sections;
|
private array $sections;
|
||||||
private array $comments;
|
|
||||||
|
|
||||||
function __construct(string $title)
|
function __construct(string $title)
|
||||||
{
|
{
|
||||||
$this->title = $title;
|
$this->title = $title;
|
||||||
$this->sections = [];
|
$this->sections = [];
|
||||||
$this->comments = [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -197,28 +162,13 @@ class Report
|
|||||||
$this->sections[] = $section;
|
$this->sections[] = $section;
|
||||||
}
|
}
|
||||||
|
|
||||||
function addComment(string $comment): void
|
|
||||||
{
|
|
||||||
$this->comments[] = $comment;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate TeX representation.
|
// Generate TeX representation.
|
||||||
function genTeX(): string
|
function genTeX(): string
|
||||||
{
|
{
|
||||||
$tex = "";
|
$tex = "";
|
||||||
// generate content
|
|
||||||
foreach ($this->sections as $section) {
|
foreach ($this->sections as $section) {
|
||||||
$tex .= $section->genTeX() . "\n\n";
|
$tex .= $section->genTeX() . "\n\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
// add comments if any
|
|
||||||
if ($this->comments != []) {
|
|
||||||
$tex .= "\\huge\\noindent A következő oldal érzékeny információkat tartalmazhat!\\newline Nem publikálandó!\n\\clearpage\n\n";
|
|
||||||
$tex .= "\\clearpage\n\small\n\\noindent ";
|
|
||||||
$tex .= join("\\\\\n", $this->comments);
|
|
||||||
}
|
|
||||||
|
|
||||||
// escape LaTeX control characters
|
|
||||||
$tex = TeXUtils::processCodeInserts($tex);
|
$tex = TeXUtils::processCodeInserts($tex);
|
||||||
$tex = TeXUtils::escape($tex);
|
$tex = TeXUtils::escape($tex);
|
||||||
return $tex;
|
return $tex;
|
||||||
|
@ -406,7 +406,7 @@ class TestMgr
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get test results by game ID.
|
// Get test results by game ID.
|
||||||
function getResultsByGameId(string $gameid, string $filter, string $orderby, bool $exclude_challenge_data, bool $best_ones_only, array ...$furtherFilters): array
|
function getResultsByGameId(string $gameid, string $filter, string $orderby, bool $exclude_challenge_data, array ...$furtherFilters): array
|
||||||
{
|
{
|
||||||
$qb = $this->db->createQueryBuilder();
|
$qb = $this->db->createQueryBuilder();
|
||||||
$qb = $qb->where(["gameid", "=", (int)$gameid]);
|
$qb = $qb->where(["gameid", "=", (int)$gameid]);
|
||||||
@ -448,34 +448,6 @@ class TestMgr
|
|||||||
}
|
}
|
||||||
|
|
||||||
$test_data_array = $qb->getQuery()->fetch();
|
$test_data_array = $qb->getQuery()->fetch();
|
||||||
|
|
||||||
// if only the best results should be included, then...
|
|
||||||
if ($best_ones_only) {
|
|
||||||
// filter out ongoing ones
|
|
||||||
$tests = array_filter($test_data_array, fn($test) => $test["state"] === Test::TEST_CONCLUDED);
|
|
||||||
|
|
||||||
// sort by result
|
|
||||||
usort($tests, fn($a, $b) => $a["summary"]["percentage"] > $b["summary"]["percentage"]);
|
|
||||||
|
|
||||||
// gather best tests by username here
|
|
||||||
$best_test_ids = [];
|
|
||||||
foreach ($tests as $test) {
|
|
||||||
$nickname = $test["nickname"];
|
|
||||||
if (!in_array($nickname, $best_test_ids)) {
|
|
||||||
$best_test_ids[$nickname] = $test["_id"];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// just keep values, drop the keys (nicknames)
|
|
||||||
$best_test_ids = array_values($best_test_ids);
|
|
||||||
|
|
||||||
// remove non-best results
|
|
||||||
$test_data_array = array_filter($test_data_array, fn($test) => in_array($test["_id"], $best_test_ids));
|
|
||||||
|
|
||||||
// renumber results
|
|
||||||
$test_data_array = array_values($test_data_array);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $test_data_array;
|
return $test_data_array;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -515,7 +487,6 @@ class TestMgr
|
|||||||
"correct_answer" => $correct_answer,
|
"correct_answer" => $correct_answer,
|
||||||
"player_answers" => array_fill(0, count($challenge["answers"]), 0),
|
"player_answers" => array_fill(0, count($challenge["answers"]), 0),
|
||||||
"answer_count" => count($challenge["answers"]),
|
"answer_count" => count($challenge["answers"]),
|
||||||
"skipped" => 0
|
|
||||||
];
|
];
|
||||||
$aggregated[$challenge_indices[$idhash]] = $challenge_info; // insert challenge info
|
$aggregated[$challenge_indices[$idhash]] = $challenge_info; // insert challenge info
|
||||||
}
|
}
|
||||||
@ -524,12 +495,9 @@ class TestMgr
|
|||||||
$challenge_idx = $challenge_indices[$idhash];
|
$challenge_idx = $challenge_indices[$idhash];
|
||||||
|
|
||||||
// add up player answer
|
// add up player answer
|
||||||
$player_answer = trim($challenge["player_answer"]);
|
if (trim($challenge["player_answer"]) !== "") {
|
||||||
if (($player_answer !== "") && ($player_answer != -1)) { // player answered
|
|
||||||
$answer_idx = array_search($challenge["answers"][$challenge["player_answer"]], $aggregated[$challenge_idx]["answers"]); // transform player answer index to report answer index
|
$answer_idx = array_search($challenge["answers"][$challenge["player_answer"]], $aggregated[$challenge_idx]["answers"]); // transform player answer index to report answer index
|
||||||
$aggregated[$challenge_idx]["player_answers"][(int)$answer_idx]++;
|
$aggregated[$challenge_idx]["player_answers"][(int)$answer_idx]++;
|
||||||
} else { // player has not answered or provided an unprocessable answer
|
|
||||||
$aggregated[$challenge_idx]["skipped"]++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
"rakibtg/sleekdb": "2.15",
|
"rakibtg/sleekdb": "2.15",
|
||||||
"ext-http": "*",
|
"ext-http": "*",
|
||||||
"ext-mbstring" : "*",
|
"ext-mbstring" : "*",
|
||||||
"ext-zip": "*",
|
"ext-zip": "*"
|
||||||
"ext-fileinfo": "*"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -146,10 +146,7 @@ if (!get_autologin_state() || (($user_data["privilege"] !== PRIVILEGE_CREATOR) &
|
|||||||
<select id="report_output_type">
|
<select id="report_output_type">
|
||||||
<option value="pdf">PDF</option>
|
<option value="pdf">PDF</option>
|
||||||
<option value="tex">TeX</option>
|
<option value="tex">TeX</option>
|
||||||
</select><br>
|
</select>
|
||||||
<input type="checkbox" id="best_only"><label for="best_only" style="font-size: 12px">Csak legjobb eredmények felhasználónként</label>
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
<input type="button" value="Előállítás" onclick="generate_game_report_by_groups()">
|
<input type="button" value="Előállítás" onclick="generate_game_report_by_groups()">
|
||||||
<input type="button" value="Bezárás" onclick="hide('report_generator')">
|
<input type="button" value="Bezárás" onclick="hide('report_generator')">
|
||||||
</section>
|
</section>
|
||||||
|
@ -67,23 +67,13 @@ if (!get_autologin_state() || ($user_data["privilege"] !== PRIVILEGE_QUIZMASTER)
|
|||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<label for="group_members">Tagok:</label><br>
|
<label for="group_members">Tagok:</label><br>
|
||||||
<input type="button" value="+" onclick="open_element_change_window('add', 'member')">
|
<input type="button" value="+" onclick="open_member_change_window('add')">
|
||||||
<input type="button" value="-" onclick="open_element_change_window('remove', 'member')">
|
<input type="button" value="-" onclick="open_member_change_window('remove')">
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<textarea id="group_members" readonly></textarea>
|
<textarea id="group_members" readonly></textarea>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<label for="group_games">Játékok:</label><br>
|
|
||||||
<input type="button" value="+" onclick="open_element_change_window('add', 'game')">
|
|
||||||
<input type="button" value="-" onclick="open_element_change_window('remove', 'game')">
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<textarea id="group_games" readonly></textarea>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
</table>
|
||||||
<section style="display: block; text-align: right">
|
<section style="display: block; text-align: right">
|
||||||
<input type="button" value="" id="group_editor_submit_btn">
|
<input type="button" value="" id="group_editor_submit_btn">
|
||||||
@ -92,13 +82,13 @@ if (!get_autologin_state() || ($user_data["privilege"] !== PRIVILEGE_QUIZMASTER)
|
|||||||
</section>
|
</section>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="window" shown="false" id="element_manager_window">
|
<section class="window" shown="false" id="member_manager_window">
|
||||||
<section class="window-inner">
|
<section class="window-inner">
|
||||||
<section id="element_manager_window_title">
|
<section id="member_manager_window_title">
|
||||||
</section>
|
</section>
|
||||||
<textarea id="add_remove_element_area"></textarea><br>
|
<textarea id="add_remove_member_area"></textarea><br>
|
||||||
<input type="button" value="OK" onclick="change_group_elements()">
|
<input type="button" value="OK" onclick="change_group_members()">
|
||||||
<input type="button" value="Mégse" onclick="hide('element_manager_window')">
|
<input type="button" value="Mégse" onclick="hide('member_manager_window')">
|
||||||
</section>
|
</section>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
@ -286,12 +286,9 @@ function patch_through_image(string $gameid, string $img_url)
|
|||||||
$image_fetch_url = $game_dir . DIRECTORY_SEPARATOR . $img_url;
|
$image_fetch_url = $game_dir . DIRECTORY_SEPARATOR . $img_url;
|
||||||
|
|
||||||
$img_fp = fopen($image_fetch_url, "r");
|
$img_fp = fopen($image_fetch_url, "r");
|
||||||
$content_type = mime_content_type($image_fetch_url);
|
|
||||||
if ($img_fp === false) {
|
if ($img_fp === false) {
|
||||||
$img_fp = fopen(MISSING_IMAGE_PLACEHOLDER, "r");
|
$img_fp = fopen(MISSING_IMAGE_PLACEHOLDER, "r");
|
||||||
$content_type = mime_content_type(MISSING_IMAGE_PLACEHOLDER);
|
|
||||||
}
|
}
|
||||||
header("Content-Type: $content_type");
|
|
||||||
fpassthru($img_fp);
|
fpassthru($img_fp);
|
||||||
fclose($img_fp);
|
fclose($img_fp);
|
||||||
}
|
}
|
||||||
@ -488,7 +485,6 @@ function get_results_by_gameid(ReqHandler &$rh, array $params): array
|
|||||||
$filter = trim($params["filter"] ?? "");
|
$filter = trim($params["filter"] ?? "");
|
||||||
$ordering = trim($params["orderby"] ?? "");
|
$ordering = trim($params["orderby"] ?? "");
|
||||||
$groups = explode_list(trim($params["groups"] ?? ""));
|
$groups = explode_list(trim($params["groups"] ?? ""));
|
||||||
$best_only = trim($params["best_only"] ?? "false") === "true";
|
|
||||||
|
|
||||||
$game = $gameMgr->getGame($gameid);
|
$game = $gameMgr->getGame($gameid);
|
||||||
|
|
||||||
@ -520,9 +516,9 @@ function get_results_by_gameid(ReqHandler &$rh, array $params): array
|
|||||||
// execute filtering
|
// execute filtering
|
||||||
$game_results = null;
|
$game_results = null;
|
||||||
if ($group_filter !== []) {
|
if ($group_filter !== []) {
|
||||||
$game_results = $testMgr->getResultsByGameId($gameid, $filter, $ordering, true, $best_only, $group_filter);
|
$game_results = $testMgr->getResultsByGameId($gameid, $filter, $ordering, true, $group_filter);
|
||||||
} else {
|
} else {
|
||||||
$game_results = $testMgr->getResultsByGameId($gameid, $filter, $ordering, true, $best_only);
|
$game_results = $testMgr->getResultsByGameId($gameid, $filter, $ordering, true);
|
||||||
}
|
}
|
||||||
$result = $game_results;
|
$result = $game_results;
|
||||||
}
|
}
|
||||||
@ -538,7 +534,6 @@ function generate_report_by_groups(ReqHandler &$rh, array $params): string
|
|||||||
$gameid = trim($params["gameid"]);
|
$gameid = trim($params["gameid"]);
|
||||||
$filter = trim($params["filter"] ?? "");
|
$filter = trim($params["filter"] ?? "");
|
||||||
$groups = explode_list(trim($params["groups"]));
|
$groups = explode_list(trim($params["groups"]));
|
||||||
$best_only = trim($params["best_only"] ?? "false") === "true";
|
|
||||||
$outtype = trim($params["outtype"] ?? "pdf");
|
$outtype = trim($params["outtype"] ?? "pdf");
|
||||||
|
|
||||||
// only PDF and TEX are valid
|
// only PDF and TEX are valid
|
||||||
@ -570,20 +565,11 @@ function generate_report_by_groups(ReqHandler &$rh, array $params): string
|
|||||||
// assemble report
|
// assemble report
|
||||||
$report = new Report($game->getName());
|
$report = new Report($game->getName());
|
||||||
foreach ($groups as $groupname) {
|
foreach ($groups as $groupname) {
|
||||||
$stats = ReportBuilder::getStatsByFilters($gameid, $filter, $groupname, $best_only);
|
$stats = ReportBuilder::getStatsByFilters($gameid, $filter, $groupname, "");
|
||||||
$section = new ReportSection($groupname, $stats);
|
$section = new ReportSection($groupname, $stats);
|
||||||
$report->addSection($section);
|
$report->addSection($section);
|
||||||
}
|
}
|
||||||
|
|
||||||
// add comments
|
|
||||||
$report->addComment("gameid: ${gameid}");
|
|
||||||
$groupsJoined = join(", ", $groups);
|
|
||||||
$report->addComment("groups: ${groupsJoined}");
|
|
||||||
$report->addComment("filter: ${filter}");
|
|
||||||
$report->addComment("best_only: ${params["best_only"]}");
|
|
||||||
$requestURL = $_SERVER["SERVER_NAME"] . ":" . $_SERVER["SERVER_PORT"] . $_SERVER["REQUEST_URI"];
|
|
||||||
$report->addComment("\\scriptsize \\path{" . $requestURL . "}");
|
|
||||||
|
|
||||||
// generate latex
|
// generate latex
|
||||||
$report->saveTeX($buildDir);
|
$report->saveTeX($buildDir);
|
||||||
|
|
||||||
@ -608,8 +594,8 @@ function generate_report_by_groups(ReqHandler &$rh, array $params): string
|
|||||||
foreach ($files as $file) {
|
foreach ($files as $file) {
|
||||||
$zip->addFile($file, basename($file));
|
$zip->addFile($file, basename($file));
|
||||||
}
|
}
|
||||||
$zip->addFromString("request.txt", "gameid: ${gameid}\ngroups: " . $groupsJoined . "\nfilter: ${filter}\nouttype: ${outtype}\nbest_only: ${params["best_only"]}");
|
$zip->addFromString("request.txt", "gameid: ${gameid}\ngroups: " . join(", ", $groups) . "\nfilter: ${filter}\nouttype: ${outtype}\n");
|
||||||
$zip->addFromString("request.url", $requestURL);
|
$zip->addFromString("request.url", $_SERVER["SERVER_NAME"] . ":" . $_SERVER["SERVER_PORT"] . $_SERVER["REQUEST_URI"]);
|
||||||
$zip->close();
|
$zip->close();
|
||||||
$contentType = "application/zip";
|
$contentType = "application/zip";
|
||||||
}
|
}
|
||||||
@ -724,14 +710,10 @@ function delete_groups(ReqHandler &$rh, array $params): string
|
|||||||
function get_all_groups(ReqHandler &$rh, array $params): array
|
function get_all_groups(ReqHandler &$rh, array $params): array
|
||||||
{
|
{
|
||||||
global $groupMgr;
|
global $groupMgr;
|
||||||
global $gameMgr;
|
|
||||||
|
|
||||||
$groups = $groupMgr->getAllGroups();
|
$groups = $groupMgr->getAllGroups();
|
||||||
$a = [];
|
$a = [];
|
||||||
foreach ($groups as $g) {
|
foreach ($groups as $g) {
|
||||||
$r = $g->toArray();
|
$a[] = $g->toArray();
|
||||||
$gameMgr->resolveGames($r["games"]);
|
|
||||||
$a[] = $r;
|
|
||||||
}
|
}
|
||||||
return $a;
|
return $a;
|
||||||
}
|
}
|
||||||
@ -824,29 +806,20 @@ function get_game_groups(ReqHandler &$rh, array $params): array
|
|||||||
return $groups;
|
return $groups;
|
||||||
}
|
}
|
||||||
|
|
||||||
function change_group_members_or_games(ReqHandler &$rh, array $params): string
|
function change_group_members(ReqHandler &$rh, array $params): string
|
||||||
{
|
{
|
||||||
global $groupMgr;
|
global $groupMgr;
|
||||||
global $user;
|
global $user;
|
||||||
|
global $userMgr;
|
||||||
|
|
||||||
$group = $groupMgr->getGroup($params["groupid"]);
|
$group = $groupMgr->getGroup($params["groupid"]);
|
||||||
if ($group !== null) {
|
if ($group !== null) {
|
||||||
if ($group->isUserContributor($user->getNickname()) || $user->hasQuizmasterPrivilege()) {
|
if ($group->isUserContributor($user->getNickname())) {
|
||||||
$add = explode_list(trim($params["add"]));
|
$add = explode_list(trim($params["add"]));
|
||||||
$remove = explode_list(trim($params["remove"]));
|
|
||||||
|
|
||||||
$action = $params["action"];
|
|
||||||
if ($action === "change_group_members") {
|
|
||||||
global $userMgr;
|
|
||||||
$add = $userMgr->sanitizeNicknames($add);
|
$add = $userMgr->sanitizeNicknames($add);
|
||||||
|
$remove = explode_list(trim($params["remove"]));
|
||||||
$remove = $userMgr->sanitizeNicknames($remove);
|
$remove = $userMgr->sanitizeNicknames($remove);
|
||||||
$group->changeMembers($add, $remove);
|
$group->changeMembers($add, $remove);
|
||||||
} else if ($action === "change_group_games") {
|
|
||||||
global $gameMgr;
|
|
||||||
$add = $gameMgr->sanitizeGames($add);
|
|
||||||
$remove = $gameMgr->sanitizeGames($remove);
|
|
||||||
$group->changeGames($add, $remove);
|
|
||||||
}
|
|
||||||
return "OK";
|
return "OK";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -867,7 +840,7 @@ $rh->add("update_group", ["groupname", "description", "owner", "editors", "id"],
|
|||||||
$rh->add("delete_groups", ["ids"], PRIVILEGE_QUIZMASTER, "delete_groups", RESP_PLAIN, "Delete group.");
|
$rh->add("delete_groups", ["ids"], PRIVILEGE_QUIZMASTER, "delete_groups", RESP_PLAIN, "Delete group.");
|
||||||
$rh->add("get_all_groups", [], PRIVILEGE_QUIZMASTER, "get_all_groups", RESP_JSON, "Get all player groups.");
|
$rh->add("get_all_groups", [], PRIVILEGE_QUIZMASTER, "get_all_groups", RESP_JSON, "Get all player groups.");
|
||||||
$rh->add("search_groups", ["needle"], PRIVILEGE_QUIZMASTER, "search_groups", RESP_JSON, "Serach and fetch player groups.");
|
$rh->add("search_groups", ["needle"], PRIVILEGE_QUIZMASTER, "search_groups", RESP_JSON, "Serach and fetch player groups.");
|
||||||
$rh->add(["change_group_members", "change_group_games"], ["groupid", "add", "remove"], PRIVILEGE_QUIZMASTER, "change_group_members_or_games", RESP_PLAIN, "Change group members or games.");
|
$rh->add("change_group_members", ["groupid", "add", "remove"], PRIVILEGE_QUIZMASTER, "change_group_members", RESP_PLAIN, "Change group members.");
|
||||||
|
|
||||||
$rh->add(["create_user", "update_user"], ["nickname", "password", "realname", "privilege"], PRIVILEGE_QUIZMASTER, "create_update_user", RESP_PLAIN, "Create or update user.");
|
$rh->add(["create_user", "update_user"], ["nickname", "password", "realname", "privilege"], PRIVILEGE_QUIZMASTER, "create_update_user", RESP_PLAIN, "Create or update user.");
|
||||||
$rh->add("delete_users", ["users"], PRIVILEGE_QUIZMASTER, "delete_users", RESP_PLAIN, "Delete users.");
|
$rh->add("delete_users", ["users"], PRIVILEGE_QUIZMASTER, "delete_users", RESP_PLAIN, "Delete users.");
|
||||||
|
@ -26,7 +26,7 @@ function list_all_games() {
|
|||||||
let tdChkBox = document.createElement("td");
|
let tdChkBox = document.createElement("td");
|
||||||
tdChkBox.appendChild(chkbox);
|
tdChkBox.appendChild(chkbox);
|
||||||
tdChkBox.classList.add("checkbox");
|
tdChkBox.classList.add("checkbox");
|
||||||
let tdGameName = create_table_cell(g["name"] + "<span style='color:gray'>#" + g["_id"] + "</span>");
|
let tdGameName = create_table_cell(g["name"]);
|
||||||
let tdGameDescription = create_table_cell(g["description"]);
|
let tdGameDescription = create_table_cell(g["description"]);
|
||||||
let tdOwner = create_table_cell(g["owner"]);
|
let tdOwner = create_table_cell(g["owner"]);
|
||||||
row.append(tdChkBox, tdGameName, tdGameDescription, tdOwner);
|
row.append(tdChkBox, tdGameName, tdGameDescription, tdOwner);
|
||||||
@ -373,13 +373,12 @@ function list_results_by_game(game) {
|
|||||||
|
|
||||||
function generate_game_report_by_groups() {
|
function generate_game_report_by_groups() {
|
||||||
let gameid = EDITED_GAME["_id"];
|
let gameid = EDITED_GAME["_id"];
|
||||||
let filter = encodeURIComponent(document.getElementById("report_filter").value.trim());
|
let filter = document.getElementById("report_filter").value.trim()
|
||||||
let groups = encodeURIComponent(document.getElementById("report_groups").value.trim());
|
let groups = document.getElementById("report_groups").value.trim()
|
||||||
let best_only = document.getElementById("best_only").checked ? "true" : "false";
|
|
||||||
let outtype = document.getElementById("report_output_type").value;
|
let outtype = document.getElementById("report_output_type").value;
|
||||||
|
|
||||||
let report_url = `interface.php?action=generate_report_by_groups&gameid=${gameid}&groups=${groups}&filter=${filter}&outtype=${outtype}&best_only=${best_only}`;
|
let report_url = `interface.php?action=generate_report_by_groups&gameid=${gameid}&groups=${groups}&filter=${filter}&outtype=${outtype}`;
|
||||||
//report_url = report_url.replaceAll("#", "%23");
|
report_url = report_url.replace("#", "%23");
|
||||||
window.open(report_url, "_blank");
|
window.open(report_url, "_blank");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,7 +44,6 @@ function create_edit_group(group = null) {
|
|||||||
let group_ownerF = document.getElementById("group_owner");
|
let group_ownerF = document.getElementById("group_owner");
|
||||||
let group_editorsF = document.getElementById("group_editors");
|
let group_editorsF = document.getElementById("group_editors");
|
||||||
let group_membersF = document.getElementById("group_members");
|
let group_membersF = document.getElementById("group_members");
|
||||||
let group_gamesF = document.getElementById("group_games");
|
|
||||||
|
|
||||||
if (!update) { // create a new group
|
if (!update) { // create a new group
|
||||||
groupnameF.value = "";
|
groupnameF.value = "";
|
||||||
@ -54,7 +53,6 @@ function create_edit_group(group = null) {
|
|||||||
group_ownerF.readOnly = true;
|
group_ownerF.readOnly = true;
|
||||||
group_editorsF.value = "";
|
group_editorsF.value = "";
|
||||||
group_membersF.value = "";
|
group_membersF.value = "";
|
||||||
group_gamesF.value = "";
|
|
||||||
hide("group_editor_additional_fields");
|
hide("group_editor_additional_fields");
|
||||||
} else { // update and existing one
|
} else { // update and existing one
|
||||||
groupnameF.value = group["groupname"];
|
groupnameF.value = group["groupname"];
|
||||||
@ -64,7 +62,6 @@ function create_edit_group(group = null) {
|
|||||||
group_ownerF.readOnly = false;
|
group_ownerF.readOnly = false;
|
||||||
group_editorsF.value = group["editors"].join(", ");
|
group_editorsF.value = group["editors"].join(", ");
|
||||||
group_membersF.value = group["users"].join(", ");
|
group_membersF.value = group["users"].join(", ");
|
||||||
group_gamesF.value = group["games"].join(", ");
|
|
||||||
show("group_editor_additional_fields");
|
show("group_editor_additional_fields");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,48 +123,47 @@ function delete_groups() {
|
|||||||
|
|
||||||
function print_group_name(group_data) {
|
function print_group_name(group_data) {
|
||||||
let record = group_data["groupname"];
|
let record = group_data["groupname"];
|
||||||
let seqNumStyle = (group_data["unique"]) ? "style='color:lightgray'" : "";
|
if (!group_data["unique"]) {
|
||||||
record += `<span ${seqNumStyle}>#` + group_data["_id"] + `</span>`;
|
record += "#" + group_data["_id"];
|
||||||
|
}
|
||||||
return record;
|
return record;
|
||||||
}
|
}
|
||||||
|
|
||||||
let ACTION = "";
|
let MEMBER_ACTION = "";
|
||||||
let TYPE = ""
|
|
||||||
|
|
||||||
function open_element_change_window(action, type) {
|
function open_member_change_window(action) {
|
||||||
ACTION = action;
|
MEMBER_ACTION = action;
|
||||||
TYPE = type;
|
let winCap = document.getElementById("member_manager_window_title");
|
||||||
|
|
||||||
let winCap = document.getElementById("element_manager_window_title");
|
|
||||||
|
|
||||||
let typeStr = (type === "member") ? "Tagok" : "Játékok";
|
|
||||||
let opStr = (action === "add") ? "hozzáadása" : "eltávolítása";
|
|
||||||
|
|
||||||
// print window title
|
// print window title
|
||||||
winCap.innerText = typeStr + " " + opStr;
|
if (action === "add") {
|
||||||
|
winCap.innerText = "Tagok hozzáadása";
|
||||||
show("element_manager_window");
|
} else if (action === "remove") {
|
||||||
|
winCap.innerText = "Tagok eltávolítása";
|
||||||
}
|
}
|
||||||
|
|
||||||
function change_group_elements() {
|
show("member_manager_window");
|
||||||
let elementListTA = document.getElementById("add_remove_element_area");
|
}
|
||||||
|
|
||||||
|
function change_group_members() {
|
||||||
|
let userListTA = document.getElementById("add_remove_member_area");
|
||||||
|
|
||||||
let req = {
|
let req = {
|
||||||
action: `change_group_${TYPE}s`,
|
action: "change_group_members",
|
||||||
groupid: EDITED_GROUP["_id"],
|
groupid: EDITED_GROUP["_id"],
|
||||||
add: [],
|
add: [],
|
||||||
remove: []
|
remove: []
|
||||||
};
|
};
|
||||||
|
|
||||||
if (ACTION === "add") {
|
if (MEMBER_ACTION === "add") {
|
||||||
req["add"] = elementListTA.value;
|
req["add"] = userListTA.value;
|
||||||
} else if (ACTION === "remove") {
|
} else if (MEMBER_ACTION === "remove") {
|
||||||
req["remove"] = elementListTA.value;
|
req["remove"] = userListTA.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
request(req).then(resp => {
|
request(req).then(resp => {
|
||||||
elementListTA.value = "";
|
userListTA.value = "";
|
||||||
hide("element_manager_window");
|
hide("member_manager_window");
|
||||||
hide("group_editor_window");
|
hide("group_editor_window");
|
||||||
list_all_groups();
|
list_all_groups();
|
||||||
});
|
});
|
||||||
|
@ -31,24 +31,11 @@ function autoconvert_datetime(str) {
|
|||||||
return filter;
|
return filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
function count_selected() {
|
|
||||||
let n = 0;
|
|
||||||
document.getElementsByName("game_select").forEach((chk) => {
|
|
||||||
if (chk.checked) {
|
|
||||||
n++;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
document.getElementById("selected_n").innerText = n.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
function fetch_results() {
|
function fetch_results() {
|
||||||
|
|
||||||
let filterF = document.getElementById("filter");
|
let filterF = document.getElementById("filter");
|
||||||
let orderbyF = document.getElementById("orderby");
|
let orderbyF = document.getElementById("orderby");
|
||||||
let groupsF = document.getElementById("groups");
|
let groupsF = document.getElementById("groups");
|
||||||
let best_onlyChk = document.getElementById("best_only");
|
|
||||||
let records_nS = document.getElementById("records_n");
|
|
||||||
|
|
||||||
let filter = autoconvert_datetime(filterF.value.trim());
|
let filter = autoconvert_datetime(filterF.value.trim());
|
||||||
|
|
||||||
@ -59,8 +46,7 @@ function fetch_results() {
|
|||||||
gameid: GAMEID,
|
gameid: GAMEID,
|
||||||
filter: filter.trim(),
|
filter: filter.trim(),
|
||||||
orderby: orderbyF.value.trim(),
|
orderby: orderbyF.value.trim(),
|
||||||
groups: groupsF.value.trim(),
|
groups: groupsF.value.trim()
|
||||||
best_only: best_onlyChk.checked ? "true" : "false"
|
|
||||||
};
|
};
|
||||||
|
|
||||||
request(req).then(resp => {
|
request(req).then(resp => {
|
||||||
@ -73,7 +59,7 @@ function fetch_results() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
records_nS.innerText = results.length;
|
// let n = results.length;
|
||||||
|
|
||||||
results.forEach((record) => {
|
results.forEach((record) => {
|
||||||
let row = document.createElement("tr");
|
let row = document.createElement("tr");
|
||||||
@ -101,9 +87,6 @@ function fetch_results() {
|
|||||||
selectChk.type = "checkbox";
|
selectChk.type = "checkbox";
|
||||||
selectChk.name = "game_select";
|
selectChk.name = "game_select";
|
||||||
selectChk.record = record;
|
selectChk.record = record;
|
||||||
selectChk.addEventListener("input", () => {
|
|
||||||
count_selected();
|
|
||||||
});
|
|
||||||
|
|
||||||
let selection_cell = create_cell();
|
let selection_cell = create_cell();
|
||||||
selection_cell.append(selectChk);
|
selection_cell.append(selectChk);
|
||||||
@ -226,7 +209,6 @@ function toggle_test_selection() {
|
|||||||
game_selectChks.forEach((chk) => {
|
game_selectChks.forEach((chk) => {
|
||||||
chk.checked = !chk.checked;
|
chk.checked = !chk.checked;
|
||||||
});
|
});
|
||||||
count_selected();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function delete_tests() {
|
function delete_tests() {
|
||||||
|
@ -1,19 +1,12 @@
|
|||||||
% !TeX spellcheck = hu_HU
|
|
||||||
% !TeX encoding = UTF-8
|
|
||||||
% !TeX program = xelatex
|
|
||||||
|
|
||||||
\documentclass[10pt]{article}
|
\documentclass[10pt]{article}
|
||||||
|
|
||||||
|
|
||||||
%% Importing packages
|
%% Importing packages
|
||||||
% General things
|
% General things
|
||||||
\usepackage[magyar]{babel}
|
\usepackage[magyar]{babel}
|
||||||
\usepackage[a4paper,margin=10mm,footskip=5mm]{geometry}
|
\usepackage[a4paper,margin=1in]{geometry}
|
||||||
\usepackage{fontspec}
|
\usepackage{fontspec}
|
||||||
\usepackage[fontsize=7pt]{fontsize}
|
\usepackage[fontsize=7pt]{fontsize}
|
||||||
\usepackage{titlesec}
|
|
||||||
\usepackage{url}
|
|
||||||
\usepackage{datetime2}
|
|
||||||
|
|
||||||
% For frame layout and content
|
% For frame layout and content
|
||||||
\usepackage{xcolor}
|
\usepackage{xcolor}
|
||||||
@ -35,10 +28,6 @@
|
|||||||
\definecolor{colpbb}{HTML}{A0A0A0} % Progressbar background
|
\definecolor{colpbb}{HTML}{A0A0A0} % Progressbar background
|
||||||
\definecolor{colanc}{HTML}{176767} % Correct answer background
|
\definecolor{colanc}{HTML}{176767} % Correct answer background
|
||||||
\definecolor{colani}{HTML}{D3E5E5} % Incorrect answer background
|
\definecolor{colani}{HTML}{D3E5E5} % Incorrect answer background
|
||||||
\definecolor{colsbg}{HTML}{AA8A7D} % Group title background
|
|
||||||
\definecolor{colsfg}{HTML}{EFEFEF} % Group title text color
|
|
||||||
\definecolor{colqsb}{HTML}{176767} % Quiz sequence number background
|
|
||||||
\definecolor{colqsf}{HTML}{EFEFEF} % Quiz sequence number text color
|
|
||||||
|
|
||||||
% Setting up outer frames
|
% Setting up outer frames
|
||||||
\mdfsetup{
|
\mdfsetup{
|
||||||
@ -64,7 +53,7 @@
|
|||||||
% Replacing ToC text
|
% Replacing ToC text
|
||||||
\addto\captionsmagyar{%
|
\addto\captionsmagyar{%
|
||||||
\renewcommand{\contentsname}%
|
\renewcommand{\contentsname}%
|
||||||
{\huge Csoportok}%
|
{\huge Kurzusok}%
|
||||||
}
|
}
|
||||||
|
|
||||||
% Add dotfill to ToC
|
% Add dotfill to ToC
|
||||||
@ -94,66 +83,32 @@
|
|||||||
\newcommand{\unnumsec}[1]{\section*{#1}%
|
\newcommand{\unnumsec}[1]{\section*{#1}%
|
||||||
\addcontentsline{toc}{section}{#1}}
|
\addcontentsline{toc}{section}{#1}}
|
||||||
|
|
||||||
% Set section title style
|
|
||||||
\titleformat{\unnumsec}{\Large\bfseries}{\thesection}{1em}{}
|
|
||||||
|
|
||||||
% Macros for answers
|
% Macros for answers
|
||||||
\newcommand{\answerCorrect}[2]{\progressbar{#1} & \begin{minipage}{0.8\columnwidth}\begin{mdframed}[backgroundcolor=colanc]\color{coltxl}{#2}\end{mdframed}\end{minipage}\\}
|
\newcommand{\answerCorrect}[2]{\progressbar{#1} & \begin{minipage}{0.8\columnwidth}\begin{mdframed}[backgroundcolor=colanc]\color{coltxl}{#2}\end{mdframed}\end{minipage}\\}
|
||||||
\newcommand{\answerIncorrect}[2]{\progressbar[filledcolor=colpbs]{#1} & \begin{minipage}{0.8\columnwidth}\begin{mdframed}[backgroundcolor=colani]\color{coltxd}{#2}\end{mdframed}\end{minipage}\\}
|
\newcommand{\answerIncorrect}[2]{\progressbar[filledcolor=colpbs]{#1} & \begin{minipage}{0.8\columnwidth}\begin{mdframed}[backgroundcolor=colani]\color{coltxd}{#2}\end{mdframed}\end{minipage}\\}
|
||||||
|
|
||||||
% Macros for questions.
|
|
||||||
\newmdenv[backgroundcolor=colqsb,align=left,innerleftmargin=0.2em,innerrightmargin=0.2em]{qsn} % Question sequence number
|
|
||||||
|
|
||||||
% Environment for questions. The parameter is the question itself, the contents of the environment should consist of \answer*{}{} macros and nothing else
|
% Environment for questions. The parameter is the question itself, the contents of the environment should consist of \answer*{}{} macros and nothing else
|
||||||
\newenvironment{question}[2]{
|
\newenvironment{question}[1]{
|
||||||
\begin{center}
|
\begin{center}
|
||||||
\begin{mdframed}
|
\begin{mdframed}
|
||||||
\raisebox{0.05em} {
|
|
||||||
\begin{minipage}{0.6cm}
|
|
||||||
\begin{qsn}[userdefinedwidth=0.5cm]
|
|
||||||
\begin{flushright}
|
|
||||||
\color{colqsf}\arabic{qc}.
|
|
||||||
\end{flushright}
|
|
||||||
\end{qsn}
|
|
||||||
\end{minipage}
|
|
||||||
}
|
|
||||||
%
|
|
||||||
{\color{coltit}\large #1\par}\medskip
|
{\color{coltit}\large #1\par}\medskip
|
||||||
%
|
|
||||||
{\hspace{1em}\small #2~kitöltő}\vspace{0.6em}\par
|
|
||||||
|
|
||||||
\stepcounter{qc}
|
|
||||||
|
|
||||||
\begin{tabular}{c c}
|
\begin{tabular}{c c}
|
||||||
}{
|
}{
|
||||||
\end{tabular}
|
\end{tabular}
|
||||||
|
|
||||||
\end{mdframed}
|
\end{mdframed}
|
||||||
\end{center}
|
\end{center}
|
||||||
}
|
}
|
||||||
|
|
||||||
% An environment to create a quiz containing questions. The parameter is either the title of the quiz, or the name of the course
|
% An environment to create a quiz containing questions. The parameter is either the title of the quiz, or the name of the course
|
||||||
\newenvironment{quiz}[2]{
|
\newenvironment{quiz}[1]{
|
||||||
% Create highlighted group title
|
|
||||||
\begin{mdframed}[backgroundcolor=colsbg]
|
|
||||||
{
|
|
||||||
\color{colsfg}
|
|
||||||
\unnumsec{#1}
|
\unnumsec{#1}
|
||||||
{\small #2~kitöltő}
|
|
||||||
\vspace{0.4em}
|
|
||||||
}
|
|
||||||
\end{mdframed}
|
|
||||||
|
|
||||||
% Reset question counter
|
|
||||||
\setcounter{qc}{1}
|
|
||||||
}{
|
}{
|
||||||
\clearpage
|
\clearpage
|
||||||
}
|
}
|
||||||
|
|
||||||
\begin{document}
|
\begin{document}
|
||||||
\begin{center}
|
\begin{center}
|
||||||
\Huge \IfFileExists{title.tex}{\input{title.tex}}{Kvíz eredmények}\\
|
\Huge \IfFileExists{stats/title.tex}{\input{title.tex}}{Kvíz eredmények}
|
||||||
\normal \DTMnow
|
|
||||||
\end{center}
|
\end{center}
|
||||||
|
|
||||||
\Large
|
\Large
|
||||||
@ -161,9 +116,6 @@
|
|||||||
\normalsize
|
\normalsize
|
||||||
\clearpage
|
\clearpage
|
||||||
|
|
||||||
% Create question counter
|
|
||||||
\newcounter{qc}
|
|
||||||
|
|
||||||
\inputIfFileExists{content.tex}
|
\inputIfFileExists{content.tex}
|
||||||
|
|
||||||
\end{document}
|
\end{document}
|
||||||
|
@ -52,9 +52,9 @@ if (!$gameMgr->getGame($game_id)->isUserContributorOrOwner($user_data["nickname"
|
|||||||
<input type="text" placeholder="Rendezés" id="orderby" style="font-family: 'Monaco', monospace; width: 30em;">
|
<input type="text" placeholder="Rendezés" id="orderby" style="font-family: 'Monaco', monospace; width: 30em;">
|
||||||
<input type="button" value="Szűrés" onclick="fetch_results()">
|
<input type="button" value="Szűrés" onclick="fetch_results()">
|
||||||
<input type="button" value="Jelentés előállítása" onclick="generate_report()">
|
<input type="button" value="Jelentés előállítása" onclick="generate_report()">
|
||||||
<input type="button" value="Kijelöltek törlése" onclick="delete_tests()"><br>
|
<input type="button" value="Kijelöltek törlése" onclick="delete_tests()">
|
||||||
<input type="checkbox" id="best_only"><label for="best_only" style="font-size: 12px">Csak legjobb eredmények felhasználónként</label>
|
|
||||||
</section>
|
</section>
|
||||||
|
<section>
|
||||||
<section id="table_section">
|
<section id="table_section">
|
||||||
<table class="management">
|
<table class="management">
|
||||||
<thead>
|
<thead>
|
||||||
@ -96,8 +96,6 @@ if (!$gameMgr->getGame($game_id)->isUserContributorOrOwner($user_data["nickname"
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</section>
|
</section>
|
||||||
<section id="summary_section">
|
|
||||||
<span id="records_n">0</span> találat, <span id="selected_n">0</span> kijelölve
|
|
||||||
</section>
|
</section>
|
||||||
<script>
|
<script>
|
||||||
let GAMEID = <?="$game_id"?>;
|
let GAMEID = <?="$game_id"?>;
|
||||||
|
@ -1,13 +1,9 @@
|
|||||||
section#table_section {
|
section#table_section {
|
||||||
position: sticky;
|
position: sticky;
|
||||||
height: calc(100vh - 6em);
|
height: calc(100vh - 4em);
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
section#summary_section {
|
|
||||||
margin-top: 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
table.management {
|
table.management {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user