rtrim((string) (getenv('REDMINE_URL') ?: ($env['REDMINE_URL'] ?? 'http://192.168.50.170')), '/'), 'redmine_api_key' => $apiKey, 'mcp_server_token' => self::optionalString(getenv('MCP_SERVER_TOKEN') ?: ($env['MCP_SERVER_TOKEN'] ?? null)), ]; } /** * @return array */ private static function loadFile(string $path): array { if (!is_file($path)) { return []; } $values = []; foreach (file($path, FILE_IGNORE_NEW_LINES) ?: [] as $line) { $line = trim($line); if ($line === '' || str_starts_with($line, '#') || !str_contains($line, '=')) { continue; } [$key, $value] = explode('=', $line, 2); $values[trim($key)] = trim(trim($value), "\"'"); } return $values; } private static function optionalString(mixed $value): ?string { if (!is_string($value) || trim($value) === '') { return null; } return $value; } }