<?php
// Controladores/EvaluacionAsigControlador.php
require_once 'Modelos/EvaluacionAsigModelo.php';
class EvaluacionAsigControlador {
private $modelo;
private $db;
public function __construct($db) {
$this->db = $db;
$this->modelo = new EvaluacionAsigModelo($db);
// Verificar autenticación y roles permitidos
if (!esta_autenticado()) {
header("Location: index.php?r=auth/login");
exit;
}
$usuario = usuario_actual();
$roles_permitidos = ['admin', 'instructor', 'student'];
if (!in_array($usuario['rol'], $roles_permitidos)) {
$_SESSION['error'] = 'Acceso denegado. Rol no autorizado.';
header("Location: index.php?r=dashboard");
exit;
}
}
// Listar mis cursos asignados
public function misCursos() {
$usuario = usuario_actual();
$uid = $usuario['id'];
$busqueda = $_GET['s'] ?? '';
// Paginación
$por_pagina = 10;
$pagina_actual = isset($_GET['p']) ? (int)$_GET['p'] : 1;
if ($pagina_actual < 1) $pagina_actual = 1;
$inicio = ($pagina_actual - 1) * $por_pagina;
// Obtener datos
$total_registros = $this->modelo->contarCursosAsignados($uid, $busqueda);
$total_paginas = ceil($total_registros / $por_pagina);
$cursos = $this->modelo->obtenerCursosAsignadosPaginados($uid, $busqueda, $por_pagina, $inicio);
require_once 'Vistas/plantilla/encabezado.php';
require_once 'Vistas/evaluaciones/mis_cursos.php';
require_once 'Vistas/plantilla/pie.php';
}
// Ver detalles de un curso específico
public function verCurso() {
$usuario = usuario_actual();
$uid = $usuario['id'];
$cid = isset($_GET['id']) ? (int)$_GET['id'] : 0;
if ($cid === 0) {
$_SESSION['error'] = 'Curso no especificado.';
header("Location: index.php?r=evaluaciones/mis-cursos");
exit;
}
// Verificar que el curso esté asignado al usuario
$curso = $this->modelo->verificarAccesoCurso($uid, $cid);
if (!$curso) {
$_SESSION['error'] = 'Curso no encontrado o no tienes acceso.';
header("Location: index.php?r=evaluaciones/mis-cursos");
exit;
}
// Obtener materiales del curso
$materiales = $this->modelo->obtenerMaterialesCurso($cid);
// Obtener evaluación del curso
$quiz = $this->modelo->obtenerEvaluacionCurso($cid);
// Si hay evaluación, verificar intentos del usuario
$attempt_count = 0;
$best_score = 0;
$last_score = 0;
if ($quiz) {
$stats = $this->modelo->obtenerEstadisticasEvaluacion($quiz['id'], $uid);
$attempt_count = $stats['attempt_count'];
$best_score = $stats['best_score'];
$last_score = $stats['last_score'];
}
// Formatear fecha límite
$limite_at_display = '';
if (!empty($curso['limite_at'])) {
$limite_at_display = date('d/m/Y H:i', strtotime($curso['limite_at']));
}
// Variables necesarias para la vista
$course = $curso;
$materials = $materiales;
$u = $usuario;
require_once 'Vistas/plantilla/encabezado.php';
require_once 'Vistas/evaluaciones/ver_curso.php';
require_once 'Vistas/plantilla/pie.php';
}
// Ver evaluaciones realizadas de un curso
public function verEvaluaciones() {
$usuario = usuario_actual();
$uid = $usuario['id'];
$course_id = isset($_GET['course_id']) ? (int)$_GET['course_id'] : 0;
if ($course_id === 0) {
$_SESSION['error'] = 'Curso no especificado.';
header("Location: index.php?r=evaluaciones/mis-cursos");
exit;
}
// Verificar acceso al curso
$curso = $this->modelo->verificarAccesoCurso($uid, $course_id);
if (!$curso) {
$_SESSION['error'] = 'Curso no encontrado o no tienes acceso.';
header("Location: index.php?r=evaluaciones/mis-cursos");
exit;
}
// Obtener intentos de evaluación
$attempts = $this->modelo->obtenerIntentosEvaluacion($uid, $course_id);
// Vista detallada de un intento específico
$attempt_id = isset($_GET['attempt_id']) ? (int)$_GET['attempt_id'] : 0;
$detailed_view = false;
$attempt_details = null;
$answers = [];
if ($attempt_id > 0) {
$attempt_details = $this->modelo->obtenerDetalleIntento($attempt_id, $uid);
if ($attempt_details) {
$detailed_view = true;
$answers = $this->modelo->obtenerRespuestasIntento($attempt_id);
}
}
// Variables para la vista
$course = $curso;
require_once 'Vistas/plantilla/encabezado.php';
require_once 'Vistas/evaluaciones/ver_evaluaciones.php';
require_once 'Vistas/plantilla/pie.php';
}
// Descargar diploma
public function diploma() {
$usuario = usuario_actual();
$uid = $usuario['id'];
$course_id = isset($_GET['course_id']) ? (int)$_GET['course_id'] : 0;
if ($course_id === 0) {
$_SESSION['error'] = 'Curso no especificado.';
header("Location: index.php?r=evaluaciones/mis-cursos");
exit;
}
// Verificar que el usuario completó el curso
$result = $this->modelo->verificarCompletacionCurso($uid, $course_id);
if (!$result) {
$_SESSION['error'] = 'Curso no encontrado o no tienes acceso.';
header("Location: index.php?r=evaluaciones/mis-cursos");
exit;
}
// Verificar que aprobó al menos un quiz
if ($result['quizzes_passed'] == 0) {
$_SESSION['error'] = 'Debes aprobar la evaluación del curso para obtener el diploma.';
header("Location: index.php?r=evaluaciones/ver-curso&id=" . $course_id);
exit;
}
// Preparar datos para el diploma
$nombre_estudiante = !empty($result['name']) ? $result['name'] : 'Nombre del Estudiante';
$nombre_profesional = !empty($result['namePro']) ? $result['namePro'] : 'Nombre del Instructor';
$cargo_estudiante = !empty($result['cargo']) ? $result['cargo'] : 'OPERARIO';
$cargo_profesional = !empty($result['cargoPro']) ? $result['cargoPro'] : 'INSTRUCTOR';
// Capitalizar nombres
$nombre_estudiante = mb_convert_case($nombre_estudiante, MB_CASE_TITLE, "UTF-8");
$nombre_profesional = mb_convert_case($nombre_profesional, MB_CASE_TITLE, "UTF-8");
// Preparar fecha
$meses = ['Enero','Febrero','Marzo','Abril','Mayo','Junio','Julio','Agosto','Septiembre','Octubre','Noviembre','Diciembre'];
$fecha_aprobacion = $result['submitted_at'] ?? date('Y-m-d H:i:s');
$timestamp_aprobacion = strtotime(substr($fecha_aprobacion, 0, 10));
$dia = date('d', $timestamp_aprobacion);
$mes = $meses[date('n', $timestamp_aprobacion) - 1];
$anio = date('Y', $timestamp_aprobacion);
$fecha_text = $dia . ' del mes de ' . $mes . ' de ' . $anio;
// Limpiar buffer
while (ob_get_level()) {
ob_end_clean();
}
require_once 'Vistas/evaluaciones/diploma.php';
exit;
}
// Tomar quiz/evaluación
public function tomarQuiz() {
$usuario = usuario_actual();
$uid = $usuario['id'];
$qid = isset($_GET['id']) ? (int)$_GET['id'] : 0;
if ($qid === 0) {
$_SESSION['error'] = 'Evaluación no especificada.';
header("Location: index.php?r=evaluaciones/mis-cursos");
exit;
}
// Obtener datos de la evaluación y el curso
$q = $this->modelo->obtenerQuizConCurso($qid);
if (!$q) {
$_SESSION['error'] = 'Evaluación no encontrada.';
header("Location: index.php?r=evaluaciones/mis-cursos");
exit;
}
// Validar fecha límite si existe
if (!empty($q['limite_at'])) {
$limite_timestamp = strtotime($q['limite_at']);
$current_timestamp = time();
if ($current_timestamp > $limite_timestamp) {
$limite_formateado = date('d/m/Y H:i', $limite_timestamp);
$_SESSION['error'] = 'El plazo para presentar esta evaluación expiró el ' . $limite_formateado . '. No puedes iniciar un nuevo intento.';
header("Location: index.php?r=evaluaciones/ver-curso&id=" . $q['course_id']);
exit;
}
}
// Verificar intentos (máximo 3)
$stats = $this->modelo->obtenerEstadisticasEvaluacion($qid, $uid);
$attempt_count = $stats['attempt_count'];
if ($attempt_count >= 3) {
$_SESSION['error'] = 'Ya has agotado tus 3 intentos para esta evaluación.';
header("Location: index.php?r=evaluaciones/ver-curso&id=" . $q['course_id']);
exit;
}
// Obtener preguntas del quiz
$qs = $this->modelo->obtenerPreguntasQuiz($qid);
// Número de intento actual
$current_attempt_number = $attempt_count + 1;
require_once 'Vistas/plantilla/encabezado.php';
require_once 'Vistas/evaluaciones/tomar_quiz.php';
require_once 'Vistas/plantilla/pie.php';
}
// Enviar respuestas del quiz
public function enviarQuiz() {
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
header("Location: index.php?r=evaluaciones/mis-cursos");
exit;
}
// Verificar CSRF si lo tienes implementado
// verificar_csrf();
$usuario = usuario_actual();
$uid = $usuario['id'];
$qid = isset($_POST['quiz_id']) ? (int)$_POST['quiz_id'] : 0;
$q = $this->modelo->obtenerQuizConCurso($qid);
if (!$q) {
$_SESSION['error'] = 'Evaluación no existe.';
header("Location: index.php?r=evaluaciones/mis-cursos");
exit;
}
// Verificar intentos (máximo 3)
$stats = $this->modelo->obtenerEstadisticasEvaluacion($qid, $uid);
$attempt_count = $stats['attempt_count'];
if ($attempt_count >= 3) {
$_SESSION['error'] = 'Ya has agotado tus 3 intentos para esta evaluación.';
header("Location: index.php?r=evaluaciones/ver-curso&id=" . $q['course_id']);
exit;
}
// Calcular número de intento actual
$attempt_number = $attempt_count + 1;
// Obtener la firma digital
$firma_digital = isset($_POST['firma_digital']) ? $_POST['firma_digital'] : '';
// Crear intento
$attempt_id = $this->modelo->crearIntento($qid, $uid, $attempt_number, $firma_digital);
// Evaluar respuestas
$total = 0.0;
$obtained = 0.0;
$preguntas = $this->modelo->obtenerPreguntasQuiz($qid);
while ($pregunta = $preguntas->fetch_assoc()) {
$total += (int)$pregunta['points'];
$field = 'q_' . $pregunta['id'];
if ($pregunta['question_type'] === 'mcq') {
$val = isset($_POST[$field]) ? $_POST[$field] : '';
$selected_option_id = 0;
if (strpos($val, 'opt_') === 0) {
$selected_option_id = (int)substr($val, 4);
}
// Verificar si es correcta
$opcion = $this->modelo->obtenerOpcion($selected_option_id);
$is_correct = $opcion ? ((int)$opcion['is_correct'] === 1) : false;
$points = $is_correct ? (int)$pregunta['points'] : 0;
$obtained += $points;
// Guardar respuesta
$this->modelo->guardarRespuestaMCQ($attempt_id, $pregunta['id'], $selected_option_id, $is_correct, $points);
} else {
// Pregunta abierta
$text = isset($_POST[$field]) ? trim($_POST[$field]) : '';
$this->modelo->guardarRespuestaAbierta($attempt_id, $pregunta['id'], $text);
}
}
// Calcular puntaje
$score = ($total > 0) ? round(($obtained / $total) * 100, 2) : 0.0;
// Actualizar intento con el puntaje
$this->modelo->actualizarIntento($attempt_id, $score);
$_SESSION['mensaje'] = 'Evaluación enviada (Intento ' . $attempt_number . ' de 3). Puntaje automático (solo opción múltiple): ' . $score . '%';
header("Location: index.php?r=evaluaciones/ver-curso&id=" . $q['course_id']);
exit;
}
}