Prepare secure config and reliable workout sync

This commit is contained in:
Hamza-Ayed
2026-10-04 00:33:44 +03:00
parent 05f1c9ec6b
commit e7f3c777d1
17 changed files with 553 additions and 119 deletions
+84
View File
@@ -0,0 +1,84 @@
<?php
/**
* Reads server-side application configuration without bundling secrets.
* The deploy layout places a .env symlink beside backend/, outside public/.
*/
final class AppConfig
{
private static $loaded = false;
public static function loadEnvironment()
{
if (self::$loaded) {
return;
}
$path = getenv('APP_ENV_FILE');
if ($path === false || $path === '') {
$path = dirname(__DIR__) . DIRECTORY_SEPARATOR . '.env';
}
if (!is_file($path) || !is_readable($path)) {
throw new RuntimeException('Server environment file is missing or unreadable');
}
$lines = file($path, FILE_IGNORE_NEW_LINES);
if ($lines === false) {
throw new RuntimeException('Unable to read server environment file');
}
foreach ($lines as $lineNumber => $line) {
$line = trim($line);
if ($line === '' || $line[0] === '#') {
continue;
}
if (!preg_match('/^([A-Z][A-Z0-9_]*)\s*=\s*(.*)$/', $line, $matches)) {
throw new RuntimeException('Invalid environment entry on line ' . ($lineNumber + 1));
}
$name = $matches[1];
$value = trim($matches[2]);
if (strlen($value) >= 2) {
$first = $value[0];
$last = substr($value, -1);
if (($first === '"' && $last === '"') || ($first === "'" && $last === "'")) {
$value = substr($value, 1, -1);
}
}
// Explicit process environment values override the file.
if (getenv($name) === false) {
putenv($name . '=' . $value);
$_ENV[$name] = $value;
}
}
self::$loaded = true;
}
public static function required($name)
{
self::loadEnvironment();
$value = getenv($name);
if ($value === false || $value === '') {
throw new RuntimeException('Required server setting is missing: ' . $name);
}
return $value;
}
public static function integer($name, $default)
{
self::loadEnvironment();
$value = getenv($name);
if ($value === false || $value === '') {
return (int) $default;
}
$parsed = filter_var($value, FILTER_VALIDATE_INT);
if ($parsed === false) {
throw new RuntimeException('Server setting must be an integer: ' . $name);
}
return $parsed;
}
}