misuzu/src/Users/UserWarning.php
flash 1d552e907b Added new banning system.
it actually works and isn't confusing this time around!
2023-07-26 18:19:48 +00:00

177 lines
5.9 KiB
PHP

<?php
namespace Misuzu\Users;
use InvalidArgumentException;
use RuntimeException;
use Misuzu\DB;
use Misuzu\Pagination;
class UserWarning {
private const PROFILE_BACKLOG = 90;
// Database fields
private $warning_id = -1;
private $user_id = -1;
private $user_ip = '::1';
private $issuer_id = -1;
private $issuer_ip = '::1';
private $warning_created = null;
private $warning_duration = null;
private $warning_type = 0;
private $warning_note = '';
private $warning_note_private = '';
private $user = null;
private $issuer = null;
public const TABLE = 'user_warnings';
private const QUERY_SELECT = 'SELECT %1$s FROM `' . DB::PREFIX . self::TABLE . '` AS '. self::TABLE;
private const SELECT = '%1$s.`warning_id`, %1$s.`user_id`, %1$s.`issuer_id`, %1$s.`warning_type`, %1$s.`warning_note`, %1$s.`warning_note_private`'
. ', UNIX_TIMESTAMP(%1$s.`warning_created`) AS `warning_created`'
. ', UNIX_TIMESTAMP(%1$s.`warning_duration`) AS `warning_duration`'
. ', INET6_NTOA(%1$s.`user_ip`) AS `user_ip`'
. ', INET6_NTOA(%1$s.`issuer_ip`) AS `issuer_ip`';
public function getId(): int {
return $this->warning_id;
}
public function getUserId(): int {
return $this->user_id;
}
public function getUser(): User {
if($this->user === null)
$this->user = User::byId($this->getUserId());
return $this->user;
}
public function getUserRemoteAddress(): string {
return $this->user_ip;
}
public function getIssuerId(): int {
return $this->issuer_id;
}
public function getIssuer(): User {
if($this->issuer === null)
$this->issuer = User::byId($this->getIssuerId());
return $this->issuer;
}
public function getIssuerRemoteAddress(): string {
return $this->issuer_ip;
}
public function getCreatedTime(): int {
return $this->warning_created === null ? -1 : $this->warning_created;
}
public function getType(): int {
return $this->warning_type;
}
public function getPublicNote(): string {
return $this->warning_note;
}
public function getPrivateNote(): string {
return $this->warning_note_private ?? '';
}
public function hasPrivateNote(): bool {
return !empty($this->warning_note_private);
}
public function delete(): void {
DB::prepare('DELETE FROM `' . DB::PREFIX . self::TABLE . '` WHERE `warning_id` = :warning')
->bind('warning', $this->warning_id)
->execute();
}
public static function create(
User $user,
User $issuer,
string $publicNote,
?string $privateNote = null,
?string $targetAddr = null,
?string $issuerAddr = null
): self {
$targetAddr ??= $user->getLastRemoteAddress();
$issuerAddr ??= $issuer->getLastRemoteAddress();
$warningId = DB::prepare(
'INSERT INTO `' . DB::PREFIX . self::TABLE . '` (`user_id`, `user_ip`, `issuer_id`, `issuer_ip`, `warning_created`, `warning_duration`, `warning_type`, `warning_note`, `warning_note_private`)'
. ' VALUES (:user, INET6_ATON(:user_addr), :issuer, INET6_ATON(:issuer_addr), NOW(), NULL, 1, :public_note, :private_note)'
) ->bind('user', $user->getId())
->bind('user_addr', $targetAddr)
->bind('issuer', $issuer->getId())
->bind('issuer_addr', $issuerAddr)
->bind('public_note', $publicNote)
->bind('private_note', $privateNote)
->executeGetId();
if($warningId < 1)
throw new RuntimeException('Failed to create new warning.');
return self::byId($warningId);
}
private static function countQueryBase(): string {
return sprintf(self::QUERY_SELECT, 'COUNT(*)');
}
public static function countAll(?User $user = null): int {
$getCount = DB::prepare(self::countQueryBase() . ($user === null ? '' : ' WHERE `user_id` = :user'));
if($user !== null)
$getCount->bind('user', $user->getId());
return (int)$getCount->fetchColumn();
}
private static function byQueryBase(): string {
return sprintf(self::QUERY_SELECT, sprintf(self::SELECT, self::TABLE));
}
public static function byId(int $warningId): self {
$object = DB::prepare(
self::byQueryBase() . ' WHERE `warning_id` = :warning'
) ->bind('warning', $warningId)
->fetchObject(self::class);
if(!$object)
throw new RuntimeException('Not warning with that ID could be found.');
return $object;
}
public static function byProfile(User $user, ?User $viewer = null): array {
if($viewer === null
|| !($user->getId() === $viewer->getId()
|| perms_check_user(MSZ_PERMS_USER, $viewer->getId(), MSZ_PERM_USER_MANAGE_WARNINGS))
) return [];
$getObjects = DB::prepare(
self::byQueryBase()
. ' WHERE `user_id` = :user'
. ' AND `warning_created` >= NOW() - INTERVAL ' . self::PROFILE_BACKLOG . ' DAY'
. ' ORDER BY `warning_created` DESC'
);
$getObjects->bind('user', $user->getId());
return $getObjects->fetchObjects(self::class);
}
public static function all(?User $user = null, ?Pagination $pagination = null): array {
$query = self::byQueryBase()
. ($user === null ? '' : ' WHERE `user_id` = :user')
. ' ORDER BY `warning_created` DESC';
if($pagination !== null)
$query .= ' LIMIT :range OFFSET :offset';
$getObjects = DB::prepare($query);
if($user !== null)
$getObjects->bind('user', $user->getId());
if($pagination !== null)
$getObjects->bind('range', $pagination->getRange())
->bind('offset', $pagination->getOffset());
return $getObjects->fetchObjects(self::class);
}
}