misuzu/src/Users/Roles.php
flash 383e2ed0e0 Rewrote the user information class.
This one took multiple days and it pretty invasive into the core of Misuzu so issue might (will) arise, there's also some features that have gone temporarily missing in the mean time and some inefficiencies introduced that will be fixed again at a later time.
The old class isn't gone entirely because I still have to figure out what I'm gonna do about validation, but for the most part this knocks out one of the "layers of backwards compatibility", as I've been referring to it, and is moving us closer to a future where Flashii actually gets real updates.
If you run into anything that's broken and you're inhibited from reporting it through the forum, do it through chat or mail me at flashii-issues@flash.moe.
2023-08-02 22:12:47 +00:00

227 lines
7.6 KiB
PHP

<?php
namespace Misuzu\Users;
use InvalidArgumentException;
use RuntimeException;
use Index\Colour\Colour;
use Index\Data\DbStatementCache;
use Index\Data\DbTools;
use Index\Data\IDbConnection;
use Misuzu\Pagination;
class Roles {
public const DEFAULT_ROLE = '1';
private IDbConnection $dbConn;
private DbStatementCache $cache;
public function __construct(IDbConnection $dbConn) {
$this->dbConn = $dbConn;
$this->cache = new DbStatementCache($dbConn);
}
public function countRoles(
UserInfo|string|null $userInfo = null,
?bool $hidden = null
): int {
if($userInfo instanceof UserInfo)
$userInfo = $userInfo->getId();
$hasUserInfo = $userInfo !== null;
$hasHidden = $hidden !== null;
$args = 0;
$query = 'SELECT COUNT(*) FROM msz_roles';
if($hasUserInfo) {
++$args;
$query .= ' WHERE role_id IN (SELECT role_id FROM msz_users_roles WHERE user_id = ?)';
}
if($hasHidden)
$query .= sprintf(' %s role_hidden %s 0', ++$args > 1 ? 'AND' : 'WHERE', $hidden ? '=' : '<>');
$args = 0;
$stmt = $this->cache->get($query);
if($hasUserInfo)
$stmt->addParameter(++$args, $userInfo);
$stmt->execute();
$count = 0;
$result = $stmt->getResult();
if($result->next())
$count = $result->getInteger(0);
return $count;
}
public function getRoles(
UserInfo|string|null $userInfo = null,
?bool $hidden = null,
?Pagination $pagination = null
): array {
if($userInfo instanceof UserInfo)
$userInfo = $userInfo->getId();
$hasUserInfo = $userInfo !== null;
$hasHidden = $hidden !== null;
$hasPagination = $pagination !== null;
$args = 0;
$query = 'SELECT role_id, role_hierarchy, role_name, role_title, role_description, role_hidden, role_can_leave, role_colour, UNIX_TIMESTAMP(role_created) FROM msz_roles';
if($hasUserInfo) {
++$args;
$query .= ' WHERE role_id IN (SELECT role_id FROM msz_users_roles WHERE user_id = ?)';
}
if($hasHidden)
$query .= sprintf(' %s role_hidden %s 0', ++$args > 1 ? 'AND' : 'WHERE', $hidden ? '<>' : '=');
if($hasPagination)
$query .= ' LIMIT ? OFFSET ?';
$args = 0;
$stmt = $this->cache->get($query);
if($hasUserInfo)
$stmt->addParameter(++$args, $userInfo);
if($hasPagination) {
$stmt->addParameter(++$args, $pagination->getRange());
$stmt->addParameter(++$args, $pagination->getOffset());
}
$stmt->execute();
$roles = [];
$result = $stmt->getResult();
while($result->next())
$roles[] = new RoleInfo($result);
return $roles;
}
public function getRole(string $roleId): RoleInfo {
$stmt = $this->cache->get('SELECT role_id, role_hierarchy, role_name, role_title, role_description, role_hidden, role_can_leave, role_colour, UNIX_TIMESTAMP(role_created) FROM msz_roles WHERE role_id = ?');
$stmt->addParameter(1, $roleId);
$stmt->execute();
$result = $stmt->getResult();
if(!$result->next())
throw new RuntimeException('Could not find role with ID $roleId.');
return new RoleInfo($result);
}
public function createRole(
string $name,
int $rank,
Colour $colour,
string $title = '',
string $description = '',
bool $hidden = false,
bool $leavable = false
): RoleInfo {
$colour = $colour->shouldInherit() ? null : Colour::toMisuzu($colour);
// should these continue to accept NULL?
if($title === '') $title = null;
if($description === '') $description = null;
$stmt = $this->cache->get('INSERT INTO msz_roles (role_hierarchy, role_name, role_title, role_description, role_hidden, role_can_leave, role_colour) VALUES (?, ?, ?, ?, ?, ?, ?)');
$stmt->addParameter(1, $rank);
$stmt->addParameter(2, $name);
$stmt->addParameter(3, $title);
$stmt->addParameter(4, $description);
$stmt->addParameter(5, $hidden ? 1 : 0);
$stmt->addParameter(6, $leavable ? 1 : 0);
$stmt->addParameter(7, $colour);
$stmt->execute();
return $this->getRole((string)$this->dbConn->getLastInsertId());
}
public function deleteRoles(RoleInfo|string|array $roleInfos): void {
if(!is_array($roleInfos))
$roleInfos = [$roleInfos];
elseif(empty($roleInfos))
return;
$stmt = $this->cache->get(sprintf(
'DELETE FROM msz_roles WHERE role_id IN (%s)',
DbTools::prepareListString($roleInfos)
));
$args = 0;
foreach($roleInfos as $roleInfo) {
if($roleInfo instanceof RoleInfo)
$roleInfo = $roleInfo->getId();
elseif(!is_string($roleInfo))
throw new InvalidArgumentException('$roleInfos must be strings of instances of RoleInfo.');
$stmt->addParameter(++$args, $roleInfo);
}
$stmt->execute();
}
public function updateRole(
RoleInfo|string $roleInfo,
?string $name = null,
?int $rank = null,
?Colour $colour = null,
?string $title = null,
?string $description = null,
?bool $hidden = null,
?bool $leavable = null
): void {
if($roleInfo instanceof RoleInfo)
$roleInfo = $roleInfo->getId();
$applyTitle = $title !== null;
$applyDescription = $description !== null;
$applyColour = $colour !== null;
$applyHidden = $hidden !== null;
$applyLeavable = $leavable !== null;
if($applyColour)
$colour = $colour->shouldInherit() ? null : Colour::toMisuzu($colour);
// should these continue to accept NULL?
if($title === '') $title = null;
if($description === '') $description = null;
$stmt = $this->cache->get('UPDATE msz_roles SET role_hierarchy = COALESCE(?, role_hierarchy), role_name = COALESCE(?, role_name), role_title = IF(?, ?, role_title), role_description = IF(?, ?, role_description), role_hidden = IF(?, ?, role_hidden), role_can_leave = IF(?, ?, role_can_leave), role_colour = IF(?, ?, role_colour) WHERE role_id = ?');
$stmt->addParameter(1, $rank);
$stmt->addParameter(2, $name);
$stmt->addParameter(3, $applyTitle ? 1 : 0);
$stmt->addParameter(4, $title);
$stmt->addParameter(5, $applyDescription ? 1 : 0);
$stmt->addParameter(6, $description);
$stmt->addParameter(7, $applyHidden ? 1 : 0);
$stmt->addParameter(8, $hidden ? 1 : 0);
$stmt->addParameter(9, $applyLeavable ? 1 : 0);
$stmt->addParameter(10, $leavable ? 1 : 0);
$stmt->addParameter(11, $applyColour ? 1 : 0);
$stmt->addParameter(12, $colour);
$stmt->addParameter(13, $roleInfo);
$stmt->execute();
}
public function getDefaultRole(): RoleInfo {
return $this->getRole(self::DEFAULT_ROLE);
}
public function countRoleUsers(RoleInfo|string $roleInfo): int {
if($roleInfo instanceof RoleInfo)
$roleInfo = $roleInfo->getId();
$stmt = $this->cache->get('SELECT COUNT(*) FROM msz_users_roles WHERE role_id = ?');
$stmt->addParameter(1, $roleInfo);
$stmt->execute();
$count = 0;
$result = $stmt->getResult();
if($result->next())
$count = $result->getInteger(0);
return $count;
}
}