Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
96.67% |
29 / 30 |
|
80.00% |
4 / 5 |
CRAP | |
0.00% |
0 / 1 |
| InstallerConfigLoader | |
96.55% |
28 / 29 |
|
80.00% |
4 / 5 |
20 | |
0.00% |
0 / 1 |
| load | |
100.00% |
14 / 14 |
|
100.00% |
1 / 1 |
7 | |||
| resolveTargetDbName | |
66.67% |
2 / 3 |
|
0.00% |
0 / 1 |
5.93 | |||
| isClientContext | |
100.00% |
10 / 10 |
|
100.00% |
1 / 1 |
6 | |||
| setConfig | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| reset | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| 1 | <?php |
| 2 | |
| 3 | declare(strict_types=1); |
| 4 | |
| 5 | /** @license For full copyright and license information, please see the LICENSE.md file. */ |
| 6 | |
| 7 | namespace App\Shared\Infrastructure\Config; |
| 8 | |
| 9 | defined('AMMONLY_APP') || exit('Direct script access is forbidden.'); |
| 10 | |
| 11 | /** |
| 12 | * Centralized Installer Configuration Loader. |
| 13 | * |
| 14 | * Provides thread-safe, static cached access to database installer configuration. |
| 15 | * |
| 16 | * @package App\Shared\Infrastructure\Config |
| 17 | */ |
| 18 | final class InstallerConfigLoader |
| 19 | { |
| 20 | /** @var array<string, mixed>|null */ |
| 21 | private static ?array $cachedFileConfig = null; |
| 22 | |
| 23 | /** @var array<string, mixed>|null */ |
| 24 | private static ?array $config = null; |
| 25 | |
| 26 | /** |
| 27 | * Loads and caches installer database configuration. |
| 28 | * |
| 29 | * @return array<string, mixed> Configuration dictionary. |
| 30 | */ |
| 31 | public static function load(): array |
| 32 | { |
| 33 | if (self::$config !== null) { |
| 34 | return self::$config; |
| 35 | } |
| 36 | |
| 37 | $configFile = dirname(__DIR__, 4) . '/database/config/installer.php'; |
| 38 | if (!file_exists($configFile)) { |
| 39 | self::$config = []; |
| 40 | return self::$config; |
| 41 | } |
| 42 | |
| 43 | if (self::$cachedFileConfig !== null) { |
| 44 | self::$config = self::$cachedFileConfig; |
| 45 | } else { |
| 46 | $loaded = (static fn(string $f) => require_once $f)($configFile); |
| 47 | self::$cachedFileConfig = is_array($loaded) ? $loaded : []; |
| 48 | self::$config = self::$cachedFileConfig; |
| 49 | } |
| 50 | |
| 51 | if (isset(self::$config['db']) && is_array(self::$config['db'])) { |
| 52 | self::$config['db']['dbname'] = self::resolveTargetDbName(); |
| 53 | } |
| 54 | |
| 55 | return self::$config; |
| 56 | } |
| 57 | |
| 58 | /** |
| 59 | * Resolves target database name based on environment and request context. |
| 60 | */ |
| 61 | private static function resolveTargetDbName(): string |
| 62 | { |
| 63 | if (isset($_ENV['DB_NAME']) && is_string($_ENV['DB_NAME']) && $_ENV['DB_NAME'] !== '') { |
| 64 | return $_ENV['DB_NAME']; |
| 65 | } |
| 66 | |
| 67 | return self::isClientContext() ? 'ammonly_client' : 'ammonly_admin'; |
| 68 | } |
| 69 | |
| 70 | /** |
| 71 | * Determines whether the current context is running under client profile. |
| 72 | */ |
| 73 | public static function isClientContext(): bool |
| 74 | { |
| 75 | $host = (string) ($_SERVER['HTTP_HOST'] ?? ''); |
| 76 | $docRoot = (string) ($_SERVER['DOCUMENT_ROOT'] ?? ''); |
| 77 | $appProfile = (string) ($_ENV['APP_PROFILE'] ?? $_SERVER['APP_PROFILE'] ?? ''); |
| 78 | $dir = __DIR__; |
| 79 | $cwd = (string) (getcwd() ?: ''); |
| 80 | |
| 81 | return stripos($host, 'client') !== false |
| 82 | || stripos($docRoot, 'client') !== false |
| 83 | || stripos($dir, 'app-client') !== false |
| 84 | || stripos($cwd, 'app-client') !== false |
| 85 | || $appProfile === 'client'; |
| 86 | } |
| 87 | |
| 88 | /** |
| 89 | * Injects custom configuration dictionary (primarily for unit testing). |
| 90 | * |
| 91 | * @param array<string, mixed>|null $config Configuration array or null. |
| 92 | */ |
| 93 | public static function setConfig(?array $config): void |
| 94 | { |
| 95 | self::$config = $config; |
| 96 | } |
| 97 | |
| 98 | /** |
| 99 | * Resets cached config state (primarily for unit testing). |
| 100 | */ |
| 101 | public static function reset(): void |
| 102 | { |
| 103 | self::$config = null; |
| 104 | } |
| 105 | } |