125 lines
3.3 KiB
PHP
Executable File
125 lines
3.3 KiB
PHP
Executable File
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace ServerManager\Models;
|
|
|
|
use ServerManager\Core\Database;
|
|
use ServerManager\Core\Security;
|
|
|
|
class User
|
|
{
|
|
private Database $db;
|
|
private Security $security;
|
|
|
|
public function __construct()
|
|
{
|
|
$this->db = Database::getInstance();
|
|
$this->security = new Security();
|
|
}
|
|
|
|
public function findById(int $id): ?array
|
|
{
|
|
return $this->db->fetch('SELECT * FROM users WHERE id = ?', [$id]);
|
|
}
|
|
|
|
public function findByUsername(string $username): ?array
|
|
{
|
|
return $this->db->fetch('SELECT * FROM users WHERE username = ?', [$username]);
|
|
}
|
|
|
|
public function findByEmail(string $email): ?array
|
|
{
|
|
return $this->db->fetch('SELECT * FROM users WHERE email = ?', [$email]);
|
|
}
|
|
|
|
public function authenticate(string $username, string $password): ?array
|
|
{
|
|
$user = $this->findByUsername($username);
|
|
|
|
if (!$user) {
|
|
return null;
|
|
}
|
|
|
|
if (!$user['is_active']) {
|
|
return null;
|
|
}
|
|
|
|
if (!$this->security->verifyPassword($password, $user['password_hash'])) {
|
|
return null;
|
|
}
|
|
|
|
$this->updateLastLogin($user['id']);
|
|
|
|
return $user;
|
|
}
|
|
|
|
public function create(array $data): int
|
|
{
|
|
$data['password_hash'] = $this->security->hashPassword($data['password']);
|
|
unset($data['password']);
|
|
|
|
$data['created_at'] = date('Y-m-d H:i:s');
|
|
$data['updated_at'] = date('Y-m-d H:i:s');
|
|
|
|
if (empty($data['api_token'])) {
|
|
$data['api_token'] = $this->security->generateApiToken();
|
|
}
|
|
|
|
return $this->db->insert('users', $data);
|
|
}
|
|
|
|
public function update(int $id, array $data): bool
|
|
{
|
|
if (isset($data['password'])) {
|
|
$data['password_hash'] = $this->security->hashPassword($data['password']);
|
|
unset($data['password']);
|
|
}
|
|
|
|
$data['updated_at'] = date('Y-m-d H:i:s');
|
|
|
|
return $this->db->update('users', $data, 'id = ?', [$id]) > 0;
|
|
}
|
|
|
|
public function delete(int $id): bool
|
|
{
|
|
return $this->db->delete('users', 'id = ?', [$id]) > 0;
|
|
}
|
|
|
|
public function getAll(int $page = 1, int $perPage = 20): array
|
|
{
|
|
$offset = ($page - 1) * $perPage;
|
|
|
|
$total = $this->db->fetch("SELECT COUNT(*) as total FROM users");
|
|
$users = $this->db->fetchAll(
|
|
'SELECT id, username, email, role, is_active, last_login_at, created_at
|
|
FROM users ORDER BY created_at DESC LIMIT ? OFFSET ?',
|
|
[$perPage, $offset]
|
|
);
|
|
|
|
return [
|
|
'data' => $users,
|
|
'total' => (int) ($total['total'] ?? 0),
|
|
'page' => $page,
|
|
'per_page' => $perPage,
|
|
'total_pages' => ceil((int) ($total['total'] ?? 0) / $perPage),
|
|
];
|
|
}
|
|
|
|
public function findByApiToken(string $token): ?array
|
|
{
|
|
return $this->db->fetch('SELECT * FROM users WHERE api_token = ? AND is_active = 1', [$token]);
|
|
}
|
|
|
|
public function updateLastLogin(int $id): void
|
|
{
|
|
$this->db->update('users', ['last_login_at' => date('Y-m-d H:i:s')], 'id = ?', [$id]);
|
|
}
|
|
|
|
public function countAll(): int
|
|
{
|
|
$result = $this->db->fetch("SELECT COUNT(*) as total FROM users");
|
|
return (int) ($result['total'] ?? 0);
|
|
}
|
|
}
|