diff --git a/class/GameMgr.php b/class/GameMgr.php
index 9ea39da..cc436a1 100644
--- a/class/GameMgr.php
+++ b/class/GameMgr.php
@@ -430,5 +430,34 @@ class GameMgr
return $games;
}
+ // Sanitize games and return game IDs.
+ function sanitizeGames(array $games) : array {
+ $sanitized = [];
+ foreach ($games as $game) {
+ // explode game identifier
+ [$name, $id] = explode("#", $game);
+
+ // fetch game
+ if ($id !== null) {
+ $records = $this->db->findBy([["name", "=", $name], "AND", ["_id", "=", (int)$id]]);
+ } else {
+ $records = $this->db->findBy(["name", "=", $name]);
+ }
+
+ // put game ID into sanitized list only if identifier is not ambiguous
+ if (count($records) === 1) {
+ $sanitized[] = $records[0]["_id"];
+ }
+ }
+
+ return $sanitized;
+ }
+
+ // Resolve group IDs to full group identifiers.
+ function resolveGames(array &$gameIds): void {
+ $a = $this->db->findBy([["_id", "IN", $gameIds]]); // no caching here...
+ $gameIds = array_map(fn($r) => $r["name"] . "#" . $r["_id"] ,$a);
+ }
+
// -------
}
diff --git a/class/GroupMgr.php b/class/GroupMgr.php
index 89b25ac..a557dea 100644
--- a/class/GroupMgr.php
+++ b/class/GroupMgr.php
@@ -192,7 +192,7 @@ class Group extends AutoStoring
alter_array_contents($this->games, $gameid, null);
}
foreach ($gameids_remove as $gameid) { // remove games
- alter_array_contents($this->members, null, $gameid);
+ alter_array_contents($this->games, null, $gameid);
}
$this->storeMods(); // store changes
diff --git a/group_manager_frame.php b/group_manager_frame.php
index 763fb88..2eebfaf 100644
--- a/group_manager_frame.php
+++ b/group_manager_frame.php
@@ -67,13 +67,23 @@ if (!get_autologin_state() || ($user_data["privilege"] !== PRIVILEGE_QUIZMASTER)
-
-
+
+
|
|
+
+
+
+
+
+ |
+
+
+ |
+
-
+
diff --git a/interface.php b/interface.php
index 00638cf..9b4920c 100644
--- a/interface.php
+++ b/interface.php
@@ -721,10 +721,14 @@ function delete_groups(ReqHandler &$rh, array $params): string
function get_all_groups(ReqHandler &$rh, array $params): array
{
global $groupMgr;
+ global $gameMgr;
+
$groups = $groupMgr->getAllGroups();
$a = [];
foreach ($groups as $g) {
- $a[] = $g->toArray();
+ $r = $g->toArray();
+ $gameMgr->resolveGames($r["games"]);
+ $a[] = $r;
}
return $a;
}
@@ -825,7 +829,7 @@ function change_group_members(ReqHandler &$rh, array $params): string
$group = $groupMgr->getGroup($params["groupid"]);
if ($group !== null) {
- if ($group->isUserContributor($user->getNickname())) {
+ if ($group->isUserContributor($user->getNickname()) || $user->hasQuizmasterPrivilege()) {
$add = explode_list(trim($params["add"]));
$add = $userMgr->sanitizeNicknames($add);
$remove = explode_list(trim($params["remove"]));
@@ -838,6 +842,27 @@ function change_group_members(ReqHandler &$rh, array $params): string
return "FAIL";
}
+function change_group_games(ReqHandler &$rh, array $params): string
+{
+ global $groupMgr;
+ global $user;
+ global $gameMgr;
+
+ $group = $groupMgr->getGroup($params["groupid"]);
+ if ($group !== null) {
+ if ($group->isUserContributor($user->getNickname()) || $user->hasQuizmasterPrivilege()) {
+ $add = explode_list(trim($params["add"]));
+ $add = $gameMgr->sanitizeGames($add);
+ $remove = explode_list(trim($params["remove"]));
+ $remove = $gameMgr->sanitizeGames($remove);
+ $group->changeGames($add, $remove);
+ return "OK";
+ }
+ }
+
+ return "FAIL";
+}
+
function import_users_from_csv(ReqHandler &$rh, array $params): string
{
if (!isset($_FILES["users_table"])) {
@@ -852,6 +877,7 @@ $rh->add("delete_groups", ["ids"], PRIVILEGE_QUIZMASTER, "delete_groups", RESP_P
$rh->add("get_all_groups", [], PRIVILEGE_QUIZMASTER, "get_all_groups", RESP_JSON, "Get all player groups.");
$rh->add("search_groups", ["needle"], PRIVILEGE_QUIZMASTER, "search_groups", RESP_JSON, "Serach and fetch player groups.");
$rh->add("change_group_members", ["groupid", "add", "remove"], PRIVILEGE_QUIZMASTER, "change_group_members", RESP_PLAIN, "Change group members.");
+$rh->add("change_group_games", ["groupid", "add", "remove"], PRIVILEGE_QUIZMASTER, "change_group_games", RESP_PLAIN, "Change group games.");
$rh->add(["create_user", "update_user"], ["nickname", "password", "realname", "privilege"], PRIVILEGE_QUIZMASTER, "create_update_user", RESP_PLAIN, "Create or update user.");
$rh->add("delete_users", ["users"], PRIVILEGE_QUIZMASTER, "delete_users", RESP_PLAIN, "Delete users.");
diff --git a/js/gamemgr.js b/js/gamemgr.js
index 1b5ba95..037acde 100644
--- a/js/gamemgr.js
+++ b/js/gamemgr.js
@@ -26,7 +26,7 @@ function list_all_games() {
let tdChkBox = document.createElement("td");
tdChkBox.appendChild(chkbox);
tdChkBox.classList.add("checkbox");
- let tdGameName = create_table_cell(g["name"]);
+ let tdGameName = create_table_cell(g["name"] + "#" + g["_id"] + "");
let tdGameDescription = create_table_cell(g["description"]);
let tdOwner = create_table_cell(g["owner"]);
row.append(tdChkBox, tdGameName, tdGameDescription, tdOwner);
diff --git a/js/groupmgr.js b/js/groupmgr.js
index 67d8b15..8e5dc9a 100644
--- a/js/groupmgr.js
+++ b/js/groupmgr.js
@@ -44,6 +44,7 @@ function create_edit_group(group = null) {
let group_ownerF = document.getElementById("group_owner");
let group_editorsF = document.getElementById("group_editors");
let group_membersF = document.getElementById("group_members");
+ let group_gamesF = document.getElementById("group_games");
if (!update) { // create a new group
groupnameF.value = "";
@@ -53,6 +54,7 @@ function create_edit_group(group = null) {
group_ownerF.readOnly = true;
group_editorsF.value = "";
group_membersF.value = "";
+ group_gamesF.value = "";
hide("group_editor_additional_fields");
} else { // update and existing one
groupnameF.value = group["groupname"];
@@ -62,6 +64,7 @@ function create_edit_group(group = null) {
group_ownerF.readOnly = false;
group_editorsF.value = group["editors"].join(", ");
group_membersF.value = group["users"].join(", ");
+ group_gamesF.value = group["games"].join(", ");
show("group_editor_additional_fields");
}
@@ -123,47 +126,48 @@ function delete_groups() {
function print_group_name(group_data) {
let record = group_data["groupname"];
- if (!group_data["unique"]) {
- record += "#" + group_data["_id"];
- }
+ let seqNumStyle = (group_data["unique"]) ? "style='color:lightgray'" : "";
+ record += `#` + group_data["_id"] + ``;
return record;
}
-let MEMBER_ACTION = "";
+let ACTION = "";
+let TYPE = ""
-function open_member_change_window(action) {
- MEMBER_ACTION = action;
- let winCap = document.getElementById("member_manager_window_title");
+function open_element_change_window(action, type) {
+ ACTION = action;
+ TYPE = type;
+
+ let winCap = document.getElementById("element_manager_window_title");
+
+ let typeStr = (type === "member") ? "Tagok" : "Játékok";
+ let opStr = (action === "add") ? "hozzáadása" : "eltávolítása";
// print window title
- if (action === "add") {
- winCap.innerText = "Tagok hozzáadása";
- } else if (action === "remove") {
- winCap.innerText = "Tagok eltávolítása";
- }
+ winCap.innerText = typeStr + " " + opStr;
- show("member_manager_window");
+ show("element_manager_window");
}
-function change_group_members() {
- let userListTA = document.getElementById("add_remove_member_area");
+function change_group_elements() {
+ let elementListTA = document.getElementById("add_remove_element_area");
let req = {
- action: "change_group_members",
+ action: `change_group_${TYPE}s`,
groupid: EDITED_GROUP["_id"],
add: [],
remove: []
};
- if (MEMBER_ACTION === "add") {
- req["add"] = userListTA.value;
- } else if (MEMBER_ACTION === "remove") {
- req["remove"] = userListTA.value;
+ if (ACTION === "add") {
+ req["add"] = elementListTA.value;
+ } else if (ACTION === "remove") {
+ req["remove"] = elementListTA.value;
}
request(req).then(resp => {
- userListTA.value = "";
- hide("member_manager_window");
+ elementListTA.value = "";
+ hide("element_manager_window");
hide("group_editor_window");
list_all_groups();
});
diff --git a/report/template/report.tex b/report/template/report.tex
index b3b764f..d05595b 100644
--- a/report/template/report.tex
+++ b/report/template/report.tex
@@ -134,7 +134,7 @@
% An environment to create a quiz containing questions. The parameter is either the title of the quiz, or the name of the course
\newenvironment{quiz}[2]{
-% Create highlighted group title
+ % Create highlighted group title
\begin{mdframed}[backgroundcolor=colsbg]
{
\color{colsfg}