*/ private array $providers = []; public function __construct(private readonly ConfigInterface $config) { } public function load(): void { $this->providers = []; // Merge providers from config/providers.php file (authoritative) with any runtime Config entries $fileCore = $fileApp = $fileModules = []; $configFile = dirname(__DIR__, 2) . '/config/providers.php'; if (is_file($configFile)) { /** @noinspection PhpIncludeInspection */ $arr = require $configFile; if (is_array($arr)) { $fileCore = (array)($arr['core'] ?? []); $fileApp = (array)($arr['app'] ?? []); $fileModules = (array)($arr['modules'] ?? []); } } $core = array_values(array_unique(array_merge($fileCore, (array) Config::get('providers.core', [])))); $app = array_values(array_unique(array_merge($fileApp, (array) Config::get('providers.app', [])))); $modules = array_values(array_unique(array_merge($fileModules, (array) Config::get('providers.modules', [])))); foreach ([$core, $app, $modules] as $group) { foreach ($group as $class) { if (is_string($class) && class_exists($class)) { $instance = new $class(); if ($instance instanceof ServiceProviderInterface) { $this->providers[] = $instance; } } } } // Initial module discovery: scan modules/*/Providers/*ServiceProvider.php $root = dirname(__DIR__, 2); $modulesDir = $root . '/modules'; if (is_dir($modulesDir)) { foreach (scandir($modulesDir) ?: [] as $entry) { if ($entry === '.' || $entry === '..') { continue; } $modulePath = $modulesDir . '/' . $entry; if (!is_dir($modulePath)) { continue; } $providersPath = $modulePath . '/Providers'; if (!is_dir($providersPath)) { continue; } foreach (scandir($providersPath) ?: [] as $file) { if ($file === '.' || $file === '..' || !str_ends_with($file, '.php')) { continue; } $classBase = substr($file, 0, -4); if (!str_ends_with($classBase, 'ServiceProvider')) { continue; } $fqcn = "Project\\\\Modules\\\\{$entry}\\\\Providers\\\\{$classBase}"; if (class_exists($fqcn)) { $instance = new $fqcn(); if ($instance instanceof ServiceProviderInterface) { $this->providers[] = $instance; } } } } } } public function registerAll(ContainerBuilder $builder): void { foreach ($this->providers as $provider) { $provider->register($builder, $this->config); } } public function bootAll(Container $container): void { foreach ($this->providers as $provider) { $provider->boot($container); } } }