groupMgr->updateGroup($this); } // -------------- 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; $this->description = $description; $this->owner = $owner; $this->editors = $editors; $this->members = $members; $this->games = $games; $this->groupMgr = &$groupMgr; } // Create Group from array static function fromArray(GroupMgr &$groupMgr, array $a): Group { return new Group($groupMgr, $a["groupname"], $a["description"], $a["owner"], $a["_id"], $a["unique"], $a["editors"], $a["users"], $a["games"]); } // Convert Group to array function toArray(array $omit = []): array { $a = [ "_id" => $this->_id, "groupname" => $this->name, "unique" => $this->unique, "description" => $this->description, "owner" => $this->owner, "editors" => $this->editors, "users" => $this->members, "games" => $this->games ]; foreach ($omit as $field) { unset($a[$field]); } return $a; } // Get group's ID. function getID(): int { return $this->_id; } // Get group's name. function getName(): string { return $this->name; } // Set group's name. function setName(string $name): void { $this->name = $name; $this->storeMods(); } // Tell if group is unique function isUnique(): bool { return $this->unique; } // Get group's description. function getDescription(): string { return $this->description; } // Set group's description. function setDescription(string $description): void { $this->description = $description; $this->storeMods(); } // Get group's owner. function getOwner(): string { return $this->owner; } // Set group's owner. function setOwner(string $owner): void { $this->owner = $owner; $this->storeMods(); } // Get list of editors. function getEditors(): array { return $this->editors; } // Set editors. function setEditors(array $editors): void { $this->editors = $editors; $this->storeMods(); } // Get group members. function getMembers(): array { return $this->members; } // Set group members. function setMembers(array $members): void { $this->members = $members; $this->storeMods(); } // Get games. function getGames(): array { return $this->games; } // Set games. function setGames(array $games): void { $this->games = $games; $this->storeMods(); } // Include/exclude members. function changeMembers(array $nicknames_add, array $nicknames_remove): void { foreach ($nicknames_add as $nickname) { // add members alter_array_contents($this->members, $nickname, null); } foreach ($nicknames_remove as $nickname) { // remove members alter_array_contents($this->members, null, $nickname); // delete from members alter_array_contents($this->editors, null, $nickname); // delete from editors } $this->storeMods(); // store changes } // Include/exclude games. function changeGames(array $gameids_add, array $gameids_remove): void { foreach ($gameids_add as $gameid) { // add games alter_array_contents($this->games, $gameid, null); } foreach ($gameids_remove as $gameid) { // remove games alter_array_contents($this->members, null, $gameid); } $this->storeMods(); // store changes } // Returns whether the user is an editor of this group. function isUserEditor(string $nickname): bool { return in_array($nickname, $this->editors); } // Returns whether the user is an editor or the owner of the group. function isUserContributor(string $nickname): bool { return $this->isUserEditor($nickname) || ($this->owner === $nickname); } // Returns if user is member of the group. function isMember(string $nickname): bool { return in_array($nickname, $this->members); } // Return if game is assigned to this group. function isGameAssigned(string $gameid): bool { return in_array($gameid, $this->games); } // Get groups unique name. function getUniqueName(): string { return $this->name . ($this->unique ? "" : ("#" . $this->_id)); } } class GroupMgr { private \SleekDB\Store $db; // database // ------------------------- 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]]); $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; $this->db->update($twins[0]); // UPDATE WITHOUT CONVERTING TO GROUP OBJECT!! BE CAREFUL! } return $unique; } // ------------------------- function __construct() { $this->db = new \SleekDB\Store(GROUPDB, DATADIR, ["timeout" => false]); } // Get group by ID. 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) : null; } // Update group. function updateGroup(Group $group): void { $a = $group->toArray(); $this->db->update($a); } // Add a new group. function addGroup(string $groupname, string $owner, string $description = ""): bool { // test name uniqueness $unique = $this->manageTwins(0, $groupname); // initialize group data $group_data = [ "groupname" => $groupname, "unique" => $unique, "owner" => $owner, "description" => $description, "editors" => [], "members" => [], "games" => [] ]; $group = Group::fromArray($this, $group_data); // create group $this->db->insert($group->toArray(["_id"])); // insert group return true; } // Delete group. function deleteGroup(string $groupid): void { //$group = $this->getGroup($groupid); //if ($group != null) { $this->db->deleteById($groupid); //} } // Get all groups. function getAllGroups(): array { return array_map(fn($a): Group => Group::fromArray($this, $a), $this->db->findAll()); } // Search groups. function searchGroups(string $needle, bool $infoOnly = true): array { if (strlen($needle) < 3) { return []; } $parts = explode("#", $needle, 2); $groupname = $parts[0]; $group_data_array = []; if (count($parts) === 1) { $group_data_array = $this->db->findBy(["groupname", "LIKE", "%$groupname%"]); } else if (count($parts) > 1) { $groupid = $parts[1]; $group_data_array = $this->db->findBy([["groupname", "LIKE", "%$groupname%"], "AND", ["_id", "LIKE", "%$groupid%"]]); } $results = []; foreach ($group_data_array as $group_data) { if ($infoOnly) { $results[] = [ "groupname" => $group_data["groupname"], "_id" => $group_data["_id"], "unique" => $group_data["unique"] ]; } else { $results[] = Group::fromArray($this, $group_data); } } return $results; } // Get group IDs by the group compounds (name#ID). function getGroupIdsByCompounds(array $compounds): array { $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 = $this->db->findBy($fetch_cmd); if (count($group_data) == 1) { // too many hits $group_data = $group_data[0]; } else { $group_data = []; } } else { $group_data = $this->db->findById($parts[1]); } if ($group_data !== []) { $groupids[] = $group_data["_id"]; } } return $groupids; } // cache for converting group ID's to unique group names private array $groupid_cache = []; // Convert group IDs into unique group names IN PLACE! function resolveGroupIds(array &$groupids): void { foreach ($groupids as &$groupid) { if (!array_key_exists($groupid, $this->groupid_cache)) { $group = $this->getGroup($groupid); // fetch group $unique_name = $group->getUniqueName(); // get group's unique name $this->groupid_cache[$groupid] = $unique_name; // store into the cache so that subsequent queries will be somewhat faster } $groupid = $this->groupid_cache[$groupid]; // replace with the unique name } } // Check if a user has access to a game, i.e. there's at least a single group that contains both the user and the game. function doesUserAccessGame(string $gameid, string $nickname): bool { $intersection = $this->db->findOneBy([["games", "CONTAINS", (int)$gameid], "AND", ["users", "CONTAINS", $nickname]]); return $intersection !== null; } // Get user's groups IDs. function getUserGroupIDs(string $nickname) : array { $qb = $this->db->createQueryBuilder(); $a = $qb->where(["users", "CONTAINS", $nickname])->select(["_id"])->getQuery()->fetch(); return array_map(fn($r) => $r["_id"], $a); } // Get game's group IDs. function getGameGroupIDs(string $gameid) : array { $qb = $this->db->createQueryBuilder(); $a = $qb->where(["games", "CONTAINS", (int)$gameid])->select(["_id"])->getQuery()->fetch(); return array_map(fn($r) => $r["_id"], $a); } }