<?php
include_once __DIR__ . '/../vendor/autoload.php'; // Define auto loading for classes
use App\Infrastructure;
use App\Kernel;
use Symfony\Component\ErrorHandler\Debug;
use Symfony\Component\HttpFoundation\Request;
global $kernel, $connection, $twig, $entityManager, $logger, $app;
if ($_SERVER['APP_DEBUG'] ?? false) {
umask(0000);
Debug::enable();
}
if ($trustedProxies = $_SERVER['TRUSTED_PROXIES'] ?? false) {
Request::setTrustedProxies(explode(',', $trustedProxies), Request::HEADER_X_FORWARDED_FOR | Request::HEADER_X_FORWARDED_PORT | Request::HEADER_X_FORWARDED_PROTO);
}
if ($trustedHosts = $_SERVER['TRUSTED_HOSTS'] ?? false) {
Request::setTrustedHosts([$trustedHosts]);
}
$kernel = new Kernel($_SERVER['APP_ENV'], (bool) ($_SERVER['APP_DEBUG'] ?? false));
$kernel->boot();
$container = $kernel->getContainer();
$session = null;
// If this variable is set to anything, we should not start the session. This
// is really only useful during the docker build process.
if (getenv('DISABLE_SESSIONS') === false) {
$session = $container->get('session');
$session->start();
}
$twig = $container->get('twig');
/** @var \Doctrine\DBAL\Connection $connection */
$connection = $container->get('database_connection');
$entityManager = $container->get('doctrine.orm.entity_manager');
$logger = $container->get('logger');
$app = [
'db' => $connection,
'twig' => $twig,
'orm.em' => $entityManager,
'logger' => $logger,
'session' => $session,
];
$request = Request::createFromGlobals();
$response = $kernel->handle($request);
$scriptFile = Infrastructure\LegacyBridge::prepareLegacyScript($request, $response, __DIR__);
if ($scriptFile !== null) {
// RouterListener (priority 32) throws NotFoundHttpException for legacy routes
// before PermissionsCheckSubscriber (priority 0) or access_control can run.
// Both auth and permission checks must happen here, as the sole gateway.
$legacyPath = trim($request->getPathInfo(), '/');
$isOpenPath = in_array($legacyPath, ['login', 'logout']);
// 1. Auth: unauthenticated users go to login.
if (!$isOpenPath && !($session?->has('user') ?? false)) {
(new \Symfony\Component\HttpFoundation\RedirectResponse('/login'))->send();
$kernel->terminate($request, $response);
exit;
}
// 2. Permissions: check sitestructure for authenticated users.
// has_permission() is available via composer files autoload (functions.php).
// Paths under includes/ are AJAX/utility endpoints that have no sitestructure
// row — they rely on their own internal permission checks, so skip them here.
// payroll.php and reports.php use query-string-dependent permission rows.
$isIncludePath = strpos($legacyPath, 'includes') !== false;
if (!$isOpenPath && !$isIncludePath) {
$permPath = $legacyPath;
if (in_array($legacyPath, ['payroll.php', 'reports.php']) && $request->getQueryString()) {
$permPath .= '?' . $request->getQueryString();
}
if (!has_permission($connection, $permPath) && !has_permission($connection, '/' . $permPath)) {
(new \Symfony\Component\HttpFoundation\RedirectResponse('/login'))->send();
$kernel->terminate($request, $response);
exit;
}
}
require $scriptFile;
} else {
$response->send();
}
$kernel->terminate($request, $response);