2023-07-27 23:26:05 +00:00
|
|
|
<?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(
|
2023-08-02 22:12:47 +00:00
|
|
|
UserInfo|string|null $userInfo = null,
|
2023-07-27 23:26:05 +00:00
|
|
|
?bool $hidden = null
|
|
|
|
): int {
|
2023-08-02 22:12:47 +00:00
|
|
|
if($userInfo instanceof UserInfo)
|
|
|
|
$userInfo = $userInfo->getId();
|
2023-07-27 23:26:05 +00:00
|
|
|
|
|
|
|
$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)
|
2023-07-27 23:49:55 +00:00
|
|
|
$query .= sprintf(' %s role_hidden %s 0', ++$args > 1 ? 'AND' : 'WHERE', $hidden ? '=' : '<>');
|
2023-07-27 23:26:05 +00:00
|
|
|
|
|
|
|
$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(
|
2023-08-02 22:12:47 +00:00
|
|
|
UserInfo|string|null $userInfo = null,
|
2023-07-27 23:26:05 +00:00
|
|
|
?bool $hidden = null,
|
|
|
|
?Pagination $pagination = null
|
2024-02-07 00:04:45 +00:00
|
|
|
): iterable {
|
2023-08-02 22:12:47 +00:00
|
|
|
if($userInfo instanceof UserInfo)
|
|
|
|
$userInfo = $userInfo->getId();
|
2023-07-27 23:26:05 +00:00
|
|
|
|
|
|
|
$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();
|
|
|
|
|
2024-02-07 00:04:45 +00:00
|
|
|
return $stmt->getResult()->getIterator(RoleInfo::fromResult(...));
|
2023-07-27 23:26:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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.');
|
|
|
|
|
2024-02-07 00:04:45 +00:00
|
|
|
return RoleInfo::fromResult($result);
|
2023-07-27 23:26:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|