210 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			210 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?php
 | 
						|
 | 
						|
require_once "vendor/autoload.php";
 | 
						|
 | 
						|
require_once "AutoStoring.php";
 | 
						|
 | 
						|
require_once "privilege_levels.php";
 | 
						|
 | 
						|
require_once "Group.php";
 | 
						|
 | 
						|
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" => [],
 | 
						|
            "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;
 | 
						|
    }
 | 
						|
} |