Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 76
0.00% covered (danger)
0.00%
0 / 9
CRAP
0.00% covered (danger)
0.00%
0 / 1
SystemConfig
0.00% covered (danger)
0.00%
0 / 76
0.00% covered (danger)
0.00%
0 / 9
1190
0.00% covered (danger)
0.00%
0 / 1
 read
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 apply
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
110
 verify
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
12
 readFromEnvironment
0.00% covered (danger)
0.00%
0 / 26
0.00% covered (danger)
0.00%
0 / 1
30
 readVersion
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
2
 boolEnv
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 stringEnv
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
12
 write
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
72
 dumpDbConfig
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2/** @noinspection PhpUnhandledExceptionInspection */
3
4class SystemConfig {
5  public static string $database_host;
6  public static string $database_name;
7  public static string $database_password;
8  public static int $database_port;
9  public static string $database_user;
10  public static string $fileService_external = "";
11  public static string $fileService_internal = "";
12  public static string $broadcastingService_external = "";
13  public static string $broadcastingService_internal = "";
14  public static string $cacheService_host = "";
15  public static string $cacheService_includeFiles = "";
16  public static int $cacheService_ram = 0;
17  public static string $password_salt = "t";
18  public static bool $system_tlsEnabled = true;
19  public static string $system_hostname;
20  public static string $system_version;
21  public static int $system_veronaMax;
22  public static int $system_veronaMin;
23  public static string $system_timezone = 'Europe/Berlin';
24  public static bool $debug_useInsecurePasswords = false;
25  public static bool $debug_allowExternalXmlSchema = true;
26  public static bool $debug_useStaticTokens = false;
27  public static bool $debug_fastLoginReuse = false;
28  public static string $debug_useStaticTime = 'now';
29  public static string $language_dateFormat = 'd/m/Y H:i';
30  // TODO server URL, port
31
32  public static function read(): void {
33    $config = parse_ini_file(ROOT_DIR . '/backend/config/config.ini', true, INI_SCANNER_TYPED);
34    if (!$config) {
35      throw new Exception('Application config file is missing!');
36    }
37    self::apply($config);
38  }
39
40  public static function apply(array $config): void {
41    foreach ($config as $sectionName => $section) {
42      foreach ($section as $key => $value) {
43        $propertyKey = "{$sectionName}_$key";
44        if (property_exists(self::class, $propertyKey)) {
45          self::$$propertyKey = $value;
46        }
47      }
48    }
49
50    if (
51      (!isset(self::$system_version) or !self::$system_version) or
52      (!isset(self::$system_veronaMax) or !self::$system_veronaMax) or
53      (!isset(self::$system_veronaMin) or !self::$system_veronaMin)
54    ) {
55      self::readVersion();
56    }
57    self::verify();
58  }
59
60  private static function verify(): void {
61    foreach (get_class_vars(self::class) as $key => $value) {
62      if (!isset(self::$$key)) {
63        throw new Exception("Application config parameter is missing: $key!");
64      }
65    }
66  }
67
68  public static function readFromEnvironment(): void {
69    $config = [];
70
71    $config['database']['name'] = self::stringEnv('MYSQL_DATABASE');
72    $config['database']['host'] = self::stringEnv('MYSQL_HOST');
73    $config['database']['port'] = self::stringEnv('MYSQL_PORT');
74    $config['database']['user'] = self::stringEnv('MYSQL_USER');
75    $config['database']['password'] = self::stringEnv('MYSQL_PASSWORD');
76
77    $config['password']['salt'] = self::stringEnv('PASSWORD_SALT');
78
79    $config['system']['tlsEnabled'] = self::boolEnv('TLS_ENABLED');
80    $config['system']['hostname'] = preg_replace('#^[Ww][Ww][Ww]\.#', '', self::stringEnv('HOSTNAME'));
81
82    if (self::boolEnv('BROADCAST_SERVICE_ENABLED')) {
83      $port = $config['system']['tlsEnabled']
84        ? (self::stringEnv('TLS_PORT', '443'))
85        : (self::stringEnv('PORT', '80'));
86      $config['broadcastingService']['external'] = self::stringEnv('HOSTNAME') . ":$port/bs/public/";
87      $config['broadcastingService']['internal']= 'testcenter-broadcasting-service:3000';
88    }
89
90    if (self::boolEnv('FILE_SERVICE_ENABLED')) {
91      $config['fileService']['external'] = self::stringEnv('HOSTNAME') . ":$port/fs/";
92      $config['fileService']['internal'] = 'testcenter-file-service';
93      $config['cacheService']['host'] = 'testcenter-cache-service';
94    }
95
96    $config['cacheService']['includeFiles'] = self::boolEnv('CACHE_SERVICE_INCLUDE_FILES');
97    $config['cacheService']['ram'] = (int) self::stringEnv('CACHE_SERVICE_RAM');
98
99    $overrideConfig = getenv('OVERRIDE_CONFIG');
100    if ($overrideConfig) {
101      $overrideConfig = parse_ini_string($overrideConfig, true, INI_SCANNER_TYPED);
102      $config = array_replace_recursive($config, $overrideConfig);
103    }
104
105    self::apply($config);
106  }
107
108  public static function readVersion(): void {
109    $packageJsonStr = file_get_contents(ROOT_DIR . '/package.json');
110    $packageJson = JSON::decode($packageJsonStr);
111    $v = "verona-player-api-versions";
112    self::$system_veronaMax = $packageJson->iqb->$v->max;
113    self::$system_veronaMin = $packageJson->iqb->$v->min;
114    self::$system_version =  $packageJson->version;
115  }
116
117  private static function boolEnv(string $name): bool {
118    return in_array(strtolower(getEnv($name)), ['on', 'true', 'yes', 1]);
119  }
120
121  private static function stringEnv(string $name, ?string $default = null): string {
122    $value = getEnv($name);
123    if (!$value) {
124      if ($default == null) {
125        throw new Exception("Environment-variable missing: `$name`.");
126      }
127      return $default;
128    }
129    return $value;
130  }
131
132  public static function write(): void {
133    $config = [];
134    foreach (get_class_vars(self::class) as $propertyName => $value) {
135      list($sectionName, $key) = explode('_', $propertyName, 2);
136      $config[$sectionName][$key] = self::$$propertyName;
137    }
138    $output = "";
139    foreach ($config as $sectionName => $section) {
140      $output .= "[$sectionName]\n";
141      foreach ($section as $key => $value) {
142        if (($key == 'version') and (getEnv('VERSION') !== self::$system_version)) {
143          continue;
144        }
145        $value = is_bool($value) ? ($value ? 'yes' : 'no') : $value;
146        $output .= "$key=$value\n";
147      }
148    }
149    file_put_contents(ROOT_DIR . '/backend/config/config.ini', $output);
150  }
151
152  public static function dumpDbConfig(): string {
153    return print_r([
154      "host" => self::$database_host,
155      "user" => self::$database_user,
156      "port" => self::$database_port,
157      "pass" => substr(self::$database_password, 0, 2) . '***',
158      "name" => self::$database_name
159    ], true);
160  }
161}