Initial commit of the Asset Management System, including project structure, Docker configuration, database migrations, and core application files. Added user authentication, asset management features, and basic UI components.
This commit is contained in:
204
app/Models/User.php
Normal file
204
app/Models/User.php
Normal file
@@ -0,0 +1,204 @@
|
||||
<?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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user