Passed
Push — feature/class-resolver-events ( b07999...bba964 )
by Chema
03:27
created

Config::getEventDispatcher()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2

Importance

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