-
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #654 from hydephp/refactor-bootstrappers-and-impro…
…ve-yaml-environment-configuration-loading Refactor bootstrappers and improve Yaml environment configuration loading
- Loading branch information
Showing
8 changed files
with
655 additions
and
452 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Hyde\Foundation\Internal; | ||
|
||
use Illuminate\Support\Env; | ||
use Hyde\Foundation\Application; | ||
|
||
use function filled; | ||
|
||
/** | ||
* @internal Inject environment variables parsed from the YAML configuration file. | ||
*/ | ||
class LoadYamlEnvironmentVariables | ||
{ | ||
protected YamlConfigurationRepository $yaml; | ||
|
||
public function bootstrap(Application $app): void | ||
{ | ||
$this->yaml = $app->make(YamlConfigurationRepository::class); | ||
|
||
if ($this->yaml->hasYamlConfigFile()) { | ||
$this->injectEnvironmentVariables(); | ||
} | ||
} | ||
|
||
protected function injectEnvironmentVariables(): void | ||
{ | ||
if ($this->canInjectSiteNameEnvironmentVariable()) { | ||
$this->injectSiteNameEnvironmentVariable(); | ||
} | ||
} | ||
|
||
protected function canInjectSiteNameEnvironmentVariable(): bool | ||
{ | ||
return $this->yamlHasSiteNameSet() && ! $this->alreadyHasEnvironmentVariable(); | ||
} | ||
|
||
protected function alreadyHasEnvironmentVariable(): bool | ||
{ | ||
return filled(Env::get('SITE_NAME')); | ||
} | ||
|
||
protected function injectSiteNameEnvironmentVariable(): void | ||
{ | ||
$name = $this->getSiteNameFromYaml(); | ||
|
||
Env::getRepository()->set('SITE_NAME', $name); | ||
} | ||
|
||
protected function yamlHasSiteNameSet(): bool | ||
{ | ||
return isset($this->yaml->getData()['hyde']['name']); | ||
} | ||
|
||
protected function getSiteNameFromYaml(): string | ||
{ | ||
return $this->yaml->getData()['hyde']['name']; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Hyde\Foundation\Internal; | ||
|
||
use Hyde\Hyde; | ||
use Illuminate\Support\Arr; | ||
use Symfony\Component\Yaml\Yaml; | ||
|
||
use function file_exists; | ||
use function file_get_contents; | ||
use function array_key_first; | ||
|
||
/** | ||
* @internal Contains shared logic for loading and parsing the YAML configuration file. | ||
* | ||
* @see LoadYamlEnvironmentVariables Which uses this repository to inject environment variables from the YAML configuration file. | ||
* @see LoadYamlConfiguration Which uses this repository to merge the YAML configuration data with the existing configuration. | ||
*/ | ||
class YamlConfigurationRepository | ||
{ | ||
protected false|string $file; | ||
protected array $data; | ||
|
||
public function __construct() | ||
{ | ||
$this->file = $this->getFilePath(); | ||
|
||
if ($this->hasYamlConfigFile()) { | ||
$data = $this->parseYamlFile(); | ||
|
||
if (! self::configurationContainsNamespaces($data)) { | ||
$data = ['hyde' => $data]; | ||
} | ||
|
||
$this->data = $data; | ||
} | ||
} | ||
|
||
/** @return array<string, array<string, null|scalar|array>> */ | ||
public function getData(): array | ||
{ | ||
return $this->data; | ||
} | ||
|
||
public function hasYamlConfigFile(): bool | ||
{ | ||
return $this->file !== false; | ||
} | ||
|
||
protected function parseYamlFile(): array | ||
{ | ||
return Arr::undot((array) Yaml::parse(file_get_contents($this->file))); | ||
} | ||
|
||
protected function getFilePath(): string|false | ||
{ | ||
return match (true) { | ||
file_exists(Hyde::path('hyde.yml')) => Hyde::path('hyde.yml'), | ||
file_exists(Hyde::path('hyde.yaml')) => Hyde::path('hyde.yaml'), | ||
default => false, | ||
}; | ||
} | ||
|
||
protected static function configurationContainsNamespaces(array $config): bool | ||
{ | ||
return array_key_first($config) === 'hyde'; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Hyde\Framework\Testing\Feature; | ||
|
||
use Hyde\Testing\TestCase; | ||
|
||
/** | ||
* High level test for the Yaml configuration feature. | ||
* | ||
* @see \Hyde\Framework\Testing\Feature\YamlConfigurationFeatureTest | ||
* | ||
* @covers \Hyde\Foundation\Internal\LoadYamlConfiguration | ||
* @covers \Hyde\Foundation\Internal\LoadYamlEnvironmentVariables | ||
* @covers \Hyde\Foundation\Internal\YamlConfigurationRepository | ||
*/ | ||
class HighLevelYamlConfigurationFeatureTest extends TestCase | ||
{ | ||
protected function setUp(): void | ||
{ | ||
$this->setUpConfigurationBeforeApplicationBoots(); | ||
|
||
parent::setUp(); | ||
} | ||
|
||
protected function tearDown(): void | ||
{ | ||
unlink('hyde.yml'); | ||
unlink('config/custom.php'); | ||
|
||
$this->clearEnvVars(); | ||
|
||
parent::tearDown(); | ||
} | ||
|
||
protected function setUpConfigurationBeforeApplicationBoots(): void | ||
{ | ||
file_put_contents('hyde.yml', <<<'YAML' | ||
hyde: | ||
name: Yaml Site Name | ||
docs: | ||
sidebar_order: | ||
# Reversed compared to the default order | ||
- getting-started | ||
- installation | ||
- readme | ||
custom: | ||
setting_one: Override | ||
setting_two: Added | ||
YAML); | ||
|
||
file_put_contents('config/custom.php', <<<'PHP' | ||
<?php | ||
return [ | ||
'setting_one' => 'Default', | ||
'setting_three' => 'Inherited' | ||
]; | ||
PHP); | ||
} | ||
|
||
public function testTestTheYamlConfigurationFeature() | ||
{ | ||
$config = config()->all(); | ||
|
||
$this->assertSame('Yaml Site Name', env('SITE_NAME')); | ||
$this->assertSame('Yaml Site Name', $_ENV['SITE_NAME']); | ||
$this->assertSame('Yaml Site Name', $_SERVER['SITE_NAME']); | ||
|
||
$this->assertSame('Yaml Site Name', $config['hyde']['name']); | ||
$this->assertSame('Yaml Site Name Docs', $config['docs']['sidebar']['header']); | ||
$this->assertSame(['getting-started', 'installation', 'readme'], $config['docs']['sidebar_order']); | ||
|
||
$this->assertSame('Override', $config['custom']['setting_one']); | ||
$this->assertSame('Added', $config['custom']['setting_two']); | ||
$this->assertSame('Inherited', $config['custom']['setting_three']); | ||
} | ||
|
||
protected function clearEnvVars(): void | ||
{ | ||
// Todo: Can we access loader? https://github.com/vlucas/phpdotenv/pull/107/files | ||
putenv('SITE_NAME'); | ||
unset($_ENV['SITE_NAME'], $_SERVER['SITE_NAME']); | ||
} | ||
} |
Oops, something went wrong.