connect(); define("redis", $redis_instance); } catch (Exception $e) { // Redis might not be available, autoloader will fall back to manual search } /** * Lightweight project autoloader: load classes/interfaces/traits/modules on demand. * Maps top-level namespaces to folders under the app root (WD). * - classes\* -> WD/classes/* * - interfaces\* -> WD/interfaces/* * - traits\* -> WD/traits/* * - objects\* -> WD/objects/* * - statistics\* -> WD/statistics/* * - modules\...\* -> WD/modules/... * - \...\* -> WD/modules//... (e.g., bird\bird_c) */ spl_autoload_register(function (string $class): void { $class = ltrim($class, '\\'); // Check Redis cache first if (defined('redis')) { try { $cached = redis->get('autoload:' . $class); if ($cached && is_file($cached)) { require_once $cached; return; } } catch (\Throwable $e) { // Fall back to manual search on Redis error } } $parts = explode('\\', $class); $top = strtolower($parts[0] ?? ''); $relative = implode(DIRECTORY_SEPARATOR, array_slice($parts, 1)); $base = WD . DIRECTORY_SEPARATOR; $candidates = []; // 1. Core folders: classes, interfaces, traits, objects, statistics $core_folders = ['classes', 'interfaces', 'traits', 'objects', 'statistics']; if (in_array($top, $core_folders)) { $candidates[] = $base . $top . DIRECTORY_SEPARATOR . $relative; } // 2. Modules folder: explicitly starting with 'modules' elseif ($top === 'modules') { $candidates[] = $base . 'modules' . DIRECTORY_SEPARATOR . $relative; } // 3. Fallback for module-specific classes without 'modules' prefix or nested in modules else { // Try directly under modules (e.g. bird\bird_c -> modules/bird/bird_c.php) $candidates[] = $base . 'modules' . DIRECTORY_SEPARATOR . str_replace('\\', DIRECTORY_SEPARATOR, $class); // Try inside each module subfolder (e.g. customers\economicCustomers -> modules/economic/customers/economicCustomers.php) static $module_dirs = null; if ($module_dirs === null) { if (defined('redis')) { try { $module_dirs = redis->get_array('autoload:module_dirs'); } catch (\Throwable $e) {} } if ($module_dirs === null) { $module_dirs = array_filter(scandir($base . 'modules'), function($item) use ($base) { return $item !== '.' && $item !== '..' && is_dir($base . 'modules' . DIRECTORY_SEPARATOR . $item); }); if (defined('redis')) { try { redis->set_array('autoload:module_dirs', $module_dirs); redis->expire('autoload:module_dirs', 3600); // Cache for 1 hour } catch (\Throwable $e) {} } } } foreach ($module_dirs as $mod) { $candidates[] = $base . 'modules' . DIRECTORY_SEPARATOR . $mod . DIRECTORY_SEPARATOR . str_replace('\\', DIRECTORY_SEPARATOR, $class); } } $suffixes = ['', '_t', '_o', '_s', '_i', '_c', '_m']; foreach ($candidates as $path) { if (empty($path)) continue; foreach ($suffixes as $suffix) { $file = $path . $suffix . '.php'; if (is_file($file)) { require_once $file; if (class_exists($class, false) || interface_exists($class, false) || trait_exists($class, false) || (function_exists('enum_exists') && enum_exists($class, false))) { if (defined('redis')) { try { redis->setEx('autoload:' . $class, $file, 86400); // Cache for 24 hours } catch (\Throwable $e) {} } return; } } } } }); use classes\db; use classes\redis; use classes\request; use classes\response; use classes\router; // Start the session $router = new router(); $response = new response(); $request = new request(); $db = new db($CONFIG_DB); // Ensure Redis is connected if (!defined('redis')) { try { define("redis", (new redis())->connect()); } catch (Exception $e) { $response->error($e->getMessage(), 500); } } // Connect to the database, and ensure the connection is successful try { $db->connect(); } catch (Exception $e) { $response->error($e->getMessage(), 500); } // If the program was called from the command line, run the cli script if (php_sapi_name() === 'cli' || isset($_GET['internalCronCall'])) { require_once 'cli.php'; exit; } // If the route ends with a MIME type, then require the file_server.php if ((preg_match('/\.(jpg|jpeg|png)$/', $_SERVER['REQUEST_URI']) || str_contains($_SERVER['REQUEST_URI'], '/files/'))) { require_once 'file_server.php'; exit; } // Autoload all the routes $router->auto_load_routes(WD . '/routes');