- challenge sequence numbers added
- package uploading added - image support added - answer correctness indication added
This commit is contained in:
parent
c3d008d4f5
commit
4ace35b770
31
gamemgr.php
31
gamemgr.php
@ -27,7 +27,7 @@ function create_game(string $name, string $owner, string $description = "", arra
|
|||||||
|
|
||||||
// prepare game context
|
// prepare game context
|
||||||
$id = $game_data["_id"];
|
$id = $game_data["_id"];
|
||||||
$current_game_media_dir = GAMEMEDIA_DIR . DIRECTORY_SEPARATOR . $id;
|
$current_game_media_dir = get_game_dir_by_gameid($id);
|
||||||
mkdir($current_game_media_dir);
|
mkdir($current_game_media_dir);
|
||||||
save_challenges($id, []);
|
save_challenges($id, []);
|
||||||
return true;
|
return true;
|
||||||
@ -92,6 +92,7 @@ const CSV_ENCODINGS = ["Windows-1252", "UTF-8"];
|
|||||||
function import_challenges_from_csv(string $csv_path, string $gameid): array
|
function import_challenges_from_csv(string $csv_path, string $gameid): array
|
||||||
{
|
{
|
||||||
$game_data = get_game($gameid);
|
$game_data = get_game($gameid);
|
||||||
|
$game_dir = get_game_dir_by_gameid($gameid);
|
||||||
if (count($game_data) === []) {
|
if (count($game_data) === []) {
|
||||||
return ["n" => 0, "encoding" => ""];
|
return ["n" => 0, "encoding" => ""];
|
||||||
}
|
}
|
||||||
@ -125,14 +126,31 @@ function import_challenges_from_csv(string $csv_path, string $gameid): array
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (count($csvline) >= 3) {
|
if (count($csvline) >= 3) {
|
||||||
|
// construct challenge record
|
||||||
$ch = [
|
$ch = [
|
||||||
"question" => $csvline[0],
|
"question" => trim($csvline[0]),
|
||||||
"image_url" => $csvline[1],
|
"image_url" => trim($csvline[1]),
|
||||||
"correct_answer" => $csvline[2],
|
"correct_answer" => trim($csvline[2]),
|
||||||
"answers" => array_filter(array_slice($csvline, 2), function ($v) {
|
"answers" => array_filter(array_slice($csvline, 2), function ($v) {
|
||||||
return trim($v) !== "";
|
return trim($v) !== "";
|
||||||
})
|
})
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// if image is attached to the challenge, then give a random name to the image
|
||||||
|
if ($ch["image_url"] !== "") {
|
||||||
|
$old_img_name = $ch["image_url"];
|
||||||
|
$ext = pathinfo($old_img_name, PATHINFO_EXTENSION);
|
||||||
|
$ext = ($ext !== "") ? ("." . $ext) : $ext;
|
||||||
|
$new_img_name = uniqid("img_", true) . $ext;
|
||||||
|
$ch["image_url"] = $new_img_name;
|
||||||
|
|
||||||
|
// rename the actual file
|
||||||
|
$old_img_path = $game_dir . DIRECTORY_SEPARATOR . $old_img_name;
|
||||||
|
$new_img_path = $game_dir . DIRECTORY_SEPARATOR . $new_img_name;
|
||||||
|
rename($old_img_path, $new_img_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
// store the challenge
|
||||||
$challenges[] = $ch;
|
$challenges[] = $ch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -208,3 +226,8 @@ function get_game_file_by_gameid(string $gameid)
|
|||||||
{
|
{
|
||||||
return GAMEMEDIA_DIR . DIRECTORY_SEPARATOR . $gameid . DIRECTORY_SEPARATOR . GAME_FILE;
|
return GAMEMEDIA_DIR . DIRECTORY_SEPARATOR . $gameid . DIRECTORY_SEPARATOR . GAME_FILE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function get_game_dir_by_gameid(string $gameid)
|
||||||
|
{
|
||||||
|
return GAMEMEDIA_DIR . DIRECTORY_SEPARATOR . $gameid;
|
||||||
|
}
|
@ -126,6 +126,20 @@ if ((($testid = trim($_REQUEST["testid"] ?: "")) !== "") &&
|
|||||||
$result = json_encode($test_data_with_current_time);
|
$result = json_encode($test_data_with_current_time);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case "get_image":
|
||||||
|
{
|
||||||
|
$img_url = trim($_REQUEST["image_url"] ?: "");
|
||||||
|
if ($img_url !== "") {
|
||||||
|
$gameid = $test_data["gameid"];
|
||||||
|
$game_dir = get_game_dir_by_gameid($gameid);
|
||||||
|
$image_fetch_url = $game_dir . DIRECTORY_SEPARATOR . $img_url;
|
||||||
|
|
||||||
|
$img_fp = fopen($image_fetch_url, "r");
|
||||||
|
fpassthru($img_fp);
|
||||||
|
fclose($img_fp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case "save_answer":
|
case "save_answer":
|
||||||
{
|
{
|
||||||
$chidx = $_REQUEST["challenge_index"];
|
$chidx = $_REQUEST["challenge_index"];
|
||||||
@ -174,8 +188,8 @@ switch ($action) {
|
|||||||
$groupids_with_editor_access[] = $groupid;
|
$groupids_with_editor_access[] = $groupid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$groupids_with_editor_access = $groupid;
|
|
||||||
|
|
||||||
|
// create or update
|
||||||
if (!$update) {
|
if (!$update) {
|
||||||
create_game($name, $owner, $description);
|
create_game($name, $owner, $description);
|
||||||
} else if (is_user_contributor_to_game($gameid, $nickname)) {
|
} else if (is_user_contributor_to_game($gameid, $nickname)) {
|
||||||
@ -209,7 +223,35 @@ switch ($action) {
|
|||||||
|
|
||||||
// update game file if supplied
|
// update game file if supplied
|
||||||
if (isset($_FILES["game_file"])) {
|
if (isset($_FILES["game_file"])) {
|
||||||
$challenge_import_status = import_challenges_from_csv($_FILES["game_file"]["tmp_name"], $data["_id"]);
|
// decide weather it's a package or a plain table
|
||||||
|
$file = $_FILES["game_file"];
|
||||||
|
$file_type = $file["type"];
|
||||||
|
$challenge_import_status = [];
|
||||||
|
if ($file_type === "application/zip") { // a package was uploaded
|
||||||
|
$zip = new ZipArchive;
|
||||||
|
if ($zip->open($file["tmp_name"])) {
|
||||||
|
|
||||||
|
$game_dir = get_game_dir_by_gameid($gameid); // get game directory
|
||||||
|
$game_files = glob($game_dir); // get list of existing game files
|
||||||
|
// remove former files recursively
|
||||||
|
$dir_iter = new RecursiveDirectoryIterator($game_dir, FilesystemIterator::SKIP_DOTS);
|
||||||
|
foreach ($dir_iter as $dir_item) {
|
||||||
|
$item_path = $dir_item->getPathname();
|
||||||
|
$dir_item->isDir() ? rmdir($item_path) : unlink($item_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
// extract package contents to the game directory
|
||||||
|
$zip->extractTo($game_dir . DIRECTORY_SEPARATOR);
|
||||||
|
|
||||||
|
// search for the CSV table file
|
||||||
|
$csv_files = glob($game_dir . DIRECTORY_SEPARATOR . "*.csv") ?: [];
|
||||||
|
if (count($csv_files)) {
|
||||||
|
$challenge_import_status = import_challenges_from_csv($csv_files[0], $gameid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if ($file_type === "text/csv") { // a plain table was uploaded
|
||||||
|
$challenge_import_status = import_challenges_from_csv($file["tmp_name"], $gameid);
|
||||||
|
}
|
||||||
$result = json_encode($challenge_import_status);
|
$result = json_encode($challenge_import_status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,8 +41,19 @@ function populate_infobox(test_data) {
|
|||||||
INTERVAL_HANDLE = null;
|
INTERVAL_HANDLE = null;
|
||||||
}
|
}
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
show("time-info");
|
||||||
|
} else {
|
||||||
|
hide("time-info");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fill further info
|
||||||
|
let further_info_box = document.getElementById("further-info");
|
||||||
|
let further_info = "";
|
||||||
|
if (!test_data["repeatable"]) {
|
||||||
|
further_info += "A teszt <i>nem</i> megismételhető!<br>";
|
||||||
|
}
|
||||||
|
further_info_box.innerHTML = further_info;
|
||||||
|
|
||||||
show("ongoing-info");
|
show("ongoing-info");
|
||||||
hide("concluded-info");
|
hide("concluded-info");
|
||||||
}
|
}
|
||||||
@ -66,6 +77,18 @@ function populate_challenges(test_data) {
|
|||||||
answer_container.classList.add("answer-container");
|
answer_container.classList.add("answer-container");
|
||||||
challenge_box.append(question, answer_container);
|
challenge_box.append(question, answer_container);
|
||||||
|
|
||||||
|
if (challenge["image_url"] !== "") {
|
||||||
|
let qimg = document.createElement("img");
|
||||||
|
qimg.src = `interface.php?action=get_image&testid=${test_data["_id"]}&image_url=${challenge["image_url"]}`;
|
||||||
|
qimg.classList.add("question-image")
|
||||||
|
challenge_box.insertBefore(qimg, answer_container);
|
||||||
|
}
|
||||||
|
|
||||||
|
let seq_num_section = document.createElement("section");
|
||||||
|
seq_num_section.innerText = String(challenge_N + 1) + "."
|
||||||
|
seq_num_section.classList.add("seq-num");
|
||||||
|
challenge_box.append(seq_num_section);
|
||||||
|
|
||||||
let answer_N = 0;
|
let answer_N = 0;
|
||||||
let player_answer = challenge["player_answer"];
|
let player_answer = challenge["player_answer"];
|
||||||
player_answer = (player_answer !== "") ? Number(player_answer) : -1;
|
player_answer = (player_answer !== "") ? Number(player_answer) : -1;
|
||||||
@ -90,6 +113,10 @@ function populate_challenges(test_data) {
|
|||||||
answer_text.setAttribute("for", answer_radio.id);
|
answer_text.setAttribute("for", answer_radio.id);
|
||||||
if (test_concluded && (challenge["correct_answer"] === answer_N)) {
|
if (test_concluded && (challenge["correct_answer"] === answer_N)) {
|
||||||
answer_text.classList.add("correct-answer")
|
answer_text.classList.add("correct-answer")
|
||||||
|
|
||||||
|
if (player_answer !== challenge["correct_answer"]) {
|
||||||
|
challenge_box.classList.add("bad-answer");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
answer_section.append(answer_radio, answer_text);
|
answer_section.append(answer_radio, answer_text);
|
||||||
|
@ -229,6 +229,7 @@ section#test_area {
|
|||||||
|
|
||||||
section.challenge {
|
section.challenge {
|
||||||
display: block;
|
display: block;
|
||||||
|
position: relative;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
width: 40em;
|
width: 40em;
|
||||||
/*border: 1px solid black;*/
|
/*border: 1px solid black;*/
|
||||||
@ -362,3 +363,33 @@ section.test-summary-record {
|
|||||||
code {
|
code {
|
||||||
font-family: 'Monaco', monospace;
|
font-family: 'Monaco', monospace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
img.question-image {
|
||||||
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
margin: 1em auto;
|
||||||
|
border-radius: 0.3em;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
section.seq-num {
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
padding: 0.5em;
|
||||||
|
bottom: 0;
|
||||||
|
background-color: #176767;
|
||||||
|
color: whitesmoke;
|
||||||
|
border-bottom-right-radius: 0.3em;
|
||||||
|
border-top-left-radius: 0.3em;
|
||||||
|
width: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
section.bad-answer {
|
||||||
|
background-color: #e5d8d3;
|
||||||
|
}
|
||||||
|
|
||||||
|
section#further-info {
|
||||||
|
font-size: 0.8em;
|
||||||
|
padding: 0.4em 0;
|
||||||
|
}
|
@ -36,8 +36,13 @@ if ($testid === "") {
|
|||||||
<span id="game_name"></span>
|
<span id="game_name"></span>
|
||||||
<section>
|
<section>
|
||||||
<section id="ongoing-info">
|
<section id="ongoing-info">
|
||||||
<span class="infobox-description">Hátralevő idő:</span>
|
<section id="time-info" shown="false">
|
||||||
<section id="timer">10:00:00</section>
|
<span class="infobox-description">Hátralevő idő:</span>
|
||||||
|
<section id="timer">10:00:00</section>
|
||||||
|
</section>
|
||||||
|
<section id="further-info">
|
||||||
|
|
||||||
|
</section>
|
||||||
<input type="button" value="Beküld" onclick="submit_test()">
|
<input type="button" value="Beküld" onclick="submit_test()">
|
||||||
</section>
|
</section>
|
||||||
<section id="concluded-info">
|
<section id="concluded-info">
|
||||||
|
Loading…
x
Reference in New Issue
Block a user