Passed
Push — master ( c969ca...f8f60c )
by Caen
04:32 queued 14s
created

supportSettingSidebarHeaderFromSiteName()   A

Complexity

Conditions 4
Paths 6

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 5
nc 6
nop 0
dl 0
loc 8
rs 10
c 0
b 0
f 0
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 Illuminate\Support\Arr;
10
use Symfony\Component\Yaml\Yaml;
11
12
use function array_key_first;
13
use function file_get_contents;
14
use function array_merge;
15
use function file_exists;
16
17
/**
18
 * @internal Bootstrap service that loads the YAML configuration file.
19
 *
20
 * @implements \LaravelZero\Framework\Contracts\BoostrapperContract [sic]
21
 *
22
 * @see docs/digging-deeper/customization.md#yaml-configuration
23
 *
24
 * It also supports loading multiple configuration namespaces, where a configuration namespace is defined
25
 * as a firs level entry in the service container configuration repository array, and corresponds
26
 * one-to-one with a file in the config directory, and a root-level key in the YAML file.
27
 *
28
 * This feature, by design, requires a top-level configuration entry to be present as 'hyde' in the YAML file.
29
 * Existing config files will be parsed as normal, but can be migrated by indenting all entries by one level,
30
 * and adding a top-level 'hyde' key. Then additional namespaces can be added underneath as needed.
31
 */
32
class LoadYamlConfiguration
33
{
34
    protected array $config;
35
    protected array $yaml;
36
37
    /**
38
     * Performs a core task that needs to be performed on
39
     * early stages of the framework.
40
     */
41
    public function bootstrap(): void
42
    {
43
        if ($this->hasYamlConfigFile()) {
44
            $this->config = Config::all();
45
            $this->yaml = $this->parseYamlFile();
46
47
            $this->supportSettingSidebarHeaderFromSiteName();
48
            $this->supportSettingRssFeedTitleFromSiteName();
49
50
            $this->mergeParsedConfiguration();
51
52
            Config::set($this->config);
53
        }
54
    }
55
56
    protected function hasYamlConfigFile(): bool
57
    {
58
        return file_exists(Hyde::path('hyde.yml'))
59
            || file_exists(Hyde::path('hyde.yaml'));
60
    }
61
62
    /** @return array<string, scalar|array> */
63
    protected function parseYamlFile(): array
64
    {
65
        return Arr::undot((array) Yaml::parse(file_get_contents($this->getFile())));
66
    }
67
68
    protected function getFile(): string
69
    {
70
        return file_exists(Hyde::path('hyde.yml'))
71
            ? Hyde::path('hyde.yml')
72
            : Hyde::path('hyde.yaml');
73
    }
74
75
    protected function mergeParsedConfiguration(): void
76
    {
77
        $yaml = $this->yaml;
78
79
        // If the Yaml file contains namespaces, we merge those using more granular logic
80
        // that only applies the namespace data to each configuration namespace.
81
        if ($this->configurationContainsNamespaces()) {
82
            /** @var array<string, array<string, scalar>> $yaml */
83
            foreach ($yaml as $namespace => $data) {
84
                $this->mergeConfiguration($namespace, Arr::undot((array) $data));
85
            }
86
        } else {
87
            // Otherwise, we can merge using the default strategy, which is simply applying all the data to the hyde namespace.
88
            $this->mergeConfiguration('hyde', $yaml);
89
        }
90
    }
91
92
    protected function mergeConfiguration(string $namespace, array $yamlData): void
93
    {
94
        $this->config[$namespace] = array_merge(
95
            $this->config[$namespace] ?? [],
96
            $yamlData
97
        );
98
    }
99
100
    protected function configurationContainsNamespaces(): bool
101
    {
102
        return array_key_first($this->yaml) === 'hyde';
103
    }
104
105
    private function supportSettingSidebarHeaderFromSiteName(): void
106
    {
107
        $sidebarHeaderIsNotSetInPhpConfig = ($this->config['docs']['sidebar']['header'] ?? null) === 'HydePHP Docs';
108
        $siteNameFromYaml = $this->configurationContainsNamespaces() ? ($this->yaml['hyde']['name'] ?? null) : ($this->yaml['name'] ?? null);
109
110
        if ($sidebarHeaderIsNotSetInPhpConfig) {
111
            if ($siteNameFromYaml !== null) {
112
                $this->config['docs']['sidebar']['header'] = $siteNameFromYaml.' Docs';
113
            }
114
        }
115
    }
116
117
    private function supportSettingRssFeedTitleFromSiteName(): void
118
    {
119
        $rssFeedTitleIsNotSetInPhpConfig = ($this->config['hyde']['rss']['description'] ?? null) === 'HydePHP RSS Feed';
120
        $siteNameFromYaml = $this->configurationContainsNamespaces() ? ($this->yaml['hyde']['name'] ?? null) : ($this->yaml['name'] ?? null);
121
122
        if ($rssFeedTitleIsNotSetInPhpConfig) {
123
            if ($siteNameFromYaml !== null) {
124
                $this->config['hyde']['rss']['description'] = $siteNameFromYaml.' RSS Feed';
125
            }
126
        }
127
    }
128
}
129