>|null */ private ?array $desktopApps = null; public function __construct( private readonly string $modulesPath, ) { } /** * @return array> */ public function desktopApps(): array { if ($this->desktopApps !== null) { return $this->desktopApps; } $apps = []; foreach ($this->moduleDirectories() as $moduleName => $modulePath) { $desktopConfigPath = $modulePath . '/desktop.php'; if (!is_file($desktopConfigPath)) { continue; } $desktopConfig = require $desktopConfigPath; if (!is_array($desktopConfig)) { continue; } $manifest = $this->readJson($modulePath . '/module.json'); $desktopConfig['module_id'] = $moduleName; $desktopConfig['title'] ??= (string) ($manifest['title'] ?? ucfirst($moduleName)); $desktopConfig['summary'] ??= (string) ($manifest['description'] ?? ''); $desktopConfig['required_groups'] ??= array_values(array_map( 'strval', (array) ($manifest['auth']['groups'] ?? []) )); $desktopConfig['enabled_by_default'] ??= (bool) ($manifest['enabled_by_default'] ?? false); $apps[] = $desktopConfig; } return $this->desktopApps = $apps; } public function modulePath(string $moduleName): ?string { $directories = $this->moduleDirectories(); return $directories[$moduleName] ?? null; } /** * @return array */ private function moduleDirectories(): array { $paths = glob(rtrim($this->modulesPath, '/') . '/*', GLOB_ONLYDIR); if (!is_array($paths)) { return []; } $directories = []; foreach ($paths as $path) { $moduleName = basename($path); if ($moduleName === '' || $moduleName[0] === '.') { continue; } $directories[$moduleName] = $path; } ksort($directories); return $directories; } /** * @return array */ private function readJson(string $path): array { if (!is_file($path)) { return []; } $raw = file_get_contents($path); if ($raw === false || trim($raw) === '') { return []; } $decoded = json_decode($raw, true); return is_array($decoded) ? $decoded : []; } }