<?php
declare(strict_types=1);
namespace Machweis\Backend;
final readonly class Config
{
/** @param list<string> $corsAllowedOrigins */
public function __construct(
public string $appEnv,
public bool $appDebug,
public string $dbHost,
public int $dbPort,
public string $dbName,
public string $dbUser,
public string $dbPassword,
public array $corsAllowedOrigins,
public bool $healthRequireDatabase,
public string $accessTokenSecret = '',
public int $accessTokenTtlSeconds = 900,
public int $refreshTokenTtlSeconds = 2592000,
public string $reportAssetStoragePath = '',
public string $assetCleanupCronUser = '',
public string $assetCleanupCronPassword = '',
public string $smtpHost = '',
public int $smtpPort = 465,
public string $smtpUser = '',
public string $smtpPassword = '',
public string $mailFromAddress = '',
public string $mailFromName = 'MACHWEIS',
) {}
public static function loadEnv(string $file): void
{
if (!is_file($file)) return;
foreach (file($file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) ?: [] as $line) {
$line = trim($line);
if ($line === '' || str_starts_with($line, '#') || !str_contains($line, '=')) continue;
[$key, $value] = explode('=', $line, 2);
$key = trim($key);
if ($key !== '' && getenv($key) === false) putenv($key . '=' . trim($value));
}
}
public static function fromEnvironment(): self
{
$origins = array_values(array_filter(array_map('trim', explode(',', self::string('CORS_ALLOWED_ORIGINS', '')))));
return new self(
self::string('APP_ENV', 'production'), self::bool('APP_DEBUG', false), self::string('DB_HOST', '127.0.0.1'),
(int) self::string('DB_PORT', '3306'), self::string('DB_NAME', ''), self::string('DB_USER', ''), self::string('DB_PASSWORD', ''),
$origins, self::bool('HEALTH_REQUIRE_DATABASE', true), self::string('ACCESS_TOKEN_SECRET', ''),
(int) self::string('ACCESS_TOKEN_TTL_SECONDS', '900'), (int) self::string('REFRESH_TOKEN_TTL_SECONDS', '2592000'),
self::string('REPORT_ASSET_STORAGE_PATH', dirname(__DIR__) . '/storage/report-assets'),
self::string('ASSET_CLEANUP_CRON_USER', ''), self::string('ASSET_CLEANUP_CRON_PASSWORD', ''),
self::string('SMTP_HOST', ''), (int) self::string('SMTP_PORT', '465'), self::string('SMTP_USER', ''), self::string('SMTP_PASSWORD', ''), self::string('MAIL_FROM_ADDRESS', ''), self::string('MAIL_FROM_NAME', 'MACHWEIS'),
);
}
private static function string(string $key, string $default): string { $value = getenv($key); return $value === false ? $default : $value; }
private static function bool(string $key, bool $default): bool { return filter_var(self::string($key, $default ? 'true' : 'false'), FILTER_VALIDATE_BOOL); }
}
