Passed
Push — feature/add-generic-listeners ( 750050...7ef9cb )
by Chema
04:40 queued 03:23
created

GacelaConfig   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 271
Duplicated Lines 0 %

Test Coverage

Coverage 95.65%

Importance

Changes 3
Bugs 0 Features 0
Metric Value
eloc 63
dl 0
loc 271
ccs 66
cts 69
cp 0.9565
rs 10
c 3
b 0
f 0
wmc 20

20 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A addAppConfigKeyValue() 0 5 1
A build() 0 15 1
A getExternalService() 0 3 1
A addAppConfig() 0 5 1
A addExternalService() 0 5 1
A addSuffixTypeFacade() 0 5 1
A addMappingInterface() 0 5 1
A setProjectNamespaces() 0 5 1
A setFileCacheEnabled() 0 5 1
A addSuffixTypeFactory() 0 5 1
A withPhpConfigDefault() 0 4 1
A registerGenericListener() 0 3 1
A addAppConfigKeyValues() 0 5 1
A resetInMemoryCache() 0 5 1
A setFileCacheDirectory() 0 5 1
A addSuffixTypeConfig() 0 5 1
A addSuffixTypeDependencyProvider() 0 5 1
A disableEventListeners() 0 5 1
A registerSpecificListener() 0 3 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Gacela\Framework\Bootstrap;
6
7
use Closure;
8
use Gacela\Framework\ClassResolver\Cache\GacelaFileCache;
9
use Gacela\Framework\Config\ConfigReaderInterface;
10
use Gacela\Framework\Config\GacelaConfigBuilder\ConfigBuilder;
11
use Gacela\Framework\Config\GacelaConfigBuilder\MappingInterfacesBuilder;
12
use Gacela\Framework\Config\GacelaConfigBuilder\SuffixTypesBuilder;
13
use Gacela\Framework\EventListener\GacelaEventInterface;
14
15
final class GacelaConfig
16
{
17
    private ConfigBuilder $configBuilder;
18
19
    private SuffixTypesBuilder $suffixTypesBuilder;
20
21
    private MappingInterfacesBuilder $mappingInterfacesBuilder;
22
23
    /** @var array<string, class-string|object|callable> */
1 ignored issue
show
Documentation Bug introduced by
The doc comment array<string, class-string|object|callable> at position 4 could not be parsed: Unknown type name 'class-string' at position 4 in array<string, class-string|object|callable>.
Loading history...
24
    private array $externalServices;
25
26
    private bool $shouldResetInMemoryCache = false;
27
28
    private bool $fileCacheEnabled = GacelaFileCache::DEFAULT_ENABLED_VALUE;
29
30
    private string $fileCacheDirectory = GacelaFileCache::DEFAULT_DIRECTORY_VALUE;
31
32
    /** @var list<string> */
33
    private array $projectNamespaces = [];
34
35
    /** @var array<string,mixed> */
36
    private array $configKeyValues = [];
37
38
    private bool $areEventListenersEnabled = true;
39
40
    /** @var list<callable> */
41
    private array $genericListeners = [];
42
43
    /** @var array<class-string,list<callable>> */
0 ignored issues
show
Documentation Bug introduced by
The doc comment array<class-string,list<callable>> at position 2 could not be parsed: Unknown type name 'class-string' at position 2 in array<class-string,list<callable>>.
Loading history...
44
    private array $listenersPerEvent = [];
45
46
    /**
47
     * @param array<string,class-string|object|callable> $externalServices
1 ignored issue
show
Documentation Bug introduced by
The doc comment array<string,class-string|object|callable> at position 4 could not be parsed: Unknown type name 'class-string' at position 4 in array<string,class-string|object|callable>.
Loading history...
48
     */
49 56
    public function __construct(array $externalServices = [])
50
    {
51 56
        $this->externalServices = $externalServices;
52 56
        $this->configBuilder = new ConfigBuilder();
53 56
        $this->suffixTypesBuilder = new SuffixTypesBuilder();
54 56
        $this->mappingInterfacesBuilder = new MappingInterfacesBuilder();
55
    }
56
57
    /**
58
     * Define 'config/*.php' as path, and 'config/local.php' as local path for the configuration.
59
     *
60
     * @return Closure(GacelaConfig):void
61
     */
62 7
    public static function withPhpConfigDefault(): callable
63
    {
64 7
        return static function (self $config): void {
65 7
            $config->addAppConfig('config/*.php', 'config/local.php');
66
        };
67
    }
68
69
    /**
70
     * Define the path where the configuration will be stored.
71
     *
72
     * @param string $path define the path where Gacela will read all the config files
73
     * @param string $pathLocal define the path where Gacela will read the local config file
74
     * @param class-string<ConfigReaderInterface>|ConfigReaderInterface|null $reader Define the reader class which will read and parse the config files
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<ConfigReade...figReaderInterface|null at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<ConfigReaderInterface>|ConfigReaderInterface|null.
Loading history...
75
     */
76 25
    public function addAppConfig(string $path, string $pathLocal = '', $reader = null): self
77
    {
78 25
        $this->configBuilder->add($path, $pathLocal, $reader);
79
80 25
        return $this;
81
    }
82
83
    /**
84
     * Allow overriding gacela facade suffixes.
85
     */
86 5
    public function addSuffixTypeFacade(string $suffix): self
87
    {
88 5
        $this->suffixTypesBuilder->addFacade($suffix);
89
90 5
        return $this;
91
    }
92
93
    /**
94
     * Allow overriding gacela factory suffixes.
95
     */
96 5
    public function addSuffixTypeFactory(string $suffix): self
97
    {
98 5
        $this->suffixTypesBuilder->addFactory($suffix);
99
100 5
        return $this;
101
    }
102
103
    /**
104
     * Allow overriding gacela config suffixes.
105
     */
106 5
    public function addSuffixTypeConfig(string $suffix): self
107
    {
108 5
        $this->suffixTypesBuilder->addConfig($suffix);
109
110 5
        return $this;
111
    }
112
113
    /**
114
     * Allow overriding gacela dependency provider suffixes.
115
     */
116 6
    public function addSuffixTypeDependencyProvider(string $suffix): self
117
    {
118 6
        $this->suffixTypesBuilder->addDependencyProvider($suffix);
119
120 6
        return $this;
121
    }
122
123
    /**
124
     * Define the mapping between interfaces and concretions, so Gacela services will auto-resolve them automatically.
125
     *
126
     * @param class-string $key
127
     * @param class-string|object|callable $value
128
     */
129 9
    public function addMappingInterface(string $key, $value): self
130
    {
131 9
        $this->mappingInterfacesBuilder->bind($key, $value);
132
133 9
        return $this;
134
    }
135
136
    /**
137
     * Useful to pass services while bootstrapping Gacela to the gacela.php config file.
138
     *
139
     * @param class-string|object|callable $value
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string|object|callable at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string|object|callable.
Loading history...
140
     */
141 2
    public function addExternalService(string $key, $value): self
142
    {
143 2
        $this->externalServices[$key] = $value;
144
145 2
        return $this;
146
    }
147
148
    /**
149
     * Get an external service from its defined key, previously added using `addExternalService()`.
150
     *
151
     * @return class-string|object|callable
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string|object|callable at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string|object|callable.
Loading history...
152
     */
153 4
    public function getExternalService(string $key)
154
    {
155 4
        return $this->externalServices[$key];
156
    }
157
158
    /**
159
     * Enable resetting the memory cache on each setup. Useful for functional tests.
160
     */
161 16
    public function resetInMemoryCache(): self
162
    {
163 16
        $this->shouldResetInMemoryCache = true;
164
165 16
        return $this;
166
    }
167
168
    /**
169
     * Define whether the file cache flag is enabled.
170
     */
171 14
    public function setFileCacheEnabled(bool $flag): self
172
    {
173 14
        $this->fileCacheEnabled = $flag;
174
175 14
        return $this;
176
    }
177
178
    /**
179
     * Define the file cache directory.
180
     */
181 2
    public function setFileCacheDirectory(string $dir): self
182
    {
183 2
        $this->fileCacheDirectory = $dir;
184
185 2
        return $this;
186
    }
187
188
    /**
189
     * Define a list of project namespaces.
190
     *
191
     * @param list<string> $list
192
     */
193 3
    public function setProjectNamespaces(array $list): self
194
    {
195 3
        $this->projectNamespaces = $list;
0 ignored issues
show
Documentation Bug introduced by
It seems like $list of type array is incompatible with the declared type Gacela\Framework\Bootstrap\list of property $projectNamespaces.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
196
197 3
        return $this;
198
    }
199
200
    /**
201
     * Add/replace an existent configuration key with a specific value.
202
     *
203
     * @param mixed $value
204
     */
205 1
    public function addAppConfigKeyValue(string $key, $value): self
206
    {
207 1
        $this->configKeyValues[$key] = $value;
208
209 1
        return $this;
210
    }
211
212
    /**
213
     * Add/replace a list of existent configuration keys with a specific value.
214
     *
215
     * @param array<string, mixed> $config
216
     */
217 1
    public function addAppConfigKeyValues(array $config): self
218
    {
219 1
        $this->configKeyValues = array_merge($this->configKeyValues, $config);
220
221 1
        return $this;
222
    }
223
224
    /**
225
     * Do not dispatch any event in the application.
226
     */
227
    public function disableEventListeners(): self
228
    {
229
        $this->areEventListenersEnabled = false;
230
231
        return $this;
232
    }
233
234
    /**
235
     * Register a generic listener when any event happens.
236
     */
237 3
    public function registerGenericListener(callable $listener): void
238
    {
239 3
        $this->genericListeners[] = $listener;
240
    }
241
242
    /**
243
     * Register a listener when some event happens.
244
     *
245
     * @param class-string $event
246
     * @param callable(GacelaEventInterface):void $listener
247
     */
248 5
    public function registerSpecificListener(string $event, callable $listener): void
249
    {
250 5
        $this->listenersPerEvent[$event][] = $listener;
251
    }
252
253
    /**
254
     * @internal
255
     *
256
     * @return array{
257
     *     external-services: array<string,class-string|object|callable>,
258
     *     config-builder: ConfigBuilder,
259
     *     suffix-types-builder: SuffixTypesBuilder,
260
     *     mapping-interfaces-builder: MappingInterfacesBuilder,
261
     *     should-reset-in-memory-cache: bool,
262
     *     file-cache-enabled: bool,
263
     *     file-cache-directory: string,
264
     *     project-namespaces: list<string>,
265
     *     config-key-values: array<string,mixed>,
266
     *     are-event-listeners-enabled: bool,
267
     *     generic-listeners: list<callable>,
268
     *     listeners-per-event: array<class-string,list<callable>>,
269
     * }
270
     */
271 55
    public function build(): array
272
    {
273
        return [
274 55
            'external-services' => $this->externalServices,
275 55
            'config-builder' => $this->configBuilder,
276 55
            'suffix-types-builder' => $this->suffixTypesBuilder,
277 55
            'mapping-interfaces-builder' => $this->mappingInterfacesBuilder,
278 55
            'should-reset-in-memory-cache' => $this->shouldResetInMemoryCache,
279 55
            'file-cache-enabled' => $this->fileCacheEnabled,
280 55
            'file-cache-directory' => $this->fileCacheDirectory,
281 55
            'project-namespaces' => $this->projectNamespaces,
282 55
            'config-key-values' => $this->configKeyValues,
283 55
            'are-event-listeners-enabled' => $this->areEventListenersEnabled,
284 55
            'generic-listeners' => $this->genericListeners,
285 55
            'listeners-per-event' => $this->listenersPerEvent,
286
        ];
287
    }
288
}
289