safeLoad(); /** * Configuration centrale avec valeurs par défaut raisonnables. * * - 'env' : environnement d'exécution ('production' par défaut) * - 'twig.cache' : résolu plus bas à partir de TWIG_CACHE ou par défaut selon l'environnement * - 'db.file' et 'db.file_mode' : fichier SQLite et permissions */ $config = [ 'env' => strtolower((string) ($_ENV['APP_ENV'] ?? $_SERVER['APP_ENV'] ?? 'production')), 'twig' => [ 'cache' => null, ], 'db' => [ 'file' => __DIR__ . '/../database/app.sqlite', 'file_mode' => 0664, ], ]; /** * Résolution de la valeur twig.cache depuis la variable d'environnement TWIG_CACHE. * Si TWIG_CACHE est vide : false en dev, chemin par défaut en production. */ $envTwigCache = $_ENV['TWIG_CACHE'] ?? $_SERVER['TWIG_CACHE'] ?? null; if ($envTwigCache !== null && $envTwigCache !== '') { $config['twig']['cache'] = (string) $envTwigCache; } else { $devEnvs = ['development', 'dev']; $config['twig']['cache'] = in_array($config['env'], $devEnvs, true) ? false : __DIR__ . '/../var/cache/twig'; } $isDebug = in_array($config['env'], ['development', 'dev'], true); /** * Affichage et rapport d'erreurs selon l'environnement. */ if ($isDebug) { ini_set('display_errors', '1'); ini_set('display_startup_errors', '1'); error_reporting(E_ALL); } else { ini_set('display_errors', '0'); ini_set('display_startup_errors', '0'); error_reporting(E_ALL & ~E_DEPRECATED & ~E_STRICT); } // ------------------------- // Base de données (SQLite) // ------------------------- $dbFile = $config['db']['file']; /** * Créer le fichier de base de données si nécessaire et appliquer les permissions. */ if (!file_exists($dbFile)) { $dbDir = dirname($dbFile); if (!is_dir($dbDir)) { mkdir($dbDir, 0755, true); } touch($dbFile); @chmod($dbFile, $config['db']['file_mode']); } /** * Options Medoo pour SQLite. */ $medooOptions = [ 'database_type' => 'sqlite', 'database_name' => $dbFile, 'charset' => 'utf8', ]; /** @var Medoo $database */ $database = new Medoo($medooOptions); /** * Schéma minimal : création de la table 'post' si elle n'existe pas. */ $database->query( <<<'SQL' CREATE TABLE IF NOT EXISTS post ( id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT NOT NULL, content TEXT NOT NULL ); SQL ); // ------------------------- // Services (container simple) // ------------------------- /** * Container simple (table associative de services). * * @var array $container */ $container = []; /** * Construire les services et les retourner dans le container. * * Cette fonction reste locale pour préserver l'encapsulation. * * @param array $config * @param Medoo $database * @return array */ $container = (static function (array $config, Medoo $database): array { $services = []; // Résoudre le cache Twig et créer le dossier si nécessaire. $twigCache = $config['twig']['cache']; if ($twigCache && $twigCache !== false && !is_dir((string) $twigCache)) { mkdir((string) $twigCache, 0755, true); } // Vue Twig $loader = new FilesystemLoader(__DIR__ . '/../views'); $services['view'] = new Twig($loader, ['cache' => $config['twig']['cache']]); // Repository Post (implémentation Medoo) $services['postRepository'] = new App\Repositories\PostRepositoryMedoo($database); return $services; })($config, $database); // ------------------------- // Slim app // ------------------------- $app = AppFactory::create(); /** * Middleware d'erreurs. * * Les trois flags correspondent à : displayErrorDetails, logErrors, logErrorDetails. */ $errorMiddleware = $app->addErrorMiddleware($isDebug, $isDebug, $isDebug); if (!$isDebug) { $errorHandler = $errorMiddleware->getDefaultErrorHandler(); // Renderer HTML générique en production pour masquer les détails d'exception. $errorHandler->registerErrorRenderer('text/html', static function (Throwable $exception, bool $displayErrorDetails): string { return 'Erreur

Erreur serveur

Une erreur est survenue. Veuillez réessayer plus tard.

'; }); } // Middlewares essentiels $app->addBodyParsingMiddleware(); $app->add(TwigMiddleware::create($app, $container['view'])); /** * Charger les routes : le fichier web.php reçoit l'application et le container. * On utilise require pour que toute exception remonte à Slim / au handler d'erreurs. */ $routesPath = __DIR__ . '/../src/Routes/web.php'; if (file_exists($routesPath)) { /** @var callable $routes */ $routes = require $routesPath; $routes($app, $container); } else { // En cas d'absence du fichier de routes, on peut laisser l'application démarrer sans routes. // (Conserver le comportement antérieur — aucune exception levée ici) } $app->run();