fix: Strict env enforcement, rock-solid Alpine portal rendering, and Nabeh/Redis test diagnostics
This commit is contained in:
+35
-33
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
/**
|
||||
* Nabeh Application Bootstrap Loader
|
||||
* Handles PSR-4 Autoloading, security settings, and error handling.
|
||||
* Saqel Application Bootstrap Loader
|
||||
* Handles PSR-4 Autoloading, security settings, and strict error handling.
|
||||
*/
|
||||
|
||||
// Define absolute path to application root
|
||||
@@ -9,35 +9,32 @@ define('APP_ROOT', dirname(__DIR__));
|
||||
|
||||
// 1. PSR-4 Autoloader
|
||||
spl_autoload_register(function ($class) {
|
||||
// Namespace prefix
|
||||
$prefix = 'App\\';
|
||||
// Directory mapping for the prefix
|
||||
$base_dir = APP_ROOT . '/app/';
|
||||
|
||||
$len = strlen($prefix);
|
||||
if (strncmp($prefix, $class, $len) !== 0) {
|
||||
return; // Move to next registered autoloader
|
||||
return;
|
||||
}
|
||||
|
||||
$relative_class = substr($class, $len);
|
||||
$file = $base_dir . str_replace('\\', '/', $relative_class) . '.php';
|
||||
|
||||
if (file_exists($file)) {
|
||||
require $file;
|
||||
require_once $file;
|
||||
}
|
||||
});
|
||||
|
||||
// 2. Load Environment Variables
|
||||
// 2. Load Environment Variables (Checks local and production server locations)
|
||||
try {
|
||||
// Find the closest .env file path (supporting local development and CloudPanel server directories)
|
||||
$candidatePaths = [
|
||||
// APP_ROOT . '/.env',
|
||||
// APP_ROOT . '/../.env',
|
||||
// APP_ROOT . '/../../.env',
|
||||
// APP_ROOT . '/../../../.env',
|
||||
// APP_ROOT . '/../../../../.env',
|
||||
'/home/intaleqapp-saqel/.env'
|
||||
APP_ROOT . '/.env',
|
||||
APP_ROOT . '/../.env',
|
||||
APP_ROOT . '/docker/.env',
|
||||
'/home/intaleqapp-saqel/.env',
|
||||
'/home/saqel/.env',
|
||||
];
|
||||
|
||||
$env_file = null;
|
||||
foreach ($candidatePaths as $path) {
|
||||
if (file_exists($path)) {
|
||||
@@ -45,18 +42,18 @@ try {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($env_file) {
|
||||
\App\Core\Env::load($env_file);
|
||||
} else {
|
||||
throw new \RuntimeException("No .env file found in candidate paths");
|
||||
error_log("⚠️ [Env Warning] No .env file found in candidate paths. Expecting variables from server environment.");
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
// In production, log error; in development, print it
|
||||
error_log('Env Load Error: ' . $e->getMessage());
|
||||
}
|
||||
|
||||
// 3. Configure Error Reporting based on environment
|
||||
$isDebug = filter_var(getenv('APP_DEBUG') ?: true, FILTER_VALIDATE_BOOLEAN);
|
||||
$isDebug = filter_var(getenv('APP_DEBUG'), FILTER_VALIDATE_BOOLEAN);
|
||||
|
||||
if ($isDebug) {
|
||||
ini_set('display_errors', '1');
|
||||
@@ -67,31 +64,36 @@ if ($isDebug) {
|
||||
error_reporting(0);
|
||||
}
|
||||
|
||||
// 4. Global Uncaught Exception Handler
|
||||
// Catches any unhandled exception anywhere in the app and returns a clean JSON error
|
||||
// instead of leaking PHP stack traces to the browser.
|
||||
// 4. Global Uncaught Exception Handler (JSON for APIs / Clean HTML for web)
|
||||
set_exception_handler(function (\Throwable $e) {
|
||||
$isDebug = filter_var(getenv('APP_DEBUG') ?: true, FILTER_VALIDATE_BOOLEAN);
|
||||
$isDebug = filter_var(getenv('APP_DEBUG'), FILTER_VALIDATE_BOOLEAN);
|
||||
|
||||
error_log('[EXCEPTION] ' . get_class($e) . ': ' . $e->getMessage() . ' in ' . $e->getFile() . ':' . $e->getLine());
|
||||
|
||||
$isApi = str_starts_with($_SERVER['REQUEST_URI'] ?? '', '/api');
|
||||
|
||||
if (!headers_sent()) {
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
http_response_code(500);
|
||||
if ($isApi) {
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
} else {
|
||||
header('Content-Type: text/html; charset=utf-8');
|
||||
}
|
||||
}
|
||||
|
||||
$body = ['error' => 'Internal Server Error'];
|
||||
|
||||
// In debug mode, expose details to the developer only
|
||||
if ($isDebug) {
|
||||
$body['debug'] = [
|
||||
'exception' => get_class($e),
|
||||
'message' => $e->getMessage(),
|
||||
'file' => $e->getFile(),
|
||||
'line' => $e->getLine(),
|
||||
if ($isApi) {
|
||||
$body = [
|
||||
'status' => 'error',
|
||||
'message' => $isDebug ? $e->getMessage() : 'حدث خطأ غير متوقع في الخادم',
|
||||
'debug' => $isDebug ? [
|
||||
'exception' => get_class($e),
|
||||
'file' => $e->getFile(),
|
||||
'line' => $e->getLine(),
|
||||
] : null
|
||||
];
|
||||
echo json_encode($body, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
|
||||
} else {
|
||||
echo "<!DOCTYPE html><html dir='rtl' lang='ar'><head><meta charset='UTF-8'><title>خطأ في الخادم</title><style>body{font-family:sans-serif;background:#0B132B;color:#fff;padding:40px;text-align:center;}</style></head><body><h2>⚠️ حدث خطأ في الخادم</h2><p>" . htmlspecialchars($e->getMessage()) . "</p></body></html>";
|
||||
}
|
||||
|
||||
echo json_encode($body, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
|
||||
exit(1);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user