Módulo 7: Máximo Boss Múltiple (Matrículas N:M)
Esta es la interfaz cumbre del estudiante. Vamos a inscribir a 1 Alumno a 5 CURSOS MATERIAS a la vez mediante un Array, y a mostrar la inmensa lista de cobros usando una Tabla Cruzada Triple Vía. Igualito a como se ve en la "Demo App" Viva de tu sistema.
7.1: El Modelo Crítico Pivote N:M
app/Models/MatriculaModelo.php<?php
namespace App\Models;
class MatriculaModelo {
private $db;
public function __construct() { $this->db = \App\Core\Database::getInstance(); }
public function crearCruce($idestudio, $idcurso) {
// Truco Maestro PRO: "INSERT IGNORE" evita Pantallazo Naranja si el alumno repite mismo curso
$sql = "INSERT IGNORE INTO matriculas (id_estudiante, id_curso) VALUES (:e, :c)";
try {
return $this->db->prepare($sql)->execute(['e'=>$idestudio, 'c'=>$idcurso]);
} catch(\PDOException $e) { return false; }
}
public function listadoTotal() {
$sql = "SELECT m.id_estudiante, e.nombre as estudiante, e.matricula, c.nombre as curso
FROM matriculas m
JOIN estudiantes e ON m.id_estudiante = e.id
JOIN cursos c ON m.id_curso = c.id";
return $this->db->query($sql)->fetchAll(\PDO::FETCH_OBJ);
}
}
7.2: Controlador Transaccional
app/Controllers/DemoController.php public function matriculas() {
$this->render('matriculas/index', [
'lista_matr' => (new \App\Models\MatriculaModelo())->listadoTotal()
]);
}
public function crearMatricula() {
$this->render('matriculas/crear', [
'estudiantes' => (new \App\Models\EstudianteModelo())->all(),
'cursos' => (new \App\Models\CursoModelo())->all()
]);
}
public function guardarMatricula() {
$inscriptor = new \App\Models\MatriculaModelo();
// ESTE BUCLE FOREACH ES EL QUE RECIBE EL SELECT[] MÚLTIPLE HTML
foreach($_POST['cursos_array_del_front'] as $mat) {
$inscriptor->crearCruce($_POST['id_est'], $mat);
}
header("Location: " . BASE_URL . "/demo/matriculas"); exit;
}
7.3: La Vista Listado y el Formulario Multi-Ticket
app/Views/matriculas/index.php<div class="card border-0 shadow-sm p-4">
<div class="d-flex justify-content-between mb-4">
<h2>Central de Ventas</h2>
<a href="/demo/matriculas/crear" class="btn btn-success">Facturar Combinación</a>
</div>
<table class="table">
<thead><tr><th>CLIENTE BD</th><th>PRODUCTO COMPRADO</th></tr></thead>
<tbody>
<?php foreach($lista_matr as $reg): ?>
<tr>
<td class="fw-bold">[COD-<?= $reg->matricula ?>] <?= $reg->estudiante ?></td>
<td class="text-success"><?= $reg->curso ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
app/Views/matriculas/crear.php<div class="container d-flex justify-content-center mt-3">
<div class="card shadow-sm border-0 p-5 bg-white w-50" style="border-radius:15px;">
<form action="/demo/matriculas/guardar" method="POST">
<label class="fw-bold fs-5 text-primary">1. Elige al Cliente</label>
<select name="id_est" class="form-select border-primary shadow-sm mb-4" required>
<?php foreach($estudiantes as $est): ?>
<option value="<?= $est->id ?>"><?= $est->nombre ?></option>
<?php endforeach; ?>
</select>
<label class="fw-bold fs-5 text-success">2. Array Múltiple de Compra</label>
<select name="cursos_array_del_front[]" class="form-select border-success shadow-sm" multiple style="height:210px;" required>
<?php foreach($cursos as $cur): ?>
<option value="<?= $cur->id ?>">🛒 <?= $cur->nombre ?></option>
<?php endforeach; ?>
</select>
<button type="submit" class="btn btn-success fw-bold w-100 py-3 mt-4">PROCESAR CARRO MULTIPLE</button>
</form>
</div>
</div>