371 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			371 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?php
 | 
						|
 | 
						|
require_once "AutoStoring.php";
 | 
						|
 | 
						|
class Group extends AutoStoring
 | 
						|
{
 | 
						|
    private int $_id; // Group's ID (assigned by SleekDB)
 | 
						|
    private string $name; // Group's name
 | 
						|
    private bool $unique; // Indicates if name is unique or not
 | 
						|
    private string $owner; // Group owner's nickname
 | 
						|
    private string $description; // Group description
 | 
						|
    private array $editors; // Nicknames of users able to manage the group
 | 
						|
    private array $members; // Nickname of group members
 | 
						|
    private array $games; // Game IDs assigned to this group
 | 
						|
    private GroupMgr $groupMgr; // Reference to GroupMgr object managing this group
 | 
						|
 | 
						|
    // --------------
 | 
						|
 | 
						|
    // store modifications to the database
 | 
						|
    public function storeMods() : void
 | 
						|
    {
 | 
						|
        $this->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
 | 
						|
        }
 | 
						|
    }
 | 
						|
} |