Contractless-PHP-API/src/Config/Environment.php

101 lines
2.8 KiB
PHP

<?php
declare(strict_types=1);
namespace Contractless\Api\Config;
use RuntimeException;
final class Environment
{
/** @var array<string, string> */
private array $values;
private function __construct(array $values)
{
$this->values = $values;
}
public static function load(string $path): self
{
if (!is_file($path) || !is_readable($path)) {
throw new RuntimeException('The API environment file is not readable.');
}
$values = parse_ini_file($path, false, INI_SCANNER_RAW);
if ($values === false) {
throw new RuntimeException('The API environment file could not be parsed.');
}
$normalized = [];
foreach ($values as $name => $value) {
if (!is_string($value)) {
throw new RuntimeException("API setting $name must be a string.");
}
$normalized[$name] = trim($value);
}
return new self($normalized);
}
public function required(string $name): string
{
$value = $this->values[$name] ?? '';
if ($value === '') {
throw new RuntimeException("Required API setting $name is missing.");
}
return $value;
}
public function string(string $name, string $default): string
{
return $this->values[$name] ?? $default;
}
public function float(string $name, float $default): float
{
$value = $this->values[$name] ?? '';
if ($value === '') {
return $default;
}
if (!is_numeric($value) || (float) $value <= 0) {
throw new RuntimeException("API setting $name must be greater than zero.");
}
return (float) $value;
}
public function int(string $name, int $default, int $minimum, int $maximum): int
{
$value = $this->values[$name] ?? '';
if ($value === '') {
return $default;
}
if (filter_var($value, FILTER_VALIDATE_INT) === false) {
throw new RuntimeException("API setting $name must be an integer.");
}
$integer = (int) $value;
if ($integer < $minimum || $integer > $maximum) {
throw new RuntimeException(
"API setting $name must be between $minimum and $maximum.",
);
}
return $integer;
}
public function bool(string $name, bool $default): bool
{
$value = strtolower($this->values[$name] ?? '');
if ($value === '') {
return $default;
}
return match ($value) {
'1', 'true', 'yes', 'on' => true,
'0', 'false', 'no', 'off' => false,
default => throw new RuntimeException(
"API setting $name must be true or false.",
),
};
}
}