205 lines
5.5 KiB
PHP
205 lines
5.5 KiB
PHP
<?php
|
|
|
|
namespace App\Models;
|
|
|
|
use App\Core\Database;
|
|
|
|
class User
|
|
{
|
|
private Database $database;
|
|
|
|
public function __construct(Database $database)
|
|
{
|
|
$this->database = $database;
|
|
}
|
|
|
|
public function find(int $id): ?array
|
|
{
|
|
return $this->database->fetch(
|
|
"SELECT * FROM users WHERE id = :id",
|
|
['id' => $id]
|
|
);
|
|
}
|
|
|
|
public function findByEmail(string $email): ?array
|
|
{
|
|
return $this->database->fetch(
|
|
"SELECT * FROM users WHERE email = :email",
|
|
['email' => $email]
|
|
);
|
|
}
|
|
|
|
public function findAll(array $filters = [], int $limit = null, int $offset = 0): array
|
|
{
|
|
$sql = "SELECT * FROM users WHERE 1=1";
|
|
$params = [];
|
|
|
|
if (!empty($filters['role'])) {
|
|
$sql .= " AND role = :role";
|
|
$params['role'] = $filters['role'];
|
|
}
|
|
|
|
if (isset($filters['active'])) {
|
|
$sql .= " AND active = :active";
|
|
$params['active'] = $filters['active'];
|
|
}
|
|
|
|
if (!empty($filters['search'])) {
|
|
$sql .= " AND (name LIKE :search OR email LIKE :search)";
|
|
$params['search'] = '%' . $filters['search'] . '%';
|
|
}
|
|
|
|
$sql .= " ORDER BY name ASC";
|
|
|
|
if ($limit) {
|
|
$sql .= " LIMIT :limit OFFSET :offset";
|
|
$params['limit'] = $limit;
|
|
$params['offset'] = $offset;
|
|
}
|
|
|
|
return $this->database->fetchAll($sql, $params);
|
|
}
|
|
|
|
public function create(array $data): int
|
|
{
|
|
$data['passhash'] = password_hash($data['password'], PASSWORD_ARGON2ID);
|
|
unset($data['password']);
|
|
|
|
$data['created_at'] = date('Y-m-d H:i:s');
|
|
$data['updated_at'] = date('Y-m-d H:i:s');
|
|
|
|
return $this->database->insert('users', $data);
|
|
}
|
|
|
|
public function update(int $id, array $data): bool
|
|
{
|
|
if (isset($data['password']) && !empty($data['password'])) {
|
|
$data['passhash'] = password_hash($data['password'], PASSWORD_ARGON2ID);
|
|
unset($data['password']);
|
|
}
|
|
|
|
$data['updated_at'] = date('Y-m-d H:i:s');
|
|
|
|
return $this->database->update('users', $data, 'id = :id', ['id' => $id]) > 0;
|
|
}
|
|
|
|
public function delete(int $id): bool
|
|
{
|
|
return $this->database->delete('users', 'id = :id', ['id' => $id]) > 0;
|
|
}
|
|
|
|
public function toggleStatus(int $id): bool
|
|
{
|
|
$user = $this->find($id);
|
|
if (!$user) {
|
|
return false;
|
|
}
|
|
|
|
$newStatus = !$user['active'];
|
|
return $this->update($id, ['active' => $newStatus]);
|
|
}
|
|
|
|
public function count(array $filters = []): int
|
|
{
|
|
$sql = "SELECT COUNT(*) as total FROM users WHERE 1=1";
|
|
$params = [];
|
|
|
|
if (!empty($filters['role'])) {
|
|
$sql .= " AND role = :role";
|
|
$params['role'] = $filters['role'];
|
|
}
|
|
|
|
if (isset($filters['active'])) {
|
|
$sql .= " AND active = :active";
|
|
$params['active'] = $filters['active'];
|
|
}
|
|
|
|
$result = $this->database->fetch($sql, $params);
|
|
return $result['total'] ?? 0;
|
|
}
|
|
|
|
public function getActiveUsers(): array
|
|
{
|
|
return $this->findAll(['active' => true]);
|
|
}
|
|
|
|
public function getUsersByRole(string $role): array
|
|
{
|
|
return $this->findAll(['role' => $role]);
|
|
}
|
|
|
|
public function searchUsers(string $search): array
|
|
{
|
|
return $this->findAll(['search' => $search]);
|
|
}
|
|
|
|
public function updateLastLogin(int $id): bool
|
|
{
|
|
return $this->update($id, ['last_login' => date('Y-m-d H:i:s')]);
|
|
}
|
|
|
|
public function changePassword(int $id, string $newPassword): bool
|
|
{
|
|
return $this->update($id, ['password' => $newPassword]);
|
|
}
|
|
|
|
public function getUsersWithStats(): array
|
|
{
|
|
$sql = "SELECT
|
|
u.*,
|
|
COUNT(DISTINCT a.id) as asset_count,
|
|
COUNT(DISTINCT al.id) as audit_count
|
|
FROM users u
|
|
LEFT JOIN assets a ON u.id = a.created_by
|
|
LEFT JOIN audit_log al ON u.id = al.user_id
|
|
GROUP BY u.id
|
|
ORDER BY u.name ASC";
|
|
|
|
return $this->database->fetchAll($sql);
|
|
}
|
|
|
|
public function getRecentActivity(int $userId, int $limit = 10): array
|
|
{
|
|
$sql = "SELECT al.*, a.inventarnummer, a.bezeichnung
|
|
FROM audit_log al
|
|
LEFT JOIN assets a ON al.table_name = 'assets' AND al.record_id = a.id
|
|
WHERE al.user_id = :user_id
|
|
ORDER BY al.created_at DESC
|
|
LIMIT :limit";
|
|
|
|
return $this->database->fetchAll($sql, [
|
|
'user_id' => $userId,
|
|
'limit' => $limit
|
|
]);
|
|
}
|
|
|
|
public function validateEmail(string $email, int $excludeId = null): bool
|
|
{
|
|
$sql = "SELECT COUNT(*) as total FROM users WHERE email = :email";
|
|
$params = ['email' => $email];
|
|
|
|
if ($excludeId) {
|
|
$sql .= " AND id != :exclude_id";
|
|
$params['exclude_id'] = $excludeId;
|
|
}
|
|
|
|
$result = $this->database->fetch($sql, $params);
|
|
return ($result['total'] ?? 0) === 0;
|
|
}
|
|
|
|
public function getRoles(): array
|
|
{
|
|
return [
|
|
'admin' => 'Administrator',
|
|
'auditor' => 'Auditor',
|
|
'employee' => 'Mitarbeiter'
|
|
];
|
|
}
|
|
|
|
public function getRoleName(string $role): string
|
|
{
|
|
$roles = $this->getRoles();
|
|
return $roles[$role] ?? $role;
|
|
}
|
|
}
|