<?php // Controladores/InduccionControlador.php require_once 'Modelos/InduccionModelo.php'; class InduccionControlador { private $modelo; public function __construct($db, $db_empleados = null) { $this->modelo = new InduccionModelo($db, $db_empleados); $usuario = usuario_actual(); $roles_autorizados = ['admin', 'instructor']; if (!$usuario || !in_array($usuario['rol'], $roles_autorizados)) { header("Location: index.php?r=dashboard"); exit; } } public function index() { $busqueda = $_GET['busqueda'] ?? ''; $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; $total_registros = $this->modelo->contarTodas($busqueda); $total_paginas = ceil($total_registros / $por_pagina); $inducciones = $this->modelo->listarPaginadas($busqueda, $por_pagina, $inicio); $usuarios = $this->modelo->obtenerUsuarios(); require_once 'Vistas/admin/induccion.php'; } public function guardar() { if ($_SERVER['REQUEST_METHOD'] !== 'POST') { header("Location: index.php?r=admin/induccion"); exit; } $nombre = trim($_POST['nombre_induccion'] ?? ''); $cedula = trim($_POST['cedula_usuario'] ?? ''); $capacitador = trim($_POST['capacitador'] ?? ''); $fecha = $_POST['fecha_induccion'] ?? ''; if (empty($nombre) || empty($cedula) || empty($capacitador) || empty($fecha)) { $_SESSION['error'] = 'Todos los campos obligatorios deben ser completados'; header("Location: index.php?r=admin/induccion"); exit; } // Resolver el nombre completo desde la BD de empleados $nombre_usuario = $this->modelo->obtenerNombreEmpleado($cedula) ?? ''; $archivo_datos = null; if (isset($_FILES['evidencia']) && $_FILES['evidencia']['error'] === UPLOAD_ERR_OK) { $resultado = $this->procesarArchivoBLOB($_FILES['evidencia']); if ($resultado['success']) { $archivo_datos = $resultado['datos']; } else { $_SESSION['error'] = $resultado['error']; header("Location: index.php?r=admin/induccion"); exit; } } try { $ok = $this->modelo->crear($nombre, $cedula, $nombre_usuario, $capacitador, $fecha, $archivo_datos); $_SESSION[$ok ? 'exito' : 'error'] = $ok ? 'Induccion creada exitosamente' : 'Error al guardar la induccion'; } catch (Exception $e) { $_SESSION['error'] = 'Error al guardar: ' . $e->getMessage(); } header("Location: index.php?r=admin/induccion"); exit; } public function eliminar() { $id = intval($_GET['id'] ?? 0); if ($id <= 0) { $_SESSION['error'] = 'ID invalido'; header("Location: index.php?r=admin/induccion"); exit; } try { $ok = $this->modelo->eliminar($id); $_SESSION[$ok ? 'exito' : 'error'] = $ok ? 'Induccion eliminada exitosamente' : 'Error al eliminar'; } catch (Exception $e) { $_SESSION['error'] = 'Error al eliminar: ' . $e->getMessage(); } header("Location: index.php?r=admin/induccion"); exit; } // borrar es alias de eliminar public function borrar() { $this->eliminar(); } // verPdf cubre tanto ver-pdf como verPDF public function verPdf() { $id = intval($_GET['id'] ?? 0); if ($id <= 0) { header("HTTP/1.0 404 Not Found"); echo "Archivo no encontrado"; exit; } try { $archivo = $this->modelo->obtenerArchivo($id); if (!$archivo || empty($archivo['evidencia'])) { header("HTTP/1.0 404 Not Found"); echo "Archivo no encontrado en la base de datos"; exit; } if (ob_get_level()) ob_end_clean(); header('Content-Type: ' . ($archivo['evidencia_tipo'] ?? 'application/pdf')); header('Content-Length: ' . strlen($archivo['evidencia'])); header('Content-Disposition: inline; filename="' . ($archivo['evidencia_nombre'] ?? 'documento.pdf') . '"'); header('Cache-Control: public, must-revalidate, max-age=0'); header('Pragma: public'); header('X-Content-Type-Options: nosniff'); echo $archivo['evidencia']; exit; } catch (Exception $e) { header("HTTP/1.0 500 Internal Server Error"); echo "Error: " . htmlspecialchars($e->getMessage()); exit; } } public function descargar() { $id = isset($_GET['id']) ? (int)$_GET['id'] : 0; $archivo = $this->modelo->obtenerArchivo($id); if ($archivo && !empty($archivo['evidencia'])) { if (ob_get_length()) ob_clean(); header("Content-Type: application/pdf"); header("Content-Disposition: attachment; filename=\"" . $archivo['evidencia_nombre'] . "\""); header("Content-Length: " . strlen($archivo['evidencia'])); echo $archivo['evidencia']; exit; } $_SESSION['error'] = "Archivo no encontrado."; header("Location: index.php?r=admin/induccion"); exit; } private function procesarArchivoBLOB($archivo) { if ($archivo['error'] !== UPLOAD_ERR_OK) { return ['success' => false, 'error' => 'Error al cargar el archivo (Codigo: ' . $archivo['error'] . ')']; } $extension = strtolower(pathinfo($archivo['name'], PATHINFO_EXTENSION)); if ($extension !== 'pdf') { return ['success' => false, 'error' => 'Solo se permiten archivos PDF.']; } $finfo = finfo_open(FILEINFO_MIME_TYPE); $tipo_mime = finfo_file($finfo, $archivo['tmp_name']); finfo_close($finfo); if (!in_array($tipo_mime, ['application/pdf', 'application/x-pdf'])) { return ['success' => false, 'error' => 'El archivo no es un PDF valido. Tipo detectado: ' . $tipo_mime]; } if ($archivo['size'] > 10 * 1024 * 1024) { return ['success' => false, 'error' => 'El archivo excede el tamano maximo de 10MB.']; } $contenido = file_get_contents($archivo['tmp_name']); if ($contenido === false) { return ['success' => false, 'error' => 'No se pudo leer el contenido del archivo']; } return [ 'success' => true, 'datos' => [ 'contenido' => $contenido, 'nombre' => $archivo['name'], 'tipo' => $tipo_mime, 'tamano' => $archivo['size'] ] ]; } }