151 lines
5.6 KiB
PHP

<?php
/**
* Usuario.php — Modelo de usuarios
*/
declare(strict_types=1);
require_once __DIR__ . '/../config/config.php';
class UsuarioModel {
private PDO $db;
public function __construct() {
$this->db = getDB();
}
public function todos(bool $incluirEliminados = false): array {
$sql = "SELECT u.*, r.nombre AS rol_nombre
FROM usuarios u
JOIN roles r ON r.id = u.rol_id
WHERE u.activo = 1";
if (!$incluirEliminados) $sql .= " AND u.deleted_at IS NULL";
$sql .= " ORDER BY u.nombre, u.apellido";
return $this->db->query($sql)->fetchAll();
}
public function buscarPorId(int $id): ?array {
$stmt = $this->db->prepare(
"SELECT u.*, r.nombre AS rol_nombre, r.permisos
FROM usuarios u JOIN roles r ON r.id = u.rol_id
WHERE u.id = ? AND u.deleted_at IS NULL"
);
$stmt->execute([$id]);
return $stmt->fetch() ?: null;
}
public function buscarPorUsername(string $username): ?array {
$stmt = $this->db->prepare(
"SELECT u.*, r.nombre AS rol_nombre, r.permisos
FROM usuarios u JOIN roles r ON r.id = u.rol_id
WHERE u.username = ? AND u.deleted_at IS NULL"
);
$stmt->execute([$username]);
return $stmt->fetch() ?: null;
}
public function buscarPorEmail(string $email): ?array {
$stmt = $this->db->prepare(
"SELECT * FROM usuarios WHERE email = ? AND deleted_at IS NULL"
);
$stmt->execute([$email]);
return $stmt->fetch() ?: null;
}
public function buscarPorToken(string $token): ?array {
$stmt = $this->db->prepare(
"SELECT * FROM usuarios WHERE token_recuperacion = ? AND deleted_at IS NULL"
);
$stmt->execute([$token]);
return $stmt->fetch() ?: null;
}
public function crear(array $datos): int {
$stmt = $this->db->prepare(
"INSERT INTO usuarios (rol_id, nombre, apellido, email, username, password_hash, cargo, area, supervisor_id)
VALUES (:rol_id, :nombre, :apellido, :email, :username, :password_hash, :cargo, :area, :supervisor_id)"
);
$stmt->execute([
':rol_id' => $datos['rol_id'],
':nombre' => $datos['nombre'],
':apellido' => $datos['apellido'],
':email' => $datos['email'],
':username' => $datos['username'],
':password_hash' => password_hash($datos['password'], PASSWORD_BCRYPT, ['cost' => 12]),
':cargo' => $datos['cargo'] ?? null,
':area' => $datos['area'] ?? null,
':supervisor_id' => $datos['supervisor_id'] ?? null,
]);
return (int)$this->db->lastInsertId();
}
public function actualizar(int $id, array $datos): bool {
$stmt = $this->db->prepare(
"UPDATE usuarios SET rol_id=:rol_id, nombre=:nombre, apellido=:apellido,
email=:email, username=:username, cargo=:cargo, area=:area,
supervisor_id=:supervisor_id, activo=:activo
WHERE id=:id"
);
return $stmt->execute([
':rol_id' => $datos['rol_id'],
':nombre' => $datos['nombre'],
':apellido' => $datos['apellido'],
':email' => $datos['email'],
':username' => $datos['username'],
':cargo' => $datos['cargo'] ?? null,
':area' => $datos['area'] ?? null,
':supervisor_id'=> $datos['supervisor_id'] ?? null,
':activo' => $datos['activo'] ?? 1,
':id' => $id,
]);
}
public function actualizarPassword(int $id, string $hash): bool {
$stmt = $this->db->prepare(
"UPDATE usuarios SET password_hash=?, token_recuperacion=NULL, token_expira=NULL WHERE id=?"
);
return $stmt->execute([$hash, $id]);
}
public function actualizarUltimoLogin(int $id): void {
$stmt = $this->db->prepare("UPDATE usuarios SET ultimo_login=NOW() WHERE id=?");
$stmt->execute([$id]);
}
public function guardarTokenRecuperacion(int $id, string $token, string $expira): void {
$stmt = $this->db->prepare(
"UPDATE usuarios SET token_recuperacion=?, token_expira=? WHERE id=?"
);
$stmt->execute([$token, $expira, $id]);
}
public function eliminarLogico(int $id): bool {
$stmt = $this->db->prepare("UPDATE usuarios SET deleted_at=NOW(), activo=0 WHERE id=?");
return $stmt->execute([$id]);
}
public function restaurar(int $id): bool {
$stmt = $this->db->prepare("UPDATE usuarios SET deleted_at=NULL, activo=1 WHERE id=?");
return $stmt->execute([$id]);
}
public function emailExiste(string $email, ?int $excepto = null): bool {
$sql = "SELECT id FROM usuarios WHERE email=? AND deleted_at IS NULL";
$params = [$email];
if ($excepto) { $sql .= " AND id != ?"; $params[] = $excepto; }
return (bool)$this->db->prepare($sql)->execute($params)
&& $this->db->query("SELECT FOUND_ROWS()")->fetchColumn();
}
public function roles(): array {
return $this->db->query("SELECT * FROM roles ORDER BY id")->fetchAll();
}
public function usuariosParaSelector(): array {
return $this->db->query(
"SELECT id, CONCAT(nombre,' ',apellido) AS nombre_completo, email, area
FROM usuarios WHERE activo=1 AND deleted_at IS NULL ORDER BY nombre"
)->fetchAll();
}
}