2025-08-14 13:55:37 -04:00

117 lines
3.0 KiB
PHP

<?php
declare(strict_types=1);
/*
* This file is a part of the Dragon-Knight project.
*
* Copyright (c) 2024-present Sharkk
*
* This file is subject to the MIT license that is bundled
* with this source code in the LICENSE.md file.
*/
namespace DragonKnight\Models;
use DragonKnight\Lib;
class User extends Model
{
protected string $table_name = 'users';
/**
* Find a user by their ID, username or email. Returns false on any failure.
*/
public static function find(int|string $id): User|false
{
$query = Lib::db()->query(
'SELECT * FROM users WHERE id=? OR username=? COLLATE NOCASE OR email=? COLLATE NOCASE LIMIT 1;',
[$id, $id, $id]
);
if ($query === false) {
return false;
}
$data = $query->fetchArray(SQLITE3_ASSOC);
if ($data === false) {
return false;
}
return new User($data);
}
/**
* Return a list of spells from this user's spell list.
*/
public function spells(): array|false
{
return Lib::get_spells_from_list($this->spells);
}
/**
* Restore all HP, MP, and TP values to their max.
*/
public function restore_points(): User
{
$this->currenthp = $this->maxhp;
$this->currentmp = $this->maxmp;
$this->currenttp = $this->maxtp;
return $this;
}
/**
* Sends a manual update to online time for this user.
*/
public function update_online_time(): void
{
if ($this->onlinetime && strtotime($this->onlinetime) > strtotime('-9 minutes')) {
return;
}
Lib::db()->query('UPDATE users SET onlinetime=CURRENT_TIMESTAMP WHERE id=?;', [$this->id]);
}
/**
* Heal HP by a given amount. Caps to max HP. Returns number of points restored.
*/
public function restore_hp(int $amount): int
{
$initial_hp = $this->currenthp;
$this->currenthp += $amount;
if ($this->currenthp > $this->maxhp) {
$this->currenthp = $this->maxhp;
}
return $this->currenthp - $initial_hp;
}
/**
* Save works just as it does on the Model class. In our case, though, user state changing may necessitate
* OOB swaps for parts of the UI that have user data displayed. Left and right nav, for example. In these cases,
* we set a flag in GLOBALS state to signify this.
*/
public function save(): bool
{
if (empty($this->changes)) {
return true;
}
$placeholders = [];
$values = [];
foreach ($this->changes as $key => $value) {
$placeholders[] = "$key=?";
$values[] = $value;
}
$values[] = $this->id;
$query = 'UPDATE '.$this->table_name.' SET '.implode(', ', $placeholders).' WHERE id = ?;';
$result = Lib::db()->query($query, $values);
if ($result === false) {
return false;
}
$GLOBALS['state']['user-state-changed'] = true;
return true;
}
}