<?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; } }