This repository has been archived on 2025-01-28. You can view files and clone it, but cannot push or open issues or pull requests.
misuzu-interim/src/Users/Roles.php

233 lines
8 KiB
PHP

<?php
namespace Misuzu\Users;
use InvalidArgumentException;
use RuntimeException;
use Index\Colour\Colour;
use Index\Db\{DbConnection,DbStatementCache,DbTools};
use Misuzu\Pagination;
class Roles {
public const DEFAULT_ROLE = '1';
private DbStatementCache $cache;
public function __construct(
private DbConnection $dbConn
) {
$this->cache = new DbStatementCache($dbConn);
}
public function countRoles(
UserInfo|string|null $userInfo = null,
?bool $hidden = null
): int {
if($userInfo instanceof UserInfo)
$userInfo = $userInfo->id;
$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 ? '=' : '<>');
$stmt = $this->cache->get($query);
if($hasUserInfo)
$stmt->nextParameter($userInfo);
$stmt->execute();
$count = 0;
$result = $stmt->getResult();
if($result->next())
$count = $result->getInteger(0);
return $count;
}
/** @return \Iterator<int, RoleInfo> */
public function getRoles(
UserInfo|string|null $userInfo = null,
?bool $hidden = null,
?bool $hasString = null,
bool $orderByRank = false,
?Pagination $pagination = null
): iterable {
if($userInfo instanceof UserInfo)
$userInfo = $userInfo->id;
$hasUserInfo = $userInfo !== null;
$hasHidden = $hidden !== null;
$hasPagination = $pagination !== null;
$args = 0;
$query = 'SELECT role_id, role_string, 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($hasString !== null)
$query .= sprintf(' %s role_string %s NULL', ++$args > 1 ? 'AND' : 'WHERE', $hasString ? 'IS NOT' : 'IS');
if($orderByRank)
$query .= ' ORDER BY role_hierarchy DESC';
if($hasPagination)
$query .= ' LIMIT ? OFFSET ?';
$stmt = $this->cache->get($query);
if($hasUserInfo)
$stmt->nextParameter($userInfo);
if($hasPagination)
$pagination->addToStatement($stmt);
$stmt->execute();
return $stmt->getResult()->getIterator(RoleInfo::fromResult(...));
}
public function getRole(string $roleId): RoleInfo {
$stmt = $this->cache->get('SELECT role_id, role_string, 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->nextParameter($roleId);
$stmt->execute();
$result = $stmt->getResult();
if(!$result->next())
throw new RuntimeException('Could not find role with ID $roleId.');
return RoleInfo::fromResult($result);
}
public function createRole(
string $name,
int $rank,
Colour $colour,
string $string = '',
string $title = '',
string $description = '',
bool $hidden = false,
bool $leavable = false
): RoleInfo {
$colour = $colour->shouldInherit() ? null : Colour::toMisuzu($colour);
if($string === '')
$string = null;
// should these continue to accept NULL?
if($title === '') $title = null;
if($description === '') $description = null;
$stmt = $this->cache->get('INSERT INTO msz_roles (role_string, role_hierarchy, role_name, role_title, role_description, role_hidden, role_can_leave, role_colour) VALUES (?, ?, ?, ?, ?, ?, ?, ?)');
$stmt->nextParameter($string);
$stmt->nextParameter($rank);
$stmt->nextParameter($name);
$stmt->nextParameter($title);
$stmt->nextParameter($description);
$stmt->nextParameter($hidden ? 1 : 0);
$stmt->nextParameter($leavable ? 1 : 0);
$stmt->nextParameter($colour);
$stmt->execute();
return $this->getRole((string)$this->dbConn->getLastInsertId());
}
/** @param RoleInfo|string|array<RoleInfo|string> $roleInfos */
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)
));
foreach($roleInfos as $roleInfo) {
if($roleInfo instanceof RoleInfo)
$roleInfo = $roleInfo->id;
elseif(!is_string($roleInfo))
throw new InvalidArgumentException('$roleInfos must be strings of instances of RoleInfo.');
$stmt->nextParameter($roleInfo);
}
$stmt->execute();
}
public function updateRole(
RoleInfo|string $roleInfo,
?string $string = null,
?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->id;
$applyString = $string !== null;
$applyTitle = $title !== null;
$applyDescription = $description !== null;
$applyColour = $colour !== null;
$applyHidden = $hidden !== null;
$applyLeavable = $leavable !== null;
if($applyColour)
$colour = $colour->shouldInherit() ? null : Colour::toMisuzu($colour);
if($string === '')
$string = null;
// should these continue to accept NULL?
if($title === '') $title = null;
if($description === '') $description = null;
$stmt = $this->cache->get('UPDATE msz_roles SET role_string = IF(?, ?, role_string), 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->nextParameter($applyString ? 1 : 0);
$stmt->nextParameter($string);
$stmt->nextParameter($rank);
$stmt->nextParameter($name);
$stmt->nextParameter($applyTitle ? 1 : 0);
$stmt->nextParameter($title);
$stmt->nextParameter($applyDescription ? 1 : 0);
$stmt->nextParameter($description);
$stmt->nextParameter($applyHidden ? 1 : 0);
$stmt->nextParameter($hidden ? 1 : 0);
$stmt->nextParameter($applyLeavable ? 1 : 0);
$stmt->nextParameter($leavable ? 1 : 0);
$stmt->nextParameter($applyColour ? 1 : 0);
$stmt->nextParameter($colour);
$stmt->nextParameter($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->id;
$stmt = $this->cache->get('SELECT COUNT(*) FROM msz_users_roles WHERE role_id = ?');
$stmt->nextParameter($roleInfo);
$stmt->execute();
$count = 0;
$result = $stmt->getResult();
if($result->next())
$count = $result->getInteger(0);
return $count;
}
}