Passed
Push — feature/remove-profiler ( 1b185f )
by Chema
04:28
created

Config   A

Complexity

Total Complexity 23

Size/Duplication

Total Lines 137
Duplicated Lines 0 %

Test Coverage

Coverage 97.83%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 41
dl 0
loc 137
ccs 45
cts 46
cp 0.9783
rs 10
c 1
b 0
f 0
wmc 23

13 Methods

Rating   Name   Duplication   Size   Complexity  
A resetInstance() 0 3 1
A __construct() 0 2 1
A get() 0 15 5
A getInstance() 0 7 2
A setSetup() 0 5 1
A getSetupGacela() 0 7 2
A getFactory() 0 10 2
A loadAllConfigValues() 0 5 1
A setAppRootDir() 0 9 3
A getAppRootDir() 0 3 2
A init() 0 5 1
A getCacheDir() 0 5 1
A hasKey() 0 3 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Gacela\Framework\Config;
6
7
use Gacela\Framework\Bootstrap\SetupGacela;
8
use Gacela\Framework\Bootstrap\SetupGacelaInterface;
9
use Gacela\Framework\Exception\ConfigException;
10
11
use function array_key_exists;
12
13
final class Config implements ConfigInterface
14
{
15
    private static ?self $instance = null;
16
17
    private ?string $appRootDir = null;
18
19
    /** @var array<string,mixed> */
20
    private array $config = [];
21
22
    private ?SetupGacelaInterface $setup = null;
23
24
    private ?ConfigFactory $configFactory = null;
25
26
    private function __construct()
27
    {
28
    }
29
30 64
    public static function getInstance(): self
31
    {
32 64
        if (self::$instance === null) {
33 9
            self::$instance = new self();
34
        }
35
36 64
        return self::$instance;
0 ignored issues
show
Bug Best Practice introduced by
The expression return self::instance could return the type null which is incompatible with the type-hinted return Gacela\Framework\Config\Config. Consider adding an additional type-check to rule them out.
Loading history...
37
    }
38
39
    /**
40
     * @internal
41
     */
42 8
    public static function resetInstance(): void
43
    {
44 8
        self::$instance = null;
45
    }
46
47
    /**
48
     * @param null|mixed $default
49
     *
50
     * @throws ConfigException
51
     *
52
     * @return mixed
53
     */
54 24
    public function get(string $key, $default = self::DEFAULT_CONFIG_VALUE)
55
    {
56 24
        if (empty($this->config)) {
57 3
            $this->init();
58
        }
59
60 24
        if ($default !== self::DEFAULT_CONFIG_VALUE && !$this->hasKey($key)) {
61 2
            return $default;
62
        }
63
64 22
        if (!$this->hasKey($key)) {
65 1
            throw ConfigException::keyNotFound($key, self::class);
66
        }
67
68 21
        return $this->config[$key];
69
    }
70
71
    /**
72
     * Force loading all config values in memory.
73
     *
74
     * @throws ConfigException
75
     */
76 64
    public function init(): void
77
    {
78 64
        $this->configFactory = null;
79 64
        $this->config = $this->loadAllConfigValues();
80 64
        $this->config = array_merge($this->config, $this->getSetupGacela()->getConfigKeyValues());
81
    }
82
83 64
    public function setAppRootDir(string $dir): self
84
    {
85 64
        $this->appRootDir = rtrim($dir, DIRECTORY_SEPARATOR);
86
87 64
        if (empty($this->appRootDir)) {
88
            $this->appRootDir = getcwd() ?: ''; // @codeCoverageIgnore
89
        }
90
91 64
        return $this;
92
    }
93
94 64
    public function getAppRootDir(): string
95
    {
96 64
        return $this->appRootDir ?? getcwd() ?: '';
97
    }
98
99 27
    public function getCacheDir(): string
100
    {
101 27
        return $this->getAppRootDir()
102
            . DIRECTORY_SEPARATOR
103 27
            . ltrim($this->getSetupGacela()->getFileCacheDirectory(), DIRECTORY_SEPARATOR);
104
    }
105
106 64
    public function setSetup(SetupGacelaInterface $setup): self
107
    {
108 64
        $this->setup = $setup;
109
110 64
        return $this;
111
    }
112
113
    /**
114
     * @internal
115
     */
116 64
    public function getFactory(): ConfigFactory
117
    {
118 64
        if ($this->configFactory === null) {
119 64
            $this->configFactory = new ConfigFactory(
120 64
                $this->getAppRootDir(),
121 64
                $this->getSetupGacela()
122
            );
123
        }
124
125 64
        return $this->configFactory;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->configFactory could return the type null which is incompatible with the type-hinted return Gacela\Framework\Config\ConfigFactory. Consider adding an additional type-check to rule them out.
Loading history...
126
    }
127
128 64
    public function getSetupGacela(): SetupGacelaInterface
129
    {
130 64
        if ($this->setup === null) {
131
            $this->setup = new SetupGacela();
132
        }
133
134 64
        return $this->setup;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->setup could return the type null which is incompatible with the type-hinted return Gacela\Framework\Bootstrap\SetupGacelaInterface. Consider adding an additional type-check to rule them out.
Loading history...
135
    }
136
137 27
    public function hasKey(string $key): bool
138
    {
139 27
        return array_key_exists($key, $this->config);
140
    }
141
142
    /**
143
     * @return array<string,mixed>
144
     */
145 64
    private function loadAllConfigValues(): array
146
    {
147 64
        return $this->getFactory()
148 64
            ->createConfigLoader()
149 64
            ->loadAll();
150
    }
151
}
152