up
This commit is contained in:
+129
@@ -0,0 +1,129 @@
|
||||
<?php
|
||||
/**
|
||||
* core/App.php
|
||||
* Bootstrap y punto de entrada del ERP.
|
||||
*
|
||||
* Uso desde index.php (punto de entrada del módulo ERP):
|
||||
*
|
||||
* define('APP_ROOT', __DIR__);
|
||||
* require_once __DIR__ . '/core/App.php';
|
||||
* App::run();
|
||||
*
|
||||
* Los archivos lab_*.php legacy en raíz siguen funcionando directamente
|
||||
* sin pasar por App — compatibilidad total garantizada.
|
||||
*/
|
||||
|
||||
// ─── Constante de raíz del proyecto ─────────────────────────────────────────
|
||||
if (!defined('APP_ROOT')) {
|
||||
define('APP_ROOT', dirname(__DIR__));
|
||||
}
|
||||
|
||||
// ─── Dependencias del core ───────────────────────────────────────────────────
|
||||
require_once APP_ROOT . '/config/config.php';
|
||||
require_once APP_ROOT . '/core/Helpers.php';
|
||||
require_once APP_ROOT . '/core/Auth.php';
|
||||
require_once APP_ROOT . '/core/Rbac.php';
|
||||
require_once APP_ROOT . '/core/Router.php';
|
||||
require_once APP_ROOT . '/core/Layout.php';
|
||||
|
||||
class App
|
||||
{
|
||||
// ─── Punto de entrada ────────────────────────────────────────────────────
|
||||
|
||||
public static function run(): void
|
||||
{
|
||||
self::boot();
|
||||
|
||||
$router = new Router();
|
||||
|
||||
// Rutas públicas: sin verificación de sesión
|
||||
if (!$router->isPublic()) {
|
||||
Auth::requireLogin();
|
||||
// Enfermeros van a su portal propio, no al panel ERP
|
||||
if (Auth::isEnfermero()) {
|
||||
header('Location: ' . APP_ROOT . '/../enfermero_portal.php');
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
self::dispatch($router);
|
||||
}
|
||||
|
||||
// ─── Bootstrap ──────────────────────────────────────────────────────────
|
||||
|
||||
/**
|
||||
* Inicializa la sesión y la zona horaria.
|
||||
* Se puede llamar también desde archivos legacy para obtener sesión lista.
|
||||
*/
|
||||
public static function boot(): void
|
||||
{
|
||||
if (session_status() === PHP_SESSION_NONE) {
|
||||
// Cookies de sesión seguras
|
||||
session_set_cookie_params([
|
||||
'lifetime' => 0,
|
||||
'path' => '/',
|
||||
'secure' => !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off',
|
||||
'httponly' => true,
|
||||
'samesite' => 'Lax',
|
||||
]);
|
||||
session_start();
|
||||
}
|
||||
|
||||
date_default_timezone_set(defined('TIMEZONE') ? TIMEZONE : 'America/Bogota');
|
||||
}
|
||||
|
||||
// ─── Dispatch ───────────────────────────────────────────────────────────
|
||||
|
||||
private static function dispatch(Router $router): void
|
||||
{
|
||||
try {
|
||||
$viewFile = $router->resolveFile();
|
||||
} catch (RuntimeException $e) {
|
||||
self::render404($router->getModule(), $router->getView());
|
||||
return;
|
||||
}
|
||||
|
||||
// Verificar permiso de módulo (solo en rutas protegidas)
|
||||
if (!$router->isPublic()) {
|
||||
$module = $router->getModule();
|
||||
// Si el módulo está registrado en SYSTEM_MODULES, verificar acceso
|
||||
if (defined('SYSTEM_MODULES') && array_key_exists($module, SYSTEM_MODULES)) {
|
||||
if (!Rbac::hasModule($module)) {
|
||||
self::render403($module);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Ejecutar la vista del módulo
|
||||
include $viewFile;
|
||||
}
|
||||
|
||||
// ─── Páginas de error ────────────────────────────────────────────────────
|
||||
|
||||
private static function render404(string $module, string $view): void
|
||||
{
|
||||
http_response_code(404);
|
||||
Layout::open('Página no encontrada', 'fas fa-exclamation-triangle');
|
||||
echo '<div class="container-fluid py-5 text-center">';
|
||||
echo '<i class="fas fa-exclamation-triangle fa-4x text-warning mb-3"></i>';
|
||||
echo '<h2>404 — Módulo no encontrado</h2>';
|
||||
echo '<p class="text-muted">El módulo <code>' . esc($module) . '</code> / vista <code>' . esc($view) . '</code> no existe.</p>';
|
||||
echo '<a href="' . esc(APP_URL ?? '/') . '" class="btn btn-primary"><i class="fas fa-home me-1"></i>Ir al inicio</a>';
|
||||
echo '</div>';
|
||||
Layout::close();
|
||||
}
|
||||
|
||||
private static function render403(string $module): void
|
||||
{
|
||||
http_response_code(403);
|
||||
Layout::open('Acceso denegado', 'fas fa-lock');
|
||||
echo '<div class="container-fluid py-5 text-center">';
|
||||
echo '<i class="fas fa-lock fa-4x text-danger mb-3"></i>';
|
||||
echo '<h2>403 — Sin permiso</h2>';
|
||||
echo '<p class="text-muted">Tu rol no tiene acceso al módulo <code>' . esc($module) . '</code>.</p>';
|
||||
echo '<a href="' . esc(APP_URL ?? '/') . '" class="btn btn-secondary"><i class="fas fa-arrow-left me-1"></i>Volver</a>';
|
||||
echo '</div>';
|
||||
Layout::close();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user