From 42190c6cba337ce6686e2cb75f278e22437b234d Mon Sep 17 00:00:00 2001 From: Epagris Date: Wed, 25 Sep 2024 09:19:28 +0200 Subject: [PATCH] Pre-merge state --- class/AutoStoring.php | 32 +++++ class/GameMgr.php | 38 ++++-- class/GroupMgr.php | 16 ++- class/UserMgr.php | 10 +- composer.json | 5 +- globals.php | 7 + groupmgr.php | 15 +++ interface.php | 250 +++++++++++++++++++++++------------- js/gamemgr.js | 2 +- js/main.js | 62 +++++++++ js/testground.js | 6 +- main.php | 25 +++- maintenance.html | 11 ++ style/spreadquiz_mobile.css | 4 + 14 files changed, 373 insertions(+), 110 deletions(-) create mode 100644 class/AutoStoring.php create mode 100644 maintenance.html diff --git a/class/AutoStoring.php b/class/AutoStoring.php new file mode 100644 index 0000000..6bda31f --- /dev/null +++ b/class/AutoStoring.php @@ -0,0 +1,32 @@ +autoStoring = true; + } + + // Disable autostoring feature. + public function disableAutoStoring() : void + { + $this->autoStoring = false; + } + + // Enable autostoring feature. + public function enableAutoStoring() : void { + $this->autoStoring = true; + } + + // Store modifications. + public function storeMods() : void { + return; + } + + public function commitMods() : void { + if ($this->autoStoring) { + $this->storeMods(); + } + } +} \ No newline at end of file diff --git a/class/GameMgr.php b/class/GameMgr.php index bd45327..7bfb8a2 100644 --- a/class/GameMgr.php +++ b/class/GameMgr.php @@ -1,6 +1,8 @@ false, // player may traverse back and forth between challenges @@ -40,12 +42,18 @@ class Game } // Store modifications. - function storeMods(): void + public function storeMods() : void { - $this->patchUpGameDate(); $this->gameMgr->updateGame($this); } + // Commit modifications. + function commitMods(): void + { + //$this->patchUpGameDate(); + parent::commitMods(); + } + // Load game challenges. public function loadChallenges(): void { @@ -66,6 +74,8 @@ class Game array $contributors = [], bool $gameFileIsPresent = false, array $properties = [], bool $public = false, string $publicId = "", int $version = 2) { + parent::__construct(); + $this->gameMgr = $gameMgr; $this->id = $id; $this->name = $name; @@ -83,17 +93,19 @@ class Game // Create game from array representation. static function fromArray(GameMgr &$gameMgr, array $a): Game { - $id = $a["id"] ?? -1; + $id = $a["_id"] ?? -1; self::patchUpGameDate($a); return new Game($gameMgr, $a["name"], $a["description"], $id, $a["owner"], $a["contributors"], - $a["gameFileIsPresent"], $a["properties"], $a["public"], $a["publicId"], $a["version"]); + $a["game_file_present"], $a["properties"], $a["public"], $a["public_id"], $a["version"]); } + const OMIT_ADVANCED_FIELDS = ["contributors", "game_file_is_present", "properties", "groups", "public", "public_id", "version"]; + // Convert game to array representation. function toArray(array $omit = []): array { $a = [ - "_id" => $this->_id, + "_id" => $this->id, "name" => $this->name, "description" => $this->description, "owner" => $this->owner, @@ -230,7 +242,7 @@ class Game $this->gameFileIsPresent = true; // store modifications - $this->storeMods(); + $this->commitMods(); return ["n" => count($this->challenges), "encoding" => $encoding]; } @@ -287,6 +299,11 @@ class Game return $this->gameFileIsPresent; } + function setProperties(array $properties): void { + $this->properties = $properties; + $this->commitMods(); + } + public function& getProperties(): array { return $this->properties; @@ -302,6 +319,11 @@ class Game return $this->publicId; } + public function setPublic(bool $public) : void { + $this->public = $public; + $this->commitMods(); + } + public function getChallenges(): array { return $this->challenges; @@ -330,7 +352,7 @@ class GameMgr function getGame(string $gameid): Game|null { $game_data_array = $this->db->findById($gameid); - return count($game_data_array) != 0 ? Game::fromArray($this, $game_data_array[0]) : null; + return count($game_data_array) != 0 ? Game::fromArray($this, $game_data_array) : null; } // Get public game. FIXME!!! diff --git a/class/GroupMgr.php b/class/GroupMgr.php index 2d2b163..f3a5020 100644 --- a/class/GroupMgr.php +++ b/class/GroupMgr.php @@ -1,6 +1,8 @@ groupMgr->updateGroup($this); } @@ -24,6 +26,8 @@ class Group function __construct(GroupMgr &$groupMgr, string $name, string $description, string $owner, int $id = -1, bool $unique = true, array $editors = [], array $members = [], array $games = []) { + parent::__construct(); + $this->_id = $id; $this->name = $name; $this->unique = $unique; @@ -38,7 +42,7 @@ class Group // Create Group from array static function fromArray(GroupMgr &$groupMgr, array $a): Group { - return new Group($groupMgr, $a["name"], $a["description"], $a["owner"], $a["_id"], $a["unique"], $a["editors"], $a["members"], $a["games"]); + return new Group($groupMgr, $a["groupname"], $a["description"], $a["owner"], $a["_id"], $a["unique"], $a["editors"], $a["users"], $a["games"]); } // Convert Group to array @@ -51,7 +55,7 @@ class Group "description" => $this->description, "owner" => $this->owner, "editors" => $this->editors, - "members" => $this->members, + "users" => $this->members, "games" => $this->games ]; @@ -216,7 +220,7 @@ class GroupMgr // ------------------------- - private function manageTwins(int $current_group_id, string $groupname): bool + public function manageTwins(int $current_group_id, string $groupname): bool { // make test on name uniqueness $twins = $this->db->findBy([["groupname", "=", "$groupname"], "AND", ["_id", "!=", $current_group_id]]); @@ -239,7 +243,7 @@ class GroupMgr function getGroup(string $groupid): Group|null { $group_data_array = $this->db->findById($groupid); - return count($group_data_array) != 0 ? Group::fromArray($this, $group_data_array[0]) : null; + return count($group_data_array) != 0 ? Group::fromArray($this, $group_data_array) : null; } // Update group. diff --git a/class/UserMgr.php b/class/UserMgr.php index 2c98b9d..7f2baee 100644 --- a/class/UserMgr.php +++ b/class/UserMgr.php @@ -2,7 +2,9 @@ require_once "common_func.php"; -class User +require_once "AutoStoring.php"; + +class User extends AutoStoring { private int $id; // User's ID private string $nickname; // User's nickname @@ -15,7 +17,7 @@ class User // ------------------------------------------- // Store modifications to the database. - private function storeMods(): void + public function storeMods(): void { $this->userMgr->updateUser($this); } @@ -24,6 +26,8 @@ class User function __construct(UserMgr &$usrmgr, int $id, string $nickname = null, string $password = null, string $realname = null, array $groups = null, string $privilege = null) { + parent::__construct(); + $this->id = $id; $this->nickname = $nickname; $this->password = $password; @@ -38,7 +42,7 @@ class User // Create user from an array static function fromArray(UserMgr &$usrmgr, array $a): User { - $id = $a["id"] ?? -1; + $id = $a["_id"] ?? -1; return new User($usrmgr, $id, $a["nickname"], $a["password"], $a["realname"], $a["groups"], $a["privilege"]); } diff --git a/composer.json b/composer.json index a5bc41a..5efc9e0 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,8 @@ { "require": { - "rakibtg/sleekdb": "2.15" + "rakibtg/sleekdb": "2.15", + "ext-http": "*", + "ext-mbstring" : "*", + "ext-zip": "*" } } \ No newline at end of file diff --git a/globals.php b/globals.php index 7ff05c3..f5d007e 100644 --- a/globals.php +++ b/globals.php @@ -14,6 +14,7 @@ const QUIZMASTER_NICKNAME = "quizmaster"; const LOGIN_URL = "login.php"; const MAIN_URL = "main.php"; const SESSION_NAME = "spreadquiz_sid"; +const MAINTENANCE_FLAG_FILE = "MAINTENANCE"; const MISSING_IMAGE_PLACEHOLDER = "media/image-missing_120px.png"; @@ -34,3 +35,9 @@ function init_datadir() { } } +// check MAINTENANCE file +if (file_exists(MAINTENANCE_FLAG_FILE)) { + header("Location: maintenance.html"); + exit(0); +} + diff --git a/groupmgr.php b/groupmgr.php index 0edbc0c..532920e 100644 --- a/groupmgr.php +++ b/groupmgr.php @@ -10,6 +10,21 @@ function create_group(string $groupname, string $owner, string $description = "" { global $groupdb; + // test name uniqueness + $unique = manage_unique_in_siblings(0, $groupname); + + // initialize group data + $group_data = [ + "groupname" => $groupname, + "unique" => $unique, + "owner" => $owner, + "description" => $description, + "editors" => [], + "users" => [], + "games" => [] + ]; + $groupdb->insert($group_data); // insert group + return true; } diff --git a/interface.php b/interface.php index 3920742..fc88ce0 100644 --- a/interface.php +++ b/interface.php @@ -26,6 +26,10 @@ require_once "class/ReqHandler.php"; require_once "class/UserMgr.php"; +require_once "class/GroupMgr.php"; + +require_once "class/GameMgr.php"; + // ------------------------ $userMgr = new UserMgr(); @@ -46,7 +50,8 @@ $is_quizmaster = false; $rh = new ReqHandler(); // action dump callback -function dump_actions(ReqHandler &$rh, array $params): string { +function dump_actions(ReqHandler &$rh, array $params): string +{ return $rh->dump_actions(); } @@ -86,6 +91,8 @@ $user = $userMgr->getUser($_SESSION["nickname"]); $nickname = $user->getNickname(); $privilege = $user->getPrivilege(); $is_quizmaster = $privilege === PRIVILEGE_QUIZMASTER; +$groupMgr = new GroupMgr(); +$gameMgr = new GameMgr(); /* ---------- ACTIONS REQUIRING BEING LOGGED IN ------------ */ @@ -107,19 +114,25 @@ function get_user_info(ReqHandler &$rh, array $params): array function get_available_games(ReqHandler &$rh, array $params): array { global $user; + global $groupMgr; + global $gameMgr; + $games_by_groups = []; $groupids = $user->getGroups(); foreach ($groupids as $groupid) { - $group_data = get_group($groupid); + $group = $groupMgr->getGroup($groupid); $game_collection = [ - "groupname" => $group_data["groupname"], - "description" => $group_data["description"], + "groupname" => $group->getName(), + "description" => $group->getDescription(), "games" => [] ]; - $gameids = $group_data["games"]; + $gameids = $group->getGames(); foreach ($gameids as $gameid) { - $game = get_game($gameid); - $game_collection["games"][] = $game; + $game = $gameMgr->getGame($gameid); + if ($game->isGameFileIsPresent()) { + $a = $game->toArray(Game::OMIT_ADVANCED_FIELDS); + $game_collection["games"][] = $a; + } } $games_by_groups[] = $game_collection; } @@ -151,7 +164,19 @@ function get_results_overview(ReqHandler &$rh, array $params): array return $overviews; } +function change_password(ReqHandler &$rh, array $params): string +{ + $oldpass = $params["oldpass"]; + $newpass = $params["newpass"]; + + global $user; + $success = $user->changePassword($newpass, $oldpass); + + return $success ? "OK" : "FAIL"; +} + $rh->add("logout", [], PRIVILEGE_PLAYER, "logout", RESP_PLAIN, "Log out the user."); +$rh->add("change_password", ["oldpass", "newpass"], PRIVILEGE_PLAYER, "change_password", RESP_PLAIN, "Change users password."); $rh->add("get_user_info", [], PRIVILEGE_PLAYER, "get_user_info", RESP_JSON, "Get user information."); $rh->add("get_available_games", [], PRIVILEGE_PLAYER, "get_available_games", RESP_JSON, "Get available games to the player."); $rh->add("start_or_continue_test", ["gameid"], PRIVILEGE_PLAYER, "start_or_continue_test", RESP_PLAIN, "Start new or continue an ongoing test."); @@ -270,8 +295,10 @@ $requester_nickname = $is_quizmaster ? "*" : $nickname; // "*" means every game function create_update_game(ReqHandler &$rh, array $params): array { global $userMgr; + global $user; global $nickname; global $is_quizmaster; + global $gameMgr; $update = $params[ReqHandler::ACTION_KEY] === "update_game"; $data = json_decode($params["data"], true) ?? []; @@ -303,43 +330,49 @@ function create_update_game(ReqHandler &$rh, array $params): array $result = []; // create or update - if (!$update) { - create_game($name, $owner, $description); - } else if (is_user_contributor_to_game($gameid, $nickname) || $is_quizmaster) { - $game_data = get_game($gameid); - if (count($game_data) !== 0) { + if (!$update) { // CREATE + $gameMgr->addGame($name, $owner, $description); + } else { // UPDATE + $game = $gameMgr->getGame($gameid); // fetch game - // 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); - } + if (($game !== null) && $game->isUserContributorOrOwner($nickname) || $user->hasQuizmasterPrivilege()) { + // group management TODO: átkerül a csoportkezelőbe +// $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); +// $game_data = get_game($gameid); + + // disable autostoring + $game->disableAutoStoring(); // update game header data - $game_data["name"] = $name; - $game_data["description"] = $description; - if (($game_data["owner"] === $nickname) || $is_quizmaster) { - $game_data["owner"] = $owner; - } + $game->setName($name); + $game->setDescription($description); - $game_data["contributors"] = array_intersect($contributors, $userMgr->getAllNicknames()); - $game_data["properties"]["time_limit"] = $properties["time_limit"]; - $game_data["properties"]["repeatable"] = $properties["repeatable"]; + if ($game->isUserOwner($nickname) || $user->hasQuizmasterPrivilege()) { + $game->setOwner($owner); + } + $game->setContributors($contributors); + $game->setProperties($properties); // process game public flag: a game might be only public if not being time-constrained and is allowed to be taken multiple times - $game_data["public"] = ($properties["time_limit"] !== 0) || (!$properties["repeatable"]) ? false : $data["public"]; + $public = ($properties["time_limit"] !== 0) || (!$properties["repeatable"]) ? false : $data["public"]; + $game->setPublic($public); - // update game data - update_game($game_data); + // store modifications + $game->storeMods(); + + // re-enable auto-storing + $game->enableAutoStoring(); // update game file if supplied if (isset($_FILES["game_file"])) { @@ -354,7 +387,7 @@ function create_update_game(ReqHandler &$rh, array $params): array $zip = new ZipArchive; if ($zip->open($file["tmp_name"])) { - $game_dir = get_game_dir_by_gameid($gameid); // get game directory + $game_dir = $game->getGameDir(); // get game directory //$game_files = glob($game_dir); // get list of existing game files // remove former files recursively $dir_iter = new RecursiveDirectoryIterator($game_dir, FilesystemIterator::SKIP_DOTS); @@ -368,12 +401,12 @@ function create_update_game(ReqHandler &$rh, array $params): array // search for the CSV table file $csv_files = glob($game_dir . DIRECTORY_SEPARATOR . "*.csv") ?? []; - if (count($csv_files)) { - $challenge_import_status = import_challenges_from_csv($csv_files[0], $gameid); + if (count($csv_files) > 0) { + $challenge_import_status = $game->importChallengesFromCSV($csv_files[0]); } } } else if ($file_type === "csv") { // a plain table was uploaded - $challenge_import_status = import_challenges_from_csv($file["tmp_name"], $gameid); + $challenge_import_status = $game->importChallengesFromCSV($file["tmp_name"]); } $result = $challenge_import_status; } @@ -386,22 +419,25 @@ function create_update_game(ReqHandler &$rh, array $params): array function get_all_game_headers(ReqHandler &$rh, array $params): array { global $requester_nickname; - $game_headers = get_all_game_data_by_contributor_nickname($requester_nickname); - foreach ($game_headers as &$game_header) { - resolve_groupids($game_header["groups"]); + global $gameMgr; + $games = $gameMgr->getAllGameDataByContributor($requester_nickname); + $a = []; + foreach ($games as &$game) { + $a[] = $game->toArray(); } - return $game_headers; + return $a; } function get_challenges(ReqHandler &$rh, array $params): string { - global $is_quizmaster; - global $requester_nickname; + global $user; + global $gameMgr; + $gameid = $params["gameid"]; - $game_data = get_game($gameid); + $game = $gameMgr->getGame($gameid); $result = ""; - 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)); + if (($game !== null) && ($user->hasQuizmasterPrivilege() || ($game->isUserContributorOrOwner($user->getNickname())))) { + $result = file_get_contents($game->getGameFile()); } return $result; @@ -409,12 +445,14 @@ function get_challenges(ReqHandler &$rh, array $params): string function delete_games(ReqHandler &$rh, array $params): string { - global $nickname; + global $user; + global $gameMgr; $gameids = explode_list(trim($params["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); + $game = $gameMgr->getGame($gameid); + if (($game !== null) && ($game->isUserOwner($user->getNickname()))) { // only the owner may delete a game + $gameMgr->deleteGame($gameid); } } @@ -423,9 +461,13 @@ function delete_games(ReqHandler &$rh, array $params): string function export_game_file_csv(ReqHandler &$rh, array $params): string { - global $nickname; + global $user; + global $gameMgr; + $gameid = trim($params["gameid"]); - if (($gameid !== "") && is_user_contributor_to_game($gameid, $nickname)) { + $game = $gameMgr->getGame($gameid); + + if (($game !== null) && ($game->isUserContributorOrOwner($user->getNickname()) || $user->hasQuizmasterPrivilege())) { $f = tmpfile(); header("Content-Type: text/csv"); header("Content-Disposition: attachment; filename=\"challenges_$gameid.csv\"\r\n"); @@ -438,16 +480,18 @@ function export_game_file_csv(ReqHandler &$rh, array $params): string function get_player_results_by_gameid(ReqHandler &$rh, array $params): array { - global $nickname; - global $is_quizmaster; + global $gameMgr; + global $user; $gameid = trim($params["gameid"]); $filter = trim($params["filter"] ?? ""); $ordering = trim($params["orderby"] ?? ""); + $game = $gameMgr->getGame($gameid); + $result = []; - if (($gameid !== "") && (is_user_contributor_to_game($gameid, $nickname) || $is_quizmaster)) { - $game_results = get_results_by_gameid($gameid, $filter, $ordering, true); + if (($game !== null) && ($game->isUserContributorOrOwner($user->getNickname()) || $user->hasQuizmasterPrivilege())) { + $game_results = get_results_by_gameid($gameid, $filter, $ordering, true); // FIXME!! $result = $game_results; } @@ -458,7 +502,7 @@ function generate_detailed_game_stats(ReqHandler &$rh, array $params): array { $testids = json_decode(trim($params["testids"]), true); $gameid = trim($params["gameid"]); - $stats = generate_detailed_stats($gameid, $testids); + $stats = generate_detailed_stats($gameid, $testids); // FIXME!!! return $stats; } @@ -481,6 +525,7 @@ if ($privilege === PRIVILEGE_CREATOR) { function create_update_group(ReqHandler &$rh, array $params): string { global $user; + global $groupMgr; $update = $params[ReqHandler::ACTION_KEY] === "update_group"; $groupname = trim($params["groupname"]); @@ -491,18 +536,23 @@ function create_update_group(ReqHandler &$rh, array $params): string $result = "FAIL"; if ($groupname != "") { if (!$update) { - create_group($groupname, $owner, $description); + $groupMgr->addGroup($groupname, $owner, $description); $result = "OK"; } else { $gid = $params["id"]; - $group = get_group($gid); - if (count($group) !== 0) { - $group["unique"] = manage_unique_in_siblings($gid, $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); + $group = $groupMgr->getGroup($gid); + if ($group !== null) { + $group->disableAutoStoring(); + $group->setName($groupname); + $group->setDescription($description); + $group->setOwner($owner); + + $editors = array_intersect($editors, $group->getMembers()); // a user cannot be an editor if not participant of the group + $group->setEditors($editors); + + $group->storeMods(); + $group->enableAutoStoring(); + $result = "OK"; } } @@ -512,21 +562,35 @@ function create_update_group(ReqHandler &$rh, array $params): string function delete_groups(ReqHandler &$rh, array $params): string { + global $groupMgr; + $groups = explode_list($params["ids"] ?? ""); foreach ($groups as $g) { - delete_group($g); + $groupMgr->deleteGroup($g); } return "OK"; } function get_all_player_groups(ReqHandler &$rh, array $params): array { - return get_all_groups(); + global $groupMgr; + $groups = $groupMgr->getAllGroups(); + $a = []; + foreach ($groups as $g) { + $a[] = $g->toArray(); + } + return $a; } function search_player_groups(ReqHandler &$rh, array $params): array { - return search_groups($params["needle"]); + global $groupMgr; + $groups = $groupMgr->searchGroups($params["needle"]); + $a = []; + foreach ($groups as $g) { + $a[] = $g->toArray(); + } + return $a; } function create_update_user(ReqHandler &$rh, array $params): string @@ -540,32 +604,33 @@ function create_update_user(ReqHandler &$rh, array $params): string $realname = trim($params["realname"]); $privilege = trim($params["privilege"]); - $groupids = get_groupids_by_compounds($groups); // convert group compounds to _ids + // $groupids = get_groupids_by_compounds($groups); // convert group compounds to _ids FIXME!!! $success = false; if (($target_nickname !== "")) { if ((!$update) && ($password !== "")) { // CREATE - $success = $userMgr->addUser($target_nickname, $password, $realname, $groupids, $privilege); + $success = $userMgr->addUser($target_nickname, $password, $realname, [], $privilege); // FIXME!!! } else if ($update) { // UPDATE - $tuser = $userMgr->getUser($target_nickname); // load user data + $tuser = $userMgr->getUser($target_nickname); // load user data if ($tuser !== null) { - // group management - $old_groupids = $tuser->getGroups(); // 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); - } + // group management FIXME!!! +// $old_groupids = $tuser->getGroups(); // 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 //$tuser = get_user($target_nickname); // load user data // further field update + $tuser->disableAutoStoring(); $tuser->setRealname($realname); $tuser->setPrivilege($privilege); @@ -574,6 +639,9 @@ function create_update_user(ReqHandler &$rh, array $params): string $tuser->changePassword(password_hash($password, PASSWORD_DEFAULT), "", false); } + $tuser->storeMods(); + $tuser->enableAutoStoring(); + $success = true; } } @@ -582,7 +650,8 @@ function create_update_user(ReqHandler &$rh, array $params): string return $success ? "OK" : "FAIL"; } -function delete_users(ReqHandler &$rh, array $params): string { +function delete_users(ReqHandler &$rh, array $params): string +{ global $userMgr; $nicknames = explode_list($params["users"]); foreach ($nicknames as $nick) { @@ -591,20 +660,22 @@ function delete_users(ReqHandler &$rh, array $params): string { return "OK"; } -function get_all_game_users(ReqHandler &$rh, array $params): array { +function get_all_game_users(ReqHandler &$rh, array $params): array +{ global $userMgr; $user_data_filtered = []; $all_users = $userMgr->getAllUsers(); for ($i = 0; $i < count($all_users); $i++) { $a = $all_users[$i]->toArray(); // convert user to array unset($a["password"]); // remove password from records - resolve_groupids($a["groups"]); // resolve group IDs + resolve_groupids($a["groups"]); // resolve group IDs FIXME!!!! $user_data_filtered[] = $a; } return $user_data_filtered; } -function import_users_from_csv(ReqHandler &$rh, array $params): string { +function import_users_from_csv(ReqHandler &$rh, array $params): string +{ if (!isset($_FILES["users_table"])) { } @@ -622,7 +693,8 @@ $rh->add("delete_users", ["users"], PRIVILEGE_QUIZMASTER, "delete_users", RESP_P $rh->add("get_all_users", [], PRIVILEGE_QUIZMASTER, "get_all_game_users", RESP_JSON, "Get all users."); $rh->add("import_users_from_csv", [], PRIVILEGE_QUIZMASTER, "import_users_from_csv", RESP_JSON, "Get all users."); -function test(ReqHandler &$rh, array $params): string { +function test(ReqHandler &$rh, array $params): string +{ $usrmgr = new UserMgr(); $nicknames = $usrmgr->getAllNicknames(); return join(", ", $nicknames); diff --git a/js/gamemgr.js b/js/gamemgr.js index 798a6e0..4521772 100644 --- a/js/gamemgr.js +++ b/js/gamemgr.js @@ -94,7 +94,7 @@ function create_edit_game(game = null) { ownerF.value = game["owner"]; ownerF.readOnly = false; contributorsF.value = game["contributors"].join(", "); - groupF.value = game["groups"].join(", "); + // groupF.value = game["groups"].join(", "); FIXME publicChk.addEventListener("change", hide_public_url_field); publicChk.checked = game["public"]; diff --git a/js/main.js b/js/main.js index 06bad90..297ee27 100644 --- a/js/main.js +++ b/js/main.js @@ -5,4 +5,66 @@ function logout() { request(req).then(resp => { location.href = "login.php"; }); +} + +function change_password() { + let oldpassF = document.getElementById("old_password"); + let newpass1F = document.getElementById("new_password_1"); + let newpass2F = document.getElementById("new_password_2"); + + let oldpass = oldpassF.value; + let newpass1 = newpass1F.value; + let newpass2 = newpass2F.value; + + if (newpass1 !== newpass2) { + alert("Az új jelszavak nem egyeznek!"); + } else { + let req = { + action: "change_password", + oldpass: oldpass, + newpass: newpass1 + } + request(req).then(resp => { + if (resp === "OK") { + alert("Sikeres jelszóváltoztatás!"); + hide("change_password_window"); + oldpassF.value = ""; + newpass1F.value = ""; + newpass2F.value = ""; + } else { + alert("Sikertelen jelszóváltoztatás!"); + } + }); + } +} + +function change_password() { + let oldpassF = document.getElementById("old_password"); + let newpass1F = document.getElementById("new_password_1"); + let newpass2F = document.getElementById("new_password_2"); + + let oldpass = oldpassF.value; + let newpass1 = newpass1F.value; + let newpass2 = newpass2F.value; + + if (newpass1 !== newpass2) { + alert("Az új jelszavak nem egyeznek!"); + } else { + let req = { + action: "change_password", + oldpass: oldpass, + newpass: newpass1 + } + request(req).then(resp => { + if (resp === "OK") { + alert("Sikeres jelszóváltoztatás!"); + hide("change_password_window"); + oldpassF.value = ""; + newpass1F.value = ""; + newpass2F.value = ""; + } else { + alert("Sikertelen jelszóváltoztatás!"); + } + }); + } } \ No newline at end of file diff --git a/js/testground.js b/js/testground.js index 5dbf9e9..a76a6fc 100644 --- a/js/testground.js +++ b/js/testground.js @@ -77,7 +77,9 @@ function assemble_answer_radio_id(challenge_N, answer_N) { function mark_answers(challenges, view_only = false) { for (let i = 0; i < challenges.length; i++) { let marked_answerR = document.getElementById(assemble_answer_radio_id(i, challenges[i]["player_answer"])); - marked_answerR.checked = true; + if (marked_answerR !== null) { + marked_answerR.checked = true; + } } } @@ -146,6 +148,8 @@ function populate_challenges(challenges, concluded, view_only = false, gameid) { test_display.appendChild(challenge_box); }); + mark_answers(challenges, view_only); + MathJax.typeset(); } diff --git a/main.php b/main.php index f38b105..f24181b 100644 --- a/main.php +++ b/main.php @@ -22,6 +22,7 @@ $privilege = $user_data["privilege"]; SpreadQuiz + @@ -40,7 +41,7 @@ $privilege = $user_data["privilege"];
-
+
@@ -57,6 +58,28 @@ $privilege = $user_data["privilege"]; +
+
+
+ + + + + + + + + + + + + +
+
+ + +
+
diff --git a/maintenance.html b/maintenance.html new file mode 100644 index 0000000..16c55fd --- /dev/null +++ b/maintenance.html @@ -0,0 +1,11 @@ + + + + + SpreadQuiz :: Karbantartás + + + +

Az oldal karbantartás alatt áll!

+ + \ No newline at end of file diff --git a/style/spreadquiz_mobile.css b/style/spreadquiz_mobile.css index 3e48cea..8f1e320 100644 --- a/style/spreadquiz_mobile.css +++ b/style/spreadquiz_mobile.css @@ -72,4 +72,8 @@ padding: 1em; max-height: calc(100vh - 2em); } + + td { + display: block; + } } \ No newline at end of file