'AzuraCast', self::LOG_LEVEL => LogLevel::NOTICE, self::IS_DOCKER => true, self::IS_CLI => ('cli' === PHP_SAPI), self::ASSET_URL => '/static', self::AUTO_ASSIGN_PORT_MIN => 8000, self::AUTO_ASSIGN_PORT_MAX => 8499, self::ENABLE_REDIS => true, self::SYNC_SHORT_EXECUTION_TIME => 600, self::SYNC_LONG_EXECUTION_TIME => 1800, self::NOW_PLAYING_DELAY_TIME => 0, self::PROFILING_EXTENSION_ENABLED => 0, self::PROFILING_EXTENSION_ALWAYS_ON => 0, self::PROFILING_EXTENSION_HTTP_KEY => 'dev', self::ENABLE_WEB_UPDATER => false, ]; public function __construct(array $elements = []) { $this->data = array_merge($this->defaults, $elements); } /** * @return mixed[] */ public function toArray(): array { return $this->data; } public function getAppEnvironmentEnum(): ApplicationEnvironment { return ApplicationEnvironment::tryFrom($this->data[self::APP_ENV] ?? '') ?? ApplicationEnvironment::default(); } public function isProduction(): bool { return ApplicationEnvironment::Production === $this->getAppEnvironmentEnum(); } public function isTesting(): bool { return ApplicationEnvironment::Testing === $this->getAppEnvironmentEnum(); } public function isDevelopment(): bool { return ApplicationEnvironment::Development === $this->getAppEnvironmentEnum(); } public function showDetailedErrors(): bool { if (self::envToBool($this->data[self::SHOW_DETAILED_ERRORS] ?? false)) { return true; } return !$this->isProduction(); } public function isDocker(): bool { return self::envToBool($this->data[self::IS_DOCKER] ?? true); } public function isCli(): bool { return $this->data[self::IS_CLI] ?? ('cli' === PHP_SAPI); } public function getAppName(): string { return $this->data[self::APP_NAME] ?? 'Application'; } public function getAssetUrl(): ?string { return $this->data[self::ASSET_URL] ?? ''; } /** * @return string The base directory of the application, i.e. `/var/app/www` for Docker installations. */ public function getBaseDirectory(): string { return $this->data[self::BASE_DIR]; } /** * @return string The directory where temporary files are stored by the application, i.e. `/var/app/www_tmp` */ public function getTempDirectory(): string { return $this->data[self::TEMP_DIR]; } /** * @return string The directory where configuration files are stored by default. */ public function getConfigDirectory(): string { return $this->data[self::CONFIG_DIR]; } /** * @return string The directory where template/view files are stored. */ public function getViewsDirectory(): string { return $this->data[self::VIEWS_DIR]; } /** * @return string The directory where user system-level uploads are stored. */ public function getUploadsDirectory(): string { return $this->data[self::UPLOADS_DIR]; } /** * @return string The parent directory the application is within, i.e. `/var/azuracast`. */ public function getParentDirectory(): string { return dirname($this->getBaseDirectory()); } /** * @return string The default directory where station data is stored. */ public function getStationDirectory(): string { return $this->getParentDirectory() . '/stations'; } public function getInternalUri(): UriInterface { return new Uri('http://127.0.0.1:6010'); } public function getLocalUri(): UriInterface { return new Uri('http://127.0.0.1'); } public function getLang(): ?string { return $this->data[self::LANG]; } public function getReleaseChannelEnum(): ReleaseChannel { return ReleaseChannel::tryFrom($this->data[self::RELEASE_CHANNEL] ?? '') ?? ReleaseChannel::default(); } public function getSftpPort(): int { return (int)($this->data[self::SFTP_PORT] ?? 2022); } public function getAutoAssignPortMin(): int { return (int)($this->data[self::AUTO_ASSIGN_PORT_MIN] ?? Configuration::DEFAULT_PORT_MIN); } public function getAutoAssignPortMax(): int { return (int)($this->data[self::AUTO_ASSIGN_PORT_MAX] ?? Configuration::DEFAULT_PORT_MAX); } public function getSyncShortExecutionTime(): int { return (int)( $this->data[self::SYNC_SHORT_EXECUTION_TIME] ?? $this->defaults[self::SYNC_SHORT_EXECUTION_TIME] ); } public function getSyncLongExecutionTime(): int { return (int)( $this->data[self::SYNC_LONG_EXECUTION_TIME] ?? $this->defaults[self::SYNC_LONG_EXECUTION_TIME] ); } public function getNowPlayingDelayTime(): int { return (int)( $this->data[self::NOW_PLAYING_DELAY_TIME] ?? $this->defaults[self::NOW_PLAYING_DELAY_TIME] ); } /** * @phpstan-return LogLevel::* */ public function getLogLevel(): string { if (!empty($this->data[self::LOG_LEVEL])) { $loggingLevel = strtolower($this->data[self::LOG_LEVEL]); $allowedLogLevels = [ LogLevel::DEBUG, LogLevel::INFO, LogLevel::NOTICE, LogLevel::WARNING, LogLevel::ERROR, LogLevel::CRITICAL, LogLevel::ALERT, LogLevel::EMERGENCY, ]; if (in_array($loggingLevel, $allowedLogLevels, true)) { return $loggingLevel; } } return $this->isProduction() ? LogLevel::NOTICE : LogLevel::INFO; } /** * @return mixed[] */ public function getDatabaseSettings(): array { $dbSettings = [ 'host' => $this->data[self::DB_HOST] ?? 'localhost', 'port' => (int)($this->data[self::DB_PORT] ?? 3306), 'dbname' => $this->data[self::DB_NAME] ?? 'azuracast', 'user' => $this->data[self::DB_USER] ?? 'azuracast', 'password' => $this->data[self::DB_PASSWORD] ?? 'azur4c457', ]; if ('localhost' === $dbSettings['host'] && $this->isDocker()) { $dbSettings['unix_socket'] = '/run/mysqld/mysqld.sock'; } return $dbSettings; } public function useLocalDatabase(): bool { return 'localhost' === ($this->data[self::DB_HOST] ?? 'localhost'); } public function enableRedis(): bool { return self::envToBool($this->data[self::ENABLE_REDIS] ?? true); } /** * @return mixed[] */ public function getRedisSettings(): array { $redisSettings = [ 'host' => $this->data[self::REDIS_HOST] ?? 'localhost', 'port' => (int)($this->data[self::REDIS_PORT] ?? 6379), 'db' => (int)($this->data[self::REDIS_DB] ?? 1), ]; if ('localhost' === $redisSettings['host'] && $this->isDocker()) { $redisSettings['socket'] = '/run/redis/redis.sock'; } return $redisSettings; } public function useLocalRedis(): bool { return $this->enableRedis() && 'localhost' === ($this->data[self::REDIS_HOST] ?? 'localhost'); } public function isProfilingExtensionEnabled(): bool { return self::envToBool($this->data[self::PROFILING_EXTENSION_ENABLED] ?? false); } public function isProfilingExtensionAlwaysOn(): bool { return self::envToBool($this->data[self::PROFILING_EXTENSION_ALWAYS_ON] ?? false); } public function getProfilingExtensionHttpKey(): string { return $this->data[self::PROFILING_EXTENSION_HTTP_KEY] ?? 'dev'; } public function enableWebUpdater(): bool { return $this->isDocker() && self::envToBool($this->data[self::ENABLE_WEB_UPDATER] ?? false); } public static function getDefaultsForEnvironment(Environment $existingEnv): self { return new self([ self::IS_CLI => $existingEnv->isCli(), self::IS_DOCKER => $existingEnv->isDocker(), ]); } public static function envToBool(mixed $value): bool { if (is_bool($value)) { return $value; } if (is_int($value)) { return 0 !== $value; } if (null === $value) { return false; } $value = (string)$value; return str_starts_with(strtolower($value), 'y') || 'true' === strtolower($value) || '1' === $value; } public static function getInstance(): Environment { return self::$instance; } public static function setInstance(Environment $instance): void { self::$instance = $instance; } }