iptv-stream-web/includes/Config.php
Vincent 41cd7a4fd8 Add comprehensive unit tests for Security, UserModel, and Validation utilities
- Implemented SecurityTest to validate token generation, CSRF protection, input sanitization, and rate limiting.
- Created UserModelTest to ensure correct database operations for user management, including creation, updating, banning, and fetching active users.
- Developed ValidationTest to verify input validation and sanitization for user IDs, nicknames, messages, and API requests.
- Introduced Security and Validation utility classes with methods for secure token generation, input sanitization, and comprehensive validation rules.
2025-09-30 21:22:28 -04:00

178 lines
4.6 KiB
PHP

<?php
/**
* Configuration Management Class
* Loads and manages application configuration from .env files
*/
class Config
{
private static $config = [];
private static $loaded = false;
/**
* Load configuration from environment and .env files
*/
public static function load()
{
if (self::$loaded) {
return self::$config;
}
// Load environment variables
self::loadEnvironment();
// Load .env file if it exists
self::loadDotEnv();
self::$loaded = true;
return self::$config;
}
/**
* Get a configuration value
*/
public static function get($key, $default = null)
{
$config = self::load();
// Support dot notation (e.g., 'database.host')
$keys = explode('.', $key);
$value = $config;
foreach ($keys as $k) {
if (!isset($value[$k])) {
return $default;
}
$value = $value[$k];
}
return $value;
}
/**
* Set a configuration value (runtime only)
*/
public static function set($key, $value)
{
$keys = explode('.', $key);
$config = &self::$config;
foreach ($keys as $i => $k) {
if ($i === count($keys) - 1) {
$config[$k] = $value;
} else {
if (!isset($config[$k]) || !is_array($config[$k])) {
$config[$k] = [];
}
$config = &$config[$k];
}
}
}
/**
* Load system environment variables
*/
private static function loadEnvironment()
{
// System environment variables get precedence
foreach ($_ENV as $key => $value) {
self::setFromEnv($key, $value);
}
foreach ($_SERVER as $key => $value) {
if (strpos($key, 'APP_') === 0 || strpos($key, 'DB_') === 0 ||
strpos($key, 'STREAM_') === 0 || strpos($key, 'ADMIN_') === 0) {
self::setFromEnv($key, $value);
}
}
}
/**
* Load .env file
*/
private static function loadDotEnv()
{
$envFile = __DIR__ . '/../.env';
if (!file_exists($envFile)) {
error_log("Warning: .env file not found. Using default configuration.");
return;
}
$lines = file($envFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
foreach ($lines as $line) {
$line = trim($line);
// Skip comments
if (strpos($line, '#') === 0) {
continue;
}
// Parse key=value pairs
if (strpos($line, '=') !== false) {
list($key, $value) = explode('=', $line, 2);
$key = trim($key);
$value = trim($value);
// Remove quotes if present
if ((strpos($value, '"') === 0 && strrpos($value, '"') === strlen($value) - 1) ||
(strpos($value, "'") === 0 && strrpos($value, "'") === strlen($value) - 1)) {
$value = substr($value, 1, -1);
}
self::setFromEnv($key, $value);
}
}
}
/**
* Set configuration value from environment variable
*/
private static function setFromEnv($key, $value)
{
// Convert environment naming to configuration naming
$configKey = strtolower(str_replace('_', '.', $key));
// Type coercion for boolean values
if (in_array($value, ['true', 'false'])) {
$value = $value === 'true';
}
// Type coercion for numeric values
if (is_numeric($value) && !is_string($value)) {
$value = strpos($value, '.') !== false ? (float)$value : (int)$value;
}
// Handle arrays (comma-separated)
if (strpos($value, ',') !== false) {
$value = array_map('trim', explode(',', $value));
}
self::set($configKey, $value);
}
/**
* Get all configuration as a flattened array
*/
public static function all()
{
return self::load();
}
/**
* Check if we are in a specific environment
*/
public static function isEnvironment($env)
{
return self::get('app.env') === $env;
}
/**
* Check if debug mode is enabled
*/
public static function isDebug()
{
return self::get('app.debug', false);
}
}