Mejoras de seguridad y nueva tabla de turnos para ayudantes

- Agregado sistema de protección CSRF con tokens
- Creada clase Session para gestión centralizada de sesiones
- Mejorado manejo de errores en Database (sin die())
- Refactorizado Auth para usar nueva clase Session
- Agregada validación CSRF a formularios de login y admin
- Agregada validación de roles en modelo User
- Mejorada vista de ayudante con tabla de horarios por semana
- Agregada tabla de Turnos de Ayudantes con fechas en columnas
This commit is contained in:
nickpons666
2026-01-20 15:24:07 -06:00
parent dc8e83db6c
commit 05631e4a63
10 changed files with 467 additions and 254 deletions

View File

@@ -3,6 +3,7 @@ require_once __DIR__ . '/../src/Auth.php';
require_once __DIR__ . '/../src/User.php';
require_once __DIR__ . '/../src/DiasHorarios.php';
require_once __DIR__ . '/../src/Asignacion.php';
require_once __DIR__ . '/../src/Database.php';
$auth = new Auth();
$auth->requireAuth();
@@ -15,18 +16,17 @@ if ($auth->isAdmin()) {
$user = $auth->getCurrentUser();
$horariosModel = new DiasHorarios();
$asignacionModel = new Asignacion();
$db = Database::getInstance()->getConnection();
$horarios = $horariosModel->getActivos();
$asignacionActual = $asignacionModel->getAsignacionActual();
// Obtener todas las asignaciones de las próximas semanas
$semanasFuturas = [];
// Encontrar el domingo de esta semana
$hoy = new DateTime();
$diaSemana = (int)$hoy->format('w'); // 0 = domingo, 6 = sábado
$diaSemana = (int)$hoy->format('w');
$domingoEstaSemana = clone $hoy;
$domingoEstaSemana->modify('-' . $diaSemana . ' days'); // Restar días para llegar al domingo
$domingoEstaSemana->modify('-' . $diaSemana . ' days');
for ($i = 0; $i <= 4; $i++) {
$semanaDomingo = clone $domingoEstaSemana;
@@ -37,7 +37,7 @@ for ($i = 0; $i <= 4; $i++) {
$semanasFuturas[] = [
'inicio' => $semanaInicio,
'fin' => date('Y-m-d', strtotime('+5 days', strtotime($semanaInicio))), // +5 días = domingo a viernes
'fin' => date('Y-m-d', strtotime('+5 days', strtotime($semanaInicio))),
'asignaciones' => $asignacionesSemana,
'asignacion' => !empty($asignacionesSemana) ? $asignacionesSemana[0] : null
];
@@ -45,7 +45,6 @@ for ($i = 0; $i <= 4; $i++) {
$miTurno = $asignacionActual && $asignacionActual['id'] == $user['id'];
// También verificar si el usuario tiene turno en las próximas semanas
$misAsignacionesFuturas = [];
foreach ($semanasFuturas as $semana) {
foreach ($semana['asignaciones'] as $asignacion) {
@@ -57,6 +56,12 @@ foreach ($semanasFuturas as $semana) {
}
}
}
$userModel = new User();
$ayudantes = $userModel->getAyudantesActivos();
$domingo = new DateTime();
$domingo->modify('-' . (int)$domingo->format('w') . ' days');
?>
<!DOCTYPE html>
<html lang="es">
@@ -81,21 +86,18 @@ foreach ($semanasFuturas as $semana) {
<h2 class="mb-4">Mis Turnos</h2>
<?php
// Verificar si tiene turno esta semana (hoy está entre domingo y viernes de la semana actual)
$hoy = new DateTime();
$diaSemana = (int)$hoy->format('w'); // 0 = domingo, 6 = sábado
$domingoActual = clone $hoy;
$domingoActual->modify('-' . $diaSemana . ' days'); // Restar días para llegar al domingo
$viernesActual = clone $domingoActual;
$viernesActual->modify('+5 days');
$asignacionEstaSemana = $asignacionModel->getAsignacionPorSemana($domingoActual->format('Y-m-d'));
$tengoTurnoEstaSemana = $asignacionEstaSemana && $asignacionEstaSemana['id'] == $user['id'];
if ($tengoTurnoEstaSemana):
?>
$hoy = new DateTime();
$diaSemana = (int)$hoy->format('w');
$domingoActual = clone $hoy;
$domingoActual->modify('-' . $diaSemana . ' days');
$asignacionEstaSemana = $asignacionModel->getAsignacionPorSemana($domingoActual->format('Y-m-d'));
$tengoTurnoEstaSemana = $asignacionEstaSemana && $asignacionEstaSemana['id'] == $user['id'];
if ($tengoTurnoEstaSemana):
?>
<div class="alert alert-success mb-4">
<strong>¡Tienes turno esta semana!</strong><br>
<strong>Tienes turno esta semana!</strong><br>
Del <?= date('d/m/y', strtotime($asignacionEstaSemana['semana_inicio'])) ?>
al <?= date('d/m/y', strtotime($asignacionEstaSemana['semana_fin'])) ?>
</div>
@@ -103,125 +105,161 @@ foreach ($semanasFuturas as $semana) {
<div class="alert alert-secondary mb-4">
<strong>Turno esta semana:</strong> <?= htmlspecialchars($asignacionEstaSemana['nombre']) ?><br>
<?php if (!empty($misAsignacionesFuturas)): ?>
Tu próximo turno: <?= date('d/m/y', strtotime($misAsignacionesFuturas[0]['semana']['inicio'])) ?>
Tu proximo turno: <?= date('d/m/y', strtotime($misAsignacionesFuturas[0]['semana']['inicio'])) ?>
al <?= date('d/m/y', strtotime($misAsignacionesFuturas[0]['semana']['fin'])) ?>
<?php else: ?>
Tu próximo turno será en las próximas semanas.
Tu proximo turno sera en las proximas semanas.
<?php endif; ?>
</div>
<?php elseif (!empty($misAsignacionesFuturas)): ?>
<div class="alert alert-info mb-4">
<strong>Próximo turno:</strong><br>
<strong>Proximo turno:</strong><br>
Del <?= date('d/m/y', strtotime($misAsignacionesFuturas[0]['semana']['inicio'])) ?>
al <?= date('d/m/y', strtotime($misAsignacionesFuturas[0]['semana']['fin'])) ?>
</div>
<?php else: ?>
<div class="alert alert-warning mb-4">
No hay turnos asignados para las próximas semanas.
No hay turnos asignados para las proximas semanas.
</div>
<?php endif; ?>
<div class="card shadow-sm">
<div class="card-header bg-primary text-white">
<h5 class="mb-0">Horarios de Apertura del Contenedor</h5>
<div class="card-header bg-warning text-dark">
<h5 class="mb-0">Horarios por Semana</h5>
</div>
<div class="card-body">
<?php
$diasNombres = [
'domingo' => 'Domingo',
'lunes' => 'Lunes',
'martes' => 'Martes',
'miercoles' => 'Miercoles',
'jueves' => 'Jueves',
'viernes' => 'Viernes',
'sabado' => 'Sabado'
];
$diasOrden = ['domingo', 'lunes', 'martes', 'miercoles', 'jueves', 'viernes', 'sabado'];
?>
<div class="table-responsive">
<table class="table table-hover mb-0">
<thead>
<table class="table table-bordered table-sm mb-0" style="min-width: 600px;">
<thead class="table-light">
<tr>
<th>Día</th>
<th>Hora Apertura</th>
<th>Hora Cierre</th>
<th class="text-center" style="min-width: 120px;">Semana</th>
<?php foreach ($diasOrden as $dia): ?>
<th class="text-center"><?= $diasNombres[$dia] ?></th>
<?php endforeach; ?>
</tr>
</thead>
<tbody>
<?php foreach ($horarios as $h): ?>
<tr class="<?= $miTurno ? 'table-primary' : '' ?>">
<td><strong><?= ucfirst($h['dia_semana']) ?></strong></td>
<td><?= date('H:i', strtotime($h['hora_apertura'])) ?></td>
<td><?= date('H:i', strtotime($h['hora_cierre'])) ?></td>
<?php foreach ($semanasFuturas as $index => $semana): ?>
<?php
$esMiTurno = !empty($semana['asignaciones']) && in_array($user['id'], array_column($semana['asignaciones'], 'id'));
$rowClass = $esMiTurno ? 'table-success' : '';
?>
<tr class="<?= $rowClass ?>">
<td class="text-center align-middle">
<strong><?= date('d/m', strtotime($semana['inicio'])) ?></strong>
<?php if ($index === 0): ?>
<span class="badge bg-primary ms-1">Actual</span>
<?php endif; ?>
<?php if ($esMiTurno): ?>
<span class="badge bg-success ms-1">Tu turno</span>
<?php endif; ?>
</td>
<?php foreach ($diasOrden as $dia): ?>
<?php
$horarioDia = null;
foreach ($horarios as $h) {
if ($h['dia_semana'] === $dia) {
$horarioDia = $h;
break;
}
}
$esActivo = $horarioDia && $horarioDia['activo'];
$claseDia = '';
if ($esMiTurno && $esActivo) {
$claseDia = 'bg-success text-white';
} elseif (!$esActivo) {
$claseDia = 'text-muted';
}
?>
<td class="text-center <?= $claseDia ?>" style="min-width: 100px;">
<?php if ($esActivo): ?>
<small><?= date('H:i', strtotime($horarioDia['hora_apertura'])) ?></small><br>
<small><?= date('H:i', strtotime($horarioDia['hora_cierre'])) ?></small>
<?php else: ?>
<small class="text-muted">Cerrado</small>
<?php endif; ?>
</td>
<?php endforeach; ?>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
</div>
<!-- Tabla de Asignaciones de Turnos -->
<div class="card mt-4 shadow-sm">
<div class="card-header bg-success text-white">
<h5 class="mb-0">Calendario de Turnos</h5>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-hover mb-0">
<thead>
<tr>
<th>Semana</th>
<th>Período</th>
<th>Asignado a</th>
<th>Estado</th>
</tr>
</thead>
<tbody>
<?php foreach ($semanasFuturas as $index => $semana): ?>
<tr class="<?= !empty($semana['asignaciones']) && in_array($user['id'], array_column($semana['asignaciones'], 'id')) ? 'table-success' : '' ?>">
<td>
<strong>Semana <?= date('d/m/y', strtotime($semana['inicio'])) ?></strong>
<?php if ($index === 0): ?>
<span class="badge bg-primary ms-1">Actual</span>
<?php endif; ?>
</td>
<td>
<?= date('d/m/y', strtotime($semana['inicio'])) ?> (Dom) -
<?= date('d/m/y', strtotime($semana['fin'])) ?> (Vie)
</td>
<td>
<?php if (!empty($semana['asignaciones'])): ?>
<?php foreach ($semana['asignaciones'] as $asignacion): ?>
<div class="mb-1">
<?= htmlspecialchars($asignacion['nombre']) ?>
<?php if ($asignacion['id'] == $user['id']): ?>
<span class="badge bg-success ms-1">Tú</span>
<?php endif; ?>
</div>
<?php endforeach; ?>
<?php else: ?>
<span class="text-muted">Sin asignar</span>
<?php endif; ?>
</td>
<td>
<?php if (!empty($semana['asignaciones']) && in_array($user['id'], array_column($semana['asignaciones'], 'id'))): ?>
<span class="badge bg-success">Tu turno</span>
<?php elseif (!empty($semana['asignaciones'])): ?>
<span class="badge bg-secondary">
<?= count($semana['asignaciones']) ?> asignado(s)
</span>
<?php else: ?>
<span class="badge bg-warning">Pendiente</span>
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<div class="mt-2">
<small class="text-muted">
<span class="badge bg-success text-white">Verde</span> = Tu turno activo |
<span class="badge bg-secondary text-white">Gris</span> = Dia cerrado |
Horario: Apertura - Cierre
</small>
</div>
</div>
</div>
<div class="card mt-4 shadow-sm">
<div class="card-header bg-info text-white">
<h5 class="mb-0">Información</h5>
<h5 class="mb-0">Turnos de Ayudantes</h5>
</div>
<div class="card-body">
<ul class="mb-0">
<li>Los turnos se asignan de forma rotativa semanalmente.</li>
<li>Cada semana inicia en lunes y termina en domingo.</li>
<li>Recuerda estar atento a tu turno para abrir y cerrar el contenedor.</li>
<li>Las filas en verde indican tus turnos asignados.</li>
</ul>
<div class="table-responsive">
<table class="table table-hover mb-0">
<thead>
<tr>
<th>Ayudante</th>
<th class="text-center">Fecha 1</th>
<th class="text-center">Fecha 2</th>
<th class="text-center">Fecha 3</th>
<th class="text-center">Fecha 4</th>
</tr>
</thead>
<tbody>
<?php foreach ($ayudantes as $ayudante): ?>
<?php
$stmt = $db->prepare("
SELECT semana_inicio, semana_fin
FROM asignaciones_turnos
WHERE user_id = ? AND semana_inicio >= CURDATE()
ORDER BY semana_inicio
LIMIT 4
");
$stmt->execute([$ayudante['id']]);
$turnos = $stmt->fetchAll();
?>
<tr class="<?= $ayudante['id'] == $user['id'] ? 'table-success' : '' ?>">
<td>
<?= htmlspecialchars($ayudante['nombre']) ?>
<?php if ($ayudante['id'] == $user['id']): ?>
<span class="badge bg-success ms-1">Tu</span>
<?php endif; ?>
</td>
<?php for ($i = 0; $i < 4; $i++): ?>
<td class="text-center">
<?php if (isset($turnos[$i])): ?>
<span class="badge bg-primary">
<?= date('d/m/Y', strtotime($turnos[$i]['semana_inicio'])) ?> -
<?= date('d/m/Y', strtotime($turnos[$i]['semana_fin'])) ?>
</span>
<?php else: ?>
<span class="text-muted">-</span>
<?php endif; ?>
</td>
<?php endfor; ?>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
</div>
</div>