From e1203ecd6f94f4d234e2ca9a8d2351a89a22456b Mon Sep 17 00:00:00 2001 From: Buster Neece Date: Thu, 2 Nov 2023 08:22:32 -0500 Subject: [PATCH] Make some env vars immutable. --- bin/console | 6 +- bin/installer | 6 +- src/AppFactory.php | 42 +--------- .../Command/Locale/GenerateCommand.php | 6 +- src/Environment.php | 79 +++++++++---------- src/Tests/Module.php | 3 - src/View.php | 5 +- util/phpstan.php | 5 +- web/index.php | 8 +- 9 files changed, 53 insertions(+), 107 deletions(-) diff --git a/bin/console b/bin/console index 2c08822c2..db901959e 100755 --- a/bin/console +++ b/bin/console @@ -8,9 +8,5 @@ ini_set('display_errors', '1'); require dirname(__DIR__) . '/vendor/autoload.php'; -$cli = App\AppFactory::createCli( - [ - App\Environment::BASE_DIR => dirname(__DIR__), - ] -); +$cli = App\AppFactory::createCli(); $cli->run(); diff --git a/bin/installer b/bin/installer index 74d33c3e3..9664a5778 100755 --- a/bin/installer +++ b/bin/installer @@ -8,11 +8,7 @@ ini_set('display_errors', '1'); $autoloader = require dirname(__DIR__) . '/vendor/autoload.php'; -$environment = App\AppFactory::buildEnvironment( - [ - App\Environment::BASE_DIR => dirname(__DIR__), - ] -); +$environment = App\AppFactory::buildEnvironment(); $console = new Symfony\Component\Console\Application( 'AzuraCast installer', diff --git a/src/AppFactory.php b/src/AppFactory.php index 4d402d2ec..030f3ffbd 100644 --- a/src/AppFactory.php +++ b/src/AppFactory.php @@ -8,7 +8,6 @@ use App\Console\Application; use App\Enums\SupportedLocales; use App\Http\Factory\ResponseFactory; use App\Http\Factory\ServerRequestFactory; -use App\Utilities\File; use App\Utilities\Logger as AppLogger; use DI; use Monolog\ErrorHandler; @@ -95,11 +94,7 @@ final class AppFactory $containerBuilder->addDefinitions($diDefinitions); - // Check for services.php file and include it if one exists. - $configDir = $environment->getConfigDirectory(); - if (file_exists($configDir . '/services.php')) { - $containerBuilder->addDefinitions($configDir . '/services.php'); - } + $containerBuilder->addDefinitions(dirname(__DIR__) . '/config/services.php'); $di = $containerBuilder->build(); @@ -118,42 +113,7 @@ final class AppFactory */ public static function buildEnvironment(array $environment = []): Environment { - if (!isset($environment[Environment::BASE_DIR])) { - throw new Exception\BootstrapException('No base directory specified!'); - } - - $baseDir = $environment[Environment::BASE_DIR]; - $parentBaseDir = dirname($baseDir); - - $environment[Environment::IS_DOCKER] = file_exists($parentBaseDir . '/.docker'); - - $environment[Environment::TEMP_DIR] ??= $parentBaseDir . '/www_tmp'; - $environment[Environment::CONFIG_DIR] ??= $baseDir . '/config'; - $environment[Environment::VIEWS_DIR] ??= $baseDir . '/templates'; - $environment[Environment::UPLOADS_DIR] ??= File::getFirstExistingDirectory([ - $parentBaseDir . '/storage/uploads', - $parentBaseDir . '/uploads', - ]); - $_ENV = getenv(); - - if (!$environment[Environment::IS_DOCKER]) { - $envPaths = [ - $parentBaseDir . '/env.ini', - $baseDir . '/env.ini', - ]; - - foreach ($envPaths as $envPath) { - if (file_exists($envPath)) { - $envIni = parse_ini_file($envPath); - if (false !== $envIni) { - $_ENV = array_merge($_ENV, $envIni); - break; - } - } - } - } - $environment = array_merge(array_filter($_ENV), $environment); return new Environment($environment); diff --git a/src/Console/Command/Locale/GenerateCommand.php b/src/Console/Command/Locale/GenerateCommand.php index 429786230..cfa62092d 100644 --- a/src/Console/Command/Locale/GenerateCommand.php +++ b/src/Console/Command/Locale/GenerateCommand.php @@ -57,9 +57,9 @@ final class GenerateCommand extends CommandAbstract // Find all PHP/PHTML files in the application's code. $translatableFolders = [ - $this->environment->getBaseDirectory() . '/src', - $this->environment->getBaseDirectory() . '/config', - $this->environment->getViewsDirectory(), + dirname(__DIR__, 4) . '/src', + dirname(__DIR__, 4) . '/config', + dirname(__DIR__, 4) . '/templates', ]; $phpScanner = new PhpScanner($translations); diff --git a/src/Environment.php b/src/Environment.php index c1db83a07..02a5e0462 100644 --- a/src/Environment.php +++ b/src/Environment.php @@ -7,6 +7,7 @@ namespace App; use App\Enums\ApplicationEnvironment; use App\Enums\ReleaseChannel; use App\Radio\Configuration; +use App\Utilities\File; use GuzzleHttp\Psr7\Uri; use Psr\Http\Message\UriInterface; use Psr\Log\LogLevel; @@ -15,16 +16,19 @@ final class Environment { private static Environment $instance; - private array $data; + // Cached immutable values that are frequently used. + private readonly string $baseDir; + private readonly string $parentDir; + private readonly bool $isDocker; + private readonly ApplicationEnvironment $appEnv; + + private readonly array $data; // Core settings values public const APP_NAME = 'APP_NAME'; public const APP_ENV = 'APPLICATION_ENV'; - public const BASE_DIR = 'BASE_DIR'; public const TEMP_DIR = 'TEMP_DIR'; - public const CONFIG_DIR = 'CONFIG_DIR'; - public const VIEWS_DIR = 'VIEWS_DIR'; public const UPLOADS_DIR = 'UPLOADS_DIR'; public const IS_DOCKER = 'IS_DOCKER'; @@ -96,7 +100,13 @@ final class Environment public function __construct(array $elements = []) { + $this->baseDir = dirname(__DIR__); + $this->parentDir = dirname($this->baseDir); + $this->isDocker = file_exists($this->parentDir . '/.docker'); + $this->data = array_merge($this->defaults, $elements); + $this->appEnv = ApplicationEnvironment::tryFrom($this->data[self::APP_ENV] ?? '') + ?? ApplicationEnvironment::default(); } /** @@ -109,8 +119,7 @@ final class Environment public function getAppEnvironmentEnum(): ApplicationEnvironment { - return ApplicationEnvironment::tryFrom($this->data[self::APP_ENV] ?? '') - ?? ApplicationEnvironment::default(); + return $this->appEnv; } public function isProduction(): bool @@ -139,7 +148,7 @@ final class Environment public function isDocker(): bool { - return self::envToBool($this->data[self::IS_DOCKER] ?? true); + return $this->isDocker; } public function isCli(): bool @@ -162,39 +171,7 @@ final class Environment */ 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 $this->baseDir; } /** @@ -202,7 +179,27 @@ final class Environment */ public function getParentDirectory(): string { - return dirname($this->getBaseDirectory()); + return $this->parentDir; + } + + /** + * @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] + ?? $this->getParentDirectory() . '/www_tmp'; + } + + /** + * @return string The directory where user system-level uploads are stored. + */ + public function getUploadsDirectory(): string + { + return $this->data[self::UPLOADS_DIR] ?? File::getFirstExistingDirectory([ + $this->getParentDirectory() . '/storage/uploads', + $this->getParentDirectory() . '/uploads', + ]); } /** diff --git a/src/Tests/Module.php b/src/Tests/Module.php index 45f2816ca..7c6ad4c58 100644 --- a/src/Tests/Module.php +++ b/src/Tests/Module.php @@ -13,7 +13,6 @@ use App\AppFactory; use App\Doctrine\ReloadableEntityManagerInterface; use App\Enums\ApplicationEnvironment; use App\Environment; -use Codeception\Configuration; use Codeception\Lib\Framework; use Codeception\Lib\Interfaces\DoctrineProvider; use Codeception\Lib\ModuleContainer; @@ -39,12 +38,10 @@ class Module extends Framework implements DoctrineProvider $this->requiredFields = ['container']; } - public function _initialize(): void { $this->app = AppFactory::createApp( [ - Environment::BASE_DIR => Configuration::projectDir(), Environment::APP_ENV => ApplicationEnvironment::Testing->value, ] ); diff --git a/src/View.php b/src/View.php index d743253d1..acf59ef66 100644 --- a/src/View.php +++ b/src/View.php @@ -38,7 +38,10 @@ final class View extends Engine Version $version, RouterInterface $router ) { - parent::__construct($environment->getViewsDirectory(), 'phtml'); + parent::__construct( + dirname(__DIR__) . '/templates', + 'phtml' + ); $this->sections = new GlobalSections(); $this->globalProps = new ArrayCollection(); diff --git a/util/phpstan.php b/util/phpstan.php index c36eee7d2..db548c3ce 100644 --- a/util/phpstan.php +++ b/util/phpstan.php @@ -12,8 +12,11 @@ const AZURACAST_VERSION = App\Version::FALLBACK_VERSION; const AZURACAST_API_URL = 'https://localhost/api'; const AZURACAST_API_NAME = 'Testing API'; +$tempDir = sys_get_temp_dir(); + App\AppFactory::createCli( [ - App\Environment::BASE_DIR => dirname(__DIR__), + App\Environment::TEMP_DIR => $tempDir, + App\Environment::UPLOADS_DIR => $tempDir, ] ); diff --git a/web/index.php b/web/index.php index 5abfa133a..80fdd35ef 100755 --- a/web/index.php +++ b/web/index.php @@ -3,17 +3,11 @@ declare(strict_types=1); use App\AppFactory; -use App\Environment; error_reporting(E_ALL & ~E_NOTICE & ~E_STRICT); ini_set('display_errors', '1'); require dirname(__DIR__) . '/vendor/autoload.php'; -$app = AppFactory::createApp( - [ - Environment::BASE_DIR => dirname(__DIR__), - ] -); - +$app = AppFactory::createApp(); $app->run();