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" => [], "users" => [], "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); } // Get group by group compound (name#id). function getGroupByUniqueName(string $uniqueName): Group|null { $a = $this->db->findOneBy([ function($g) use ($uniqueName) : bool { $group = Group::fromArray($this, $g); return $group->getUniqueName() === $uniqueName; }]); if ($a !== null) { return Group::fromArray($this, $a); } else { return null; } } // Get the union of all members in the groups specified function getJoinedMembersByUniqueNames(array $uniqueNames) : array { $nicknames = []; foreach ($uniqueNames as $uniqueName) { $group = $this->getGroupByUniqueName($uniqueName); if ($group !== null) { $nicknames = array_merge($nicknames, $group->getMembers()); } } return $nicknames; } }