From 012f4fcec5dab85b7d7ba917891d25898ec8cb7a Mon Sep 17 00:00:00 2001 From: Holger Veltrup Date: Fri, 24 May 2024 09:42:59 +0200 Subject: [PATCH] feat: EnvVarLoader to determine resource-root --- config/services.yaml | 4 + src/Env/EnvVarLoader.php | 86 +++++++++++++++++ test/Env/EnvVarLoaderTest.php | 94 +++++++++++++++++++ .../documentRootLayout/WEB-IES/context.php | 5 + .../hostDir/resources/context.php | 5 + 5 files changed, 194 insertions(+) create mode 100644 src/Env/EnvVarLoader.php create mode 100644 test/Env/EnvVarLoaderTest.php create mode 100644 test/resources/Env/EnvVarLoader/documentRootLayout/WEB-IES/context.php create mode 100644 test/resources/Env/EnvVarLoader/hostDir/resources/context.php diff --git a/config/services.yaml b/config/services.yaml index f7c2114..06bf457 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -3,6 +3,10 @@ parameters: services: + Atoolo\Resource\Env\EnvVarLoader: + tags: + - { name: 'container.env_var_loader', priority: 10 } + atoolo_resource.resource_channel_factory: class: Atoolo\Resource\SiteKitResourceChannelFactory arguments: diff --git a/src/Env/EnvVarLoader.php b/src/Env/EnvVarLoader.php new file mode 100644 index 0000000..0f9dbe4 --- /dev/null +++ b/src/Env/EnvVarLoader.php @@ -0,0 +1,86 @@ +baseDir = $baseDir ?? (getcwd() ?: ''); + } + + /** + * @return array{ + * RESOURCE_ROOT?: non-empty-string, + * } + */ + public function loadEnvVars(): array + { + $env = []; + + $resourceRoot = $_SERVER['RESOURCE_ROOT'] ?? ''; + if (!is_string($resourceRoot) || empty($resourceRoot)) { + $resourceRoot = $this->determineResourceRootForCliCall(); + if (!empty($resourceRoot)) { + $env['RESOURCE_ROOT'] = $resourceRoot; + // other EnvVarLoader needs this value + $_SERVER['RESOURCE_ROOT'] = $resourceRoot; + } + } + return $env; + } + + /** + * If the call was made via a CLI command, an attempt is made to + * the resource root via the path of the `bin/console` script. + * to determine the resource root. + * This is successful if the script is called via the absolute + * path to the `app` folder below the host directory. + * + * E.G. + * /var/www/example.com/www/app/bin/console + * + */ + private function determineResourceRootForCliCall(): ?string + { + /** @var string[] $directories */ + $directories = [ + $this->baseDir + ]; + + $filename = $_SERVER['SCRIPT_FILENAME'] ?? null; + if (is_string($filename)) { + $binDir = dirname($filename); + $appDir = dirname($binDir); + $hostDir = dirname($appDir); + $directories[] = $hostDir; + } + + foreach ($directories as $dir) { + $realpath = realpath($dir); + if ($realpath === false) { + continue; + } + + if (is_file($realpath . '/resources/context.php')) { + return $realpath . '/resources'; + } + if (is_file($realpath . '/context.php')) { + return $realpath; + } + if (is_file($realpath . '/WEB-IES/context.php')) { + return $realpath; + } + } + + return null; + } +} diff --git a/test/Env/EnvVarLoaderTest.php b/test/Env/EnvVarLoaderTest.php new file mode 100644 index 0000000..5db2158 --- /dev/null +++ b/test/Env/EnvVarLoaderTest.php @@ -0,0 +1,94 @@ +scriptFileNameBackup = $_SERVER['SCRIPT_FILENAME'] ?? null; + } + public function tearDown(): void + { + unset($_SERVER['RESOURCE_ROOT']); + $_SERVER['SCRIPT_FILENAME'] = $this->scriptFileNameBackup; + } + + public function testLoadVarsWithExistsResourceRoot(): void + { + $_SERVER['RESOURCE_ROOT'] = 'test'; + $loader = new EnvVarLoader(); + $env = $loader->loadEnvVars(); + $this->assertFalse( + isset($env['RESOURCE_ROOT']), + 'RESOURCE_ROOT should no set' + ); + } + + public function testDetermineResourceWithInvalidDir(): void + { + $loader = new EnvVarLoader('/invalid-dir'); + $env = $loader->loadEnvVars(); + $this->assertFalse( + isset($env['RESOURCE_ROOT']), + 'RESOURCE_ROOT should no set' + ); + } + + public function testDetermineResourceViaScriptFilename(): void + { + $_SERVER['SCRIPT_FILENAME'] = + $this->baseDir . '/hostDir/app/bin/console'; + $loader = new EnvVarLoader('/tmp'); + $env = $loader->loadEnvVars(); + $this->assertEquals( + $this->baseDir . '/hostDir/resources', + isset($env['RESOURCE_ROOT']), + 'unexpected RESOURCE_ROOT' + ); + } + + public function testDetermineResourceRootInHostDir(): void + { + $loader = new EnvVarLoader($this->baseDir . '/hostDir'); + $env = $loader->loadEnvVars(); + $this->assertEquals( + $this->baseDir . '/hostDir/resources', + isset($env['RESOURCE_ROOT']), + 'unexpected RESOURCE_ROOT' + ); + } + + public function testDetermineResourceRootInResourceDir(): void + { + $loader = new EnvVarLoader($this->baseDir . '/hostDir/resources'); + $env = $loader->loadEnvVars(); + $this->assertEquals( + $this->baseDir . '/hostDir/resources', + isset($env['RESOURCE_ROOT']), + 'unexpected RESOURCE_ROOT' + ); + } + + public function testDetermineResourceRootWithDocumentRootLayout(): void + { + $loader = new EnvVarLoader($this->baseDir . '/documentRootLayout'); + $env = $loader->loadEnvVars(); + $this->assertEquals( + $this->baseDir . '/documentRootLayout', + isset($env['RESOURCE_ROOT']), + 'unexpected RESOURCE_ROOT' + ); + } +} diff --git a/test/resources/Env/EnvVarLoader/documentRootLayout/WEB-IES/context.php b/test/resources/Env/EnvVarLoader/documentRootLayout/WEB-IES/context.php new file mode 100644 index 0000000..0dae23d --- /dev/null +++ b/test/resources/Env/EnvVarLoader/documentRootLayout/WEB-IES/context.php @@ -0,0 +1,5 @@ +