Passed
Push — master ( c63ee8...afbe69 )
by Caen
03:29 queued 12s
created

LoadYamlConfiguration::mergeConfiguration()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 1
eloc 3
c 2
b 0
f 0
nc 1
nop 2
dl 0
loc 5
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Hyde\Foundation\Internal;
6
7
use Hyde\Hyde;
8
use Hyde\Facades\Config;
9
use Symfony\Component\Yaml\Yaml;
10
11
use function array_key_first;
12
use function file_get_contents;
13
use function array_merge;
14
use function file_exists;
15
16
/**
17
 * @internal Bootstrap service that loads the YAML configuration file.
18
 *
19
 * @see docs/digging-deeper/customization.md#yaml-configuration
20
 *
21
 * It also supports loading multiple configuration namespaces, where a configuration namespace is defined
22
 * as the first level in the service container configuration repository array, and usually corresponds
23
 * one-to-one with a file in the config directory. This feature, by design, requires a top-level
24
 * configuration entry to be present as 'hyde' in the YAML file. Existing config files
25
 * will be parsed as normal, but can be migrated by indenting all entries by one
26
 * level, and adding a top-level 'hyde' key. Then additional namespaces can
27
 * be added underneath as needed.
28
 */
29
class LoadYamlConfiguration
30
{
31
    /**
32
     * Performs a core task that needs to be performed on
33
     * early stages of the framework.
34
     */
35
    public function bootstrap(): void
36
    {
37
        if ($this->hasYamlConfigFile()) {
38
            $this->mergeParsedConfiguration();
39
        }
40
    }
41
42
    protected function hasYamlConfigFile(): bool
43
    {
44
        return file_exists(Hyde::path('hyde.yml'))
45
            || file_exists(Hyde::path('hyde.yaml'));
46
    }
47
48
    protected function getYaml(): array
49
    {
50
        return (array) Yaml::parse(file_get_contents($this->getFile()));
51
    }
52
53
    protected function getFile(): string
54
    {
55
        return file_exists(Hyde::path('hyde.yml'))
56
            ? Hyde::path('hyde.yml')
57
            : Hyde::path('hyde.yaml');
58
    }
59
60
    protected function mergeParsedConfiguration(): void
61
    {
62
        $yaml = $this->getYaml();
63
64
        // If the Yaml file contains namespaces, we merge those using more granular logic
65
        // that only applies the namespace data to each configuration namespace.
66
        if ($this->configurationContainsNamespaces($yaml)) {
67
            foreach ($yaml as $namespace => $data) {
68
                $this->mergeConfiguration($namespace, (array) $data);
69
            }
70
71
            return;
72
        }
73
74
        // Otherwise, we can merge using the default strategy, which is simply applying all the data to the hyde namespace.
75
        $this->mergeConfiguration('hyde', $yaml);
76
    }
77
78
    protected function mergeConfiguration(string $namespace, array $yamlData): void
79
    {
80
        Config::set($namespace, array_merge(
81
            Config::getArray($namespace, []),
82
            $yamlData
83
        ));
84
    }
85
86
    protected function configurationContainsNamespaces(array $yaml): bool
87
    {
88
        return array_key_first($yaml) === 'hyde';
89
    }
90
}
91