initial
This commit is contained in:
		
						commit
						dc9c7e5ded
					
				
							
								
								
									
										22
									
								
								autologin.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								autologin.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,22 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					require_once "globals.php";
 | 
				
			||||||
 | 
					require_once "usermgr.php";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// attempt to auto-login
 | 
				
			||||||
 | 
					$autologin_user_data = [];
 | 
				
			||||||
 | 
					$auto_logged_in = false;
 | 
				
			||||||
 | 
					if ((session_status() === PHP_SESSION_ACTIVE) && isset($_SESSION["nickname"])) {
 | 
				
			||||||
 | 
					    $autologin_user_data = get_user($_SESSION["nickname"]);
 | 
				
			||||||
 | 
					    $auto_logged_in = count($autologin_user_data) != 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function get_autologin_state() : bool {
 | 
				
			||||||
 | 
					    global $auto_logged_in;
 | 
				
			||||||
 | 
					    return $auto_logged_in;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function get_autologin_user_data() : array {
 | 
				
			||||||
 | 
					    global $autologin_user_data;
 | 
				
			||||||
 | 
					    return $autologin_user_data;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										14
									
								
								common_func.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								common_func.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,14 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function explode_list(string $str) : array {
 | 
				
			||||||
 | 
					    return explode(",", str_replace(" ", "", $str));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function alter_array_contents(array &$a, $add, $remove) {
 | 
				
			||||||
 | 
					    if (($add !== null) && !array_search($add, $a)) { // if user was not assigned to the corresponding group
 | 
				
			||||||
 | 
					        $a[] = $add;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (($remove !== null) && (($i = array_search($remove, $a)) !== false)) { // only perform deleting if user is assigned to the passed group
 | 
				
			||||||
 | 
					        array_splice($a, $i, 1);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										7
									
								
								composer.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								composer.json
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					  "require": {
 | 
				
			||||||
 | 
					    "rakibtg/sleekdb": "2.15",
 | 
				
			||||||
 | 
					    "ext-http": "*",
 | 
				
			||||||
 | 
					    "ext-json": "*"
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										33
									
								
								default_frame.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								default_frame.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,33 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					require_once "globals.php";
 | 
				
			||||||
 | 
					require_once "autologin.php";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$user_data = get_autologin_user_data();
 | 
				
			||||||
 | 
					if (!get_autologin_state()) {
 | 
				
			||||||
 | 
					    exit();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					?>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<!DOCTYPE html>
 | 
				
			||||||
 | 
					<html>
 | 
				
			||||||
 | 
					<head>
 | 
				
			||||||
 | 
					    <meta charset="UTF-8">
 | 
				
			||||||
 | 
					    <title>SpreadQuiz</title>
 | 
				
			||||||
 | 
					    <script src="js/spreadquiz.js"></script>
 | 
				
			||||||
 | 
					    <script src="js/req.js"></script>
 | 
				
			||||||
 | 
					    <script src="js/o.js"></script>
 | 
				
			||||||
 | 
					    <script src="js/default_frame.js"></script>
 | 
				
			||||||
 | 
					    <link rel="stylesheet" href="style/spreadquiz.css">
 | 
				
			||||||
 | 
					</head>
 | 
				
			||||||
 | 
					<body>
 | 
				
			||||||
 | 
					<section id="game_list_panel">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					</section>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script>
 | 
				
			||||||
 | 
					    list_available_games();
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					</body>
 | 
				
			||||||
 | 
					</html>
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								examples/minta_quiz_táblázat.xlsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								examples/minta_quiz_táblázat.xlsx
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										66
									
								
								game_manager_frame.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								game_manager_frame.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,66 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					require_once "globals.php";
 | 
				
			||||||
 | 
					require_once "autologin.php";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$user_data = get_autologin_user_data();
 | 
				
			||||||
 | 
					if (!get_autologin_state() || (($user_data["privilege"] !== PRIVILEGE_CREATOR) && ($user_data["privilege"] !== PRIVILEGE_QUIZMASTER))) {
 | 
				
			||||||
 | 
					    exit(); // this page is only available for quizmasters
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					?>
 | 
				
			||||||
 | 
					<!DOCTYPE html>
 | 
				
			||||||
 | 
					<html>
 | 
				
			||||||
 | 
					<head>
 | 
				
			||||||
 | 
					    <meta charset="UTF-8">
 | 
				
			||||||
 | 
					    <title>SpreadQuiz</title>
 | 
				
			||||||
 | 
					    <script src="js/req.js"></script>
 | 
				
			||||||
 | 
					    <script src="js/spreadquiz.js"></script>
 | 
				
			||||||
 | 
					    <script src="js/o.js"></script>
 | 
				
			||||||
 | 
					    <script src="js/hintbox.js"></script>
 | 
				
			||||||
 | 
					    <script src="js/usermgr.js"></script>
 | 
				
			||||||
 | 
					    <script src="js/gamemgr.js"></script>
 | 
				
			||||||
 | 
					    <link rel="stylesheet" href="style/spreadquiz.css"/>
 | 
				
			||||||
 | 
					</head>
 | 
				
			||||||
 | 
					<body>
 | 
				
			||||||
 | 
					<section id="table_section">
 | 
				
			||||||
 | 
					    <table class="management">
 | 
				
			||||||
 | 
					        <thead>
 | 
				
			||||||
 | 
					        <tr>
 | 
				
			||||||
 | 
					            <th></th>
 | 
				
			||||||
 | 
					            <th>Név</th>
 | 
				
			||||||
 | 
					            <th>Leírás</th>
 | 
				
			||||||
 | 
					            <th>Tulajdonos</th>
 | 
				
			||||||
 | 
					        </tr>
 | 
				
			||||||
 | 
					        </thead>
 | 
				
			||||||
 | 
					        <tbody id="game_manager_table">
 | 
				
			||||||
 | 
					        </tbody>
 | 
				
			||||||
 | 
					    </table>
 | 
				
			||||||
 | 
					</section>
 | 
				
			||||||
 | 
					<section>
 | 
				
			||||||
 | 
					    <input type="button" value="Új játék" onclick="create_edit_game();">
 | 
				
			||||||
 | 
					    <input type="button" value="Játék(ok) törlése" onclick="delete_games()">
 | 
				
			||||||
 | 
					</section>
 | 
				
			||||||
 | 
					<section class="window" shown="false" id="game_editor_window">
 | 
				
			||||||
 | 
					    <section class="window-inner">
 | 
				
			||||||
 | 
					        <section style="text-align: right">
 | 
				
			||||||
 | 
					            <span>Név: <input type="text" id="game_name"></span><br>
 | 
				
			||||||
 | 
					            <span>Leírás: <input type="text" id="game_description"></span><br>
 | 
				
			||||||
 | 
					            <span>Tulajdonos: <input type="text" id="game_owner" readonly></span><br>
 | 
				
			||||||
 | 
					            <span>Szerkesztők: <input type="text" id="game_contributors"></span><br>
 | 
				
			||||||
 | 
					            <span>Kérdés-fájl: <input type="button" id="download_challenges_btn" value="Letöltés CSV-ként" shown="false" onclick="download_challenges()">
 | 
				
			||||||
 | 
					                <input type="button" value="Új feltöltése" id="show_game_file_upload" onclick="show_hide_gamefile_upload(true)">
 | 
				
			||||||
 | 
					                <input type="file" id="game_file" shown="false">
 | 
				
			||||||
 | 
					                <input type="button" value="Mégse" id="cancel_game_file_upload" shown="false" onclick="show_hide_gamefile_upload(false);"></span><br>
 | 
				
			||||||
 | 
					            <span>Csoportok:   <input type="text" id="game_groups"></span><br>
 | 
				
			||||||
 | 
					        </section>
 | 
				
			||||||
 | 
					        <span><input type="button" value="" id="game_editor_submit_btn"><input type="button" value="Mégse" onclick="hide('game_editor_window')"></span>
 | 
				
			||||||
 | 
					    </section>
 | 
				
			||||||
 | 
					</section>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script>
 | 
				
			||||||
 | 
					    list_all_games();
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					</body>
 | 
				
			||||||
 | 
					</html>
 | 
				
			||||||
							
								
								
									
										186
									
								
								gamemgr.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										186
									
								
								gamemgr.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,186 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					require_once "globals.php";
 | 
				
			||||||
 | 
					require_once "common_func.php";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$gamedb = new \SleekDB\Store(GAMEDB, DATADIR, ["timeout" => false]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const DEFAULT_GAME_PROPERTIES = [
 | 
				
			||||||
 | 
					    "forward_only" => false, // player may traverse back and forth between challenges
 | 
				
			||||||
 | 
					    "time_limit" => -1, // no time limit; otherwise, this field indicates time limit in seconds
 | 
				
			||||||
 | 
					    "repeatable" => false // this test can be taken multiple times
 | 
				
			||||||
 | 
					];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function create_game(string $name, string $owner, string $description = "", array $properties = DEFAULT_GAME_PROPERTIES, array $contributors = [], array $challenges = []): bool
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    global $testdb;
 | 
				
			||||||
 | 
					    $game_data = [
 | 
				
			||||||
 | 
					        "name" => $name,
 | 
				
			||||||
 | 
					        "owner" => $owner,
 | 
				
			||||||
 | 
					        "contributors" => $contributors,
 | 
				
			||||||
 | 
					        "description" => $description,
 | 
				
			||||||
 | 
					        "game_file_present" => false,
 | 
				
			||||||
 | 
					        "properties" => $properties,
 | 
				
			||||||
 | 
					        "groups" => [],
 | 
				
			||||||
 | 
					    ];
 | 
				
			||||||
 | 
					    $game_data = $testdb->insert($game_data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // prepare game context
 | 
				
			||||||
 | 
					    $id = $game_data["_id"];
 | 
				
			||||||
 | 
					    $current_game_media_dir = GAMEMEDIA_DIR . DIRECTORY_SEPARATOR . $id;
 | 
				
			||||||
 | 
					    mkdir($current_game_media_dir);
 | 
				
			||||||
 | 
					    save_challenges($id, []);
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function get_game(string $gameid): array
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    global $testdb;
 | 
				
			||||||
 | 
					    return $testdb->findById($gameid);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function update_game(array $game_data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    global $testdb;
 | 
				
			||||||
 | 
					    $testdb->update($game_data);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function delete_game(string $gameid)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    global $testdb;
 | 
				
			||||||
 | 
					    $game_data = get_game($gameid);
 | 
				
			||||||
 | 
					    if (count($game_data) != 0) {
 | 
				
			||||||
 | 
					        foreach ($game_data["groups"] as $groupid) {
 | 
				
			||||||
 | 
					            change_group_game_assignments($groupid, null, $gameid);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $testdb->deleteById($gameid);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function change_game_group_assignments(string $gid, $groupname_add, $groupname_remove)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    $game_data = get_game($gid);
 | 
				
			||||||
 | 
					    if (count($game_data) != 0) {
 | 
				
			||||||
 | 
					        alter_array_contents($game_data["groups"], $groupname_add, $groupname_remove);
 | 
				
			||||||
 | 
					        update_game($game_data); // update user
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function get_all_games()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    global $testdb;
 | 
				
			||||||
 | 
					    return $testdb->findAll();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function get_all_game_data_by_contributor_nickname(string $nickname): array
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    global $testdb;
 | 
				
			||||||
 | 
					    $game_headers = [];
 | 
				
			||||||
 | 
					    if ($nickname !== "*") {
 | 
				
			||||||
 | 
					        $game_data_array = $testdb->findBy([["owner", "=", $nickname], "OR", ["contributors", "CONTAINS", $nickname]]);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        $game_data_array = $testdb->findAll();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    foreach ($game_data_array as $game_data) {
 | 
				
			||||||
 | 
					        $game_headers[] = $game_data;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return $game_headers;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function import_challenges_from_csv(string $csv_path, string $gameid)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    $game_data = get_game($gameid);
 | 
				
			||||||
 | 
					    if (count($game_data) === []) {
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $challenges = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // load filled CSV file
 | 
				
			||||||
 | 
					    $f = fopen($csv_path, "r");
 | 
				
			||||||
 | 
					    if (!$f) { // failed to open file
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    while ($csvline = fgetcsv($f)) {
 | 
				
			||||||
 | 
					        if (count($csvline) >= 3) {
 | 
				
			||||||
 | 
					            $ch = [
 | 
				
			||||||
 | 
					                "question" => $csvline[0],
 | 
				
			||||||
 | 
					                "image_url" => $csvline[1],
 | 
				
			||||||
 | 
					                "correct_answer" => $csvline[2],
 | 
				
			||||||
 | 
					                "answers" => array_filter(array_slice($csvline, 2), function ($v) {
 | 
				
			||||||
 | 
					                    return trim($v) !== "";
 | 
				
			||||||
 | 
					                })
 | 
				
			||||||
 | 
					            ];
 | 
				
			||||||
 | 
					            $challenges[] = $ch;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    fclose($f);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // save challenges
 | 
				
			||||||
 | 
					    save_challenges($gameid, $challenges);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // update game with game file present
 | 
				
			||||||
 | 
					    $game_data["game_file_present"] = true;
 | 
				
			||||||
 | 
					    update_game($game_data);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function is_user_contributor_to_game(string $gameid, string $nickname): bool
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    $game_data = get_game($gameid);
 | 
				
			||||||
 | 
					    if (count($game_data) === 0) {
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return in_array($nickname, $game_data["contributors"]) || ($game_data["owner"] === $nickname);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function is_user_owner_of_the_game(string $gameid, string $nickname): bool
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    $game_data = get_game($gameid);
 | 
				
			||||||
 | 
					    if (count($game_data) === 0) {
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return $game_data["owner"] === $nickname;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function save_challenges(string $gameid, array $challenges)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    file_put_contents(get_game_file_by_gameid($gameid), json_encode($challenges));     // store challenges in JSON-format
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function load_challenges(string $gameid)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return json_decode(file_get_contents(get_game_file_by_gameid($gameid)), true);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function export_challenges_to_csv($f, string $gameid)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    $game_data = get_game($gameid);
 | 
				
			||||||
 | 
					    if ((count($game_data) === []) || (!$game_data["game_file_present"])) {
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // load challenges
 | 
				
			||||||
 | 
					    $challenges = load_challenges($gameid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // populate CSV file
 | 
				
			||||||
 | 
					    foreach ($challenges as $ch) {
 | 
				
			||||||
 | 
					        $csvline = [
 | 
				
			||||||
 | 
					            $ch["question"],
 | 
				
			||||||
 | 
					            $ch["image_url"],
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					        $csvline = array_merge($csvline, $ch["answers"]);
 | 
				
			||||||
 | 
					        fputcsv($f, $csvline);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function get_contributors(string $gameid): array
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    $game_data = get_game($gameid);
 | 
				
			||||||
 | 
					    return $game_data["contributors"];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function get_game_file_by_gameid(string $gameid)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return GAMEMEDIA_DIR . DIRECTORY_SEPARATOR . $gameid . DIRECTORY_SEPARATOR . GAME_FILE;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										34
									
								
								globals.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								globals.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,34 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					require_once "vendor/autoload.php";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const DATADIR = "appdata";
 | 
				
			||||||
 | 
					const GAMEMEDIA_DIR = DATADIR . DIRECTORY_SEPARATOR . "game_media";
 | 
				
			||||||
 | 
					const GAME_FILE = "challenges.json";
 | 
				
			||||||
 | 
					const USERDB = "users";
 | 
				
			||||||
 | 
					const GROUPDB = "groups";
 | 
				
			||||||
 | 
					const GAMEDB = "games";
 | 
				
			||||||
 | 
					const TESTDB = "tests";
 | 
				
			||||||
 | 
					const INSTALL_INDICATOR = "INSTALLED";
 | 
				
			||||||
 | 
					const QUIZMASTER_NICKNAME = "quizmaster";
 | 
				
			||||||
 | 
					const LOGIN_URL = "login.php";
 | 
				
			||||||
 | 
					const MAIN_URL = "main.php";
 | 
				
			||||||
 | 
					const SESSION_NAME = "spreadquiz_sid";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					session_name(SESSION_NAME);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// autoload session
 | 
				
			||||||
 | 
					if ((session_status() === PHP_SESSION_NONE) && isset($_COOKIE[SESSION_NAME])) {
 | 
				
			||||||
 | 
					    session_start();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ----------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// initialize data directory
 | 
				
			||||||
 | 
					function init_datadir() {
 | 
				
			||||||
 | 
					    if (!file_exists(DATADIR)) {
 | 
				
			||||||
 | 
					        mkdir(DATADIR);
 | 
				
			||||||
 | 
					        mkdir(GAMEMEDIA_DIR);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										62
									
								
								group_manager_frame.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								group_manager_frame.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,62 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					require_once "globals.php";
 | 
				
			||||||
 | 
					require_once "autologin.php";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$user_data = get_autologin_user_data();
 | 
				
			||||||
 | 
					if (!get_autologin_state() || ($user_data["privilege"] !== PRIVILEGE_QUIZMASTER)) {
 | 
				
			||||||
 | 
					    exit(); // this page is only available for quizmasters
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					?>
 | 
				
			||||||
 | 
					<!DOCTYPE html>
 | 
				
			||||||
 | 
					<html>
 | 
				
			||||||
 | 
					<head>
 | 
				
			||||||
 | 
					    <meta charset="UTF-8">
 | 
				
			||||||
 | 
					    <title>SpreadQuiz</title>
 | 
				
			||||||
 | 
					    <script src="js/req.js"></script>
 | 
				
			||||||
 | 
					    <script src="js/spreadquiz.js"></script>
 | 
				
			||||||
 | 
					    <script src="js/o.js"></script>
 | 
				
			||||||
 | 
					    <script src="js/groupmgr.js"></script>
 | 
				
			||||||
 | 
					    <link rel="stylesheet" href="style/spreadquiz.css"/>
 | 
				
			||||||
 | 
					</head>
 | 
				
			||||||
 | 
					<body>
 | 
				
			||||||
 | 
					<section id="table_section">
 | 
				
			||||||
 | 
					    <table class="management">
 | 
				
			||||||
 | 
					        <thead>
 | 
				
			||||||
 | 
					        <tr>
 | 
				
			||||||
 | 
					            <th></th>
 | 
				
			||||||
 | 
					            <th>Név</th>
 | 
				
			||||||
 | 
					            <th>Leírás</th>
 | 
				
			||||||
 | 
					            <th>Tulajdonos</th>
 | 
				
			||||||
 | 
					        </tr>
 | 
				
			||||||
 | 
					        </thead>
 | 
				
			||||||
 | 
					        <tbody id="group_manager_table">
 | 
				
			||||||
 | 
					        </tbody>
 | 
				
			||||||
 | 
					    </table>
 | 
				
			||||||
 | 
					</section>
 | 
				
			||||||
 | 
					<section>
 | 
				
			||||||
 | 
					    <input type="button" value="Új csoport" onclick="create_edit_group();">
 | 
				
			||||||
 | 
					    <input type="button" value="Csoport(ok) törlése" onclick="delete_groups();">
 | 
				
			||||||
 | 
					</section>
 | 
				
			||||||
 | 
					<section class="window" shown="false" id="group_editor_window">
 | 
				
			||||||
 | 
					    <section class="window-inner">
 | 
				
			||||||
 | 
					        <section style="text-align: right">
 | 
				
			||||||
 | 
					            <span>Név: <input type="text" id="groupname"></span><br>
 | 
				
			||||||
 | 
					            <span>Leírás: <input type="text" id="group_description"></span><br>
 | 
				
			||||||
 | 
					            <span>Tulajdonos: <input type="text" id="group_owner" readonly></span><br>
 | 
				
			||||||
 | 
					            <span>Szerkesztők: <input type="text" id="group_editors"></span><br>
 | 
				
			||||||
 | 
					            <span>Tagok: <textarea id="group_members" readonly></textarea></span>
 | 
				
			||||||
 | 
					        </section>
 | 
				
			||||||
 | 
					        <span><input type="button" value="" id="group_editor_submit_btn"><input type="button" value="Mégse" onclick="hide('group_editor_window')"></span>
 | 
				
			||||||
 | 
					    </section>
 | 
				
			||||||
 | 
					</section>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script>
 | 
				
			||||||
 | 
					    list_all_groups();
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					</body>
 | 
				
			||||||
 | 
					</html>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										192
									
								
								groupmgr.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										192
									
								
								groupmgr.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,192 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					require_once "globals.php";
 | 
				
			||||||
 | 
					require_once "common_func.php";
 | 
				
			||||||
 | 
					require_once "usermgr.php";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$groupdb = new \SleekDB\Store(GROUPDB, DATADIR, ["timeout" => false]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function create_group(string $groupname, string $owner, string $description = "", array $editors = []): bool
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    global $groupdb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // test name uniqueness
 | 
				
			||||||
 | 
					    $unique = clear_unique_in_siblings($groupname);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // initialize group data
 | 
				
			||||||
 | 
					    $group_data = [
 | 
				
			||||||
 | 
					        "groupname" => $groupname,
 | 
				
			||||||
 | 
					        "unique" => $unique,
 | 
				
			||||||
 | 
					        "owner" => $owner,
 | 
				
			||||||
 | 
					        "description" => $description,
 | 
				
			||||||
 | 
					        "editors" => $editors,
 | 
				
			||||||
 | 
					        "users" => [],
 | 
				
			||||||
 | 
					        "games" => []
 | 
				
			||||||
 | 
					    ];
 | 
				
			||||||
 | 
					    $groupdb->insert($group_data); // insert group
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function get_group(string $groupid): array
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    global $groupdb;
 | 
				
			||||||
 | 
					    return $groupdb->findById($groupid);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function update_group(array $group_data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    global $groupdb;
 | 
				
			||||||
 | 
					    $groupdb->update($group_data);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function delete_group(string $groupid)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    global $groupdb;
 | 
				
			||||||
 | 
					    $group_data = get_group($groupid);
 | 
				
			||||||
 | 
					    if (count($group_data) !== 0) {
 | 
				
			||||||
 | 
					        foreach ($group_data["users"] as $nickname) { // remove all references to this group
 | 
				
			||||||
 | 
					            change_user_group_assignments($nickname, null, $groupid);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    $groupdb->deleteById($groupid);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function get_all_groups()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    global $groupdb;
 | 
				
			||||||
 | 
					    return $groupdb->findAll();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function change_group_user_assignments(string $groupid, $nickname_add, $nickname_remove)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    $group_data = get_group($groupid);
 | 
				
			||||||
 | 
					    if (count($group_data) != 0) {
 | 
				
			||||||
 | 
					        // --------- UPDATE group assignments (DEV ONLY!)------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $group_data["editors"] = $group_data["editors"] ?: [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // ---------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        alter_array_contents($group_data["users"], $nickname_add, $nickname_remove); // add to local storage
 | 
				
			||||||
 | 
					        alter_array_contents($group_data["editors"], null, $nickname_remove); // removed users must be excluded from the editors' list as well
 | 
				
			||||||
 | 
					        update_group($group_data); // update user
 | 
				
			||||||
 | 
					        if ($nickname_add !== null) {
 | 
				
			||||||
 | 
					            change_user_group_assignments($nickname_add, $groupid, null); // add to user's storage remote
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if ($nickname_remove !== null) {
 | 
				
			||||||
 | 
					            change_user_group_assignments($nickname_remove, null, $groupid); // remove from user's storage
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function change_group_game_assignments(string $groupid, $gameid_add, $gameid_remove)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    $group_data = get_group($groupid);
 | 
				
			||||||
 | 
					    if (count($group_data) != 0) {
 | 
				
			||||||
 | 
					        alter_array_contents($group_data["games"], $gameid_add, $gameid_remove); // add to local storage
 | 
				
			||||||
 | 
					        update_group($group_data); // update user
 | 
				
			||||||
 | 
					        if ($gameid_add !== null) {
 | 
				
			||||||
 | 
					            change_game_group_assignments($gameid_add, $groupid, null); // add to user's storage remote
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if ($gameid_remove !== null) {
 | 
				
			||||||
 | 
					            change_game_group_assignments($gameid_remove, null, $groupid); // remove from user's storage
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function search_groups(string $needle): array
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (strlen($needle) < 3) {
 | 
				
			||||||
 | 
					        return [];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    global $groupdb;
 | 
				
			||||||
 | 
					    $parts = explode("#", $needle, 2);
 | 
				
			||||||
 | 
					    $groupname = $parts[0];
 | 
				
			||||||
 | 
					    $group_data_array = [];
 | 
				
			||||||
 | 
					    if (count($parts) === 1) {
 | 
				
			||||||
 | 
					        $group_data_array = $groupdb->findBy(["groupname", "LIKE", "%$groupname%"]);
 | 
				
			||||||
 | 
					    } else if (count($parts) > 1) {
 | 
				
			||||||
 | 
					        $groupid = $parts[1];
 | 
				
			||||||
 | 
					        $group_data_array = $groupdb->findBy([["groupname", "LIKE", "%$groupname%"], "AND", ["_id", "LIKE", "%$groupid%"]]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $results = [];
 | 
				
			||||||
 | 
					    foreach ($group_data_array as $group_data) {
 | 
				
			||||||
 | 
					        $results[] = [
 | 
				
			||||||
 | 
					            "groupname" => $group_data["groupname"],
 | 
				
			||||||
 | 
					            "_id" => $group_data["_id"],
 | 
				
			||||||
 | 
					            "unique" => $group_data["unique"]
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return $results;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function clear_unique_in_siblings($groupname): bool
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    // make test on name uniqueness
 | 
				
			||||||
 | 
					    global $groupdb;
 | 
				
			||||||
 | 
					    $twins = $groupdb->findBy(["groupname", "=", "$groupname"]);
 | 
				
			||||||
 | 
					    $unique = count($twins) == 0;
 | 
				
			||||||
 | 
					    if (count($twins) === 1) { // if fails, then also indicate in the original group that its name is no longer unique
 | 
				
			||||||
 | 
					        $twins[0]["unique"] = false;
 | 
				
			||||||
 | 
					        update_group($twins[0]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return $unique;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function get_groupids_by_compounds(array $compounds): array
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    global $groupdb;
 | 
				
			||||||
 | 
					    $groupids = [];
 | 
				
			||||||
 | 
					    foreach ($compounds as $compound) {
 | 
				
			||||||
 | 
					        if (trim($compound) === "") { // skip empty entries
 | 
				
			||||||
 | 
					            continue;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // fetch the group
 | 
				
			||||||
 | 
					        $parts = explode("#", $compound);
 | 
				
			||||||
 | 
					        $group_data = [];
 | 
				
			||||||
 | 
					        if (count($parts) === 1) {
 | 
				
			||||||
 | 
					            $fetch_cmd = ["groupname", "=", $parts[0]];
 | 
				
			||||||
 | 
					            $group_data = $groupdb->findBy($fetch_cmd);
 | 
				
			||||||
 | 
					            if (count($group_data) == 1) { // too many hits
 | 
				
			||||||
 | 
					                $group_data = $group_data[0];
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                $group_data = [];
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            $group_data = $groupdb->findById($parts[1]);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if ($group_data !== []) {
 | 
				
			||||||
 | 
					            $groupids[] = $group_data["_id"];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return $groupids;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function is_user_editor_to_group(string $groupid, string $nickname): bool
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    $group_data = get_group($groupid);
 | 
				
			||||||
 | 
					    if (count($group_data) === 0) {
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return in_array($nickname, $group_data["editors"]) || ($group_data["owner"] === $nickname);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function get_group_unique_name(string $groupid): string
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    $group_data = get_group($groupid);
 | 
				
			||||||
 | 
					    if (count($group_data) !== 0) {
 | 
				
			||||||
 | 
					        return $group_data["groupname"] . (!$group_data["unique"] ? "#" . $groupid : "");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return "";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function resolve_groupids(array &$groups): void
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    for ($i = 0; $i < count($groups); $i++) {
 | 
				
			||||||
 | 
					        $groups[$i] = get_group_unique_name($groups[$i]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										10
									
								
								index.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								index.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,10 @@
 | 
				
			|||||||
 | 
					<!DOCTYPE html>
 | 
				
			||||||
 | 
					<html lang="hu">
 | 
				
			||||||
 | 
					<head>
 | 
				
			||||||
 | 
					    <meta charset="UTF-8">
 | 
				
			||||||
 | 
					    <title>SpreadQuiz</title>
 | 
				
			||||||
 | 
					</head>
 | 
				
			||||||
 | 
					<body>
 | 
				
			||||||
 | 
					    <?="asd" ?>
 | 
				
			||||||
 | 
					</body>
 | 
				
			||||||
 | 
					</html>
 | 
				
			||||||
							
								
								
									
										24
									
								
								install.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								install.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,24 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					require_once "globals.php";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (file_exists(INSTALL_INDICATOR)) {
 | 
				
			||||||
 | 
					    echo "SpreadQuiz already installed!";
 | 
				
			||||||
 | 
					    exit();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					init_datadir(); // create data directory
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// auto-create databases
 | 
				
			||||||
 | 
					require_once "usermgr.php";
 | 
				
			||||||
 | 
					require_once "groupmgr.php";
 | 
				
			||||||
 | 
					require_once "gamemgr.php";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// create "quizmaster" (admin) user
 | 
				
			||||||
 | 
					$pw = uniqid();
 | 
				
			||||||
 | 
					add_user(QUIZMASTER_NICKNAME, $pw, "");
 | 
				
			||||||
 | 
					change_privilege_level(QUIZMASTER_NICKNAME, PRIVILEGE_QUIZMASTER);
 | 
				
			||||||
 | 
					echo "Quizmaster account: quizmaster, $pw\n";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// deploy install indicator
 | 
				
			||||||
 | 
					touch(INSTALL_INDICATOR);
 | 
				
			||||||
							
								
								
									
										324
									
								
								interface.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										324
									
								
								interface.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,324 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					require_once "globals.php";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (!file_exists(INSTALL_INDICATOR)) {
 | 
				
			||||||
 | 
					    exit();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (!isset($_REQUEST["action"])) {
 | 
				
			||||||
 | 
					    exit();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					require_once "common_func.php";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// load databases only if something meaningful have arrived
 | 
				
			||||||
 | 
					require_once "usermgr.php";
 | 
				
			||||||
 | 
					require_once "groupmgr.php";
 | 
				
			||||||
 | 
					require_once "gamemgr.php";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$action = $_REQUEST["action"];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$result = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// no-login accessible actions
 | 
				
			||||||
 | 
					switch ($action) {
 | 
				
			||||||
 | 
					    case "login":
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            $nickname = $_REQUEST["nickname"];
 | 
				
			||||||
 | 
					            $password = $_REQUEST["password"];
 | 
				
			||||||
 | 
					            if (check_user_credentials($nickname, $password)) {
 | 
				
			||||||
 | 
					                session_start();
 | 
				
			||||||
 | 
					                $_SESSION["nickname"] = $nickname;
 | 
				
			||||||
 | 
					                $result = "OK";
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                $result = "FAIL";
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// exit script if there's no live session or nickname is missing or the referenced user is non-existent
 | 
				
			||||||
 | 
					if ((session_status() != PHP_SESSION_ACTIVE) || (!isset($_SESSION["nickname"])) || (count(get_user($_SESSION["nickname"])) == 0)) {
 | 
				
			||||||
 | 
					    goto print_result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$user_data = get_user($_SESSION["nickname"]);
 | 
				
			||||||
 | 
					$nickname = $user_data["nickname"];
 | 
				
			||||||
 | 
					$privilege = $user_data["privilege"];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// login-requiring actions
 | 
				
			||||||
 | 
					switch ($action) {
 | 
				
			||||||
 | 
					    case "logout":
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            $_SESSION = []; // clean up session data
 | 
				
			||||||
 | 
					            setcookie(SESSION_NAME, "", -1); // invalidate cookie
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case "get_user_info":
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            $user_data_filtered = $user_data;
 | 
				
			||||||
 | 
					            unset($user_data_filtered["password"]);
 | 
				
			||||||
 | 
					            $result = json_encode($user_data_filtered);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case "get_available_games":
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            $games_by_groups = [];
 | 
				
			||||||
 | 
					            $groupids = $user_data["groups"];
 | 
				
			||||||
 | 
					            foreach ($groupids as $groupid) {
 | 
				
			||||||
 | 
					                $group_data = get_group($groupid);
 | 
				
			||||||
 | 
					                $game_collection = [
 | 
				
			||||||
 | 
					                    "groupname" => $group_data["groupname"],
 | 
				
			||||||
 | 
					                    "description" => $group_data["description"],
 | 
				
			||||||
 | 
					                    "games" => []
 | 
				
			||||||
 | 
					                ];
 | 
				
			||||||
 | 
					                $gameids = $group_data["games"];
 | 
				
			||||||
 | 
					                foreach ($gameids as $gameid) {
 | 
				
			||||||
 | 
					                    $game = get_game($gameid);
 | 
				
			||||||
 | 
					                    $game_collection["games"][] = $game;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                $games_by_groups[] = $game_collection;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            $result = json_encode($games_by_groups);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// creator or quizmaster actions
 | 
				
			||||||
 | 
					if (($privilege !== PRIVILEGE_CREATOR) && ($privilege !== PRIVILEGE_QUIZMASTER)) {
 | 
				
			||||||
 | 
					    goto print_result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					switch ($action) {
 | 
				
			||||||
 | 
					    case "create_game":
 | 
				
			||||||
 | 
					    case "update_game":
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            $update = $action === "update_game";
 | 
				
			||||||
 | 
					            $data = json_decode($_REQUEST["data"], true) ?: [];
 | 
				
			||||||
 | 
					            if (($data === []) || (trim($data["name"] ?: "") === "")) { // no further processing
 | 
				
			||||||
 | 
					                goto print_result; // ~exit...
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            $gameid = $data["_id"];
 | 
				
			||||||
 | 
					            $name = $data["name"];
 | 
				
			||||||
 | 
					            $description = $data["description"];
 | 
				
			||||||
 | 
					            $contributors = explode_list($data["contributors"] ?: "");
 | 
				
			||||||
 | 
					            $owner = $update ? trim($data["owner"] ?: $nickname) : $nickname;
 | 
				
			||||||
 | 
					            $groups = explode_list($data["groups"] ?: "");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $groupids = get_groupids_by_compounds($groups); // convert group compounds to _ids
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // remove group ID's this user cannot edit
 | 
				
			||||||
 | 
					            $groupids_with_editor_access = [];
 | 
				
			||||||
 | 
					            foreach ($groupids as $groupid) {
 | 
				
			||||||
 | 
					                if (is_user_editor_to_group($groupid, $nickname)) {
 | 
				
			||||||
 | 
					                    $groupids_with_editor_access[] = $groupid;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            $groupids_with_editor_access = $groupid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (!$update) {
 | 
				
			||||||
 | 
					                create_game($name, $owner, $description);
 | 
				
			||||||
 | 
					            } else if (is_user_contributor_to_game($gameid, $nickname)) {
 | 
				
			||||||
 | 
					                $game_data = get_game($gameid);
 | 
				
			||||||
 | 
					                if (count($game_data) !== 0) {
 | 
				
			||||||
 | 
					                    // group management
 | 
				
			||||||
 | 
					                    $old_groupids = $game_data["groups"]; // retain old groupids
 | 
				
			||||||
 | 
					                    $new_groupids = $groupids; // get new groupids
 | 
				
			||||||
 | 
					                    $groupids_add = array_diff($new_groupids, $old_groupids); // groups this user needs to be added to
 | 
				
			||||||
 | 
					                    $groupids_remove = array_diff($old_groupids, $new_groupids); // groups this user need to be removed from
 | 
				
			||||||
 | 
					                    foreach ($groupids_add as $groupid) { // execute insertion and removal
 | 
				
			||||||
 | 
					                        change_group_game_assignments($groupid, $gameid, null);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    foreach ($groupids_remove as $groupid) {
 | 
				
			||||||
 | 
					                        change_group_game_assignments($groupid, null, $gameid);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    // re-fetch game data
 | 
				
			||||||
 | 
					                    $game_data = get_game($gameid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    // update game header data
 | 
				
			||||||
 | 
					                    $game_data["name"] = $name;
 | 
				
			||||||
 | 
					                    $game_data["description"] = $description;
 | 
				
			||||||
 | 
					                    if (($game_data["owner"] === $nickname) || ($privilege === PRIVILEGE_QUIZMASTER)) {
 | 
				
			||||||
 | 
					                        $game_data["owner"] = $owner;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    $game_data["contributors"] = array_intersect($contributors, get_all_nicknames());
 | 
				
			||||||
 | 
					                    update_game($game_data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    // update game file if supplied
 | 
				
			||||||
 | 
					                    if (isset($_FILES["game_file"])) {
 | 
				
			||||||
 | 
					                        import_challenges_from_csv($_FILES["game_file"]["tmp_name"], $data["_id"]);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case "get_all_game_headers":
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            $requester_nickname = ($privilege === PRIVILEGE_QUIZMASTER) ? "*" : $nickname; // "*" means every game
 | 
				
			||||||
 | 
					            $game_headers = get_all_game_data_by_contributor_nickname($requester_nickname);
 | 
				
			||||||
 | 
					            foreach ($game_headers as &$game_header) {
 | 
				
			||||||
 | 
					                resolve_groupids($game_header["groups"]);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            $result = json_encode($game_headers);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case "delete_games":
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            $gameids = explode_list(trim($_REQUEST["ids"] ?: ""));
 | 
				
			||||||
 | 
					            foreach ($gameids as $gameid) {
 | 
				
			||||||
 | 
					                if (($gameid !== "") && (is_user_owner_of_the_game($gameid, $nickname))) { // only the owner may delete a game
 | 
				
			||||||
 | 
					                    delete_game($gameid);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case "export_game_file_csv":
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            $gameid = trim($_REQUEST["gameid"] ?: "");
 | 
				
			||||||
 | 
					            if (($gameid !== "") && is_user_contributor_to_game($gameid, $nickname)) {
 | 
				
			||||||
 | 
					                $f = tmpfile();
 | 
				
			||||||
 | 
					                header("Content-Type: text/csv");
 | 
				
			||||||
 | 
					                header("Content-Disposition: attachment; filename=\"challenges_$gameid.csv\"\r\n");
 | 
				
			||||||
 | 
					                export_challenges_to_csv($f, $gameid);
 | 
				
			||||||
 | 
					                fseek($f, 0);
 | 
				
			||||||
 | 
					                fpassthru($f);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// quizmaster actions
 | 
				
			||||||
 | 
					if ($privilege !== PRIVILEGE_QUIZMASTER) {
 | 
				
			||||||
 | 
					    goto print_result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					switch ($action) {
 | 
				
			||||||
 | 
					    case "create_group":
 | 
				
			||||||
 | 
					    case "update_group":
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            $update = $action === "update_group";
 | 
				
			||||||
 | 
					            $groupname = trim($_REQUEST["groupname"] ?: "");
 | 
				
			||||||
 | 
					            $description = trim($_REQUEST["description"] ?: "");
 | 
				
			||||||
 | 
					            $editors = explode_list(trim($_REQUEST["editors"] ?: ""));
 | 
				
			||||||
 | 
					            $owner = (!$update) ? $user_data["nickname"] : trim($_REQUEST["owner"]);
 | 
				
			||||||
 | 
					            if ($owner === "") {
 | 
				
			||||||
 | 
					                $owner = $user_data["nickname"];
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if ($groupname != "") {
 | 
				
			||||||
 | 
					                switch ($action) {
 | 
				
			||||||
 | 
					                    case "create_group":
 | 
				
			||||||
 | 
					                        create_group($groupname, $owner, $description, $editors);
 | 
				
			||||||
 | 
					                        break;
 | 
				
			||||||
 | 
					                    case "update_group":
 | 
				
			||||||
 | 
					                        {
 | 
				
			||||||
 | 
					                            $gid = $_REQUEST["id"];
 | 
				
			||||||
 | 
					                            $group = get_group($gid);
 | 
				
			||||||
 | 
					                            if (count($group) !== 0) {
 | 
				
			||||||
 | 
					                                $group["unique"] = clear_unique_in_siblings($groupname); // manage unique flag in case of renaming
 | 
				
			||||||
 | 
					                                $group["groupname"] = $groupname;
 | 
				
			||||||
 | 
					                                $group["description"] = $description;
 | 
				
			||||||
 | 
					                                $group["editors"] = array_intersect($editors, $group["users"]); // a user cannot be an editor if not part of the group
 | 
				
			||||||
 | 
					                                $group["owner"] = $owner;
 | 
				
			||||||
 | 
					                                update_group($group);
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                        break;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case "delete_groups":
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            $groups = explode_list($_REQUEST["ids"] ?: "");
 | 
				
			||||||
 | 
					            foreach ($groups as $g) {
 | 
				
			||||||
 | 
					                delete_group($g);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case "get_all_groups":
 | 
				
			||||||
 | 
					        $result = json_encode(get_all_groups());
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case "search_groups":
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            $needle = $_REQUEST["needle"] ?: "";
 | 
				
			||||||
 | 
					            $result = json_encode(search_groups($needle));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case "create_user":
 | 
				
			||||||
 | 
					    case "update_user":
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            $update = $action === "update_user";
 | 
				
			||||||
 | 
					            $target_nickname = trim($_REQUEST["nickname"] ?: "");
 | 
				
			||||||
 | 
					            $password = trim($_REQUEST["password"] ?: "");
 | 
				
			||||||
 | 
					            $groups = explode_list($_REQUEST["groups"] ?: "");
 | 
				
			||||||
 | 
					            $realname = trim($_REQUEST["realname"] ?: "");
 | 
				
			||||||
 | 
					            $privilege = trim($_REQUEST["privilege"] ?: PRIVILEGE_PLAYER);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $groupids = get_groupids_by_compounds($groups); // convert group compounds to _ids
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (($target_nickname !== "")) {
 | 
				
			||||||
 | 
					                if ((!$update) && ($password !== "")) { // CREATE
 | 
				
			||||||
 | 
					                    add_user($target_nickname, $password, $realname, $groupids, $privilege);
 | 
				
			||||||
 | 
					                } else if ($update) { // UPDATE
 | 
				
			||||||
 | 
					                    $user_data = get_user($target_nickname); // load user data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    // group management
 | 
				
			||||||
 | 
					                    $old_groupids = $user_data["groups"]; // retain old groupids
 | 
				
			||||||
 | 
					                    $new_groupids = $groupids; // get new groupids
 | 
				
			||||||
 | 
					                    $groupids_add = array_diff($new_groupids, $old_groupids); // groups this user needs to be added to
 | 
				
			||||||
 | 
					                    $groupids_remove = array_diff($old_groupids, $new_groupids); // groups this user need to be removed from
 | 
				
			||||||
 | 
					                    foreach ($groupids_add as $groupid) { // execute insertion and removal
 | 
				
			||||||
 | 
					                        change_group_user_assignments($groupid, $target_nickname, null);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    foreach ($groupids_remove as $groupid) {
 | 
				
			||||||
 | 
					                        change_group_user_assignments($groupid, null, $target_nickname);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    // re-fetch user
 | 
				
			||||||
 | 
					                    $user_data = get_user($target_nickname); // load user data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    // further field update
 | 
				
			||||||
 | 
					                    $user_data["realname"] = $realname;
 | 
				
			||||||
 | 
					                    $user_data["privilege"] = $privilege;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    // password replacement, if requested
 | 
				
			||||||
 | 
					                    if ($password !== "") {
 | 
				
			||||||
 | 
					                        $user_data["password"] = password_hash($password, PASSWORD_DEFAULT);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    update_user($user_data);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case "delete_users":
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            $users = explode_list($_REQUEST["users"] ?: "");
 | 
				
			||||||
 | 
					            foreach ($users as $g) {
 | 
				
			||||||
 | 
					                delete_user($g);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case "get_all_users":
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            $user_data_filtered = get_all_users();
 | 
				
			||||||
 | 
					            for ($i = 0; $i < count($user_data_filtered); $i++) {
 | 
				
			||||||
 | 
					                unset($user_data_filtered[$i]["password"]); // remove password from records
 | 
				
			||||||
 | 
					                resolve_groupids($user_data_filtered[$i]["groups"]);  // resolve group IDs
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            $result = json_encode($user_data_filtered);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ----------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					print_result:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if ($result !== "") {
 | 
				
			||||||
 | 
					    echo $result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										29
									
								
								js/default_frame.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								js/default_frame.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,29 @@
 | 
				
			|||||||
 | 
					function list_available_games() {
 | 
				
			||||||
 | 
					    let game_list_panel = document.getElementById("game_list_panel");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let req = {
 | 
				
			||||||
 | 
					        action: "get_available_games"
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    request(req).then(resp => {
 | 
				
			||||||
 | 
					        let games_by_groups = JSON.parse(resp);
 | 
				
			||||||
 | 
					        games_by_groups.forEach((game_collection) => {
 | 
				
			||||||
 | 
					            let group_box = document.createElement("section");
 | 
				
			||||||
 | 
					            group_box.classList.add("group-box");
 | 
				
			||||||
 | 
					            let group_box_caption = document.createElement("span");
 | 
				
			||||||
 | 
					            group_box_caption.classList.add("group-box-caption");
 | 
				
			||||||
 | 
					            group_box_caption.innerHTML = game_collection["groupname"];
 | 
				
			||||||
 | 
					            let group_box_inner = document.createElement("section");
 | 
				
			||||||
 | 
					            group_box_inner.classList.add("group-box-inner");
 | 
				
			||||||
 | 
					            group_box.append(group_box_caption, group_box_inner);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            game_collection["games"].forEach((game) => {
 | 
				
			||||||
 | 
					               let game_box = document.createElement("section");
 | 
				
			||||||
 | 
					               game_box.classList.add("game-box");
 | 
				
			||||||
 | 
					               game_box.innerHTML = game["name"];
 | 
				
			||||||
 | 
					               group_box_inner.appendChild(game_box);
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            game_list_panel.appendChild(group_box);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										175
									
								
								js/gamemgr.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										175
									
								
								js/gamemgr.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,175 @@
 | 
				
			|||||||
 | 
					function list_all_games() {
 | 
				
			||||||
 | 
					    let req = {action: "get_all_game_headers"};
 | 
				
			||||||
 | 
					    let tbody = document.getElementById("game_manager_table");
 | 
				
			||||||
 | 
					    tbody.innerHTML = "";
 | 
				
			||||||
 | 
					    request(req).then(resp => {
 | 
				
			||||||
 | 
					        let games = JSON.parse(resp);
 | 
				
			||||||
 | 
					        for (let i = 0; i < games.length; i++) {
 | 
				
			||||||
 | 
					            let g = games[i];
 | 
				
			||||||
 | 
					            let row = document.createElement("tr");
 | 
				
			||||||
 | 
					            let chkbox = document.createElement("input");
 | 
				
			||||||
 | 
					            chkbox.type = "checkbox";
 | 
				
			||||||
 | 
					            chkbox.name = "game_chkbox";
 | 
				
			||||||
 | 
					            chkbox.game = g;
 | 
				
			||||||
 | 
					            let tdChkBox = document.createElement("td");
 | 
				
			||||||
 | 
					            tdChkBox.appendChild(chkbox);
 | 
				
			||||||
 | 
					            tdChkBox.classList.add("checkbox");
 | 
				
			||||||
 | 
					            let tdGameName = create_table_cell(g["name"]);
 | 
				
			||||||
 | 
					            let tdGameDescription = create_table_cell(g["description"]);
 | 
				
			||||||
 | 
					            let tdOwner = create_table_cell(g["owner"]);
 | 
				
			||||||
 | 
					            row.append(tdChkBox, tdGameName, tdGameDescription, tdOwner);
 | 
				
			||||||
 | 
					            tbody.appendChild(row);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            let edit_group_action = () => {
 | 
				
			||||||
 | 
					                create_edit_game(g);
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            tdGameName.addEventListener("click", edit_group_action);
 | 
				
			||||||
 | 
					            tdGameDescription.addEventListener("click", edit_group_action);
 | 
				
			||||||
 | 
					            tdOwner.addEventListener("click", edit_group_action);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var EDITED_GAME = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function create_edit_game(game = null) {
 | 
				
			||||||
 | 
					    EDITED_GAME = game;
 | 
				
			||||||
 | 
					    let updating = game !== null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let nameF = document.getElementById("game_name");
 | 
				
			||||||
 | 
					    let descriptionF = document.getElementById("game_description");
 | 
				
			||||||
 | 
					    let submit_btn = document.getElementById("game_editor_submit_btn");
 | 
				
			||||||
 | 
					    let ownerF = document.getElementById("game_owner");
 | 
				
			||||||
 | 
					    let contributorsF = document.getElementById("game_contributors");
 | 
				
			||||||
 | 
					    let gameFileF = document.getElementById("game_file");
 | 
				
			||||||
 | 
					    let download_challenges_btn = document.getElementById("download_challenges_btn");
 | 
				
			||||||
 | 
					    let show_game_file_upload_btn = document.getElementById("show_game_file_upload");
 | 
				
			||||||
 | 
					    let cancel_game_file_upload_btn = document.getElementById("cancel_game_file_upload");
 | 
				
			||||||
 | 
					    let groupF = document.getElementById("game_groups");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!updating) { // creating a new game
 | 
				
			||||||
 | 
					        nameF.value = "";
 | 
				
			||||||
 | 
					        descriptionF.value = "";
 | 
				
			||||||
 | 
					        submit_btn.value = "Létrehozás"
 | 
				
			||||||
 | 
					        ownerF.value = USERDATA["nickname"];
 | 
				
			||||||
 | 
					        ownerF.readOnly = true;
 | 
				
			||||||
 | 
					        contributorsF.value = "";
 | 
				
			||||||
 | 
					        groupF.value = "";
 | 
				
			||||||
 | 
					    } else { // editing an existing one
 | 
				
			||||||
 | 
					        nameF.value = game["name"];
 | 
				
			||||||
 | 
					        descriptionF.value = game["description"];
 | 
				
			||||||
 | 
					        submit_btn.value = "Mentés"
 | 
				
			||||||
 | 
					        ownerF.value = game["owner"];
 | 
				
			||||||
 | 
					        ownerF.readOnly = false;
 | 
				
			||||||
 | 
					        contributorsF.value = game["contributors"].join(", ");
 | 
				
			||||||
 | 
					        groupF.value = game["groups"].join(", ");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    gameFileF.value = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let game_file_present = updating && game["game_file_present"];
 | 
				
			||||||
 | 
					    if (game_file_present) {
 | 
				
			||||||
 | 
					        show(download_challenges_btn);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    show_hide_gamefile_upload(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    submit_btn.onclick = () => {
 | 
				
			||||||
 | 
					        let game_name = document.getElementById("game_name").value.trim();
 | 
				
			||||||
 | 
					        if (game_name !== "") {
 | 
				
			||||||
 | 
					            let reqData = {
 | 
				
			||||||
 | 
					                name: game_name,
 | 
				
			||||||
 | 
					                description: descriptionF.value.trim(),
 | 
				
			||||||
 | 
					                owner: updating ? ownerF.value.trim() : USERDATA["nickname"],
 | 
				
			||||||
 | 
					                contributors: contributorsF.value.trim(),
 | 
				
			||||||
 | 
					                groups: groupF.value.trim()
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					            if (updating) {
 | 
				
			||||||
 | 
					                reqData["_id"] = game["_id"];
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            let req = {
 | 
				
			||||||
 | 
					                action: updating ? "update_game" : "create_game",
 | 
				
			||||||
 | 
					                data: JSON.stringify(reqData)
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					            if (gameFileF.files.length > 0) { // append game file if selected
 | 
				
			||||||
 | 
					                req["game_file"] = gameFileF.files[0];
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            request(req).then(resp => {
 | 
				
			||||||
 | 
					                list_all_games();
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					            hide("game_editor_window");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    show("game_editor_window");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function show_hide_gamefile_upload(en) {
 | 
				
			||||||
 | 
					    if (en) {
 | 
				
			||||||
 | 
					        // hide("download_challenges_btn");
 | 
				
			||||||
 | 
					        hide("show_game_file_upload");
 | 
				
			||||||
 | 
					        show("game_file");
 | 
				
			||||||
 | 
					        show("cancel_game_file_upload");
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        // show("download_challenges_btn");
 | 
				
			||||||
 | 
					        show("show_game_file_upload");
 | 
				
			||||||
 | 
					        hide("game_file");
 | 
				
			||||||
 | 
					        hide("cancel_game_file_upload");
 | 
				
			||||||
 | 
					        document.getElementById("game_file").value = "";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function download_challenges() {
 | 
				
			||||||
 | 
					    let action = "export_game_file_csv";
 | 
				
			||||||
 | 
					    let gameid = EDITED_GAME["_id"];
 | 
				
			||||||
 | 
					    window.open(`interface.php?action=${action}&gameid=${gameid}`, "_blank");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function get_selected_games() {
 | 
				
			||||||
 | 
					    let selected_chkboxes = document.getElementsByName("game_chkbox");
 | 
				
			||||||
 | 
					    let selected_games = [];
 | 
				
			||||||
 | 
					    selected_chkboxes.forEach((chkbox) => {
 | 
				
			||||||
 | 
					        if (chkbox.checked) {
 | 
				
			||||||
 | 
					            selected_games.push(chkbox.game);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    return selected_games;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function delete_games() {
 | 
				
			||||||
 | 
					    let games = get_selected_games();
 | 
				
			||||||
 | 
					    if (games.length === 0) {
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let game_names = [];
 | 
				
			||||||
 | 
					    let game_ids = [];
 | 
				
			||||||
 | 
					    games.forEach((g) => {
 | 
				
			||||||
 | 
					        game_names.push(g["name"]);
 | 
				
			||||||
 | 
					        game_ids.push(g["_id"]);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    let msg = "Biztosan törölni kívánja a következő játéko(ka)t?\n\n" + game_names.join(", ") + "\n\n"
 | 
				
			||||||
 | 
					        + "A törlés nem vonható vissza!";
 | 
				
			||||||
 | 
					    if (confirm(msg)) {
 | 
				
			||||||
 | 
					        let req = {action: "delete_games", ids: game_ids.join(",")};
 | 
				
			||||||
 | 
					        request(req).then(resp => {
 | 
				
			||||||
 | 
					            list_all_games();
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// function hint_all_groups(target_element_id) {
 | 
				
			||||||
 | 
					//     const hintbox_insert_fn = (record) => {
 | 
				
			||||||
 | 
					//         let targetF = document.getElementById(target_element_id);
 | 
				
			||||||
 | 
					//         let groups = explode_sanitize_string_list(targetF.value);
 | 
				
			||||||
 | 
					//         groups.pop();
 | 
				
			||||||
 | 
					//         groups.push(record);
 | 
				
			||||||
 | 
					//         targetF.value = groups.join(", ");
 | 
				
			||||||
 | 
					//         close_hintbox(true);
 | 
				
			||||||
 | 
					//     }
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//     let req = {
 | 
				
			||||||
 | 
					//         action: "search_groups",
 | 
				
			||||||
 | 
					//     }
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//     open_hintbox_at(target_element_id, req, print_group_name, hintbox_insert_fn);
 | 
				
			||||||
 | 
					// }
 | 
				
			||||||
							
								
								
									
										123
									
								
								js/groupmgr.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								js/groupmgr.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,123 @@
 | 
				
			|||||||
 | 
					function list_all_groups() {
 | 
				
			||||||
 | 
					    let req = {action: "get_all_groups"};
 | 
				
			||||||
 | 
					    let tbody = document.getElementById("group_manager_table");
 | 
				
			||||||
 | 
					    tbody.innerHTML = "";
 | 
				
			||||||
 | 
					    request(req).then(resp => {
 | 
				
			||||||
 | 
					        let groups = JSON.parse(resp);
 | 
				
			||||||
 | 
					        for (let i = 0; i < groups.length; i++) {
 | 
				
			||||||
 | 
					            let g = groups[i];
 | 
				
			||||||
 | 
					            let row = document.createElement("tr");
 | 
				
			||||||
 | 
					            let chkbox = document.createElement("input");
 | 
				
			||||||
 | 
					            chkbox.type = "checkbox";
 | 
				
			||||||
 | 
					            chkbox.name = "group_chkbox";
 | 
				
			||||||
 | 
					            chkbox.group = g;
 | 
				
			||||||
 | 
					            let tdChkBox = document.createElement("td");
 | 
				
			||||||
 | 
					            tdChkBox.appendChild(chkbox);
 | 
				
			||||||
 | 
					            tdChkBox.classList.add("checkbox");
 | 
				
			||||||
 | 
					            let tdGroupName = create_table_cell(print_group_name(g));
 | 
				
			||||||
 | 
					            let tdGroupDescription = create_table_cell(g["description"]);
 | 
				
			||||||
 | 
					            let tdOwner = create_table_cell(g["owner"]);
 | 
				
			||||||
 | 
					            row.append(tdChkBox, tdGroupName, tdGroupDescription, tdOwner);
 | 
				
			||||||
 | 
					            tbody.appendChild(row);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            let edit_group_action = () => {
 | 
				
			||||||
 | 
					                create_edit_group(g);
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            tdGroupName.addEventListener("click", edit_group_action);
 | 
				
			||||||
 | 
					            tdGroupDescription.addEventListener("click", edit_group_action);
 | 
				
			||||||
 | 
					            tdOwner.addEventListener("click", edit_group_action);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function create_edit_group(group = null) {
 | 
				
			||||||
 | 
					    let update = group !== null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let groupnameF = document.getElementById("groupname");
 | 
				
			||||||
 | 
					    let group_descriptionF = document.getElementById("group_description");
 | 
				
			||||||
 | 
					    let submit_btn = document.getElementById("group_editor_submit_btn");
 | 
				
			||||||
 | 
					    let group_ownerF = document.getElementById("group_owner");
 | 
				
			||||||
 | 
					    let group_editorsF = document.getElementById("group_editors");
 | 
				
			||||||
 | 
					    let group_membersF = document.getElementById("group_members");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!update) { // create a new group
 | 
				
			||||||
 | 
					        groupnameF.value = "";
 | 
				
			||||||
 | 
					        group_descriptionF.value = "";
 | 
				
			||||||
 | 
					        submit_btn.value = "Létrehozás"
 | 
				
			||||||
 | 
					        group_ownerF.value = USERDATA["nickname"];
 | 
				
			||||||
 | 
					        group_ownerF.readOnly = true;
 | 
				
			||||||
 | 
					        group_editorsF.value = "";
 | 
				
			||||||
 | 
					        group_membersF.value = "";
 | 
				
			||||||
 | 
					    } else { // update and existing one
 | 
				
			||||||
 | 
					        groupnameF.value = group["groupname"];
 | 
				
			||||||
 | 
					        group_descriptionF.value = group["description"];
 | 
				
			||||||
 | 
					        submit_btn.value = "Mentés"
 | 
				
			||||||
 | 
					        group_ownerF.value = group["owner"];
 | 
				
			||||||
 | 
					        group_ownerF.readOnly = false;
 | 
				
			||||||
 | 
					        group_editorsF.value = group["editors"].join(", ");
 | 
				
			||||||
 | 
					        group_membersF.value = group["users"].join(", ");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    submit_btn.onclick = () => {
 | 
				
			||||||
 | 
					        let groupname = document.getElementById("groupname").value.trim();
 | 
				
			||||||
 | 
					        if (groupname !== "") {
 | 
				
			||||||
 | 
					            let req = {
 | 
				
			||||||
 | 
					                action: update ? "update_group" : "create_group",
 | 
				
			||||||
 | 
					                groupname: groupname,
 | 
				
			||||||
 | 
					                description: group_descriptionF.value.trim(),
 | 
				
			||||||
 | 
					                editors: group_editorsF.value.trim()
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					            if (update) {
 | 
				
			||||||
 | 
					                req["id"] = group["_id"];
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            request(req).then(resp => {
 | 
				
			||||||
 | 
					                list_all_groups();
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					            hide("group_editor_window");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    show("group_editor_window");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function get_selected_groups() {
 | 
				
			||||||
 | 
					    let selected_chkboxes = document.getElementsByName("group_chkbox");
 | 
				
			||||||
 | 
					    let selected_groups = [];
 | 
				
			||||||
 | 
					    selected_chkboxes.forEach((chkbox) => {
 | 
				
			||||||
 | 
					        if (chkbox.checked) {
 | 
				
			||||||
 | 
					            selected_groups.push(chkbox.group);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    return selected_groups;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function delete_groups() {
 | 
				
			||||||
 | 
					    let groups = get_selected_groups();
 | 
				
			||||||
 | 
					    if (groups.length === 0) {
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let group_names = [];
 | 
				
			||||||
 | 
					    let group_ids = [];
 | 
				
			||||||
 | 
					    groups.forEach((g) => {
 | 
				
			||||||
 | 
					       group_names.push(g["groupname"]);
 | 
				
			||||||
 | 
					       group_ids.push(g["_id"]);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    let msg = "Biztosan törölni kívánja a következő csoporto(ka)t?\n\n" + group_names.join(", ") + "\n\n"
 | 
				
			||||||
 | 
					        + "A törlés nem vonható vissza!";
 | 
				
			||||||
 | 
					    if (confirm(msg)) {
 | 
				
			||||||
 | 
					        let req = {action: "delete_groups", ids: group_ids.join(",")};
 | 
				
			||||||
 | 
					        request(req).then(resp => {
 | 
				
			||||||
 | 
					            list_all_groups();
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function print_group_name(group_data) {
 | 
				
			||||||
 | 
					    let record = group_data["groupname"];
 | 
				
			||||||
 | 
					    if (!group_data["unique"]) {
 | 
				
			||||||
 | 
					        record += "#" + group_data["_id"];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return record;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										70
									
								
								js/hintbox.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								js/hintbox.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,70 @@
 | 
				
			|||||||
 | 
					function explode_sanitize_string_list(list, explodeAt = ",") {
 | 
				
			||||||
 | 
					    let elements = list.split(explodeAt);
 | 
				
			||||||
 | 
					    let sanitized = [];
 | 
				
			||||||
 | 
					    elements.forEach((e) => {
 | 
				
			||||||
 | 
					        if (e.trim() !== "") {
 | 
				
			||||||
 | 
					            sanitized.push(e);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    return sanitized;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const HINTBOX_ID = "HINTBOX";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function close_hintbox(close_if_focused = false) {
 | 
				
			||||||
 | 
					    setTimeout(() => {
 | 
				
			||||||
 | 
					        if (close_if_focused || (document.getElementById(HINTBOX_ID).firstChild !== document.activeElement)) {
 | 
				
			||||||
 | 
					            hide(HINTBOX_ID);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }, 20);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					function open_hintbox(x, y, contents, print_fun, insert_fun) {
 | 
				
			||||||
 | 
					    let hbw = document.getElementById(HINTBOX_ID);
 | 
				
			||||||
 | 
					    if (hbw === null) {
 | 
				
			||||||
 | 
					        hbw = document.createElement("section");
 | 
				
			||||||
 | 
					        hbw.id = HINTBOX_ID;
 | 
				
			||||||
 | 
					        hbw.classList.add("hintbox-window");
 | 
				
			||||||
 | 
					        let lb = document.createElement("select");
 | 
				
			||||||
 | 
					        lb.size = 5;
 | 
				
			||||||
 | 
					        lb.style.width = "100%";
 | 
				
			||||||
 | 
					        hbw.appendChild(lb);
 | 
				
			||||||
 | 
					        document.body.appendChild(hbw);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    let lb = hbw.firstChild;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    hbw.style.left = `${x}px`;
 | 
				
			||||||
 | 
					    hbw.style.top = `${y}px`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    lb.innerHTML = "";
 | 
				
			||||||
 | 
					    contents.forEach((record) => {
 | 
				
			||||||
 | 
					        let line = print_fun(record);
 | 
				
			||||||
 | 
					        let opt = document.createElement("option");
 | 
				
			||||||
 | 
					        opt.value = line;
 | 
				
			||||||
 | 
					        opt.innerText = line;
 | 
				
			||||||
 | 
					        lb.appendChild(opt);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    lb.ondblclick = () => {
 | 
				
			||||||
 | 
					        insert_fun(lb.value);
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    show(HINTBOX_ID);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function open_hintbox_at(target_element_id, req_data, print_fn, insert_fn) {
 | 
				
			||||||
 | 
					    let targetF = document.getElementById(target_element_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let bbox = targetF.getBoundingClientRect();
 | 
				
			||||||
 | 
					    let list_str = targetF.value.trim().split(",");
 | 
				
			||||||
 | 
					    if (list_str.length > 0) {
 | 
				
			||||||
 | 
					        let last_le_str = list_str[list_str.length - 1].trim();
 | 
				
			||||||
 | 
					        if (last_le_str.length > 2) {
 | 
				
			||||||
 | 
					            req_data["needle"] = last_le_str; // auto-insert needle
 | 
				
			||||||
 | 
					            request(req_data).then(resp => {
 | 
				
			||||||
 | 
					                let groups = JSON.parse(resp);
 | 
				
			||||||
 | 
					                let x = bbox.x + bbox.width;
 | 
				
			||||||
 | 
					                let y = bbox.y;
 | 
				
			||||||
 | 
					                open_hintbox(x, y, groups, print_fn, insert_fn);
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										21
									
								
								js/o.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								js/o.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,21 @@
 | 
				
			|||||||
 | 
					function o(input) {
 | 
				
			||||||
 | 
					    var o;
 | 
				
			||||||
 | 
					    if (typeof input === "string")
 | 
				
			||||||
 | 
					        o = document.getElementById(input);
 | 
				
			||||||
 | 
					    else if (typeof input === "object")
 | 
				
			||||||
 | 
					        o = input;
 | 
				
			||||||
 | 
					    return o;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// megjelenítés / eltüntetés
 | 
				
			||||||
 | 
					function show(obj) {
 | 
				
			||||||
 | 
					    o(obj).setAttribute("shown", "true");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function hide(obj) {
 | 
				
			||||||
 | 
					    o(obj).setAttribute("shown", "false");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function toggle_show(obj) {
 | 
				
			||||||
 | 
					    o(obj).setAttribute("shown", o(obj).getAttribute("shown") === "false");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										31
									
								
								js/req.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								js/req.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,31 @@
 | 
				
			|||||||
 | 
					// kérés indítása a szerver felé (eredeti: KL.)
 | 
				
			||||||
 | 
					function request(data, url = "interface.php", method = "POST") {
 | 
				
			||||||
 | 
					    return new Promise((resolve, reject) => {
 | 
				
			||||||
 | 
					        var fd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // ha van adat megadva...
 | 
				
			||||||
 | 
					        if (data != null) {
 | 
				
			||||||
 | 
					            fd = new FormData();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // mezők hozzáfűzése a kéréshez
 | 
				
			||||||
 | 
					            for (let prop in data) {
 | 
				
			||||||
 | 
					                if (Object.prototype.hasOwnProperty.call(data, prop)) {
 | 
				
			||||||
 | 
					                    fd.append(prop, data[prop]);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // kérés feladása
 | 
				
			||||||
 | 
					        fetch(url, {
 | 
				
			||||||
 | 
					            method: method,
 | 
				
			||||||
 | 
					            body: fd,
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					            .then(response => response.text())
 | 
				
			||||||
 | 
					            .then(data => resolve(data))
 | 
				
			||||||
 | 
					            .catch((error) => {
 | 
				
			||||||
 | 
					                console.error('Error: ', error);
 | 
				
			||||||
 | 
					                reject(error);
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										52
									
								
								js/spreadquiz.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								js/spreadquiz.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,52 @@
 | 
				
			|||||||
 | 
					function login() {
 | 
				
			||||||
 | 
					    let nicknameF = document.getElementById("nickname"); // fetch fields
 | 
				
			||||||
 | 
					    let pwF = document.getElementById("password");
 | 
				
			||||||
 | 
					    let nickname = nicknameF.value; // extract values
 | 
				
			||||||
 | 
					    let pw = pwF.value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let loginReq = {
 | 
				
			||||||
 | 
					        action: "login",
 | 
				
			||||||
 | 
					        nickname: nickname,
 | 
				
			||||||
 | 
					        password: pw
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    request(loginReq).then(resp => {
 | 
				
			||||||
 | 
					        if (resp === "OK") {
 | 
				
			||||||
 | 
					            location.href = "main.php"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function open_in_content_frame(url) {
 | 
				
			||||||
 | 
					    document.getElementById("content_frame").src = url;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var USERDATA = {};
 | 
				
			||||||
 | 
					function load_userdata() {
 | 
				
			||||||
 | 
					    let req = {action: "get_user_info"};
 | 
				
			||||||
 | 
					    request(req).then(resp => {
 | 
				
			||||||
 | 
					        USERDATA = JSON.parse(resp);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					load_userdata();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function create_table_cell(content, styleClass = "") {
 | 
				
			||||||
 | 
					    if (content.trim() === "") {
 | 
				
			||||||
 | 
					        content = "<i>(üres)</i>";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    let td = document.createElement("td");
 | 
				
			||||||
 | 
					    td.innerHTML = content;
 | 
				
			||||||
 | 
					    if (styleClass !== "") {
 | 
				
			||||||
 | 
					        td.classList.add(styleClass);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return td;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ---------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function highlight_row(nickname) {
 | 
				
			||||||
 | 
					    let hl_on = document.getElementById("user_chk_" + nickname).checked;
 | 
				
			||||||
 | 
					    let row = document.getElementById("row_" + nickname);
 | 
				
			||||||
 | 
					    row.setAttribute("highlight", hl_on ? "true" : "false");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										30
									
								
								js/testground.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								js/testground.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,30 @@
 | 
				
			|||||||
 | 
					function populate_test(test_id) {
 | 
				
			||||||
 | 
					    let test_display = document.getElementById("test_display");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let req = {
 | 
				
			||||||
 | 
					        action: "get_test",
 | 
				
			||||||
 | 
					        id: test_id
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    request(req).then(resp => {
 | 
				
			||||||
 | 
					        let test_data = JSON.parse(resp);
 | 
				
			||||||
 | 
					        test_data["challenges"].forEach((challenge) => {
 | 
				
			||||||
 | 
					            let challenge_box = document.createElement("section");
 | 
				
			||||||
 | 
					            challenge_box.classList.add("challenge");
 | 
				
			||||||
 | 
					            let question = document.createElement("span");
 | 
				
			||||||
 | 
					            question.classList.add("question");
 | 
				
			||||||
 | 
					            question.innerHTML = challenge["question"];
 | 
				
			||||||
 | 
					            let answer_container = document.createElement("section");
 | 
				
			||||||
 | 
					            answer_container.classList.add("answer-container");
 | 
				
			||||||
 | 
					            challenge_box.append(question, answer_container);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            challenge["answers"].forEach((answer) => {
 | 
				
			||||||
 | 
					                let answer_section = document.createElement("section");
 | 
				
			||||||
 | 
					                answer_section.classList.add("answer");
 | 
				
			||||||
 | 
					                answer_section.innerHTML = answer;
 | 
				
			||||||
 | 
					                answer_container.appendChild(answer_section);
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            test_display.appendChild(challenge_box);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										164
									
								
								js/usermgr.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										164
									
								
								js/usermgr.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,164 @@
 | 
				
			|||||||
 | 
					function list_all_users() {
 | 
				
			||||||
 | 
					    let tbody = document.getElementById("user_manager_table_body");
 | 
				
			||||||
 | 
					    tbody.innerHTML = "";
 | 
				
			||||||
 | 
					    let req = {action: "get_all_users"};
 | 
				
			||||||
 | 
					    request(req).then(resp => {
 | 
				
			||||||
 | 
					        let users = JSON.parse(resp);
 | 
				
			||||||
 | 
					        for (let i = 0; i < users.length; i++) {
 | 
				
			||||||
 | 
					            let u = users[i];
 | 
				
			||||||
 | 
					            let row = document.createElement("tr");
 | 
				
			||||||
 | 
					            let chkbox = document.createElement("input");
 | 
				
			||||||
 | 
					            chkbox.type = "checkbox";
 | 
				
			||||||
 | 
					            chkbox.name = "user_chkbox";
 | 
				
			||||||
 | 
					            chkbox.user = u;
 | 
				
			||||||
 | 
					            let tdChkBox = document.createElement("td");
 | 
				
			||||||
 | 
					            tdChkBox.appendChild(chkbox);
 | 
				
			||||||
 | 
					            tdChkBox.classList.add("checkbox");
 | 
				
			||||||
 | 
					            let tdNickName = create_table_cell(u["nickname"]);
 | 
				
			||||||
 | 
					            let tdRealName = create_table_cell(u["realname"]);
 | 
				
			||||||
 | 
					            let tdGroups = create_table_cell(u["groups"].join(", "));
 | 
				
			||||||
 | 
					            let tdPrivilege = create_table_cell(u["privilege"]);
 | 
				
			||||||
 | 
					            row.append(tdChkBox, tdNickName, tdRealName, tdGroups, tdPrivilege);
 | 
				
			||||||
 | 
					            tbody.appendChild(row);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            let edit_user_action = () => {
 | 
				
			||||||
 | 
					                if (get_selected_users().length === 0) {
 | 
				
			||||||
 | 
					                    edit_user(u);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            tdNickName.addEventListener("click", edit_user_action);
 | 
				
			||||||
 | 
					            tdRealName.addEventListener("click", edit_user_action);
 | 
				
			||||||
 | 
					            tdGroups.addEventListener("click", edit_user_action);
 | 
				
			||||||
 | 
					            tdPrivilege.addEventListener("click", edit_user_action)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function create_new_user() {
 | 
				
			||||||
 | 
					    const generateRandomString = () => {
 | 
				
			||||||
 | 
					        return Math.floor(Math.random() * Date.now()).toString(36);
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let nicknameF = document.getElementById("nickname");
 | 
				
			||||||
 | 
					    let realnameF = document.getElementById("realname");
 | 
				
			||||||
 | 
					    let passwordF = document.getElementById("password");
 | 
				
			||||||
 | 
					    let groupsF = document.getElementById("groups");
 | 
				
			||||||
 | 
					    let privilegeF = document.getElementById("privilege");
 | 
				
			||||||
 | 
					    let submit_btn = document.getElementById("user_editor_submit_btn");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    nicknameF.value = "";
 | 
				
			||||||
 | 
					    nicknameF.readOnly = false;
 | 
				
			||||||
 | 
					    realnameF.value = "";
 | 
				
			||||||
 | 
					    passwordF.type = "text";
 | 
				
			||||||
 | 
					    passwordF.value = generateRandomString();
 | 
				
			||||||
 | 
					    passwordF.readOnly = true;
 | 
				
			||||||
 | 
					    groupsF.value = "";
 | 
				
			||||||
 | 
					    submit_btn.value = "Létrehozás"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    submit_btn.onclick = () => {
 | 
				
			||||||
 | 
					        let nickname = nicknameF.value.trim();
 | 
				
			||||||
 | 
					        if (nickname !== "") {
 | 
				
			||||||
 | 
					            let req = {
 | 
				
			||||||
 | 
					                action: "create_user",
 | 
				
			||||||
 | 
					                nickname: nickname,
 | 
				
			||||||
 | 
					                realname: realnameF.value.trim(),
 | 
				
			||||||
 | 
					                password: passwordF.value,
 | 
				
			||||||
 | 
					                groups: groupsF.value.trim(),
 | 
				
			||||||
 | 
					                privilege: privilegeF.value
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					            request(req).then(resp => {
 | 
				
			||||||
 | 
					                list_all_users();
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					            hide("user_editor_window");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    show("user_editor_window");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function edit_user(user) {
 | 
				
			||||||
 | 
					    let nicknameF = document.getElementById("nickname");
 | 
				
			||||||
 | 
					    let realnameF = document.getElementById("realname");
 | 
				
			||||||
 | 
					    let passwordF = document.getElementById("password");
 | 
				
			||||||
 | 
					    let groupsF = document.getElementById("groups");
 | 
				
			||||||
 | 
					    let privilegeF = document.getElementById("privilege");
 | 
				
			||||||
 | 
					    let submit_btn = document.getElementById("user_editor_submit_btn");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    nicknameF.value = user["nickname"];
 | 
				
			||||||
 | 
					    nicknameF.readOnly = true;
 | 
				
			||||||
 | 
					    realnameF.value = user["realname"];
 | 
				
			||||||
 | 
					    passwordF.type = "password";
 | 
				
			||||||
 | 
					    passwordF.value = "";
 | 
				
			||||||
 | 
					    passwordF.readOnly = false;
 | 
				
			||||||
 | 
					    groupsF.value = user["groups"].join(", ");
 | 
				
			||||||
 | 
					    privilegeF.value = user["privilege"];
 | 
				
			||||||
 | 
					    submit_btn.value = "Mentés"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    submit_btn.onclick = () => {
 | 
				
			||||||
 | 
					        let nickname = nicknameF.value.trim();
 | 
				
			||||||
 | 
					        if (nickname !== "") {
 | 
				
			||||||
 | 
					            let req = {
 | 
				
			||||||
 | 
					                action: "update_user",
 | 
				
			||||||
 | 
					                nickname: nickname,
 | 
				
			||||||
 | 
					                realname: realnameF.value.trim(),
 | 
				
			||||||
 | 
					                password: passwordF.value,
 | 
				
			||||||
 | 
					                groups: groupsF.value.trim(),
 | 
				
			||||||
 | 
					                privilege: privilegeF.value
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					            request(req).then(resp => {
 | 
				
			||||||
 | 
					                list_all_users();
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					            hide("user_editor_window");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    show("user_editor_window");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function get_selected_users() {
 | 
				
			||||||
 | 
					    let selected_chkboxes = document.getElementsByName("user_chkbox");
 | 
				
			||||||
 | 
					    let selected_users = [];
 | 
				
			||||||
 | 
					    selected_chkboxes.forEach((chkbox) => {
 | 
				
			||||||
 | 
					        if (chkbox.checked) {
 | 
				
			||||||
 | 
					            selected_users.push(chkbox.user);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    return selected_users;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function delete_users() {
 | 
				
			||||||
 | 
					    let users = get_selected_users();
 | 
				
			||||||
 | 
					    if (users.length === 0) {
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    let user_nicknames = [];
 | 
				
			||||||
 | 
					    users.forEach((u) => {
 | 
				
			||||||
 | 
					        user_nicknames.push(u["nickname"]);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    let msg = "Biztosan törölni kívánja a következő felhasználó(ka)t?\n\n" + user_nicknames.join(", ") + "\n\n"
 | 
				
			||||||
 | 
					        + "A törlés nem vonható vissza!";
 | 
				
			||||||
 | 
					    if (confirm(msg)) {
 | 
				
			||||||
 | 
					        let req = {action: "delete_users", users: user_nicknames.join(",")};
 | 
				
			||||||
 | 
					        request(req).then(resp => {
 | 
				
			||||||
 | 
					            list_all_users();
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function hint_all_groups(target_element_id) {
 | 
				
			||||||
 | 
					    const hintbox_insert_fn = (record) => {
 | 
				
			||||||
 | 
					        let targetF = document.getElementById(target_element_id);
 | 
				
			||||||
 | 
					        let groups = explode_sanitize_string_list(targetF.value);
 | 
				
			||||||
 | 
					        groups.pop();
 | 
				
			||||||
 | 
					        groups.push(record);
 | 
				
			||||||
 | 
					        targetF.value = groups.join(", ");
 | 
				
			||||||
 | 
					        close_hintbox(true);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let req = {
 | 
				
			||||||
 | 
					        action: "search_groups",
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    open_hintbox_at(target_element_id, req, print_group_name, hintbox_insert_fn);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										24
									
								
								login.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								login.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,24 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					require_once "globals.php";
 | 
				
			||||||
 | 
					require_once "autologin.php";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (get_autologin_state()) {
 | 
				
			||||||
 | 
					    header("Location: " . MAIN_URL);
 | 
				
			||||||
 | 
					    exit();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					?>
 | 
				
			||||||
 | 
					<!DOCTYPE html>
 | 
				
			||||||
 | 
					<html>
 | 
				
			||||||
 | 
					<head>
 | 
				
			||||||
 | 
					    <meta charset="UTF-8">
 | 
				
			||||||
 | 
					    <title>SpreadQuiz :: Bejelentkezés</title>
 | 
				
			||||||
 | 
					    <script src="js/req.js"></script>
 | 
				
			||||||
 | 
					    <script src="js/spreadquiz.js"></script>
 | 
				
			||||||
 | 
					</head>
 | 
				
			||||||
 | 
					<body>
 | 
				
			||||||
 | 
					<input type="text" placeholder="Felhasználónév" id="nickname">
 | 
				
			||||||
 | 
					<input type="password" placeholder="Jelszó" id="password">
 | 
				
			||||||
 | 
					<input type="button" value="Belépés" onclick="login()">
 | 
				
			||||||
 | 
					</body>
 | 
				
			||||||
 | 
					</html>
 | 
				
			||||||
							
								
								
									
										50
									
								
								main.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								main.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,50 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					require_once "globals.php";
 | 
				
			||||||
 | 
					require_once "usermgr.php";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					require_once "autologin.php";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// if not logged in, then redirect to login page
 | 
				
			||||||
 | 
					$logged_in = get_autologin_state();
 | 
				
			||||||
 | 
					if (!$logged_in) {
 | 
				
			||||||
 | 
					    header("Location: " . LOGIN_URL);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$user_data = get_autologin_user_data();
 | 
				
			||||||
 | 
					$privilege = $user_data["privilege"];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					?>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<?php if ($logged_in) { ?>
 | 
				
			||||||
 | 
					    <!DOCTYPE html>
 | 
				
			||||||
 | 
					    <html>
 | 
				
			||||||
 | 
					    <head>
 | 
				
			||||||
 | 
					        <meta charset="UTF-8">
 | 
				
			||||||
 | 
					        <title>SpreadQuiz</title>
 | 
				
			||||||
 | 
					        <script src="js/req.js"></script>
 | 
				
			||||||
 | 
					        <script src="js/spreadquiz.js"></script>
 | 
				
			||||||
 | 
					        <link rel="stylesheet" href="style/spreadquiz.css"/>
 | 
				
			||||||
 | 
					    </head>
 | 
				
			||||||
 | 
					    <body>
 | 
				
			||||||
 | 
					    <section id="screen_panel">
 | 
				
			||||||
 | 
					        <section id="content_pane">
 | 
				
			||||||
 | 
					            <iframe id="content_frame" src="default_frame.php"></iframe>
 | 
				
			||||||
 | 
					        </section>
 | 
				
			||||||
 | 
					        <section id="info_pane">
 | 
				
			||||||
 | 
					            <section id="user_info" class="info-pane-element"><?= $user_data["nickname"]; ?></section>
 | 
				
			||||||
 | 
					            <?php if ($privilege != PRIVILEGE_PLAYER) { ?>
 | 
				
			||||||
 | 
					                <section id="action_panel" class="info-pane-element">
 | 
				
			||||||
 | 
					                    <?php if (($privilege === PRIVILEGE_CREATOR) || ($privilege === PRIVILEGE_QUIZMASTER)) { ?>
 | 
				
			||||||
 | 
					                        <input type="button" value="Tartalmak kezelése" onclick="open_in_content_frame('game_manager_frame.php')">
 | 
				
			||||||
 | 
					                    <?php } ?>
 | 
				
			||||||
 | 
					                    <?php if ($privilege === PRIVILEGE_QUIZMASTER) { ?>
 | 
				
			||||||
 | 
					                        <input type="button" value="Felhasználók kezelése" onclick="open_in_content_frame('user_manager_frame.php')">
 | 
				
			||||||
 | 
					                        <input type="button" value="Csoportok kezelése" onclick="open_in_content_frame('group_manager_frame.php')">
 | 
				
			||||||
 | 
					                    <?php } ?>
 | 
				
			||||||
 | 
					                </section>
 | 
				
			||||||
 | 
					            <?php } ?>
 | 
				
			||||||
 | 
					        </section>
 | 
				
			||||||
 | 
					    </section>
 | 
				
			||||||
 | 
					    </body>
 | 
				
			||||||
 | 
					    </html>
 | 
				
			||||||
 | 
					<?php } ?>
 | 
				
			||||||
							
								
								
									
										197
									
								
								style/spreadquiz.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										197
									
								
								style/spreadquiz.css
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,197 @@
 | 
				
			|||||||
 | 
					*[shown="false"] {
 | 
				
			||||||
 | 
					    visibility: hidden;
 | 
				
			||||||
 | 
					    display: none;
 | 
				
			||||||
 | 
					    opacity: 0;
 | 
				
			||||||
 | 
					    width: 0;
 | 
				
			||||||
 | 
					    height: 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					*[shown="true"] {
 | 
				
			||||||
 | 
					    opacity: 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* ----------------- */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					section#screen_panel {
 | 
				
			||||||
 | 
					    display: block;
 | 
				
			||||||
 | 
					    position: fixed;
 | 
				
			||||||
 | 
					    left: 0;
 | 
				
			||||||
 | 
					    right: 0;
 | 
				
			||||||
 | 
					    top: 0;
 | 
				
			||||||
 | 
					    bottom: 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					section#content_pane, section#info_pane {
 | 
				
			||||||
 | 
					    position: absolute;
 | 
				
			||||||
 | 
					    display: block;
 | 
				
			||||||
 | 
					    top: 0;
 | 
				
			||||||
 | 
					    bottom: 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					section#content_pane {
 | 
				
			||||||
 | 
					    left: 0;
 | 
				
			||||||
 | 
					    width: 80vw;
 | 
				
			||||||
 | 
					    background-color: lightcyan;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					section#info_pane {
 | 
				
			||||||
 | 
					    right: 0;
 | 
				
			||||||
 | 
					    width: 20vw;
 | 
				
			||||||
 | 
					    background-color: beige;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.info-pane-element {
 | 
				
			||||||
 | 
					    display: block;
 | 
				
			||||||
 | 
					    left: 0;
 | 
				
			||||||
 | 
					    right: 0;
 | 
				
			||||||
 | 
					    padding: 1em;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					section#user_info {
 | 
				
			||||||
 | 
					    position: relative;
 | 
				
			||||||
 | 
					    top: 0;
 | 
				
			||||||
 | 
					    background-color: aquamarine;
 | 
				
			||||||
 | 
					    font-size: 18pt;
 | 
				
			||||||
 | 
					    text-align: center;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					section#action_panel {
 | 
				
			||||||
 | 
					    background-color: antiquewhite;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					iframe#content_frame {
 | 
				
			||||||
 | 
					    display: block;
 | 
				
			||||||
 | 
					    width: 100%;
 | 
				
			||||||
 | 
					    height: 100%;
 | 
				
			||||||
 | 
					    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 {
 | 
				
			||||||
 | 
					    position: fixed;
 | 
				
			||||||
 | 
					    display: block;
 | 
				
			||||||
 | 
					    top: 0;
 | 
				
			||||||
 | 
					    right: 0;
 | 
				
			||||||
 | 
					    bottom: 0;
 | 
				
			||||||
 | 
					    left: 0;
 | 
				
			||||||
 | 
					    background-color: rgba(128, 128, 128, 0.7);
 | 
				
			||||||
 | 
					    padding: 4em;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					section.window-inner {
 | 
				
			||||||
 | 
					    margin: 0 auto;
 | 
				
			||||||
 | 
					    display: block;
 | 
				
			||||||
 | 
					    border: 2pt solid darkslategray;
 | 
				
			||||||
 | 
					    background-color: whitesmoke;
 | 
				
			||||||
 | 
					    padding: 1em;
 | 
				
			||||||
 | 
					    width: fit-content;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					td.checkbox {
 | 
				
			||||||
 | 
					    width: 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.hintbox-window {
 | 
				
			||||||
 | 
					    position: fixed;
 | 
				
			||||||
 | 
					    display: block;
 | 
				
			||||||
 | 
					    width: 15em;
 | 
				
			||||||
 | 
					    height: 8em;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* ----- */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					section#game_list_panel {
 | 
				
			||||||
 | 
					    display: block;
 | 
				
			||||||
 | 
					    position: absolute;
 | 
				
			||||||
 | 
					    left: 0;
 | 
				
			||||||
 | 
					    right: 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					section.group-box {
 | 
				
			||||||
 | 
					    margin: 1em;
 | 
				
			||||||
 | 
					    left: 0;
 | 
				
			||||||
 | 
					    right: 0;
 | 
				
			||||||
 | 
					    background-color: beige;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					span.group-box-caption {
 | 
				
			||||||
 | 
					    display: block;
 | 
				
			||||||
 | 
					    left: 0;
 | 
				
			||||||
 | 
					    right: 0;
 | 
				
			||||||
 | 
					    padding: 1em;
 | 
				
			||||||
 | 
					    background-color: chartreuse;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					section.group-box-inner {
 | 
				
			||||||
 | 
					    display: inline-table;
 | 
				
			||||||
 | 
					    padding: 1em;
 | 
				
			||||||
 | 
					    collapse: 1em;
 | 
				
			||||||
 | 
					    border-spacing: 1em;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					section.game-box {
 | 
				
			||||||
 | 
					    display: table-cell;
 | 
				
			||||||
 | 
					    width: 8em;
 | 
				
			||||||
 | 
					    height: 8em;
 | 
				
			||||||
 | 
					    border: 2pt dashed gray;
 | 
				
			||||||
 | 
					    text-align: center;
 | 
				
			||||||
 | 
					    vertical-align: middle;
 | 
				
			||||||
 | 
					    cursor: pointer;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					section#test_area {
 | 
				
			||||||
 | 
					    display: block;
 | 
				
			||||||
 | 
					    position: absolute;
 | 
				
			||||||
 | 
					    left: 0;
 | 
				
			||||||
 | 
					    right: 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					section.challenge {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					span.question {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					section.answer-container {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					section.answer {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										31
									
								
								testground.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								testground.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,31 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					require_once "globals.php";
 | 
				
			||||||
 | 
					require_once "autologin.php";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$user_data = get_autologin_user_data();
 | 
				
			||||||
 | 
					if (!get_autologin_state() || !isset($_REQUEST["testid"])) {
 | 
				
			||||||
 | 
					    exit();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$testid = $_REQUEST["testid"];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					?>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<!DOCTYPE html>
 | 
				
			||||||
 | 
					<html>
 | 
				
			||||||
 | 
					<head>
 | 
				
			||||||
 | 
					    <meta charset="UTF-8">
 | 
				
			||||||
 | 
					    <title>SpreadQuiz</title>
 | 
				
			||||||
 | 
					    <script src="js/spreadquiz.js"></script>
 | 
				
			||||||
 | 
					    <script src="js/req.js"></script>
 | 
				
			||||||
 | 
					    <script src="js/o.js"></script>
 | 
				
			||||||
 | 
					    <script src="js/testground.js"></script>
 | 
				
			||||||
 | 
					    <link rel="stylesheet" href="style/spreadquiz.css">
 | 
				
			||||||
 | 
					</head>
 | 
				
			||||||
 | 
					<body>
 | 
				
			||||||
 | 
					    <section id="test_display">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    </section>
 | 
				
			||||||
 | 
					</body>
 | 
				
			||||||
 | 
					</html>
 | 
				
			||||||
							
								
								
									
										93
									
								
								testmgr.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								testmgr.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,93 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					require_once "globals.php";
 | 
				
			||||||
 | 
					require_once "common_func.php";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					require_once "gamemgr.php";
 | 
				
			||||||
 | 
					require_once "usermgr.php";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$testdb = new \SleekDB\Store(TESTDB, DATADIR, ["timeout" => false]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const TEST_ONGOING = "ongoing";
 | 
				
			||||||
 | 
					const TEST_CONCLUDED = "concluded";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function create_or_continue_test(string $gameid, string $nickname): string
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    global $testdb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // get game and user data
 | 
				
			||||||
 | 
					    $game_data = get_game($gameid);
 | 
				
			||||||
 | 
					    $user_data = get_user($nickname);
 | 
				
			||||||
 | 
					    if ((count($game_data) === 0) || (count($user_data) === 0)) {
 | 
				
			||||||
 | 
					        return "";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // check if this user has permission to take this test
 | 
				
			||||||
 | 
					    // if the intersection of user's groups and game's assigned groups is zero, then the user has no access to this game
 | 
				
			||||||
 | 
					    if (count(array_intersect($game_data["groups"], $user_data["groups"])) === 0) {
 | 
				
			||||||
 | 
					        return "";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // check if the user had taken this test before
 | 
				
			||||||
 | 
					    $fetch_criteria = [["gameid", "=", $gameid], "AND", ["nickname", "=", $nickname]];
 | 
				
			||||||
 | 
					    $previous_tests = $testdb->findBy($fetch_criteria);
 | 
				
			||||||
 | 
					    if (count($previous_tests) > 0) { // if there are previous attempts, then...
 | 
				
			||||||
 | 
					        // update timed tests to see if they had expired
 | 
				
			||||||
 | 
					        update_timed_tests($previous_tests);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // re-fetch tests, look only for ongoing
 | 
				
			||||||
 | 
					        $ongoing_tests = $testdb->findBy([$fetch_criteria, "AND", ["state", "=", TEST_ONGOING]]);
 | 
				
			||||||
 | 
					        if (count($ongoing_tests) !== 0) { // if there's an ongoing test
 | 
				
			||||||
 | 
					            return $ongoing_tests[0]["_id"];
 | 
				
			||||||
 | 
					        } else { // there's no ongoing test
 | 
				
			||||||
 | 
					            if ($game_data["properties"]["repeatable"]) { // test is repeatable...
 | 
				
			||||||
 | 
					                return create_test($game_data, $user_data);
 | 
				
			||||||
 | 
					            } else { // test is non-repeatable, cannot be attempted more times
 | 
				
			||||||
 | 
					                return "";
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    } else { // there were no previous attempts
 | 
				
			||||||
 | 
					        return create_test($game_data, $user_data);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function create_test(array $game_data, array $user_data) : string
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    $gameid = $game_data["_id"];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // fill basic data
 | 
				
			||||||
 | 
					    $game_data = [
 | 
				
			||||||
 | 
					        "gameid" => $gameid,
 | 
				
			||||||
 | 
					        "nickname" => $user_data["nickname"],
 | 
				
			||||||
 | 
					    ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // fill challenges
 | 
				
			||||||
 | 
					    $challenges = load_challenges($gameid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // shuffle answers
 | 
				
			||||||
 | 
					    foreach ($challenges as &$ch) {
 | 
				
			||||||
 | 
					        shuffle($ch["answers"]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $game_data["challenges"] = $challenges;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // involve properties
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function update_timed_tests(array $test_data_array)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    $now = time();
 | 
				
			||||||
 | 
					    foreach ($test_data_array as $test_data) {
 | 
				
			||||||
 | 
					        // look for unprocessed expired tests
 | 
				
			||||||
 | 
					        if (($test_data["state"] === TEST_ONGOING) && ($test_data["end_limit_time"] < $now)) {
 | 
				
			||||||
 | 
					            $test_data["state"] = TEST_CONCLUDED;
 | 
				
			||||||
 | 
					            update_test($test_data);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function update_test(array $test_data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    global $testdb;
 | 
				
			||||||
 | 
					    $testdb->update($test_data);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										104
									
								
								user_manager_frame.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								user_manager_frame.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,104 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					require_once "globals.php";
 | 
				
			||||||
 | 
					require_once "autologin.php";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$user_data = get_autologin_user_data();
 | 
				
			||||||
 | 
					if (!get_autologin_state() || ($user_data["privilege"] !== PRIVILEGE_QUIZMASTER)) {
 | 
				
			||||||
 | 
					    exit(); // this page is only available for quizmasters
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					?>
 | 
				
			||||||
 | 
					<!DOCTYPE html>
 | 
				
			||||||
 | 
					<html>
 | 
				
			||||||
 | 
					<head>
 | 
				
			||||||
 | 
					    <meta charset="UTF-8">
 | 
				
			||||||
 | 
					    <title>SpreadQuiz</title>
 | 
				
			||||||
 | 
					    <script src="js/req.js"></script>
 | 
				
			||||||
 | 
					    <script src="js/spreadquiz.js"></script>
 | 
				
			||||||
 | 
					    <script src="js/o.js"></script>
 | 
				
			||||||
 | 
					    <script src="js/groupmgr.js"></script>
 | 
				
			||||||
 | 
					    <script src="js/hintbox.js"></script>
 | 
				
			||||||
 | 
					    <script src="js/usermgr.js"></script>
 | 
				
			||||||
 | 
					    <link rel="stylesheet" href="style/spreadquiz.css"/>
 | 
				
			||||||
 | 
					</head>
 | 
				
			||||||
 | 
					<body>
 | 
				
			||||||
 | 
					<section id="table_section">
 | 
				
			||||||
 | 
					    <table id="user_manager_table" class="management">
 | 
				
			||||||
 | 
					        <thead>
 | 
				
			||||||
 | 
					        <tr>
 | 
				
			||||||
 | 
					            <th></th>
 | 
				
			||||||
 | 
					            <th>Felhasználónév</th>
 | 
				
			||||||
 | 
					            <th>Név</th>
 | 
				
			||||||
 | 
					            <th>Csoportok</th>
 | 
				
			||||||
 | 
					            <th>Jogosultság</th>
 | 
				
			||||||
 | 
					        </tr>
 | 
				
			||||||
 | 
					        </thead>
 | 
				
			||||||
 | 
					        <tbody id="user_manager_table_body">
 | 
				
			||||||
 | 
					        <!--        --><?php
 | 
				
			||||||
 | 
					        //        function create_cell(string $content, string $class = "")
 | 
				
			||||||
 | 
					        //        {
 | 
				
			||||||
 | 
					        //            if (trim($content) === "") {
 | 
				
			||||||
 | 
					        //                $content = "<i>(üres)</i>";
 | 
				
			||||||
 | 
					        //            }
 | 
				
			||||||
 | 
					        //            return "<td class='$class'>$content</td>";
 | 
				
			||||||
 | 
					        //        }
 | 
				
			||||||
 | 
					        //
 | 
				
			||||||
 | 
					        //        function create_table_row(array $keys, array $record)
 | 
				
			||||||
 | 
					        //        {
 | 
				
			||||||
 | 
					        //            $tr = "<tr>";
 | 
				
			||||||
 | 
					        //            foreach ($keys as $k) {
 | 
				
			||||||
 | 
					        //                $tr .= "<td>${record[$k]}</td>";
 | 
				
			||||||
 | 
					        //            }
 | 
				
			||||||
 | 
					        //            $tr .= "</tr>";
 | 
				
			||||||
 | 
					        //            return $tr;
 | 
				
			||||||
 | 
					        //        }
 | 
				
			||||||
 | 
					        //
 | 
				
			||||||
 | 
					        //        $users = get_all_users();
 | 
				
			||||||
 | 
					        //        foreach ($users as $u) {
 | 
				
			||||||
 | 
					        //            $nickname = $u["nickname"];
 | 
				
			||||||
 | 
					        //            $tr = "<tr id='row_$nickname'>";
 | 
				
			||||||
 | 
					        //            $tr .= create_cell("<input type='checkbox' id='user_chk_$nickname' onchange='highlight_row(\"$nickname\")'>", "checkbox");
 | 
				
			||||||
 | 
					        //            $tr .= create_cell($u["nickname"]);
 | 
				
			||||||
 | 
					        //            $tr .= create_cell($u["realname"]);
 | 
				
			||||||
 | 
					        //            $tr .= create_cell(implode(",", $u["groups"]));
 | 
				
			||||||
 | 
					        //            $tr .= create_cell($u["privilege"]);
 | 
				
			||||||
 | 
					        //            $tr .= "</tr>";
 | 
				
			||||||
 | 
					        //            echo $tr;
 | 
				
			||||||
 | 
					        //        }
 | 
				
			||||||
 | 
					        //        ?>
 | 
				
			||||||
 | 
					        </tbody>
 | 
				
			||||||
 | 
					    </table>
 | 
				
			||||||
 | 
					</section>
 | 
				
			||||||
 | 
					<section>
 | 
				
			||||||
 | 
					    <input type="button" value="Új felhasználó" onclick="create_new_user()">
 | 
				
			||||||
 | 
					    <input type="button" value="Felhasználó(k) törlése" onclick="delete_users()">
 | 
				
			||||||
 | 
					    <input type="button" value="Felhasználók importálása CSV-ből">
 | 
				
			||||||
 | 
					</section>
 | 
				
			||||||
 | 
					<section class="window" shown="false" id="user_editor_window">
 | 
				
			||||||
 | 
					    <section class="window-inner">
 | 
				
			||||||
 | 
					        <section style="text-align: right">
 | 
				
			||||||
 | 
					            <span>Felhasználónév: <input type="text" id="nickname"></span><br>
 | 
				
			||||||
 | 
					            <span>Teljes név: <input type="text" id="realname"></span><br>
 | 
				
			||||||
 | 
					            <span>Jelszó: <input type="text" id="password" readonly></span><br>
 | 
				
			||||||
 | 
					            <span>Csoportok: <input type="text" id="groups" oninput="hint_all_groups('groups')" onblur="close_hintbox()"></span><br>
 | 
				
			||||||
 | 
					            <span>Jogosultság:
 | 
				
			||||||
 | 
					                <select id="privilege">
 | 
				
			||||||
 | 
					                    <option value="player">játékos</option>
 | 
				
			||||||
 | 
					                    <option value="creator">szerkesztő</option>
 | 
				
			||||||
 | 
					                    <option value="admin">kvízmester</option>
 | 
				
			||||||
 | 
					                </select>
 | 
				
			||||||
 | 
					            </span>
 | 
				
			||||||
 | 
					        </section>
 | 
				
			||||||
 | 
					        <span><input type="button" value="" id="user_editor_submit_btn"><input type="button" value="Mégse" onclick="hide('user_editor_window')"></span>
 | 
				
			||||||
 | 
					    </section>
 | 
				
			||||||
 | 
					</section>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script>
 | 
				
			||||||
 | 
					    list_all_users();
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					</body>
 | 
				
			||||||
 | 
					</html>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										113
									
								
								usermgr.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										113
									
								
								usermgr.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,113 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					require_once "globals.php";
 | 
				
			||||||
 | 
					require_once "common_func.php";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$userdb = new \SleekDB\Store(USERDB, DATADIR, ["timeout" => false]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const PRIVILEGE_PLAYER = "player";
 | 
				
			||||||
 | 
					const PRIVILEGE_CREATOR = "creator";
 | 
				
			||||||
 | 
					const PRIVILEGE_QUIZMASTER = "admin"; // TODO: refactor!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function add_user(string $nickname, string $password, string $realname, array $groups = [], string $privilege = PRIVILEGE_PLAYER): bool
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    global $userdb;
 | 
				
			||||||
 | 
					    if (count(get_user($nickname)) != 0) { // user exists
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $user_data = [
 | 
				
			||||||
 | 
					        "nickname" => $nickname,
 | 
				
			||||||
 | 
					        "password" => password_hash($password, PASSWORD_DEFAULT),
 | 
				
			||||||
 | 
					        "realname" => $realname,
 | 
				
			||||||
 | 
					        "groups" => $groups,
 | 
				
			||||||
 | 
					        "privilege" => $privilege
 | 
				
			||||||
 | 
					    ];
 | 
				
			||||||
 | 
					    $userdb->insert($user_data);
 | 
				
			||||||
 | 
					    return true; // user registration successful
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function delete_user(string $nickname)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    global $userdb;
 | 
				
			||||||
 | 
					    if ($nickname == QUIZMASTER_NICKNAME) {
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $user_data = get_user($nickname);
 | 
				
			||||||
 | 
					    if (count($user_data) !== 0) {
 | 
				
			||||||
 | 
					        foreach ($user_data["groups"] as $groupid) {
 | 
				
			||||||
 | 
					            change_group_user_assignments($groupid, null, $nickname);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $userdb->deleteBy(["nickname", "=", $nickname]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function get_user(string $nickname): array
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    global $userdb;
 | 
				
			||||||
 | 
					    $user_data_array = $userdb->findBy(["nickname", "=", $nickname]);
 | 
				
			||||||
 | 
					    return count($user_data_array) != 0 ? $user_data_array[0] : [];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function update_user(array $user_data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    global $userdb;
 | 
				
			||||||
 | 
					    return $userdb->update($user_data);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function change_password(string $nickname, string $old, string $new): bool
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    $user_data = get_user($nickname);
 | 
				
			||||||
 | 
					    if (count($user_data) != 0) {
 | 
				
			||||||
 | 
					        if (password_verify($old, $user_data["password"])) {
 | 
				
			||||||
 | 
					            $user_data["password"] = password_hash($new, PASSWORD_DEFAULT);
 | 
				
			||||||
 | 
					            update_user($user_data);
 | 
				
			||||||
 | 
					            return true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function change_user_group_assignments(string $nickname, $groupname_add, $groupname_remove)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    $user_data = get_user($nickname);
 | 
				
			||||||
 | 
					    if (count($user_data) != 0) {
 | 
				
			||||||
 | 
					        alter_array_contents($user_data["groups"], $groupname_add, $groupname_remove);
 | 
				
			||||||
 | 
					        update_user($user_data); // update user
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function change_privilege_level(string $nickname, string $privilege)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    $user_data = get_user($nickname);
 | 
				
			||||||
 | 
					    if (count($user_data) != 0) {
 | 
				
			||||||
 | 
					        $user_data["privilege"] = $privilege;
 | 
				
			||||||
 | 
					        update_user($user_data);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function check_user_credentials(string $nickname, string $password): bool
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    $user_data = get_user($nickname);
 | 
				
			||||||
 | 
					    if (count($user_data) != 0) {
 | 
				
			||||||
 | 
					        return password_verify($password, $user_data["password"]);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function get_all_users(): array
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    global $userdb;
 | 
				
			||||||
 | 
					    return $userdb->findAll();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function get_all_nicknames() : array {
 | 
				
			||||||
 | 
					    $nicknames = [];
 | 
				
			||||||
 | 
					    $user_data_array = get_all_users();
 | 
				
			||||||
 | 
					    foreach ($user_data_array as $user_data) {
 | 
				
			||||||
 | 
					        $nicknames[] = $user_data["nickname"];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return $nicknames;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user