177 lines
5.9 KiB
PHP
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);
|
|
}
|
|
}
|