- human readable to unix timestamp conversion in clion code added

- test-related request block redesigned
- elvis operator replaced with the more adequate null coalescing one
This commit is contained in:
Wiesner András 2024-09-12 14:35:36 +02:00
parent 68b9310069
commit 59e113333a
9 changed files with 129 additions and 84 deletions

View File

@ -90,7 +90,7 @@ function get_all_games()
function patch_up_game_data(array &$game_data) function patch_up_game_data(array &$game_data)
{ {
$game_version = $game_data["version"] ?: 0; $game_version = $game_data["version"] ?? 0;
if ($game_version < 2) { // update to game version 2 if ($game_version < 2) { // update to game version 2
if (!key_exists("public_id", $game_data)) { if (!key_exists("public_id", $game_data)) {
$game_data["public"] = false; $game_data["public"] = false;

View File

@ -15,6 +15,8 @@ const LOGIN_URL = "login.php";
const MAIN_URL = "main.php"; const MAIN_URL = "main.php";
const SESSION_NAME = "spreadquiz_sid"; const SESSION_NAME = "spreadquiz_sid";
const MISSING_IMAGE_PLACEHOLDER = "media/image-missing_120px.png";
session_name(SESSION_NAME); session_name(SESSION_NAME);
// autoload session // autoload session

View File

@ -63,7 +63,7 @@ function change_group_user_assignments(string $groupid, $nickname_add, $nickname
if (count($group_data) != 0) { if (count($group_data) != 0) {
// --------- UPDATE group assignments (DEV ONLY!)------ // --------- UPDATE group assignments (DEV ONLY!)------
$group_data["editors"] = $group_data["editors"] ?: []; $group_data["editors"] = $group_data["editors"] ?? [];
// --------- // ---------

View File

@ -22,7 +22,6 @@ require_once "testmgr.php";
require_once "controller.php"; require_once "controller.php";
const MISSING_IMAGE_PLACEHOLDER = "media/image-missing_120px.png";
function patch_through_image(string $gameid, string $img_url) function patch_through_image(string $gameid, string $img_url)
{ {
$game_dir = get_game_dir_by_gameid($gameid); $game_dir = get_game_dir_by_gameid($gameid);
@ -105,14 +104,14 @@ switch ($action) {
break; break;
case "start_or_continue_test": case "start_or_continue_test":
{ {
$gameid = trim($_REQUEST["gameid"] ?: ""); $gameid = trim($_REQUEST["gameid"] ?? "");
$testid = create_or_continue_test($gameid, $nickname); $testid = create_or_continue_test($gameid, $nickname);
$result = $testid; $result = $testid;
} }
break; break;
case "get_results_overview": case "get_results_overview":
{ {
$gameid = trim($_REQUEST["gameid"] ?: ""); $gameid = trim($_REQUEST["gameid"] ?? "");
$concluded_tests = get_concluded_tests($gameid, $nickname); $concluded_tests = get_concluded_tests($gameid, $nickname);
$overviews = []; $overviews = [];
foreach ($concluded_tests as $ct) { foreach ($concluded_tests as $ct) {
@ -130,8 +129,12 @@ switch ($action) {
} }
// test-related queries // test-related queries
$is_a_default_test_with_access = isset($_REQUEST["testid"]) && (($testid = trim($_REQUEST["testid"])) !== "") && const TEST_RELATED_ACTIONS = ["get_test", "save_answer", "submit_test"];
((count($test_data = get_test($testid))) > 0) && (($test_data["nickname"] === $nickname)); if (in_array($action, TEST_RELATED_ACTIONS)) {
$testid = trim($_REQUEST["testid"] ?? "");
$test_data = ($testid !== "") ? get_test($testid) : [];
$is_a_default_test_with_access = ($testid !== "") && ((count($test_data)) > 0) && (($test_data["nickname"] === $nickname));
$user_is_contributor_or_quizmaster = $is_quizmaster || is_user_contributor_to_game($test_data["gameid"], $nickname); $user_is_contributor_or_quizmaster = $is_quizmaster || is_user_contributor_to_game($test_data["gameid"], $nickname);
@ -168,14 +171,16 @@ if ($is_a_default_test_with_access || $user_is_contributor_or_quizmaster) {
// get_image needs special treatment // get_image needs special treatment
if ($action === "get_image") { if ($action === "get_image") {
if ($is_a_default_test_with_access || $user_is_contributor_or_quizmaster) { // default case if ($is_a_default_test_with_access || $user_is_contributor_or_quizmaster) { // default case
$img_url = trim($_REQUEST["img_url"] ?: ""); $img_url = trim($_REQUEST["img_url"] ?? "");
if ($img_url !== "") { if ($img_url !== "") {
$gameid = $test_data["gameid"]; $gameid = $_REQUEST["gameid"];
patch_through_image($gameid, $img_url); patch_through_image($gameid, $img_url);
} }
} }
} }
}
// creator or quizmaster actions // creator or quizmaster actions
if (($privilege !== PRIVILEGE_CREATOR) && ($privilege !== PRIVILEGE_QUIZMASTER)) { if (($privilege !== PRIVILEGE_CREATOR) && ($privilege !== PRIVILEGE_QUIZMASTER)) {
goto print_result; goto print_result;
@ -188,17 +193,17 @@ switch ($action) {
case "update_game": case "update_game":
{ {
$update = $action === "update_game"; $update = $action === "update_game";
$data = json_decode($_REQUEST["data"], true) ?: []; $data = json_decode($_REQUEST["data"], true) ?? [];
if (($data === []) || (trim($data["name"] ?: "") === "")) { // no further processing if (($data === []) || (trim($data["name"] ?? "") === "")) { // no further processing
goto print_result; // ~exit... goto print_result; // ~exit...
} }
$gameid = $data["_id"]; $gameid = $data["_id"];
$name = $data["name"]; $name = $data["name"];
$description = $data["description"]; $description = $data["description"];
$contributors = explode_list($data["contributors"] ?: ""); $contributors = explode_list($data["contributors"] ?? "");
$owner = $update ? trim($data["owner"] ?: $nickname) : $nickname; $owner = $update ? trim($data["owner"] ?? $nickname) : $nickname;
$groups = explode_list($data["groups"] ?: ""); $groups = explode_list($data["groups"] ?? "");
$properties = $data["properties"] ?: []; $properties = $data["properties"] ?? [];
$groupids = get_groupids_by_compounds($groups); // convert group compounds to _ids $groupids = get_groupids_by_compounds($groups); // convert group compounds to _ids
@ -277,7 +282,7 @@ switch ($action) {
$zip->extractTo($game_dir . DIRECTORY_SEPARATOR); $zip->extractTo($game_dir . DIRECTORY_SEPARATOR);
// search for the CSV table file // search for the CSV table file
$csv_files = glob($game_dir . DIRECTORY_SEPARATOR . "*.csv") ?: []; $csv_files = glob($game_dir . DIRECTORY_SEPARATOR . "*.csv") ?? [];
if (count($csv_files)) { if (count($csv_files)) {
$challenge_import_status = import_challenges_from_csv($csv_files[0], $gameid); $challenge_import_status = import_challenges_from_csv($csv_files[0], $gameid);
} }
@ -302,7 +307,7 @@ switch ($action) {
break; break;
case "get_challenges": case "get_challenges":
{ {
$gameid = ($_REQUEST["gameid"] ?: ""); $gameid = ($_REQUEST["gameid"] ?? "");
$game_data = get_game($gameid); $game_data = get_game($gameid);
if ((count($game_data) > 0) && ($is_quizmaster || (is_user_contributor_to_game($gameid, $requester_nickname)))) { if ((count($game_data) > 0) && ($is_quizmaster || (is_user_contributor_to_game($gameid, $requester_nickname)))) {
$result = file_get_contents(get_game_file_by_gameid($gameid)); $result = file_get_contents(get_game_file_by_gameid($gameid));
@ -311,7 +316,7 @@ switch ($action) {
break; break;
case "delete_games": case "delete_games":
{ {
$gameids = explode_list(trim($_REQUEST["ids"] ?: "")); $gameids = explode_list(trim($_REQUEST["ids"] ?? ""));
foreach ($gameids as $gameid) { foreach ($gameids as $gameid) {
if (($gameid !== "") && (is_user_owner_of_the_game($gameid, $nickname))) { // only the owner may delete a game if (($gameid !== "") && (is_user_owner_of_the_game($gameid, $nickname))) { // only the owner may delete a game
delete_game($gameid); delete_game($gameid);
@ -321,7 +326,7 @@ switch ($action) {
break; break;
case "export_game_file_csv": case "export_game_file_csv":
{ {
$gameid = trim($_REQUEST["gameid"] ?: ""); $gameid = trim($_REQUEST["gameid"] ?? "");
if (($gameid !== "") && is_user_contributor_to_game($gameid, $nickname)) { if (($gameid !== "") && is_user_contributor_to_game($gameid, $nickname)) {
$f = tmpfile(); $f = tmpfile();
header("Content-Type: text/csv"); header("Content-Type: text/csv");
@ -334,9 +339,9 @@ switch ($action) {
break; break;
case "get_results_by_gameid": case "get_results_by_gameid":
{ {
$gameid = trim($_REQUEST["gameid"] ?: ""); $gameid = trim($_REQUEST["gameid"] ?? "");
$filter = trim($_REQUEST["filter"] ?: ""); $filter = trim($_REQUEST["filter"] ?? "");
$ordering = trim($_REQUEST["orderby"] ?: ""); $ordering = trim($_REQUEST["orderby"] ?? "");
if (($gameid !== "") && (is_user_contributor_to_game($gameid, $nickname) || $is_quizmaster)) { if (($gameid !== "") && (is_user_contributor_to_game($gameid, $nickname) || $is_quizmaster)) {
$game_results = get_results_by_gameid($gameid, $filter, $ordering, true); $game_results = get_results_by_gameid($gameid, $filter, $ordering, true);
$result = json_encode($game_results); $result = json_encode($game_results);
@ -345,20 +350,20 @@ switch ($action) {
break; break;
case "generate_detailed_stats": case "generate_detailed_stats":
{ {
$testids = json_decode(trim($_REQUEST["testids"] ?: "[]"), true); $testids = json_decode(trim($_REQUEST["testids"] ?? "[]"), true);
$gameid = trim($_REQUEST["gameid"] ?: ""); $gameid = trim($_REQUEST["gameid"] ?? "");
$stats = generate_detailed_stats($gameid, $testids); $stats = generate_detailed_stats($gameid, $testids);
$result = json_encode($stats); $result = json_encode($stats);
} }
break; break;
case "get_image": // case "get_image":
{ // {
$gameid = trim($_REQUEST["gameid"] ?: ""); // $gameid = trim($_REQUEST["gameid"] ?? "");
$img_url = trim($_REQUEST["img_url"] ?: ""); // $img_url = trim($_REQUEST["img_url"] ?? "");
patch_through_image($gameid, $img_url); // patch_through_image($gameid, $img_url);
} // }
break; // break;
} }
// quizmaster actions // quizmaster actions
@ -371,9 +376,9 @@ switch ($action) {
case "update_group": case "update_group":
{ {
$update = $action === "update_group"; $update = $action === "update_group";
$groupname = trim($_REQUEST["groupname"] ?: ""); $groupname = trim($_REQUEST["groupname"] ?? "");
$description = trim($_REQUEST["description"] ?: ""); $description = trim($_REQUEST["description"] ?? "");
$editors = explode_list(trim($_REQUEST["editors"] ?: "")); $editors = explode_list(trim($_REQUEST["editors"] ?? ""));
$owner = (!$update) ? $user_data["nickname"] : trim($_REQUEST["owner"]); $owner = (!$update) ? $user_data["nickname"] : trim($_REQUEST["owner"]);
if ($owner === "") { if ($owner === "") {
$owner = $user_data["nickname"]; $owner = $user_data["nickname"];
@ -404,7 +409,7 @@ switch ($action) {
break; break;
case "delete_groups": case "delete_groups":
{ {
$groups = explode_list($_REQUEST["ids"] ?: ""); $groups = explode_list($_REQUEST["ids"] ?? "");
foreach ($groups as $g) { foreach ($groups as $g) {
delete_group($g); delete_group($g);
} }
@ -415,7 +420,7 @@ switch ($action) {
break; break;
case "search_groups": case "search_groups":
{ {
$needle = $_REQUEST["needle"] ?: ""; $needle = $_REQUEST["needle"] ?? "";
$result = json_encode(search_groups($needle)); $result = json_encode(search_groups($needle));
} }
break; break;
@ -423,11 +428,11 @@ switch ($action) {
case "update_user": case "update_user":
{ {
$update = $action === "update_user"; $update = $action === "update_user";
$target_nickname = trim($_REQUEST["nickname"] ?: ""); $target_nickname = trim($_REQUEST["nickname"] ?? "");
$password = trim($_REQUEST["password"] ?: ""); $password = trim($_REQUEST["password"] ?? "");
$groups = explode_list($_REQUEST["groups"] ?: ""); $groups = explode_list($_REQUEST["groups"] ?? "");
$realname = trim($_REQUEST["realname"] ?: ""); $realname = trim($_REQUEST["realname"] ?? "");
$privilege = trim($_REQUEST["privilege"] ?: PRIVILEGE_PLAYER); $privilege = trim($_REQUEST["privilege"] ?? PRIVILEGE_PLAYER);
$groupids = get_groupids_by_compounds($groups); // convert group compounds to _ids $groupids = get_groupids_by_compounds($groups); // convert group compounds to _ids
@ -469,7 +474,7 @@ switch ($action) {
break; break;
case "delete_users": case "delete_users":
{ {
$users = explode_list($_REQUEST["users"] ?: ""); $users = explode_list($_REQUEST["users"] ?? "");
foreach ($users as $g) { foreach ($users as $g) {
delete_user($g); delete_user($g);
} }

View File

@ -1,7 +1,11 @@
function unix_time_to_human_readable(tunix, date_delim = ". ") { function unix_time_to_human_readable(tunix) {
const date = new Date(Number(tunix) * 1000); const date = new Date(Number(tunix) * 1000);
return date.getFullYear() + date_delim + String(date.getMonth() + 1).padStart(2, "0") + date_delim + String(date.getDate()).padStart(2, "0") + ". " return date.getFullYear() + "-" + String(date.getMonth() + 1).padStart(2, "0") + "-" + String(date.getDate()).padStart(2, "0") + " " +
+ String(date.getHours()).padStart(2, "0") + ":" + String(date.getMinutes()).padStart(2, "0") + ":" + String(date.getSeconds()).padStart(2, "0"); String(date.getHours()).padStart(2, "0") + ":" + String(date.getMinutes()).padStart(2, "0") + ":" + String(date.getSeconds()).padStart(2, "0");
}
function human_readable_to_unix_time(hrtime) {
return (new Date(hrtime)).getTime() / 1000;
} }
function seconds_to_time(s) { function seconds_to_time(s) {

View File

@ -4,15 +4,46 @@ function create_cell(content = "") {
return cell; return cell;
} }
function autoconvert_datetime(str) {
// preprocess time fields in filter string
const dateTimeRE = /([0-9]{4}-[0-1][0-9]-[0-3][0-9] [0-2][0-9]:[0-5][0-9]:[0-5][0-9])/;
let filterParts = str.split(dateTimeRE);
// First, process full datetime entries
// datetime values will be at the odd indices
for (let i = 1; i < filterParts.length; i += 2) {
filterParts[i] = human_readable_to_unix_time(filterParts[i]);
}
// join the surrounding and converted parts
let filter = filterParts.join("");
// Now, process the only date parts
const dateRE = /([0-9]{4}-[0-1][0-9]-[0-3][0-9])/;
filterParts = filter.split(dateRE);
for (let i = 1; i < filterParts.length; i += 2) {
filterParts[i] = human_readable_to_unix_time(filterParts[i] + " 00:00:00");
}
filter = filterParts.join("");
return filter;
}
function fetch_results() { function fetch_results() {
let filterF = document.getElementById("filter"); let filterF = document.getElementById("filter");
let orderbyF = document.getElementById("orderby"); let orderbyF = document.getElementById("orderby");
let filter = autoconvert_datetime(filterF.value.trim());
// ----------
let req = { let req = {
action: "get_results_by_gameid", action: "get_results_by_gameid",
gameid: GAMEID, gameid: GAMEID,
filter: filterF.value.trim(), filter: filter.trim(),
orderby: orderbyF.value.trim() orderby: orderbyF.value.trim()
}; };

View File

@ -36,6 +36,11 @@ if (!is_user_contributor_to_game($game_id, $user_data["nickname"]) && ($user_dat
<script src="js/result_analyzer.js"></script> <script src="js/result_analyzer.js"></script>
<link rel="stylesheet" href="style/spreadquiz.css"> <link rel="stylesheet" href="style/spreadquiz.css">
<link rel="stylesheet" href="style/quizmaster_area.css"/> <link rel="stylesheet" href="style/quizmaster_area.css"/>
<style>
tbody#results_display > tr {
cursor: auto;
}
</style>
</head> </head>
<body> <body>

View File

@ -8,9 +8,9 @@ if (!get_autologin_state() || !isset($_REQUEST["testid"])) {
exit(); exit();
} }
$testid = trim($_REQUEST["testid"] ?: ""); $testid = trim($_REQUEST["testid"] ?? "");
$view_only = trim($_REQUEST["view_only"] ?: "false") === "true" ? true : false; $view_only = trim($_REQUEST["view_only"] ?? "false") === "true";
$gameid = trim($_REQUEST["gameid"] ?: ""); $gameid = trim($_REQUEST["gameid"] ?? "");
if ($testid === "") { if ($testid === "") {
exit(); exit();

View File

@ -187,8 +187,6 @@ function automatic_typecast(string $rval)
} else { // is it a float? } else { // is it a float?
return (double)$rval; return (double)$rval;
} }
} elseif (str_starts_with($rval, 'T')) { // is it a date/time value?
return strtotime(substr($rval, 1)); // convert to UNIX timestamp
} else { // it's a string } else { // it's a string
return substr($rval, 1, strlen($rval) - 2); // strip leading and trailing quotes return substr($rval, 1, strlen($rval) - 2); // strip leading and trailing quotes
} }