Passed
Push — feature/add-cache-created-even... ( 3ab8b0...7e365d )
by Chema
08:25 queued 04:45
created

Config::resetInstance()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

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