# Referencia Técnica — `admin_alumnos`

Portal del Estudiante. Interfaz SB Admin 2 (Bootstrap 4) para que el alumno y su representante consulten y gestionen su información académica y administrativa.

---

## Índice

1. [Stack tecnológico](#1-stack-tecnológico)
2. [Estructura de directorios](#2-estructura-de-directorios)
3. [Archivos externos referenciados](#3-archivos-externos-referenciados)
4. [Constantes globales — `inicia.php`](#4-constantes-globales--iniciaphp)
5. [Base de datos — `conexion.php`](#5-base-de-datos--conexionphp)
6. [Sistema de sesión](#6-sistema-de-sesión)
7. [Layout base — `layout/base.php`](#7-layout-base--layoutbasephp)
8. [Módulo: Autenticación — `login.php`](#8-módulo-autenticación--loginphp)
9. [Módulo: Inicio — `home.php`](#9-módulo-inicio--homephp)
10. [Módulo: Perfil — `perfil.php`](#10-módulo-perfil--perfilphp)
11. [Módulo: Actualizar Perfil — `procesos/actualizar.php`](#11-módulo-actualizar-perfil--procesosactualizarphp)
12. [Módulo: Comunicados — `comunicados.php`](#12-módulo-comunicados--comunicadosphp)
13. [Módulo: Publicaciones — `publicacion.php`](#13-módulo-publicaciones--publicacionphp)
14. [Módulo: Registrar Pago — `registrar-pago.php`](#14-módulo-registrar-pago--registrar-pagophp)
15. [Módulo: Historial de Pagos — `historial-pagos.php`](#15-módulo-historial-de-pagos--historial-pagosphp)
16. [Módulo: Boletín de Calificaciones — `boletin.php`](#16-módulo-boletín-de-calificaciones--boletinphp)
17. [Módulo: Corte de Notas — `corte-notas.php`](#17-módulo-corte-de-notas--corte-notasphp)
18. [Módulo: Horario de Clases — `horario.php`](#18-módulo-horario-de-clases--horariophp)
19. [Módulo: Calendario de Actividades — `calendario.php`](#19-módulo-calendario-de-actividades--calendariophp)
20. [Módulo: Calendario de Evaluaciones — `cal-evaluaciones.php`](#20-módulo-calendario-de-evaluaciones--cal-evaluacionesphp)
21. [Módulo: Planificación Escolar — `planificacion.php`](#21-módulo-planificación-escolar--planificacionphp)
22. [Módulo: Chat con Docentes](#22-módulo-chat-con-docentes)
23. [Módulo: Docente Guía — `docente-guia.php`](#23-módulo-docente-guía--docente-guiaphp)
24. [Módulo: Encuestas](#24-módulo-encuestas)
25. [Módulo: Video Aula — `video-aula.php`](#25-módulo-video-aula--video-aulaphp)
26. [Módulo: Material de Clases — `material.php`](#26-módulo-material-de-clases--materialphp)
27. [Módulo: Lista de Útiles — `utiles.php`](#27-módulo-lista-de-útiles--utilesphp)
28. [Módulo: Constancias](#28-módulo-constancias)
29. [Módulo: Carnet de Estudio — `carnet.php`](#29-módulo-carnet-de-estudio--carnetphp)
30. [Módulo: Planilla de Inscripción — `planilla.php`](#30-módulo-planilla-de-inscripción--planillaphp)
31. [Módulo: Registrar Inscripción — `encuesta.php` (reinscripción)](#31-módulo-reinscripción--encuestaphp)
32. [Procesos auxiliares — `procesos/`](#32-procesos-auxiliares--procesos)
33. [Tablas de base de datos referenciadas](#33-tablas-de-base-de-datos-referenciadas)
34. [Seguridad y validaciones](#34-seguridad-y-validaciones)
35. [Sidebar — menú y visibilidad condicional](#35-sidebar--menú-y-visibilidad-condicional)
36. [Assets frontend](#36-assets-frontend)

---

## 1. Stack tecnológico

| Capa | Tecnología |
|------|-----------|
| Backend | PHP (procedimental, mysqli) |
| UI framework | SB Admin 2 (Bootstrap 4.x) |
| CSS extra | `assets/css/portal-alumnos.css` |
| JS | jQuery, Bootstrap Bundle, jQuery Easing, DataTables, SweetAlert2 (CDN) |
| Iconos | FontAwesome Free (local) |
| PDF | FPDF (`../fpdf/fpdf.php`) |
| Email | PHPMailer (`../includes/PHPMailerMaster/`) |
| Timezone | `America/Caracas` |
| Locale | `spanish` (para `strftime` y `setlocale`) |

---

## 2. Estructura de directorios

```
admin_alumnos/
├── login.php                   # Autenticación (página pública)
├── home.php                    # Dashboard / inicio (requiere sesión)
├── perfil.php                  # Ver y editar perfil
├── perfil-actualizar.php       # Procesador POST del perfil (deprecated, ver procesos/)
├── comunicados.php             # Comunicados recientes (últimos 4)
├── publicacion.php             # Listado completo de publicaciones
├── registrar-pago.php          # Formulario de registro de pago
├── historial-pagos.php         # Historial de recibos procesados
├── boletin.php                 # Selector e impresión de boletín
├── corte-notas.php             # Selector e impresión de corte de notas
├── horario.php                 # Visualizador de horario de clases
├── calendario.php              # Calendario de actividades institucional
├── cal-evaluaciones.php        # Calendario de evaluaciones del docente
├── planificacion.php           # Planificación escolar por materia/lapso
├── chat-docentes.php           # Lista de docentes para chatear
├── chat-buscar.php             # AJAX: historial de mensajes de un chat
├── chat-enviar.php             # AJAX: enviar mensaje al docente
├── docente-guia.php            # Docentes guía del grado
├── encuestas.php               # Listado de encuestas del período
├── encuesta.php                # Encuesta de reinscripción (cupo/retiro/zonificación)
├── encuesta-hacer.php          # Responder encuesta dinámica
├── encuesta-guarda.php         # Guardar respuestas de encuesta
├── video-aula.php              # Listado de video clases
├── material.php                # Material de clases / tareas
├── utiles.php                  # Lista de útiles escolares
├── const-asistencia.php        # Formulario constancia de asistencia
├── const-estudio.php           # Formulario constancia de estudio
├── const-inscripcion.php       # Formulario constancia de inscripción
├── const-promedio.php          # Formulario constancia de promedio
├── carnet.php                  # Carnet de estudio (impresión PDF)
├── planilla.php                # Planilla de inscripción (impresión PDF)
├── verifica-sesion.php         # Endpoint AJAX de verificación de sesión
├── comentaActual.php           # Comentarios/publicaciones adicionales
├── layout/
│   ├── base.php                # Plantilla HTML completa (sidebar + topbar + footer)
│   └── _cal_tmpl.php           # Plantilla del widget de calendario
├── procesos/
│   ├── actualizar.php          # Procesador POST del perfil (principal)
│   ├── cons-asi.php            # Genera PDF constancia de asistencia
│   ├── encuesta-pdf.php        # Genera PDF de encuesta de reinscripción
│   └── subefoto.php            # Subir foto desde boletin/corte-notas
├── assets/
│   ├── css/
│   │   ├── sb-admin-2.css      # Framework SB Admin 2
│   │   ├── sb-admin-2.min.css
│   │   └── portal-alumnos.css  # Estilos personalizados del portal
│   ├── js/
│   │   ├── sb-admin-2.js
│   │   ├── sb-admin-2.min.js
│   │   └── demo/               # Demos de charts (no usados en producción)
│   ├── img/
│   │   ├── fondo_login.webp    # Fondo de la pantalla de login
│   │   ├── capture.jpg         # Portada video tutorial de foto
│   │   └── ...otros SVG/JPG
│   └── vendor/
│       ├── bootstrap/          # Bootstrap 4 JS bundle
│       ├── fontawesome-free/   # Iconos FA (local)
│       ├── jquery/
│       ├── jquery-easing/
│       ├── chart.js/
│       └── datatables/
└── documentacion/
    ├── modulos/                # Documentación por módulo (archivos .md)
    └── docs/                   # Este directorio (referencia técnica completa)
```

---

## 3. Archivos externos referenciados

Estos archivos existen **fuera de `admin_alumnos/`** y son incluidos o enlazados desde los módulos internos.

### Includes PHP obligatorios

| Archivo | Ruta relativa | Función |
|---------|--------------|---------|
| `inicia.php` | `../inicia.php` | Define todas las constantes institucionales (nombre, RIF, bancos, etc.) |
| `conexion.php` | `../conexion.php` | Funciones `Conectarse()`, `Conectarse3()`, `Conectarse1()` (mysqli) |
| `includes/funciones.php` | `../includes/funciones.php` | `encriptar()`, `desencriptar()`, `ValCed()`, máscaras, etc. |
| `includes/reconectar.php` | `../includes/reconectar.php` | Reconexión fallback |
| `fpdf/fpdf.php` | `../fpdf/fpdf.php` | Librería FPDF para generación de PDFs |
| `includes/PHPMailerMaster/` | `../includes/PHPMailerMaster/src/` | PHPMailer para envío de email (registro de pago) |
| `includes/jquery.maskedinput/` | `../includes/jquery.maskedinput/src/jquery.mask.js` | Máscara de teléfonos en perfil |

### Páginas externas referenciadas (redirect/window.open)

| Archivo | Ruta | Cuándo se usa |
|---------|------|--------------|
| `cierra.php` | `../cierra.php` | Cerrar sesión (topbar + modal logout) |
| `olvidoClave.php` | `../olvidoClave.php` | Recuperar contraseña (AJAX POST desde login) |
| `consulta.php` | `../consulta.php?complet` | Redirige si el perfil está incompleto (sin foto o sin correo) al hacer login |
| `usuario-busca.php` | `../usuario-busca.php` | Verificar si un nombre de usuario ya existe (AJAX desde perfil) |
| `bole-liceo.php` | `../bole-liceo.php` | Boletín PDF para bachillerato (`grado > 60`) |
| `bole-liceo-corte.php` | `../bole-liceo-corte.php` | Corte de notas PDF para bachillerato |
| `bole-primaria.php` | `../bole-primaria.php` | Boletín/corte PDF para primaria (`grado 51–60`) |
| `bole-inicial.php` | `../bole-inicial.php` | Boletín PDF para inicial (`grado ≤ 50`) |
| `encuesta-pdf.php` | `../encuesta-pdf.php` | PDF de reinscripción ya realizada |
| `encuestas-pdf.php` | `../encuestas-pdf.php` | PDF de encuesta dinámica ya respondida |
| `calendario-get.php` | `../calendario-get.php` | AJAX: detalle de evento del calendario |
| `index.php` | `../index.php` | Link "Volver al inicio" en login |
| `docentes/index.php` | `../docentes/index.php?ingreso=1` | Redirige docentes al portal de docentes si se autentican aquí |
| `pagina.jesistemas.com.ve/login.php` | externo HTTPS | Redirige usuarios con `admin != null` al sistema administrativo |

### Directorios de archivos dinámicos

| Directorio | Ruta | Contenido |
|-----------|------|----------|
| `fotoalu/` | `../fotoalu/` | Fotos de alumnos — nombre: `{cedula}{ext}` (ej: `12345678.jpg`) |
| `fotorep/` | `../fotorep/` | Fotos de representantes — nombre: `{ced_rep}{ext}` |
| `horario/` | `../horario/` | Archivos de horario (PDF/imagen) subidos por administración |
| `archivos/` | `../archivos/` | Documentos adjuntos a comunicados institucionales |
| `comunicaDocen/` | `../comunicaDocen/` | Archivos adjuntos a comunicados publicados por docentes |
| `imagenes/` | `../imagenes/` | Imágenes generales (logo, fotocarnet.jpg, loader.gif, usuario.png) |
| `assets/img/` | `../assets/img/` | Logo institucional usado en PDFs y login |

### Archivo de configuración de servidor externo

```php
// En registrar-pago.php — carga credenciales SMTP del servidor de producción:
include("/var/www/todos/inicia.php");
// Define: HOSTMAILTODOS, MAILUSERTODOS, CLAVEMAILTODOS, CORREOM
```

---

## 4. Constantes globales — `inicia.php`

Definidas en `../inicia.php`. Usadas en todo el portal vía `include_once "../inicia.php"`.

| Constante | Valor ejemplo | Uso |
|-----------|--------------|-----|
| `NKXS` | `"Unidad Educativa Privada "` | Nombre tipo institución |
| `EKKS` | `'JESISTEMAS.COM'` | Nombre corto del colegio |
| `CKLS` | `"PD 12345678"` | Código de plantel |
| `RIFCOLM` | `"J-50314157-3"` | RIF institucional |
| `TELEMPM` | `"0412-457.80.84"` | Teléfono |
| `ANOESCM` | `"2024-2025"` | Año escolar actual |
| `ANOANTE` | `"2023-2024"` | Año escolar anterior |
| `PROXANOE` | `"2024-2025"` | Próximo año escolar |
| `CIUDADM` | `"Maracay"` | Ciudad |
| `ESTADOM` | `"Aragua"` | Estado |
| `DIRECCM` | `"Av. principal de San Jose Maracay"` | Dirección institucional |
| `BANCO1M`…`BANCO5M` | nombres de bancos | Bancos receptores de pago (sidebar pago) |
| `CUENT1M`…`CUENT5M` | números de cuenta | Cuentas bancarias |
| `BENEF1M`…`BENEF5M` | nombres de beneficiarios | Beneficiarios bancarios |
| `DIRECTM` | `"Jose Chacon"` | Nombre del director |
| `CEDDIRM` | `"V-10.340.266"` | Cédula del director |
| `CTRLEST` | `"Mariela Naranjo"` | Jefe de Control de Estudios |
| `CTRLPAG` | `"Mariela Naranjo"` | Responsable de pagos |
| `DOMINIO` | `"colegio.jesistemas.com.ve"` | Dominio web |
| `SUCORREO` | `"ventas@jesistemas.com"` | Correo institucional |
| `MAILUSER` | credenciales SMTP | Usuario SMTP |
| `CLAVEMAIL` | credenciales SMTP | Contraseña SMTP |
| `FUNDADA` | `'1996-03-18'` | Fecha de fundación |
| `PERIDOM` | `1` | Período activo (flag) |
| `CERTIPLAN` | `1` | Habilita impresión de planilla |

---

## 5. Base de datos — `conexion.php`

```php
// Base de datos principal
$bd = "colegio";  // host: localhost, user: root, pw: ""

// Función principal usada en admin_alumnos
$link = Conectarse();   // → DB "colegio"
$link = conectarse();   // alias idéntico (case-insensitive en PHP)

// Funciones adicionales (no usadas en admin_alumnos directamente)
Conectarse3();  // → DB "jesistemas"
Conectarse1();  // → DB "facilfact"
```

---

## 6. Sistema de sesión

### Variables de sesión establecidas en `login.php`

| Variable | Tipo | Descripción |
|----------|------|-------------|
| `$_SESSION['usuario']` | string | Cédula del alumno (actúa como identificador principal) |
| `$_SESSION['idAlum']` | int | PK de `alumcer` |
| `$_SESSION['nomuser']` | string | Nombre del alumno |
| `$_SESSION['apelluser']` | string | Apellido del alumno |
| `$_SESSION['cargo']` | int | Tipo de usuario: 1=alumno, >1=docente |
| `$_SESSION['admin']` | string/null | Si no es null, es usuario administrativo |
| `$_SESSION['grado']` | int | Código numérico del grado |
| `$_SESSION['seccion']` | int | ID de la sección |
| `$_SESSION['nombreGrado']` | string | Nombre legible del grado |
| `$_SESSION['nomSecci']` | string | Nombre de la sección |
| `$_SESSION['fotoAlum']` | string | Nombre de archivo de la foto (`cedula.ext`) |
| `$_SESSION['correo']` | string | Email del alumno |
| `$_SESSION['password']` | string | Contraseña en claro (para `verifica-sesion.php`) |
| `$_SESSION['periodoAlum']` | string | Tabla del período del alumno (ej: `2425`) |
| `$_SESSION['nombre_periodo']` | string | Nombre legible del período (ej: `"2024-2025"`) |
| `$_SESSION['tablaPeriodo']` | string | Tabla del período activo del sistema |
| `$_SESSION['periodoActivo']` | string | Nombre del período activo |
| `$_SESSION['lapsoActivo']` | int | Lapso escolar activo (1, 2 o 3) |
| `$_SESSION['morosida']` | float | Deuda pendiente en Bs. (0 = al día) |
| `$_SESSION['pagado']` | float | Total pagado en el período |
| `$_SESSION['totalPeriodo']` | float | Total a pagar en el período |
| `$_SESSION['exoneraMorosidad']` | date/string | Fecha hasta la que se exonera la morosidad |
| `$_SESSION['msjHay']` | int | Cantidad de mensajes nuevos del docente |
| `$_SESSION['tareaPend']` | int | 2 = hay tareas pendientes, 0 = sin pendientes |
| `$_SESSION['consulVoto']` | - | Flag de votación |
| `$_SESSION['reinscribe']` | int | ID de encuesta de reinscripción ya respondida |
| `$_SESSION['ced_papa']` | string | Cédula del padre |
| `$_SESSION['ced_mama']` | string | Cédula de la madre |
| `$_SESSION['nom_emerg_1']` | string | Nombre contacto de emergencia #1 |

### Cookies persistentes (8 horas, path `/`)

| Cookie | Contenido | Función |
|--------|----------|---------|
| `usuarioCol` | `encriptar($usuario)` | Auto-login si sesión cae |
| `passwordCol` | `encriptar($password)` | Auto-login |
| `lapAct` | `encriptar($lapsoActivo)` | Lapso activo encriptado |
| `moroCol` | `encriptar($morosida)` | Morosidad encriptada |
| `pagoCol` | `encriptar($pagado)` | Pagado encriptado |
| `totalPeriodo` | `encriptar($totalPeriodo)` | Total período encriptado |
| `periodoActivo` | `encriptar($periodoActivo)` | Período activo encriptado |

> **Nota:** Si el usuario tiene `admin != null`, se destruyen todas las cookies y la sesión, y redirige al sistema administrativo externo.

### Flujo de verificación de sesión

Cada módulo hace:
```php
if (!isset($_SESSION['usuario'])) {
    header("Location: login.php?vencio=1");
    exit;
}
```

`layout/base.php` también verifica y redirige a `../admin_alumnos/login.php?vencio=1`.

`verifica-sesion.php` — endpoint AJAX que devuelve JSON `{isSuccessful: true/false}` según si existe `$_SESSION['usuario']`.

---

## 7. Layout base — `layout/base.php`

Plantilla HTML completa que todos los módulos utilizan con el patrón:

```php
$pageTitle  = 'Nombre de la Página';
$activePage = 'slug-del-menu';   // coincide con los checks en sidebar
ob_start();
// ... HTML del contenido ...
$content = ob_get_clean();
$extraScripts = '<script>...</script>';  // opcional
require_once "layout/base.php";
```

### Variables esperadas por `base.php`

| Variable | Tipo | Descripción |
|----------|------|-------------|
| `$pageTitle` | string | Título en `<title>` y breadcrumb del topbar |
| `$activePage` | string | Slug que controla clase `active` en el sidebar |
| `$content` | string | HTML completo del área de contenido |
| `$extraScripts` | string | Scripts adicionales inyectados antes de `</body>` |

### Variables leídas de sesión en `base.php`

- `nomuser`, `apelluser` → nombre completo en topbar
- `grado`, `seccion`, `nombreGrado`, `nomSecci` → visibilidad condicional de menú
- `morosida` → muestra ícono de advertencia en topbar si > 0
- `msjHay` → badge rojo en topbar y sidebar si > 0
- `periodoActivo` → badge pequeño en el ítem "Encuestas" del sidebar
- `fotoAlum` → foto de perfil en topbar (ruta: `../fotoalu/{ruta}`)

### Visibilidad condicional del sidebar (lógica de grado)

```php
// Constancia de Promedio — oculta para grados 40–60 (no aplica)
if ($grado < 40 || $grado > 60) { /* mostrar */ }

// Corte de Notas — oculta para grados 40–60
if ($grado < 40 || $grado > 60) { /* mostrar */ }
```

> Grados 40–60 corresponden a niveles sin calificación numérica por lapso (probable nivel inicial/especial).

### Scripts cargados globalmente por `base.php`

```
assets/vendor/jquery/jquery.min.js
assets/vendor/bootstrap/js/bootstrap.bundle.min.js
assets/vendor/jquery-easing/jquery.easing.min.js
assets/js/sb-admin-2.min.js
assets/vendor/datatables/jquery.dataTables.min.js
assets/vendor/datatables/dataTables.bootstrap4.min.js
https://cdn.jsdelivr.net/npm/sweetalert2@11/dist/sweetalert2.all.min.js   (CDN externo)
```

CSS globales:
```
assets/vendor/fontawesome-free/css/all.min.css
assets/css/sb-admin-2.css?1
assets/vendor/datatables/dataTables.bootstrap4.min.css
assets/css/portal-alumnos.css?1
https://fonts.googleapis.com/css?family=Nunito  (CDN externo)
```

El cierre de sesión usa `../cierra.php` con `confirm()` JS nativo.

---

## 8. Módulo: Autenticación — `login.php`

**URL:** `admin_alumnos/login.php`  
**Método:** GET (formulario) / POST (procesar)  
**Requiere sesión:** No (si ya tiene sesión redirige a `home.php`)

### Flujo POST

1. Busca en `alumcer` por `cedula` o `miUsuario` + `clave` + `statusAlum='1'`
2. Carga datos en `$_SESSION`
3. Consulta `grado{peri}` para nombre del grado
4. Consulta `secciones` para nombre de la sección
5. Consulta `periodos` — período del alumno y período activo del sistema
6. Consulta `preinscripcion` — lapso activo
7. Consulta `evalua_calendario` — evaluaciones próximas (próximos 5 días) para alerta en `home.php`
8. Calcula morosidad:
   - Primaria (`grado < 61`): `notaprimaria{periodo}`
   - Bachillerato (`grado >= 61`): `matri{periodo}`
   - Montos: `montos{periodo}` — suma mensualidades vencidas y resta descuentos y pagado
9. Verifica tareas pendientes: `tareaspri{tabla}` / `tareas{tabla}` + `vio_tarea` + `tarea_indpri_{tabla}` / `tarea_ind_{tabla}`
10. Verifica encuestas sin responder: `encuesta` + `encuesta_respuesta`
11. Registra acceso en `acceso_alum`
12. Cuenta mensajes nuevos: `chat WHERE visto='2' AND envia='1'`

### Redirecciones post-login

| Condición | Destino |
|-----------|---------|
| `admin != null` | `https://pagina.jesistemas.com.ve/login.php` + destruye sesión |
| `cargo > 1` (docente) | `../docentes/index.php?ingreso=1` |
| Perfil incompleto (sin foto o sin correo) | `../consulta.php?complet` |
| Encuestas sin responder | `encuestas.php?sinresp` |
| Normal | `home.php?ingreso=1&evaluar={eventos}` |

### Función `olvidoClave()` (JS)

AJAX POST a `../olvidoClave.php` con `{cedula: ced}` — devuelve JSON `{isSuccessful: bool}`.

### Parámetros GET manejados

- `?vencio` → muestra alerta "Sesión expirada"

---

## 9. Módulo: Inicio — `home.php`

**URL:** `admin_alumnos/home.php`  
**Datos:** Solo de sesión, sin queries adicionales

### Tarjetas de resumen (4 widgets)

| Widget | Condición de color | Dato fuente |
|--------|-------------------|-------------|
| Estado de Pagos | warning si `morosida > 0`, success si = 0 | `$_SESSION['morosida']` |
| Grado / Sección | siempre info | `$_SESSION['nombreGrado']`, `nomSecci` |
| Período Activo | siempre primary | `$_SESSION['periodoActivo']` |
| Mensajes Nuevos | danger si > 0, secondary si = 0 | `$_SESSION['msjHay']` |

### Accesos rápidos

Botones directos a: `horario.php`, `corte-notas.php` (oculto si grado 40–60), `registrar-pago.php`, `chat-docentes.php`, `cal-evaluaciones.php`, `boletin.php`, `historial-pagos.php`, `material.php`.

---

## 10. Módulo: Perfil — `perfil.php`

**URL:** `admin_alumnos/perfil.php`  
**Acción del formulario:** `procesos/actualizar.php` (POST multipart/form-data)

### Queries ejecutadas

```sql
-- Datos completos del alumno + grado + representante + sección
SELECT A.*, B.nombreGrado, C.cedula as cedRep, C.representante, C.correo, ...
FROM alumcer A, grado{tablaPeriodo} B, represe C, secciones D
WHERE A.idAlum='{idAlum}' AND B.grado=A.grado AND C.cedula=A.ced_rep AND A.seccion=D.id

-- Datos de la madre
SELECT * FROM madres WHERE ced_mama='{ced_mama}'

-- Datos del padre
SELECT * FROM padres WHERE ced_papa='{ced_papa}'

-- Estados (select)
SELECT * FROM estado

-- Ciudades/municipios (select dinámico por estado)
SELECT id_ciudad, ciudad, id_estado FROM ciudades ORDER BY ciudad ASC
SELECT id_municipio, municipio, id_estado FROM municipios ORDER BY municipio ASC

-- Parentescos
SELECT * FROM parentescos
```

### Secciones del formulario

1. **Fotografías** — foto alumno (`../fotoalu/`) y foto representante (`../fotorep/`)
2. **Datos del Estudiante** — nación, cédula (readonly), usuario, contraseña, grado (readonly), nombres, apellidos, fecha nacimiento, estado, lugar nacimiento, municipio, país, género, celular, dirección, email
3. **Datos del Representante** — cédula, nombre, parentesco, fecha nacimiento, dirección, email, teléfono hab., celular, lugar de trabajo, profesión
4. **Datos de la Madre** — cédula, nombre, celular, dirección, teléfono hab., lugar trabajo, profesión, dedicación
5. **Datos del Padre** — mismos campos que madre
6. **Contactos de Emergencia** — 2 personas: nombre, parentesco, 3 teléfonos c/u

### Control de edición — campo `alumcer.editable`

| Valor | Comportamiento |
|-------|---------------|
| ≠ `'N'` | Todos los campos editables |
| `'N'` | Campos sensibles en `readonly`/`disabled`: nombres, apellidos, cédula, fecha nac., estado, ciudad, municipio, país, cédula rep., nombre rep. |

### Validaciones cliente (JS)

- `validacion()` en `onsubmit`: verifica estado, lugar nac., municipio y parentesco — usa SweetAlert2
- `buscaUsu()` en `onchange` del campo usuario: verifica unicidad con AJAX a `../usuario-busca.php`
- `valida(e)`: permite solo números, guiones y puntos en campos de teléfono
- `ValCed(e)`: permite solo números en campos de cédula
- Máscara de teléfonos con `jquery.mask.js`: formato `????-???.??.??` aplicada a todos los campos de teléfono
- Preview de imagen: valida tipo y tamaño máximo 5000 KB antes de mostrar preview

### Parámetros GET manejados

- `?actual` → SweetAlert "datos almacenados exitosamente"
- `?complet` → SweetAlert informando que debe completar todos los datos + subir fotos

### Campo oculto encriptado

```html
<input type="hidden" name="id" value="<?= encriptar($idAlum) ?>">
```

El procesador desencripta con `desencriptar($_POST['id'])`.

### Tutorial de foto (modal)

Botón que abre modal con video de YouTube embebido (`youtube.com/embed/ThlkVpyrKwY`). El iframe se carga con `autoplay=1` solo al hacer clic (lazy load manual).

---

## 11. Módulo: Actualizar Perfil — `procesos/actualizar.php`

**Método:** POST (solo, sin UI propia)  
**Redirect final:** `../perfil.php?actual`

### Procesamiento de imágenes

```php
// Foto alumno
$ruta = "$ced_alu$ext";           // ej: "12345678.jpg"
$guardaRutaAlu = '../fotoalu/' . $ruta;
// Versión antigua (perfil-actualizar.php): move_uploaded_file() directo
// Versión nueva (procesos/actualizar.php): move_uploaded_file() directo también
// Nota: perfil-actualizar.php (raíz) usa reducirImagen() con redimensión 300x300 q=30%
//       procesos/actualizar.php NO usa reducirImagen — sube original
```

Formatos aceptados: `.jpg`, `.jpeg`, `.png`

### Lógica del representante

Si la cédula del representante cambió (`$ced_rep != $ced_rep_1`):
- Si no existe en `represe` → INSERT
- Si ya existe → UPDATE sin tocar la foto

Si la cédula no cambió → UPDATE directo al representante original.

### Sanitización de campos de texto (madre y padre)

```php
$sanitize = ['"', "'", ':', '/', 'sudo su', '*', '[', ']', '{', '}', '#', '_'];
str_replace($sanitize, '', $campo);
```

> **Nota de seguridad:** Esta sanitización es rudimentaria. Las queries usan mysqli_query con interpolación directa (sin prepared statements).

### Actualización del alumno según `editable`

- `editable != 'N'`: actualiza todos los campos incluyendo nombres, fecha nac., estado, grado info
- `editable = 'N'`: solo actualiza `miUsuario`, `direccion`, `telefono`, `correo`, `clave`, `parentesco`, emergencias, `ced_mama`, `ced_papa`, `matpen`, `planteProcede`, `escolaridad`

Registra en `actualiza_datos (idAlum, fecha)` en ambos casos.

---

## 12. Módulo: Comunicados — `comunicados.php`

**Condición de visibilidad del contenido:**
```php
$mostrar = isset($_SESSION['password']) && $_SESSION['nombre_periodo'] == $_SESSION['periodoActivo'];
```
Solo muestra comunicados si el alumno está en el período activo del sistema.

**Query:**
```sql
SELECT DISTINCT * FROM tbl_documentos 
WHERE adultos IS NULL AND activo=1 AND todos='S' 
OR (activo=1 AND ('{grado}'>=gradoDesde AND '{grado}'<=gradoHasta) 
AND (('{seccion}'>=seccionDesde AND '{seccion}'<=seccionHasta) OR seccionDesde IS NULL))
ORDER BY fecha_doc DESC LIMIT 4
```

Muestra los **4 comunicados más recientes**. Enlace "Ver Todos" redirige a `publicacion.php`.

El archivo adjunto se abre en iframe dentro de un modal (`../archivos/{nombre_archivo}`).

---

## 13. Módulo: Publicaciones — `publicacion.php`

Muestra **todos** los comunicados sin límite. Dos fuentes:

1. `tbl_documentos` — comunicados institucionales (sin filtro `adultos`)
2. `comunica_docen` — comunicados publicados por docentes (filtro: `codGrado`, `codSecci`, fecha vigente)

Archivos de `tbl_documentos` → `../archivos/`  
Archivos de `comunica_docen` → `../comunicaDocen/`

---

## 14. Módulo: Registrar Pago — `registrar-pago.php`

**Método:** GET (vista) / POST (procesar en el mismo archivo)

### Datos del formulario

| Campo | Nombre HTML | Descripción |
|-------|-------------|-------------|
| Tipo operación | `operacion` | T=Transferencia Bs, Td=Transferencia $, Pa=Pago Móvil, Ze=Zelle |
| Fecha | `fec_depo` | Fecha de la operación |
| Referencia | `ref_depo` | Número de comprobante (max 20) |
| Monto | `mon_depo` | Decimal con coma (ej: `1.500,00`) — se normaliza antes de guardar |
| Banco receptor | `banco_rec` | Banco del colegio (visible según operación) |
| Banco emisor | `banco_emi` | Banco del titular (de tabla `bancos`) |
| RIF/CI titular | `rif_titular` | Identificación del pagador |
| Nombre titular | `nombre_titular` | Nombre del pagador |
| Email titular | `correoRep` | Email (default: correo del representante) |
| Archivos | `archivos[]` | Múltiples capturas (múltiple file input) |
| Motivo | `mot_depo` | Concepto del pago (max 58) |
| Comentario | `comenta` | Observaciones opcionales (max 100) |

### Calculadora de Bs.

JS que calcula `montoPagarDiv × montoTasa = montoPagarBs` sin query al servidor. El campo `mon_depo` se rellena automáticamente si ambos valores están presentes.

### Validación de duplicado (server-side)

```sql
SELECT nrodeposito FROM pagos WHERE ced_alu='{ced}' AND nrodeposito='{ref_depo}'
```
Si ya existe ese número de referencia → error "Los datos del pago ya existen".

### Visibilidad de bancos (JS)

```js
// T o Pa → muestra .bolivar (BANCO1M, BANCO2M, BANCO3M)
// Ze     → muestra .divZell (BANCO5M)
// Td     → muestra .bolivar
```

### Email de notificación

Usa PHPMailer con credenciales de `/var/www/todos/inicia.php`. Envía a `sisjch.tlf@gmail.com` con HTML que incluye nombre del alumno, cédula, monto, banco, referencia y adjunta los archivos del capture.

> **Nota:** La query INSERT en `pagos` está comentada en el código. El registro del pago se hace en otro sistema o manualmente.

### Validaciones cliente

- Tipo de operación no seleccionado → SweetAlert error
- Banco receptor no seleccionado → SweetAlert error
- Banco emisor no seleccionado (excepto Zelle) → SweetAlert error
- Monto: solo acepta números y coma decimal (`validarNumero()`)

---

## 15. Módulo: Historial de Pagos — `historial-pagos.php`

**Query principal de datos:**
```sql
SELECT A.nombre, B.nombreGrado, A.cedula, A.apellido, A.ruta AS foto_alu, A.grado, 
       A.Periodo, C.ruta AS foto_rep
FROM alumcer A, grado{tablaPeriodo} B, represe C
WHERE A.idAlum='{idAlum}' AND B.grado=A.grado AND C.cedula=A.ced_rep
```

**Query de pagos:**
```sql
SELECT recibo, fecha, concepto, monto 
FROM pagos{tablaPeriodo} 
WHERE status=1 AND idAlum='{idAlum}' AND recibo>0 
ORDER BY fecha DESC
```

- Tabla dinámica: `pagos{tablaPeriodo}` (nombre de tabla varía por período)
- El número de recibo se muestra con padding de 6 dígitos (`str_pad 6, "0", STR_PAD_LEFT`)
- Si `totalPeriodo == 0` → SweetAlert informando que no hay pagos registrados
- DataTables con idioma español (CDN externo: `datatables.net`)

---

## 16. Módulo: Boletín de Calificaciones — `boletin.php`

**Restricción de acceso:**
```php
if ($_SESSION['morosida'] > 0) { header("Location: home.php?moro=1"); exit; }
```
El alumno con deuda pendiente **no puede acceder** al boletín.

**Query:**
```sql
SELECT A.cedula, A.nombre, A.apellido, A.grado, A.ruta, A.Periodo, 
       B.nombreGrado, C.nombre AS nomsec
FROM alumcer A, grado{tablaPeriodo} B, secciones C
WHERE cedula='{usuario}' AND A.grado=B.grado AND A.seccion=C.id
```

**Selectors:**
- Período: lista de todos los períodos (`periodos` tabla, ORDER BY `orden DESC`)
- Lapso: 1er, 2do, 3er Momento

**Lógica de impresión (JS):**
```js
if (grado > 60)      window.open("../bole-liceo.php?lapsom=" + lap + "&peri=" + per);
else if (grado > 50) window.open("../bole-primaria.php?lapsom=" + lap + "&peri=" + per);
else                 window.open("../bole-inicial.php?lapsom=" + lap + "&peri=" + per);
```

**Requisito previo:** Si `ruta` (foto del alumno) está vacía, muestra botón "Cargar Foto Primero" que abre modal para subir foto a `procesos/subefoto.php`.

---

## 17. Módulo: Corte de Notas — `corte-notas.php`

Idéntico a `boletin.php` en estructura y restricciones. Diferencia en la impresión:

```js
if (grado > 60) window.open("../bole-liceo-corte.php?lapsom=" + lap + "&peri=" + per);
else            window.open("../bole-primaria.php?lapsom=" + lap + "&peri=" + per);
```

**No disponible** para grados 40–60 (oculto desde el sidebar en `layout/base.php`).

---

## 18. Módulo: Horario de Clases — `horario.php`

**Query:**
```sql
SELECT archivo FROM horario 
WHERE grado='{grado}' AND seccion='{seccion}' AND periodo='{periodo}' AND status='1'
```

- Si existe registro: renderiza `<iframe src="../horario/{archivo}">` con height 580px
- Si no existe: muestra mensaje "Horario aún no publicado"
- El archivo puede ser un PDF o imagen subido por administración en el panel principal

---

## 19. Módulo: Calendario de Actividades — `calendario.php`

**Query:**
```sql
SELECT * FROM eventos_calendario 
WHERE ((grado_des<='{grado}' AND grado_has>='{grado}' AND sec_des<='{seccion}' AND sec_has>='{seccion}') 
       OR todos='S')
```

Los eventos se serializan como JSON y se pasan al widget JavaScript de calendario. El widget JS implementa vistas: mes, semana, día, año con navegación por botones prev/next.

**Detalle de evento (AJAX):** Al hacer clic en un evento, llama `../calendario-get.php?id={id}` (GET, devuelve JSON) y muestra el detalle en un modal.

**Template:** `layout/_cal_tmpl.php` — plantilla del widget de calendario.

---

## 20. Módulo: Calendario de Evaluaciones — `cal-evaluaciones.php`

Evaluaciones programadas por los docentes para el grado/sección. Usa la tabla `evalua_calendario`.

---

## 21. Módulo: Planificación Escolar — `planificacion.php`

Muestra la planificación de contenidos por materia y lapso. Tabla fuente: tablas relacionadas con `trgsmp{periodo}` y `materiass{periodo}`.

---

## 22. Módulo: Chat con Docentes

### `chat-docentes.php` — Vista principal

**Query docentes:**
```sql
SELECT DISTINCT A.ced_prof, B.nombre, B.apellido, B.ruta AS foto_doc, B.idAlum as idDocente,
       C.codigo AS cod_mat, C.completo AS nom_mat
FROM trgsmp{tablaPeriodo} A, alumcer B, materiass{tablaPeriodo} C
WHERE A.cod_grado='{grado}' AND A.cod_seccion='{seccion}'
  AND A.ced_prof=B.cedula AND A.cod_materia=C.codigo
ORDER BY C.completo
```

Para cada docente cuenta mensajes nuevos:
```sql
SELECT count(id_chat) AS cnt FROM chat 
WHERE idAlum='{idAlum}' AND id_docente='{idDocente}' 
  AND id_materia='{cod_mat}' AND visto='2' AND envia='1'
```

Fotos de docentes: `../docentes/fotodoc/{foto_doc}`  
IDs se encriptan antes de pasar al JS: `encriptar($doc['ced_prof'])`, `encriptar($doc['cod_mat'])`

### `chat-buscar.php` — Historial (AJAX)

POST: `{id_doc: encrypted, id_mat: encrypted}`  
Desencripta IDs, consulta `chat` WHERE `idAlum + id_docente + id_materia`, devuelve JSON `{isSuccessful, historia}` con HTML de la tabla de mensajes.

Al leer un mensaje nuevo lo marca como visto:
```sql
UPDATE chat SET visto='1' WHERE id_chat='{id}' AND envia='1'
```

Colores en los mensajes:
- Docente (`envia='1'`): fondo `#B39DDB` (violeta)
- Alumno (`envia='2'`): fondo `#B2DFDB` (verde agua)
- Mensaje nuevo no leído: fondo `#E6EE9C` con etiqueta "(MENSAJE NUEVO)"

### `chat-enviar.php` — Enviar mensaje (AJAX)

POST: `{id_doc, id_mat, mensaje}`  
Inserta en tabla `chat` con `envia='2'` (alumno envía), `visto='2'` (docente no ha visto).

---

## 23. Módulo: Docente Guía — `docente-guia.php`

Muestra los docentes guía asignados al grado del alumno. Consulta tabla de asignación de docentes guía.

---

## 24. Módulo: Encuestas

### `encuestas.php` — Listado

Siempre muestra la fila de reinscripción (cupo/retiro/zonificación):
- Si `$_SESSION['reinscribe'] > 0`: botón "Imprimir" → `../encuesta-pdf.php?encuesta={reinscribe}`
- Si no: botón "Responder" → `encuesta.php`

Encuestas dinámicas de la tabla `encuesta`:
```sql
SELECT * FROM encuesta 
WHERE status!='2' AND periodo='{periodo}' 
  AND '{fechahoy}'>=fecha_ini AND '{fechahoy}'<=fecha_fin
  AND IF(todos='S', periodo='{periodo}', '{grado}'>=grado_des AND '{grado}'<=grado_has 
         AND '{seccion}'>=sec_des AND '{seccion}'<=sec_has)
```

Para cada encuesta verifica si el alumno ya respondió:
```sql
SELECT id_respuesta FROM encuesta_respuesta WHERE id_encuesta='{id}' AND id_alum='{idAlum}'
```
- Respondidas: botón imprimir → `../encuestas-pdf.php?idEnc={encriptar(id)}`
- Pendientes: botón responder → `encuesta-hacer.php?idEnc={encriptar(id)}` — fondo lila en la fila
- Fuera de fecha: botón deshabilitado con SweetAlert "Tiempo expirado"

Parámetros GET: `?sinresp` → SweetAlert "Encuesta Pendiente por responder"

### `encuesta.php` — Encuesta de reinscripción

Formulario con 3 opciones radio:
- A) Reserva cupo (value=1)
- B) Solicita retiro (value=2)  
- C) Zonificación para plantel oficial (value=3)

Submite a `procesos/encuesta-pdf.php` (target `_BLANK`).

También puede mostrar preguntas dinámicas de `encuesta_pregunta` y `encuesta_preguntas` con 3 tipos:
- `tipo_pregunta=1`: radio (simple)
- `tipo_pregunta=2`: checkbox (múltiple)
- `tipo_pregunta=3`: textarea (texto libre)

Si la pregunta ya fue respondida, los campos se muestran en `readonly`.

### `encuesta-hacer.php` — Encuesta dinámica
### `encuesta-guarda.php` — Guardar respuestas

---

## 25. Módulo: Video Aula — `video-aula.php`

Lista los videos publicados por los docentes para el grado/sección del alumno. Los videos son típicamente enlaces de YouTube. Fuente: tablas `videos{periodo}` / `videospri{periodo}`.

---

## 26. Módulo: Material de Clases — `material.php`

Lista tareas y material publicado por docentes. Fuente: tablas `tareas{periodo}` / `tareaspri{periodo}`. También muestra si la tarea fue vista por el alumno (tabla `vio_tarea`).

---

## 27. Módulo: Lista de Útiles — `utiles.php`

Lista de materiales escolares por grado. Fuente: tabla `utiles` o similar.

---

## 28. Módulo: Constancias

Todas las constancias tienen el mismo patrón: formulario con campos de motivo/fecha → POST a `procesos/` → genera PDF con FPDF.

### `const-asistencia.php` → `procesos/cons-asi.php`

**Formulario:** `motivo` (textarea) + `diaasis` (date)

**Procesador PDF (`procesos/cons-asi.php`):**

Requiere `$_SESSION['password']` (verifica con sesión) y `tablaPeriodo`.

Valida que el alumno tenga datos completos antes de generar:
```php
if (empty($correo) || empty($ced_rep) || empty($gra_alu)) {
    // Muestra página de error en HTML con botón cerrar
    exit;
}
```

**Query:**
```sql
SELECT A.nombre, A.cedula, A.nacion, B.nombreGrado, A.apellido, A.Periodo, 
       A.correo, A.ced_rep, B.especialidad, C.representante
FROM alumcer A, grado{tablaPeriodo} B, represe C
WHERE A.cedula={usuario} AND A.grado=B.grado AND C.cedula=A.ced_rep
```

Consulta `periodos` para obtener `directorPeriodo` (nombre del director que firma).

El PDF usa FPDF con imagen de logo (`../assets/img/logo.png`), imagen de fondo (`../assets/img/fondoagua.jpg`), fuente Times, texto generado dinámicamente con fecha en español.

Incluye al pie: dirección, dominio y email institucional.

### `const-estudio.php` → `procesos/`
### `const-inscripcion.php` → `procesos/`
### `const-promedio.php` → `procesos/`

No disponible para grados 40–60 (condicional en sidebar).

---

## 29. Módulo: Carnet de Estudio — `carnet.php`

Genera PDF del carnet del estudiante. Usa FPDF con foto del alumno y datos básicos.

---

## 30. Módulo: Planilla de Inscripción — `planilla.php`

Imprime la planilla oficial de inscripción con todos los datos del formulario de perfil.

---

## 31. Módulo: Reinscripción — `encuesta.php`

Ver sección [24 - Encuestas](#24-módulo-encuestas). La encuesta de reinscripción es la primera fila siempre visible en el listado de encuestas y tiene su propio procesador en `procesos/encuesta-pdf.php`.

---

## 32. Procesos auxiliares — `procesos/`

| Archivo | Entrada | Salida | Descripción |
|---------|---------|--------|-------------|
| `actualizar.php` | POST multipart | Redirect `../perfil.php?actual` | Actualiza alumno, representante, madre, padre, emergencias. Ver sección 11. |
| `cons-asi.php` | POST `{motivo, diaasis}` | PDF inline | Constancia de asistencia. Ver sección 28. |
| `encuesta-pdf.php` | POST `{encuesta, idEnc, ...}` | PDF + INSERT en BD | Guarda respuesta de reinscripción y genera PDF. |
| `subefoto.php` | POST multipart `{foto_alu, redir}` | Redirect a `$redir` | Sube foto del alumno desde boletin/corte-notas. Guarda en `../fotoalu/`, actualiza `alumcer.ruta` y `$_SESSION['fotoAlum']`. |

---

## 33. Tablas de base de datos referenciadas

### Tablas estáticas (nombre fijo)

| Tabla | Uso principal |
|-------|--------------|
| `alumcer` | Datos completos del alumno + credenciales + grado + fotos |
| `represe` | Representantes |
| `madres` | Datos de la madre |
| `padres` | Datos del padre |
| `periodos` | Períodos escolares — `tablaPeriodo`, `nombre_periodo`, `activoPeriodo`, `directorPeriodo` |
| `preinscripcion` | Configuración del lapso activo (`lapso` WHERE `id='2'`) |
| `secciones` | Nombre de las secciones |
| `estado` | Estados geográficos |
| `ciudades` | Ciudades / lugares de nacimiento |
| `municipios` | Municipios |
| `parentescos` | Tipos de parentesco |
| `bancos` | Listado de bancos venezolanos (para pago) |
| `chat` | Mensajes del chat alumno-docente |
| `encuesta` | Definición de encuestas activas |
| `encuesta_pregunta` | Preguntas de cada encuesta |
| `encuesta_preguntas` | Opciones de cada pregunta |
| `encuesta_respuesta` | Respuestas del alumno a cada pregunta |
| `evalua_calendario` | Calendario de evaluaciones por grado/sección |
| `eventos_calendario` | Actividades del calendario institucional |
| `vio_tarea` | Control de tareas vistas por el alumno |
| `acceso_alum` | Log de accesos: `idAlum`, `fecha` |
| `actualiza_datos` | Log de actualizaciones de perfil: `idAlum`, `fecha` |
| `tbl_documentos` | Comunicados institucionales |
| `comunica_docen` | Comunicados publicados por docentes |
| `horario` | Archivos de horario por grado/sección/período |

### Tablas dinámicas (nombre varía por período)

El sufijo `{periodo}` es el valor de `periodos.tablaPeriodo` (ej: `2425` para 2024-2025).

| Patrón | Descripción |
|--------|-------------|
| `grado{periodo}` | Grados del período: `grado`, `nombreGrado`, `especialidad` |
| `matri{periodo}` | Mensualidades de bachillerato |
| `notaprimaria{periodo}` | Mensualidades de primaria |
| `montos{periodo}` | Montos mensuales por grado: `monto`, `fecha_vence`, `id_grado` |
| `pagos{periodo}` | Recibos procesados: `recibo`, `fecha`, `concepto`, `monto`, `status`, `idAlum` |
| `tareas{periodo}` | Tareas de bachillerato |
| `tareaspri{periodo}` | Tareas de primaria |
| `tarea_ind_{periodo}` | Asignación individual de tareas bachillerato |
| `tarea_indpri_{periodo}` | Asignación individual de tareas primaria |
| `trgsmp{periodo}` | Asignación docente-materia-grado-sección |
| `materiass{periodo}` | Catálogo de materias del período |
| `videos{periodo}` | Video clases de bachillerato |
| `videospri{periodo}` | Video clases de primaria |

---

## 34. Seguridad y validaciones

### Autenticación

- Sin sesión activa → redirect inmediato a `login.php?vencio=1`
- `login.php` verifica `statusAlum='1'` — alumnos inactivos no pueden ingresar
- La cédula se puede usar como usuario O el campo `miUsuario` personalizado

### Encriptación de IDs en HTML

La función `encriptar()` de `../includes/funciones.php` se usa para pasar IDs sensibles en campos hidden y parámetros GET. `desencriptar()` los recupera en el servidor.

### Control de morosidad

`boletin.php` y `corte-notas.php` redirigen a `home.php?moro=1` si `$_SESSION['morosida'] > 0`. El cálculo de morosidad se hace en `login.php` y se almacena en sesión. Un usuario específico (cédula `25662937`) tiene la morosidad forzada a 0 (cuenta de prueba).

### Exoneración de morosidad

```php
$morosida = (!empty($exoneraMorosidad) && $exoneraMorosidad >= $fechahoy) ? 0 : $morosida;
```
Si `alumcer.exoneraMorosidad` es una fecha futura o presente, la deuda se considera 0.

### Validación de foto (cliente)

- Tipo: solo `image/*`
- Tamaño: máximo 5000 KB en perfil, 200 KB en boletin/corte-notas
- Preview antes de enviar con FileReader API

### Sanitización de texto

Caracteres bloqueados en campos de madre/padre: `" ' : / sudo su * [ ] { } # _`

### Sin prepared statements

Las queries usan interpolación directa en cadenas SQL. Principal riesgo de inyección SQL si los valores de sesión o POST no son de confianza.

---

## 35. Sidebar — menú y visibilidad condicional

### Grupos del menú

| Sección | Items | Condición |
|---------|-------|-----------|
| — | Inicio | siempre |
| — | Mi Perfil | siempre |
| — | Comunicados | siempre |
| **Administración** | Registrar Pago, Historial Pagos | siempre |
| **Documentos** | Planilla, Útiles, Horario, Carnet, Constancias... | siempre (Constancia Promedio solo si grado ≠ 40-60) |
| **Calificaciones** | Corte de Notas, Boletín | Corte solo si grado ≠ 40-60 |
| — | Encuestas | siempre (badge con período activo) |
| — | Calendario de Actividades | siempre |
| **Evaluaciones** | Planificación, Cal. Evaluaciones | siempre |
| **Aula Virtual** | Video Aula, Material, Chat, Docente Guía | siempre (Chat con badge de mensajes) |

### Estado `active` del sidebar

El `$activePage` del módulo debe coincidir con los slugs verificados en `base.php`:
```
home, perfil, comunicados, registrar-pago, historial-pagos,
horario, utiles, carnet, planilla, const-inscripcion, const-estudio,
const-asistencia, const-promedio, corte-notas, boletin,
encuestas, calendario, planificacion, cal-evaluaciones,
video-aula, material, chat-docentes, docente guia
```

---

## 36. Assets frontend

### CSS personalizado — `portal-alumnos.css`

Clases de utilidad usadas en los módulos:

| Clase | Uso |
|-------|-----|
| `.ms-green` | Encabezados de card verde (datos del alumno, confirmaciones) |
| `.ms-red` | Encabezados de card rojo (encuestas pendientes, alertas) |
| `.ms-blue` | Encabezados de card azul (contenido principal, comunicados) |
| `.ms-yellow` | Encabezados de card amarillo (formularios, cálculos) |

### SweetAlert2

Usado en todos los módulos con la API `Swal.fire({icon, title, text, confirmButtonText})`. Cargado vía CDN en `base.php`.

### DataTables

Inicializado en los módulos que lo requieren vía `$extraScripts`:
```js
$("#tablaXxx").DataTable({ 
    language: { url: "//cdn.datatables.net/plug-ins/1.10.16/i18n/Spanish.json" } 
});
```
Traducciones vía CDN externo de datatables.net.

### jQuery Mask

Cargado solo en `perfil.php` vía `$extraScripts`:
```html
<script src="../includes/jquery.maskedinput/src/jquery.mask.js"></script>
```
Formato aplicado: `????-???.??.??` en todos los campos de teléfono.

---

*Documento generado 2026-06-29. Refleja el estado actual del código en `main`.*
