File "EvaluacionAsigControlador.php"

Full Path: C:/wamp64/www/Formaciones/Controladores/EvaluacionAsigControlador.php
File size: 12.9 KB
MIME-type: text/x-php
Charset: utf-8

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