-
This commit is contained in:
		
							parent
							
								
									2c9a744667
								
							
						
					
					
						commit
						319b3410ba
					
				@ -15,15 +15,24 @@ if (!get_autologin_state()) {
 | 
				
			|||||||
<head>
 | 
					<head>
 | 
				
			||||||
    <meta charset="UTF-8">
 | 
					    <meta charset="UTF-8">
 | 
				
			||||||
    <title>SpreadQuiz</title>
 | 
					    <title>SpreadQuiz</title>
 | 
				
			||||||
    <script src="js/spreadquiz.js"></script>
 | 
					 | 
				
			||||||
    <script src="js/req.js"></script>
 | 
					    <script src="js/req.js"></script>
 | 
				
			||||||
    <script src="js/o.js"></script>
 | 
					    <script src="js/o.js"></script>
 | 
				
			||||||
 | 
					    <script src="js/common.js"></script>
 | 
				
			||||||
 | 
					    <script src="js/spreadquiz.js"></script>
 | 
				
			||||||
    <script src="js/default_frame.js"></script>
 | 
					    <script src="js/default_frame.js"></script>
 | 
				
			||||||
    <link rel="stylesheet" href="style/spreadquiz.css">
 | 
					    <link rel="stylesheet" href="style/spreadquiz.css">
 | 
				
			||||||
</head>
 | 
					</head>
 | 
				
			||||||
<body>
 | 
					<body>
 | 
				
			||||||
<section id="game_list_panel">
 | 
					<section id="game_list_panel">
 | 
				
			||||||
 | 
					</section>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<section class="window" shown="false" id="results_window">
 | 
				
			||||||
 | 
					    <section class="window-inner">
 | 
				
			||||||
 | 
					        <section id="results_overview_display">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        </section>
 | 
				
			||||||
 | 
					        <input type="button" value="Bezárás" onclick="hide('results_window')">
 | 
				
			||||||
 | 
					    </section>
 | 
				
			||||||
</section>
 | 
					</section>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script>
 | 
					<script>
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										26
									
								
								gamemgr.php
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								gamemgr.php
									
									
									
									
									
								
							@ -13,7 +13,7 @@ const DEFAULT_GAME_PROPERTIES = [
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
function create_game(string $name, string $owner, string $description = "", array $properties = DEFAULT_GAME_PROPERTIES, array $contributors = [], array $challenges = []): bool
 | 
					function create_game(string $name, string $owner, string $description = "", array $properties = DEFAULT_GAME_PROPERTIES, array $contributors = [], array $challenges = []): bool
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    global $testdb;
 | 
					    global $gamedb;
 | 
				
			||||||
    $game_data = [
 | 
					    $game_data = [
 | 
				
			||||||
        "name" => $name,
 | 
					        "name" => $name,
 | 
				
			||||||
        "owner" => $owner,
 | 
					        "owner" => $owner,
 | 
				
			||||||
@ -23,7 +23,7 @@ function create_game(string $name, string $owner, string $description = "", arra
 | 
				
			|||||||
        "properties" => $properties,
 | 
					        "properties" => $properties,
 | 
				
			||||||
        "groups" => [],
 | 
					        "groups" => [],
 | 
				
			||||||
    ];
 | 
					    ];
 | 
				
			||||||
    $game_data = $testdb->insert($game_data);
 | 
					    $game_data = $gamedb->insert($game_data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // prepare game context
 | 
					    // prepare game context
 | 
				
			||||||
    $id = $game_data["_id"];
 | 
					    $id = $game_data["_id"];
 | 
				
			||||||
@ -35,25 +35,25 @@ function create_game(string $name, string $owner, string $description = "", arra
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
function get_game(string $gameid): array
 | 
					function get_game(string $gameid): array
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    global $testdb;
 | 
					    global $gamedb;
 | 
				
			||||||
    return $testdb->findById($gameid);
 | 
					    return $gamedb->findById($gameid);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function update_game(array $game_data)
 | 
					function update_game(array $game_data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    global $testdb;
 | 
					    global $gamedb;
 | 
				
			||||||
    $testdb->update($game_data);
 | 
					    $gamedb->update($game_data);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function delete_game(string $gameid)
 | 
					function delete_game(string $gameid)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    global $testdb;
 | 
					    global $gamedb;
 | 
				
			||||||
    $game_data = get_game($gameid);
 | 
					    $game_data = get_game($gameid);
 | 
				
			||||||
    if (count($game_data) != 0) {
 | 
					    if (count($game_data) != 0) {
 | 
				
			||||||
        foreach ($game_data["groups"] as $groupid) {
 | 
					        foreach ($game_data["groups"] as $groupid) {
 | 
				
			||||||
            change_group_game_assignments($groupid, null, $gameid);
 | 
					            change_group_game_assignments($groupid, null, $gameid);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        $testdb->deleteById($gameid);
 | 
					        $gamedb->deleteById($gameid);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -68,18 +68,18 @@ function change_game_group_assignments(string $gid, $groupname_add, $groupname_r
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
function get_all_games()
 | 
					function get_all_games()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    global $testdb;
 | 
					    global $gamedb;
 | 
				
			||||||
    return $testdb->findAll();
 | 
					    return $gamedb->findAll();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function get_all_game_data_by_contributor_nickname(string $nickname): array
 | 
					function get_all_game_data_by_contributor_nickname(string $nickname): array
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    global $testdb;
 | 
					    global $gamedb;
 | 
				
			||||||
    $game_headers = [];
 | 
					    $game_headers = [];
 | 
				
			||||||
    if ($nickname !== "*") {
 | 
					    if ($nickname !== "*") {
 | 
				
			||||||
        $game_data_array = $testdb->findBy([["owner", "=", $nickname], "OR", ["contributors", "CONTAINS", $nickname]]);
 | 
					        $game_data_array = $gamedb->findBy([["owner", "=", $nickname], "OR", ["contributors", "CONTAINS", $nickname]]);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        $game_data_array = $testdb->findAll();
 | 
					        $game_data_array = $gamedb->findAll();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    foreach ($game_data_array as $game_data) {
 | 
					    foreach ($game_data_array as $game_data) {
 | 
				
			||||||
        $game_headers[] = $game_data;
 | 
					        $game_headers[] = $game_data;
 | 
				
			||||||
 | 
				
			|||||||
@ -16,6 +16,7 @@ require_once "common_func.php";
 | 
				
			|||||||
require_once "usermgr.php";
 | 
					require_once "usermgr.php";
 | 
				
			||||||
require_once "groupmgr.php";
 | 
					require_once "groupmgr.php";
 | 
				
			||||||
require_once "gamemgr.php";
 | 
					require_once "gamemgr.php";
 | 
				
			||||||
 | 
					require_once "testmgr.php";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
$action = $_REQUEST["action"];
 | 
					$action = $_REQUEST["action"];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -83,6 +84,61 @@ switch ($action) {
 | 
				
			|||||||
            $result = json_encode($games_by_groups);
 | 
					            $result = json_encode($games_by_groups);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
 | 
					    case "start_or_continue_test":
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            $gameid = trim($_REQUEST["gameid"] ?: "");
 | 
				
			||||||
 | 
					            $testid = create_or_continue_test($gameid, $nickname);
 | 
				
			||||||
 | 
					            $result = $testid;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case "get_results_overview":
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            $gameid = trim($_REQUEST["gameid"] ?: "");
 | 
				
			||||||
 | 
					            $concluded_tests = get_concluded_tests($gameid, $nickname);
 | 
				
			||||||
 | 
					            $overviews = [];
 | 
				
			||||||
 | 
					            foreach ($concluded_tests as $ct) {
 | 
				
			||||||
 | 
					                $overview = [
 | 
				
			||||||
 | 
					                    "testid" => $ct["_id"],
 | 
				
			||||||
 | 
					                    "start_time" => $ct["start_time"],
 | 
				
			||||||
 | 
					                    "end_time" => $ct["end_time"],
 | 
				
			||||||
 | 
					                    ...$ct["summary"]
 | 
				
			||||||
 | 
					                ];
 | 
				
			||||||
 | 
					                $overviews[] = $overview;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            $result = json_encode($overviews);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// test-related queries
 | 
				
			||||||
 | 
					if ((($testid = trim($_REQUEST["testid"] ?: "")) !== "") &&
 | 
				
			||||||
 | 
					    ((count($test_data = get_test($testid))) > 0) &&
 | 
				
			||||||
 | 
					    ($test_data["nickname"] === $nickname)) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // update the test if timed
 | 
				
			||||||
 | 
					    update_timed_tests([ $test_data ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    switch ($action) {
 | 
				
			||||||
 | 
					        case "get_test":
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                $test_data_with_current_time = $test_data;
 | 
				
			||||||
 | 
					                $test_data_with_current_time["current_time"] = time();
 | 
				
			||||||
 | 
					                $result = json_encode($test_data_with_current_time);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case "save_answer":
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                $chidx = $_REQUEST["challenge_index"];
 | 
				
			||||||
 | 
					                $answeridx = $_REQUEST["answer_index"];
 | 
				
			||||||
 | 
					                save_answer($testid, $chidx, $answeridx);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case "submit_test":
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                conclude_test($testid);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// creator or quizmaster actions
 | 
					// creator or quizmaster actions
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										5
									
								
								js/common.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								js/common.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,5 @@
 | 
				
			|||||||
 | 
					function unix_time_to_human_readable(tunix) {
 | 
				
			||||||
 | 
					    const date = new Date(Number(tunix) * 1000);
 | 
				
			||||||
 | 
					    return date.getFullYear() + ". " + String(date.getMonth() + 1).padStart(2, "0") + ". " + String(date.getDate()).padStart(2, "0") + ". "
 | 
				
			||||||
 | 
					        + String(date.getHours()).padStart(2, "0") + ":" + String(date.getMinutes()).padStart(2, "0") + ":" + String(date.getSeconds()).padStart(2, "0");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -9,21 +9,103 @@ function list_available_games() {
 | 
				
			|||||||
        games_by_groups.forEach((game_collection) => {
 | 
					        games_by_groups.forEach((game_collection) => {
 | 
				
			||||||
            let group_box = document.createElement("section");
 | 
					            let group_box = document.createElement("section");
 | 
				
			||||||
            group_box.classList.add("group-box");
 | 
					            group_box.classList.add("group-box");
 | 
				
			||||||
 | 
					            let group_box_caption_container = document.createElement("span");
 | 
				
			||||||
 | 
					            group_box_caption_container.classList.add("group-box-caption-container");
 | 
				
			||||||
            let group_box_caption = document.createElement("span");
 | 
					            let group_box_caption = document.createElement("span");
 | 
				
			||||||
            group_box_caption.classList.add("group-box-caption");
 | 
					            group_box_caption.classList.add("group-box-caption");
 | 
				
			||||||
            group_box_caption.innerHTML = game_collection["groupname"];
 | 
					            group_box_caption.innerHTML = game_collection["groupname"];
 | 
				
			||||||
 | 
					            group_box_caption_container.append(group_box_caption);
 | 
				
			||||||
            let group_box_inner = document.createElement("section");
 | 
					            let group_box_inner = document.createElement("section");
 | 
				
			||||||
            group_box_inner.classList.add("group-box-inner");
 | 
					            group_box_inner.classList.add("group-box-inner");
 | 
				
			||||||
            group_box.append(group_box_caption, group_box_inner);
 | 
					            group_box.append(group_box_caption_container, group_box_inner);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            game_collection["games"].forEach((game) => {
 | 
					            game_collection["games"].forEach((game) => {
 | 
				
			||||||
                let game_box = document.createElement("section");
 | 
					                let game_box = document.createElement("section");
 | 
				
			||||||
                game_box.classList.add("game-box");
 | 
					                game_box.classList.add("game-box");
 | 
				
			||||||
               game_box.innerHTML = game["name"];
 | 
					                game_box.addEventListener("click", () => {
 | 
				
			||||||
               group_box_inner.appendChild(game_box);
 | 
					                    start_or_continue_test(game["_id"]);
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                let game_box_caption = document.createElement("section");
 | 
				
			||||||
 | 
					                game_box_caption.classList.add("game-box-caption");
 | 
				
			||||||
 | 
					                game_box_caption.innerHTML = game["name"];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                let list_results_btn = document.createElement("section");
 | 
				
			||||||
 | 
					                list_results_btn.classList.add("list-results-btn", "material", "btn");
 | 
				
			||||||
 | 
					                list_results_btn.addEventListener("click", (event) => {
 | 
				
			||||||
 | 
					                    event.stopPropagation();
 | 
				
			||||||
 | 
					                    list_corresponding_results(game["_id"]);
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					                list_results_btn.innerHTML = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                game_box.append(game_box_caption, list_results_btn);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                group_box_inner.append(game_box);
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            game_list_panel.appendChild(group_box);
 | 
					            game_list_panel.appendChild(group_box);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function start_or_continue_test(gameid) {
 | 
				
			||||||
 | 
					    let req = {
 | 
				
			||||||
 | 
					        action: "start_or_continue_test",
 | 
				
			||||||
 | 
					        gameid: gameid
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    request(req).then(resp => {
 | 
				
			||||||
 | 
					        if (resp.length > 0) // response is non-zero
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            open_test(resp);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function open_test(testid) {
 | 
				
			||||||
 | 
					    window.open("testground.php?testid=" + testid, "_new");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function list_corresponding_results(gameid) {
 | 
				
			||||||
 | 
					    let results_overview_display = document.getElementById("results_overview_display");
 | 
				
			||||||
 | 
					    results_overview_display.innerHTML = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let req = {
 | 
				
			||||||
 | 
					        action: "get_results_overview",
 | 
				
			||||||
 | 
					        gameid: gameid
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    request(req).then(resp => {
 | 
				
			||||||
 | 
					        let results = JSON.parse(resp);
 | 
				
			||||||
 | 
					        let n = results.length;
 | 
				
			||||||
 | 
					        if (n === 0) { // don't continue with processing an empty array
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        results.sort((a,b) => {return Number(b["testid"]) - Number(a["testid"])}); // sort records by ID
 | 
				
			||||||
 | 
					        results.forEach((record) => {
 | 
				
			||||||
 | 
					           let test_summary_record = document.createElement("section");
 | 
				
			||||||
 | 
					           test_summary_record.classList.add("test-summary-record");
 | 
				
			||||||
 | 
					           test_summary_record.addEventListener("click", () => {
 | 
				
			||||||
 | 
					              open_test(record["testid"]);
 | 
				
			||||||
 | 
					           });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					           let sequence_number_sec = document.createElement("section");
 | 
				
			||||||
 | 
					           sequence_number_sec.classList.add("summary-sequence-number");
 | 
				
			||||||
 | 
					           sequence_number_sec.innerText = "#" + n;
 | 
				
			||||||
 | 
					           let duration_sec = document.createElement("section");
 | 
				
			||||||
 | 
					           duration_sec.classList.add("summary-duration");
 | 
				
			||||||
 | 
					           let start_time = unix_time_to_human_readable(record["start_time"]);
 | 
				
			||||||
 | 
					           let end_time = unix_time_to_human_readable(record["end_time"]);
 | 
				
			||||||
 | 
					           duration_sec.innerHTML = `${start_time}-<br>${end_time}<br>${record["correct_answer_n"]}/${record["challenge_n"]}`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					           let percentage = document.createElement("section");
 | 
				
			||||||
 | 
					           percentage.classList.add("summary-percentage");
 | 
				
			||||||
 | 
					           let r = Math.floor((record["correct_answer_n"] / record["challenge_n"]) * 100);
 | 
				
			||||||
 | 
					           percentage.innerHTML = `${r}%`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					           test_summary_record.append(sequence_number_sec, duration_sec, percentage);
 | 
				
			||||||
 | 
					           results_overview_display.appendChild(test_summary_record);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					           n--;
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        show("results_window")
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										8
									
								
								js/main.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								js/main.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,8 @@
 | 
				
			|||||||
 | 
					function logout() {
 | 
				
			||||||
 | 
					    let req = {
 | 
				
			||||||
 | 
					        action: "logout"
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    request(req).then(resp => {
 | 
				
			||||||
 | 
					        location.href = "login.php";
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										154
									
								
								js/testground.js
									
									
									
									
									
								
							
							
						
						
									
										154
									
								
								js/testground.js
									
									
									
									
									
								
							@ -1,30 +1,164 @@
 | 
				
			|||||||
function populate_test(test_id) {
 | 
					let TEST_DATA = {}
 | 
				
			||||||
    let test_display = document.getElementById("test_display");
 | 
					let INTERVAL_HANDLE = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let req = {
 | 
					function print_time_left(t) {
 | 
				
			||||||
        action: "get_test",
 | 
					    let timerS = document.getElementById("timer");
 | 
				
			||||||
        id: test_id
 | 
					    let hours = Math.floor(t / 3600);
 | 
				
			||||||
 | 
					    t -= hours * 3600;
 | 
				
			||||||
 | 
					    let minutes = Math.floor(t / 60);
 | 
				
			||||||
 | 
					    t -= minutes * 60;
 | 
				
			||||||
 | 
					    let seconds = t;
 | 
				
			||||||
 | 
					    timerS.innerHTML = String(hours).padStart(2, "0") + ":"
 | 
				
			||||||
 | 
					        + String(minutes).padStart(2, "0") + ":"
 | 
				
			||||||
 | 
					        + String(seconds).padStart(2, "0");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
    request(req).then(resp => {
 | 
					
 | 
				
			||||||
        let test_data = JSON.parse(resp);
 | 
					function populate_infobox(test_data) {
 | 
				
			||||||
 | 
					    if (INTERVAL_HANDLE !== null) {
 | 
				
			||||||
 | 
					        clearInterval(INTERVAL_HANDLE);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let test_concluded = TEST_DATA["state"] === "concluded";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let game_nameS = document.getElementById("game_name");
 | 
				
			||||||
 | 
					    let durationS = document.getElementById("duration");
 | 
				
			||||||
 | 
					    let percentageS = document.getElementById("percentage");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    game_nameS.innerHTML = test_data["gamename"];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (test_concluded) {
 | 
				
			||||||
 | 
					        let summary = test_data["summary"];
 | 
				
			||||||
 | 
					        let correct_answer_n = summary["correct_answer_n"];
 | 
				
			||||||
 | 
					        let challenge_n = summary["challenge_n"];
 | 
				
			||||||
 | 
					        let r = Math.ceil((correct_answer_n / challenge_n) * 100);
 | 
				
			||||||
 | 
					        percentageS.innerHTML = `${r}% (${correct_answer_n}/${challenge_n})`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let start_time = unix_time_to_human_readable(test_data["start_time"]);
 | 
				
			||||||
 | 
					        let end_time = unix_time_to_human_readable(test_data["end_time"]);
 | 
				
			||||||
 | 
					        durationS.value = `${start_time} - ${end_time}`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        hide("ongoing-info");
 | 
				
			||||||
 | 
					        show("concluded-info");
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        if (test_data["time_limited"]) {
 | 
				
			||||||
 | 
					            let time_left_s = Number(test_data["end_limit_time"]) - Number(test_data["current_time"]);
 | 
				
			||||||
 | 
					            print_time_left(time_left_s);
 | 
				
			||||||
 | 
					            INTERVAL_HANDLE = setInterval(() => {
 | 
				
			||||||
 | 
					                time_left_s--;
 | 
				
			||||||
 | 
					                print_time_left(time_left_s);
 | 
				
			||||||
 | 
					                if (time_left_s <= 0) {
 | 
				
			||||||
 | 
					                    populate_all(test_data["_id"]);
 | 
				
			||||||
 | 
					                    clearInterval(INTERVAL_HANDLE);
 | 
				
			||||||
 | 
					                    INTERVAL_HANDLE = null;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }, 1000);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        show("ongoing-info");
 | 
				
			||||||
 | 
					        hide("concluded-info");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function populate_challenges(test_data) {
 | 
				
			||||||
 | 
					    let test_display = document.getElementById("test_display");
 | 
				
			||||||
 | 
					    test_display.innerHTML = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let test_concluded = TEST_DATA["state"] === "concluded";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let challenge_N = 0;
 | 
				
			||||||
    test_data["challenges"].forEach((challenge) => {
 | 
					    test_data["challenges"].forEach((challenge) => {
 | 
				
			||||||
 | 
					        let challenge_N_snapshot = challenge_N;
 | 
				
			||||||
        let challenge_box = document.createElement("section");
 | 
					        let challenge_box = document.createElement("section");
 | 
				
			||||||
        challenge_box.classList.add("challenge");
 | 
					        challenge_box.classList.add("challenge");
 | 
				
			||||||
        let question = document.createElement("span");
 | 
					        let question = document.createElement("span");
 | 
				
			||||||
        question.classList.add("question");
 | 
					        question.classList.add("question");
 | 
				
			||||||
            question.innerHTML = challenge["question"];
 | 
					        question.innerHTML = preprocess_inserts(challenge["question"]);
 | 
				
			||||||
        let answer_container = document.createElement("section");
 | 
					        let answer_container = document.createElement("section");
 | 
				
			||||||
        answer_container.classList.add("answer-container");
 | 
					        answer_container.classList.add("answer-container");
 | 
				
			||||||
        challenge_box.append(question, answer_container);
 | 
					        challenge_box.append(question, answer_container);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let answer_N = 0;
 | 
				
			||||||
 | 
					        let player_answer = challenge["player_answer"];
 | 
				
			||||||
 | 
					        player_answer = (player_answer !== "") ? Number(player_answer) : -1;
 | 
				
			||||||
        challenge["answers"].forEach((answer) => {
 | 
					        challenge["answers"].forEach((answer) => {
 | 
				
			||||||
            let answer_section = document.createElement("section");
 | 
					            let answer_section = document.createElement("section");
 | 
				
			||||||
            answer_section.classList.add("answer");
 | 
					            answer_section.classList.add("answer");
 | 
				
			||||||
                answer_section.innerHTML = answer;
 | 
					            let answer_radio = document.createElement("input");
 | 
				
			||||||
                answer_container.appendChild(answer_section);
 | 
					            answer_radio.type = "radio";
 | 
				
			||||||
 | 
					            answer_radio.id = `${challenge_N}_${answer_N}`;
 | 
				
			||||||
 | 
					            answer_radio.name = `challenge_${challenge_N}`;
 | 
				
			||||||
 | 
					            answer_radio.disabled = test_concluded;
 | 
				
			||||||
 | 
					            let answer_N_snapshot = answer_N;
 | 
				
			||||||
 | 
					            answer_radio.addEventListener("input", () => {
 | 
				
			||||||
 | 
					                save_answer(challenge_N_snapshot, answer_N_snapshot);
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
 | 
					            if (player_answer === answer_N) {
 | 
				
			||||||
 | 
					                answer_radio.checked = true;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            let answer_text = document.createElement("label");
 | 
				
			||||||
 | 
					            answer_text.innerHTML = preprocess_inserts(answer);
 | 
				
			||||||
 | 
					            answer_text.setAttribute("for", answer_radio.id);
 | 
				
			||||||
 | 
					            if (test_concluded && (challenge["correct_answer"] === answer_N)) {
 | 
				
			||||||
 | 
					                answer_text.classList.add("correct-answer")
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            answer_section.append(answer_radio, answer_text);
 | 
				
			||||||
 | 
					            answer_container.appendChild(answer_section);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            answer_N++;
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        challenge_N++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        test_display.appendChild(challenge_box);
 | 
					        test_display.appendChild(challenge_box);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    MathJax.typeset();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function populate_all(test_id) {
 | 
				
			||||||
 | 
					    let req = {
 | 
				
			||||||
 | 
					        action: "get_test",
 | 
				
			||||||
 | 
					        testid: test_id
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    request(req).then(resp => {
 | 
				
			||||||
 | 
					        TEST_DATA = JSON.parse(resp);
 | 
				
			||||||
 | 
					        populate_challenges(TEST_DATA);
 | 
				
			||||||
 | 
					        populate_infobox(TEST_DATA);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function save_answer(chidx, aidx) {
 | 
				
			||||||
 | 
					    let req = {
 | 
				
			||||||
 | 
					        action: "save_answer",
 | 
				
			||||||
 | 
					        testid: TEST_DATA["_id"],
 | 
				
			||||||
 | 
					        challenge_index: chidx,
 | 
				
			||||||
 | 
					        answer_index: aidx,
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    request(req);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function preprocess_inserts(str) {
 | 
				
			||||||
 | 
					    let code_delim = '`';
 | 
				
			||||||
 | 
					    let parts = str.split(code_delim);
 | 
				
			||||||
 | 
					    let res = "";
 | 
				
			||||||
 | 
					    for (let i = 0; i < parts.length; i++) {
 | 
				
			||||||
 | 
					        res += parts[i];
 | 
				
			||||||
 | 
					        if (i % 2 === 0) {
 | 
				
			||||||
 | 
					            res += "<code>";
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            res += "</code>";
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return res;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function submit_test() {
 | 
				
			||||||
 | 
					    let req = {
 | 
				
			||||||
 | 
					        action: "submit_test",
 | 
				
			||||||
 | 
					        testid: TEST_DATA["_id"]
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    request(req).then(resp => {
 | 
				
			||||||
 | 
					        populate_all(TEST_DATA["_id"]);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
							
								
								
									
										9
									
								
								main.php
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								main.php
									
									
									
									
									
								
							@ -22,6 +22,7 @@ $privilege = $user_data["privilege"];
 | 
				
			|||||||
        <meta charset="UTF-8">
 | 
					        <meta charset="UTF-8">
 | 
				
			||||||
        <title>SpreadQuiz</title>
 | 
					        <title>SpreadQuiz</title>
 | 
				
			||||||
        <script src="js/req.js"></script>
 | 
					        <script src="js/req.js"></script>
 | 
				
			||||||
 | 
					        <script src="js/main.js"></script>
 | 
				
			||||||
        <script src="js/spreadquiz.js"></script>
 | 
					        <script src="js/spreadquiz.js"></script>
 | 
				
			||||||
        <link rel="stylesheet" href="style/spreadquiz.css"/>
 | 
					        <link rel="stylesheet" href="style/spreadquiz.css"/>
 | 
				
			||||||
    </head>
 | 
					    </head>
 | 
				
			||||||
@ -31,7 +32,13 @@ $privilege = $user_data["privilege"];
 | 
				
			|||||||
            <iframe id="content_frame" src="default_frame.php"></iframe>
 | 
					            <iframe id="content_frame" src="default_frame.php"></iframe>
 | 
				
			||||||
        </section>
 | 
					        </section>
 | 
				
			||||||
        <section id="info_pane">
 | 
					        <section id="info_pane">
 | 
				
			||||||
            <section id="user_info" class="info-pane-element"><?= $user_data["nickname"]; ?></section>
 | 
					            <section id="user_info" class="info-pane-element">
 | 
				
			||||||
 | 
					                <?= $user_data["nickname"]; ?>
 | 
				
			||||||
 | 
					                <section style="margin-top: 1em">
 | 
				
			||||||
 | 
					                    <input type="button" value="Beállítások"><br>
 | 
				
			||||||
 | 
					                    <input type="button" value="Kijelentkezés" onclick="logout()">
 | 
				
			||||||
 | 
					                </section>
 | 
				
			||||||
 | 
					            </section>
 | 
				
			||||||
            <?php if ($privilege != PRIVILEGE_PLAYER) { ?>
 | 
					            <?php if ($privilege != PRIVILEGE_PLAYER) { ?>
 | 
				
			||||||
                <section id="action_panel" class="info-pane-element">
 | 
					                <section id="action_panel" class="info-pane-element">
 | 
				
			||||||
                    <?php if (($privilege === PRIVILEGE_CREATOR) || ($privilege === PRIVILEGE_QUIZMASTER)) { ?>
 | 
					                    <?php if (($privilege === PRIVILEGE_CREATOR) || ($privilege === PRIVILEGE_QUIZMASTER)) { ?>
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										45
									
								
								style/quizmaster_area.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								style/quizmaster_area.css
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,45 @@
 | 
				
			|||||||
 | 
					section#table_section {
 | 
				
			||||||
 | 
					    position: sticky;
 | 
				
			||||||
 | 
					    height: calc(100vh - 4em);
 | 
				
			||||||
 | 
					    overflow-y: auto;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					table.management {
 | 
				
			||||||
 | 
					    width: 100%;
 | 
				
			||||||
 | 
					    border-collapse: collapse;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					table.management thead th {
 | 
				
			||||||
 | 
					    padding: 0.5em 0;
 | 
				
			||||||
 | 
					    position: sticky;
 | 
				
			||||||
 | 
					    top: 0;
 | 
				
			||||||
 | 
					    background-color: darkgray;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					table.management tbody td {
 | 
				
			||||||
 | 
					    border: 1pt lightgrey solid;
 | 
				
			||||||
 | 
					    padding: 0.3em 0.5em;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					table.management tbody tr[highlight="true"] {
 | 
				
			||||||
 | 
					    background-color: antiquewhite;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					table.management tbody tr[highlight="false"] td input {
 | 
				
			||||||
 | 
					    pointer-events: none;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					section#user_manager_action_bar {
 | 
				
			||||||
 | 
					    margin-top: 0.5em;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					td.checkbox {
 | 
				
			||||||
 | 
					    width: 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.hintbox-window {
 | 
				
			||||||
 | 
					    position: fixed;
 | 
				
			||||||
 | 
					    display: block;
 | 
				
			||||||
 | 
					    width: 15em;
 | 
				
			||||||
 | 
					    height: 8em;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -1,3 +1,10 @@
 | 
				
			|||||||
 | 
					@import url('https://fonts.googleapis.com/css2?family=Autour+One&family=Kanit:wght@500&display=swap');
 | 
				
			||||||
 | 
					@import url("https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					body {
 | 
				
			||||||
 | 
					    font-family: 'Autour One', sans-serif;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
*[shown="false"] {
 | 
					*[shown="false"] {
 | 
				
			||||||
    visibility: hidden;
 | 
					    visibility: hidden;
 | 
				
			||||||
    display: none;
 | 
					    display: none;
 | 
				
			||||||
@ -10,6 +17,10 @@
 | 
				
			|||||||
    opacity: 1;
 | 
					    opacity: 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.material {
 | 
				
			||||||
 | 
					    font-family: 'Material Symbols Outlined', sans-serif;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* ----------------- */
 | 
					/* ----------------- */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
section#screen_panel {
 | 
					section#screen_panel {
 | 
				
			||||||
@ -31,13 +42,15 @@ section#content_pane, section#info_pane {
 | 
				
			|||||||
section#content_pane {
 | 
					section#content_pane {
 | 
				
			||||||
    left: 0;
 | 
					    left: 0;
 | 
				
			||||||
    width: 80vw;
 | 
					    width: 80vw;
 | 
				
			||||||
    background-color: lightcyan;
 | 
					    /*background-color: lightcyan;*/
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
section#info_pane {
 | 
					section#info_pane {
 | 
				
			||||||
    right: 0;
 | 
					    right: 0;
 | 
				
			||||||
    width: 20vw;
 | 
					    width: 20vw;
 | 
				
			||||||
    background-color: beige;
 | 
					    background-color: whitesmoke;
 | 
				
			||||||
 | 
					    border-left: 5px solid #176767;
 | 
				
			||||||
 | 
					    box-shadow: -5px 0 #d3e5e5;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.info-pane-element {
 | 
					.info-pane-element {
 | 
				
			||||||
@ -50,9 +63,19 @@ section#info_pane {
 | 
				
			|||||||
section#user_info {
 | 
					section#user_info {
 | 
				
			||||||
    position: relative;
 | 
					    position: relative;
 | 
				
			||||||
    top: 0;
 | 
					    top: 0;
 | 
				
			||||||
    background-color: aquamarine;
 | 
					    background-color: #176767;
 | 
				
			||||||
 | 
					    color: whitesmoke;
 | 
				
			||||||
    font-size: 18pt;
 | 
					    font-size: 18pt;
 | 
				
			||||||
    text-align: center;
 | 
					    text-align: center;
 | 
				
			||||||
 | 
					    height: 1.2em;
 | 
				
			||||||
 | 
					    overflow: clip;
 | 
				
			||||||
 | 
					    transition: 0.3s ease;
 | 
				
			||||||
 | 
					    border-bottom: 0 dashed whitesmoke;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					section#user_info:hover {
 | 
				
			||||||
 | 
					    height: 5em;
 | 
				
			||||||
 | 
					    border-width: 0.5em;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
section#action_panel {
 | 
					section#action_panel {
 | 
				
			||||||
@ -61,46 +84,11 @@ section#action_panel {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
iframe#content_frame {
 | 
					iframe#content_frame {
 | 
				
			||||||
    display: block;
 | 
					    display: block;
 | 
				
			||||||
    width: 100%;
 | 
					    width: calc(100% - 1em);
 | 
				
			||||||
    height: 100%;
 | 
					    height: 100%;
 | 
				
			||||||
    border: 0 transparent;
 | 
					    border: 0 transparent;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
section#table_section {
 | 
					 | 
				
			||||||
    position: sticky;
 | 
					 | 
				
			||||||
    height: calc(100vh - 4em);
 | 
					 | 
				
			||||||
    overflow-y: auto;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
table.management {
 | 
					 | 
				
			||||||
    width: 100%;
 | 
					 | 
				
			||||||
    border-collapse: collapse;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
table.management thead th {
 | 
					 | 
				
			||||||
    padding: 0.5em 0;
 | 
					 | 
				
			||||||
    position: sticky;
 | 
					 | 
				
			||||||
    top: 0;
 | 
					 | 
				
			||||||
    background-color: darkgray;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
table.management tbody td {
 | 
					 | 
				
			||||||
    border: 1pt lightgrey solid;
 | 
					 | 
				
			||||||
    padding: 0.3em 0.5em;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
table.management tbody tr[highlight="true"] {
 | 
					 | 
				
			||||||
    background-color: antiquewhite;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
table.management tbody tr[highlight="false"] td input {
 | 
					 | 
				
			||||||
    pointer-events: none;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
section#user_manager_action_bar {
 | 
					 | 
				
			||||||
    margin-top: 0.5em;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
section.window {
 | 
					section.window {
 | 
				
			||||||
    position: fixed;
 | 
					    position: fixed;
 | 
				
			||||||
    display: block;
 | 
					    display: block;
 | 
				
			||||||
@ -115,23 +103,12 @@ section.window {
 | 
				
			|||||||
section.window-inner {
 | 
					section.window-inner {
 | 
				
			||||||
    margin: 0 auto;
 | 
					    margin: 0 auto;
 | 
				
			||||||
    display: block;
 | 
					    display: block;
 | 
				
			||||||
    border: 2pt solid darkslategray;
 | 
					    border: 2pt solid #176767;
 | 
				
			||||||
    background-color: whitesmoke;
 | 
					    background-color: whitesmoke;
 | 
				
			||||||
    padding: 1em;
 | 
					    padding: 1em;
 | 
				
			||||||
    width: fit-content;
 | 
					    width: fit-content;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
td.checkbox {
 | 
					 | 
				
			||||||
    width: 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.hintbox-window {
 | 
					 | 
				
			||||||
    position: fixed;
 | 
					 | 
				
			||||||
    display: block;
 | 
					 | 
				
			||||||
    width: 15em;
 | 
					 | 
				
			||||||
    height: 8em;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* ----- */
 | 
					/* ----- */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
section#game_list_panel {
 | 
					section#game_list_panel {
 | 
				
			||||||
@ -145,15 +122,30 @@ section.group-box {
 | 
				
			|||||||
    margin: 1em;
 | 
					    margin: 1em;
 | 
				
			||||||
    left: 0;
 | 
					    left: 0;
 | 
				
			||||||
    right: 0;
 | 
					    right: 0;
 | 
				
			||||||
    background-color: beige;
 | 
					    background-color: #f8fbfb;
 | 
				
			||||||
 | 
					    border: 0.5px solid #176767;
 | 
				
			||||||
 | 
					    /*border-radius:  0 0 0.2em 0.2em;*/
 | 
				
			||||||
 | 
					    box-shadow: 5px 5px #d3e5e5;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
span.group-box-caption {
 | 
					span.group-box-caption-container {
 | 
				
			||||||
    display: block;
 | 
					    display: block;
 | 
				
			||||||
    left: 0;
 | 
					    left: 0;
 | 
				
			||||||
    right: 0;
 | 
					    right: 0;
 | 
				
			||||||
 | 
					    background-color: #176767;
 | 
				
			||||||
 | 
					    box-shadow: 0 5px #d3e5e5;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					span.group-box-caption {
 | 
				
			||||||
 | 
					    display: inline-block;
 | 
				
			||||||
 | 
					    /*position: relative;*/
 | 
				
			||||||
 | 
					    /*top: -0.5em;*/
 | 
				
			||||||
 | 
					    color: #176767;
 | 
				
			||||||
 | 
					    background-color: #d3e5e5;
 | 
				
			||||||
 | 
					    font-weight: bold;
 | 
				
			||||||
 | 
					    font-size: 1.2em;
 | 
				
			||||||
    padding: 1em;
 | 
					    padding: 1em;
 | 
				
			||||||
    background-color: chartreuse;
 | 
					    margin-left: 1em;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
section.group-box-inner {
 | 
					section.group-box-inner {
 | 
				
			||||||
@ -164,13 +156,45 @@ section.group-box-inner {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
section.game-box {
 | 
					section.game-box {
 | 
				
			||||||
    display: table-cell;
 | 
					    display: inline-block;
 | 
				
			||||||
    width: 8em;
 | 
					    position: relative;
 | 
				
			||||||
    height: 8em;
 | 
					    width: 12em;
 | 
				
			||||||
    border: 2pt dashed gray;
 | 
					    height: 12em;
 | 
				
			||||||
 | 
					    border: 2pt solid #176767;
 | 
				
			||||||
    text-align: center;
 | 
					    text-align: center;
 | 
				
			||||||
    vertical-align: middle;
 | 
					    vertical-align: middle;
 | 
				
			||||||
    cursor: pointer;
 | 
					    cursor: pointer;
 | 
				
			||||||
 | 
					    margin-right: 1em;
 | 
				
			||||||
 | 
					    overflow: clip;
 | 
				
			||||||
 | 
					    box-shadow: 5px 5px #d3e5e5;
 | 
				
			||||||
 | 
					    transform: scale(100%) rotate(0);
 | 
				
			||||||
 | 
					    background-color: whitesmoke;
 | 
				
			||||||
 | 
					    transition: ease 0.3s;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					section.game-box:hover {
 | 
				
			||||||
 | 
					    transform: scale(105%) rotate(3deg);
 | 
				
			||||||
 | 
					    z-index: 1000;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					section.game-box-caption {
 | 
				
			||||||
 | 
					    margin-top: 2em;
 | 
				
			||||||
 | 
					    font-size: 1.3em;
 | 
				
			||||||
 | 
					    rotate: -10deg;
 | 
				
			||||||
 | 
					    background-color: #176767;
 | 
				
			||||||
 | 
					    width: 13em;
 | 
				
			||||||
 | 
					    position: relative;
 | 
				
			||||||
 | 
					    left: -3em;
 | 
				
			||||||
 | 
					    padding: 0.6em;
 | 
				
			||||||
 | 
					    color: whitesmoke;
 | 
				
			||||||
 | 
					    box-shadow: 0 5px #d3e5e5;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					section.list-results-btn {
 | 
				
			||||||
 | 
					    display: block;
 | 
				
			||||||
 | 
					    position: absolute;
 | 
				
			||||||
 | 
					    right: 0.2em;
 | 
				
			||||||
 | 
					    bottom: 0.2em;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
section#test_area {
 | 
					section#test_area {
 | 
				
			||||||
@ -181,11 +205,20 @@ section#test_area {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
section.challenge {
 | 
					section.challenge {
 | 
				
			||||||
 | 
					    display: block;
 | 
				
			||||||
 | 
					    margin: 0 auto;
 | 
				
			||||||
 | 
					    width: 40em;
 | 
				
			||||||
 | 
					    /*border: 1px solid black;*/
 | 
				
			||||||
 | 
					    padding: 1em;
 | 
				
			||||||
 | 
					    background-color: #d3e5e5;
 | 
				
			||||||
 | 
					    margin-bottom: 0.5em;
 | 
				
			||||||
 | 
					    border-radius: 0.3em;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
span.question {
 | 
					span.question {
 | 
				
			||||||
 | 
					    font-size: 1.3em;
 | 
				
			||||||
 | 
					    font-weight: bold;
 | 
				
			||||||
 | 
					    color: #176767;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
section.answer-container {
 | 
					section.answer-container {
 | 
				
			||||||
@ -193,5 +226,112 @@ section.answer-container {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
section.answer {
 | 
					section.answer {
 | 
				
			||||||
 | 
					    margin: 0.3em 0.8em;
 | 
				
			||||||
 | 
					    display: block;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					section.answer label {
 | 
				
			||||||
 | 
					    margin-left: 0.5em;
 | 
				
			||||||
 | 
					    padding: 0.3em 0.5em;
 | 
				
			||||||
 | 
					    border-radius: 0.3em;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					section.answer label.correct-answer {
 | 
				
			||||||
 | 
					    border: 2px solid #176767 !important;
 | 
				
			||||||
 | 
					    padding: 0.1em;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					section.answer input[type="radio"]:checked+label:not(.correct-answer) {
 | 
				
			||||||
 | 
					    background-color: #176767;
 | 
				
			||||||
 | 
					    color: whitesmoke;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					section#infobox {
 | 
				
			||||||
 | 
					    display: block;
 | 
				
			||||||
 | 
					    position: fixed;
 | 
				
			||||||
 | 
					    left: 0;
 | 
				
			||||||
 | 
					    top: 0;
 | 
				
			||||||
 | 
					    margin: 1em;
 | 
				
			||||||
 | 
					    /*padding: 1em;*/
 | 
				
			||||||
 | 
					    background: #f8fbfb;
 | 
				
			||||||
 | 
					    border: 0.5px solid #176767;
 | 
				
			||||||
 | 
					    min-width: 15em;
 | 
				
			||||||
 | 
					    min-height: 5em;
 | 
				
			||||||
 | 
					    box-shadow: 5px 5px #d3e5e5;
 | 
				
			||||||
 | 
					    overflow: clip;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					section#infobox > section {
 | 
				
			||||||
 | 
					    padding: 1em;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					span#game_name {
 | 
				
			||||||
 | 
					    display: block;
 | 
				
			||||||
 | 
					    width: 100%;
 | 
				
			||||||
 | 
					    padding: 1em;
 | 
				
			||||||
 | 
					    background-color: #176767;
 | 
				
			||||||
 | 
					    box-shadow: 0px 5px #d3e5e5;
 | 
				
			||||||
 | 
					    color: whitesmoke;
 | 
				
			||||||
 | 
					    font-size: 1.2em;
 | 
				
			||||||
 | 
					    font-weight: bold;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					section#timer {
 | 
				
			||||||
 | 
					    color: #176767;
 | 
				
			||||||
 | 
					    margin-bottom: 0.5em;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					section#percentage {
 | 
				
			||||||
 | 
					    color: #176767;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					span.infobox-description {
 | 
				
			||||||
 | 
					    font-size: 0.8em;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.btn {
 | 
				
			||||||
 | 
					    background-color: transparent;
 | 
				
			||||||
 | 
					    padding: 0.3em;
 | 
				
			||||||
 | 
					    border-radius: 0.2em;
 | 
				
			||||||
 | 
					    font-size: 1.3em;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.btn:hover {
 | 
				
			||||||
 | 
					    background-color: rgba(128, 128, 128, 0.30);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					section.test-summary-record {
 | 
				
			||||||
 | 
					    position: relative;
 | 
				
			||||||
 | 
					    cursor: pointer;
 | 
				
			||||||
 | 
					    border: 0.5px solid #176767;
 | 
				
			||||||
 | 
					    margin-bottom: 0.3em;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.summary-sequence-number {
 | 
				
			||||||
 | 
					    font-size: 2em;
 | 
				
			||||||
 | 
					    display: inline-block;
 | 
				
			||||||
 | 
					    background-color: #176767;
 | 
				
			||||||
 | 
					    color: whitesmoke;
 | 
				
			||||||
 | 
					    padding: 0.5em;
 | 
				
			||||||
 | 
					    width: 1.5em;
 | 
				
			||||||
 | 
					    box-shadow: 5px 0 #d3e5e5;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.summary-duration {
 | 
				
			||||||
 | 
					    display: inline-block;
 | 
				
			||||||
 | 
					    margin-left: 1em;
 | 
				
			||||||
 | 
					    color: #176767;
 | 
				
			||||||
 | 
					    font-size: 0.7em;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.summary-percentage {
 | 
				
			||||||
 | 
					    display: inline-block;
 | 
				
			||||||
 | 
					    position: absolute;
 | 
				
			||||||
 | 
					    right: 0;
 | 
				
			||||||
 | 
					    margin-left: 1em;
 | 
				
			||||||
 | 
					    background-color: #176767;
 | 
				
			||||||
 | 
					    padding: 0 1em;
 | 
				
			||||||
 | 
					    box-shadow: -5px 0 #d3e5e5;
 | 
				
			||||||
 | 
					    color: whitesmoke;
 | 
				
			||||||
 | 
					    bottom: 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -8,7 +8,10 @@ if (!get_autologin_state() || !isset($_REQUEST["testid"])) {
 | 
				
			|||||||
    exit();
 | 
					    exit();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
$testid = $_REQUEST["testid"];
 | 
					$testid = trim($_REQUEST["testid"] ?: "");
 | 
				
			||||||
 | 
					if ($testid === "") {
 | 
				
			||||||
 | 
					    exit();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
?>
 | 
					?>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -17,15 +20,35 @@ $testid = $_REQUEST["testid"];
 | 
				
			|||||||
<head>
 | 
					<head>
 | 
				
			||||||
    <meta charset="UTF-8">
 | 
					    <meta charset="UTF-8">
 | 
				
			||||||
    <title>SpreadQuiz</title>
 | 
					    <title>SpreadQuiz</title>
 | 
				
			||||||
    <script src="js/spreadquiz.js"></script>
 | 
					 | 
				
			||||||
    <script src="js/req.js"></script>
 | 
					    <script src="js/req.js"></script>
 | 
				
			||||||
 | 
					    <script src="js/spreadquiz.js"></script>
 | 
				
			||||||
    <script src="js/o.js"></script>
 | 
					    <script src="js/o.js"></script>
 | 
				
			||||||
 | 
					    <script src="js/common.js"></script>
 | 
				
			||||||
    <script src="js/testground.js"></script>
 | 
					    <script src="js/testground.js"></script>
 | 
				
			||||||
    <link rel="stylesheet" href="style/spreadquiz.css">
 | 
					    <link rel="stylesheet" href="style/spreadquiz.css">
 | 
				
			||||||
 | 
					    <script id="MathJax-script" src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
 | 
				
			||||||
</head>
 | 
					</head>
 | 
				
			||||||
<body>
 | 
					<body>
 | 
				
			||||||
<section id="test_display">
 | 
					<section id="test_display">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
</section>
 | 
					</section>
 | 
				
			||||||
 | 
					<section id="infobox">
 | 
				
			||||||
 | 
					    <span id="game_name"></span>
 | 
				
			||||||
 | 
					    <section>
 | 
				
			||||||
 | 
					        <section id="ongoing-info">
 | 
				
			||||||
 | 
					            <span class="infobox-description">Hátralevő idő:</span>
 | 
				
			||||||
 | 
					            <section id="timer">10:00:00</section>
 | 
				
			||||||
 | 
					            <input type="button" value="Beküld" onclick="submit_test()">
 | 
				
			||||||
 | 
					        </section>
 | 
				
			||||||
 | 
					        <section id="concluded-info">
 | 
				
			||||||
 | 
					            <section id="duration"></section>
 | 
				
			||||||
 | 
					            <span class="infobox-description">Eredmény:</span>
 | 
				
			||||||
 | 
					            <section id="percentage">95% (19/20)</section>
 | 
				
			||||||
 | 
					        </section>
 | 
				
			||||||
 | 
					    </section>
 | 
				
			||||||
 | 
					</section>
 | 
				
			||||||
 | 
					<script>
 | 
				
			||||||
 | 
					    populate_all("<?=$testid ?>");
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
</body>
 | 
					</body>
 | 
				
			||||||
</html>
 | 
					</html>
 | 
				
			||||||
							
								
								
									
										103
									
								
								testmgr.php
									
									
									
									
									
								
							
							
						
						
									
										103
									
								
								testmgr.php
									
									
									
									
									
								
							@ -29,7 +29,7 @@ function create_or_continue_test(string $gameid, string $nickname): string
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // check if the user had taken this test before
 | 
					    // check if the user had taken this test before
 | 
				
			||||||
    $fetch_criteria = [["gameid", "=", $gameid], "AND", ["nickname", "=", $nickname]];
 | 
					    $fetch_criteria = [["gameid", "=", (int)$gameid], "AND", ["nickname", "=", $nickname]];
 | 
				
			||||||
    $previous_tests = $testdb->findBy($fetch_criteria);
 | 
					    $previous_tests = $testdb->findBy($fetch_criteria);
 | 
				
			||||||
    if (count($previous_tests) > 0) { // if there are previous attempts, then...
 | 
					    if (count($previous_tests) > 0) { // if there are previous attempts, then...
 | 
				
			||||||
        // update timed tests to see if they had expired
 | 
					        // update timed tests to see if they had expired
 | 
				
			||||||
@ -53,12 +53,15 @@ function create_or_continue_test(string $gameid, string $nickname): string
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
function create_test(array $game_data, array $user_data) : string
 | 
					function create_test(array $game_data, array $user_data) : string
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    global $testdb;
 | 
				
			||||||
    $gameid = $game_data["_id"];
 | 
					    $gameid = $game_data["_id"];
 | 
				
			||||||
 | 
					    $game_properties = $game_data["properties"];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // fill basic data
 | 
					    // fill basic data
 | 
				
			||||||
    $game_data = [
 | 
					    $test_data = [
 | 
				
			||||||
        "gameid" => $gameid,
 | 
					        "gameid" => $gameid,
 | 
				
			||||||
        "nickname" => $user_data["nickname"],
 | 
					        "nickname" => $user_data["nickname"],
 | 
				
			||||||
 | 
					        "gamename" => $game_data["name"]
 | 
				
			||||||
    ];
 | 
					    ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // fill challenges
 | 
					    // fill challenges
 | 
				
			||||||
@ -67,11 +70,33 @@ function create_test(array $game_data, array $user_data) : string
 | 
				
			|||||||
    // shuffle answers
 | 
					    // shuffle answers
 | 
				
			||||||
    foreach ($challenges as &$ch) {
 | 
					    foreach ($challenges as &$ch) {
 | 
				
			||||||
        shuffle($ch["answers"]);
 | 
					        shuffle($ch["answers"]);
 | 
				
			||||||
 | 
					        $ch["correct_answer"] = "";
 | 
				
			||||||
 | 
					        $ch["player_answer"] = "";
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    $game_data["challenges"] = $challenges;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // involve properties
 | 
					    // involve properties
 | 
				
			||||||
 | 
					    $now = time();
 | 
				
			||||||
 | 
					    $properties = [
 | 
				
			||||||
 | 
					        "state" => TEST_ONGOING,
 | 
				
			||||||
 | 
					        "time_limited" => (($game_properties["time_limit"] ?: -1) > -1),
 | 
				
			||||||
 | 
					        "start_time" => $now,
 | 
				
			||||||
 | 
					        "repeatable" => $game_properties["repeatable"] ?: false
 | 
				
			||||||
 | 
					    ];
 | 
				
			||||||
 | 
					    if ($properties["time_limited"]) {
 | 
				
			||||||
 | 
					        $properties["end_limit_time"] = $now + $game_properties["time_limit"];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // merge properties and test data
 | 
				
			||||||
 | 
					    $test_data = array_merge($test_data, $properties);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // add challenges
 | 
				
			||||||
 | 
					    $test_data["challenges"] = $challenges;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // store game
 | 
				
			||||||
 | 
					    $test_data = $testdb->insert($test_data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $testid = $test_data["_id"];
 | 
				
			||||||
 | 
					    return $testid;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function update_timed_tests(array $test_data_array)
 | 
					function update_timed_tests(array $test_data_array)
 | 
				
			||||||
@ -79,9 +104,8 @@ function update_timed_tests(array $test_data_array)
 | 
				
			|||||||
    $now = time();
 | 
					    $now = time();
 | 
				
			||||||
    foreach ($test_data_array as $test_data) {
 | 
					    foreach ($test_data_array as $test_data) {
 | 
				
			||||||
        // look for unprocessed expired tests
 | 
					        // look for unprocessed expired tests
 | 
				
			||||||
        if (($test_data["state"] === TEST_ONGOING) && ($test_data["end_limit_time"] < $now)) {
 | 
					        if (($test_data["state"] === TEST_ONGOING) && ($test_data["time_limited"]) && ($test_data["end_limit_time"] < $now)) {
 | 
				
			||||||
            $test_data["state"] = TEST_CONCLUDED;
 | 
					            conclude_test($test_data["_id"]);
 | 
				
			||||||
            update_test($test_data);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -91,3 +115,68 @@ function update_test(array $test_data)
 | 
				
			|||||||
    global $testdb;
 | 
					    global $testdb;
 | 
				
			||||||
    $testdb->update($test_data);
 | 
					    $testdb->update($test_data);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function get_test(string $testid): array
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    global $testdb;
 | 
				
			||||||
 | 
					    return $testdb->findById($testid);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function save_answer(string $testid, $chidx, $ansidx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    $test_data = get_test($testid);
 | 
				
			||||||
 | 
					    $chidx = (int)$chidx;
 | 
				
			||||||
 | 
					    if ((count($test_data) > 0) && ($test_data["state"] === TEST_ONGOING)) {
 | 
				
			||||||
 | 
					        if ($chidx < count($test_data["challenges"])) {
 | 
				
			||||||
 | 
					            $test_data["challenges"][$chidx]["player_answer"] = $ansidx;
 | 
				
			||||||
 | 
					            update_test($test_data);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function get_concluded_tests(string $gameid, string $nickname) {
 | 
				
			||||||
 | 
					    global $testdb;
 | 
				
			||||||
 | 
					    $fetch_criteria = [["gameid", "=", (int)$gameid], "AND", ["nickname", "=", $nickname], "AND", ["state", "=", TEST_CONCLUDED]];
 | 
				
			||||||
 | 
					    $test_data_array = $testdb->findBy($fetch_criteria);
 | 
				
			||||||
 | 
					    return $test_data_array;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function conclude_test(string $testid) {
 | 
				
			||||||
 | 
					    $test_data = get_test($testid);
 | 
				
			||||||
 | 
					    if (count($test_data) === 0) {
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // load game data
 | 
				
			||||||
 | 
					    //$game_data = get_game($test_data["gameid"]);
 | 
				
			||||||
 | 
					    $game_challenges = load_challenges($test_data["gameid"]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // check the answers
 | 
				
			||||||
 | 
					    $challenge_n = count($test_data["challenges"]); // number of challenges
 | 
				
			||||||
 | 
					    $cans_n = 0; // number of correct answers
 | 
				
			||||||
 | 
					    for ($chidx = 0; $chidx < $challenge_n; $chidx++) {
 | 
				
			||||||
 | 
					        // get challenge
 | 
				
			||||||
 | 
					        $tch = &$test_data["challenges"][$chidx];
 | 
				
			||||||
 | 
					        $gch = $game_challenges[$chidx];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // translate correct answer into an index by the shuffled answer order
 | 
				
			||||||
 | 
					        $cans_idx = array_search($gch["correct_answer"], $tch["answers"]);
 | 
				
			||||||
 | 
					        $tch["correct_answer"] = $cans_idx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // check the player's answer
 | 
				
			||||||
 | 
					        $player_answer = trim($tch["player_answer"]);
 | 
				
			||||||
 | 
					        if (($player_answer !== "") && ($cans_idx === (int)$player_answer)) {
 | 
				
			||||||
 | 
					            $cans_n++;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // set state and fill summary
 | 
				
			||||||
 | 
					    $test_data["state"] = TEST_CONCLUDED;
 | 
				
			||||||
 | 
					    $test_data["end_time"] = time();
 | 
				
			||||||
 | 
					    $test_data["summary"] = [
 | 
				
			||||||
 | 
					        "challenge_n" => $challenge_n,
 | 
				
			||||||
 | 
					        "correct_answer_n" => $cans_n
 | 
				
			||||||
 | 
					    ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    update_test($test_data);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user