GacelaConfig   A
last analyzed

Complexity

Total Complexity 26

Size/Duplication

Total Lines 340
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 6
Bugs 1 Features 0
Metric Value
wmc 26
eloc 83
c 6
b 1
f 0
dl 0
loc 340
ccs 86
cts 86
cp 1
rs 10

26 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A toTransfer() 0 18 1
A addAppConfigKeyValue() 0 5 1
A defaultPhpConfig() 0 4 1
A setFileCache() 0 6 1
A getExternalService() 0 3 1
A enableFileCache() 0 3 1
A addAppConfig() 0 5 1
A addSuffixTypeFacade() 0 5 1
A addMappingInterface() 0 3 1
A setProjectNamespaces() 0 5 1
A addSuffixTypeFactory() 0 5 1
A addPlugins() 0 5 1
A registerGenericListener() 0 6 1
A addAppConfigKeyValues() 0 5 1
A extendGacelaConfig() 0 5 1
A resetInMemoryCache() 0 5 1
A extendService() 0 6 1
A addSuffixTypeConfig() 0 5 1
A disableEventListeners() 0 5 1
A extendGacelaConfigs() 0 5 1
A addPlugin() 0 5 1
A registerSpecificListener() 0 6 1
A addBinding() 0 5 1
A addSuffixTypeProvider() 0 5 1
A addExternalService() 0 5 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Gacela\Framework\Bootstrap;
6
7
use Closure;
8
use Gacela\Framework\Bootstrap\Setup\GacelaConfigTransfer;
9
use Gacela\Framework\Config\ConfigReaderInterface;
10
use Gacela\Framework\Config\GacelaConfigBuilder\AppConfigBuilder;
11
use Gacela\Framework\Config\GacelaConfigBuilder\BindingsBuilder;
12
use Gacela\Framework\Config\GacelaConfigBuilder\SuffixTypesBuilder;
13
use Gacela\Framework\Event\GacelaEventInterface;
14
15
final class GacelaConfig
16
{
17
    private readonly AppConfigBuilder $appConfigBuilder;
18
19
    private readonly SuffixTypesBuilder $suffixTypesBuilder;
20
21
    private readonly BindingsBuilder $bindingsBuilder;
22
23
    private ?bool $shouldResetInMemoryCache = null;
24
25
    private ?bool $fileCacheEnabled = null;
26
27
    private ?string $fileCacheDirectory = null;
28
29
    /** @var list<string> */
30
    private ?array $projectNamespaces = null;
31
32
    /** @var array<string,mixed> */
33
    private ?array $configKeyValues = null;
34
35
    private ?bool $areEventListenersEnabled = null;
36
37
    /** @var list<callable> */
38
    private ?array $genericListeners = null;
39
40
    /** @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...
41
    private ?array $specificListeners = null;
42
43
    /** @var list<class-string> */
44
    private ?array $gacelaConfigsToExtend = null;
45
46
    /** @var list<class-string|callable> */
47
    private ?array $plugins = null;
48
49
    /** @var array<string,list<Closure>> */
50
    private array $servicesToExtend = [];
51
52
    /**
53
     * @param array<string,class-string|object|callable> $externalServices
54
     */
55
    public function __construct(private array $externalServices = [])
56
    {
57
        $this->appConfigBuilder = new AppConfigBuilder();
0 ignored issues
show
Bug introduced by
The property appConfigBuilder is declared read-only in Gacela\Framework\Bootstrap\GacelaConfig.
Loading history...
58 94
        $this->suffixTypesBuilder = new SuffixTypesBuilder();
0 ignored issues
show
Bug introduced by
The property suffixTypesBuilder is declared read-only in Gacela\Framework\Bootstrap\GacelaConfig.
Loading history...
59
        $this->bindingsBuilder = new BindingsBuilder();
0 ignored issues
show
Bug introduced by
The property bindingsBuilder is declared read-only in Gacela\Framework\Bootstrap\GacelaConfig.
Loading history...
60 94
    }
61 94
62 94
    /**
63 94
     * Define 'config/*.php' as path, and 'config/local.php' as local path for the configuration.
64
     *
65
     * @codeCoverageIgnore
66
     *
67
     * @return Closure(GacelaConfig):void
68
     */
69
    public static function defaultPhpConfig(): callable
70
    {
71
        return static function (self $config): void {
72
            $config->addAppConfig('config/*.php', 'config/local.php');
73
        };
74
    }
75
76
    /**
77
     * Define the path where the configuration will be stored.
78
     *
79
     * @param string $path define the path where Gacela will read all the config files
80
     * @param string $pathLocal define the path where Gacela will read the local config file
81
     * @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...
82
     */
83
    public function addAppConfig(string $path, string $pathLocal = '', string|ConfigReaderInterface|null $reader = null): self
84
    {
85
        $this->appConfigBuilder->add($path, $pathLocal, $reader);
86
87 20
        return $this;
88
    }
89 20
90
    /**
91 20
     * Allow overriding gacela facade suffixes.
92
     */
93
    public function addSuffixTypeFacade(string $suffix): self
94
    {
95
        $this->suffixTypesBuilder->addFacade($suffix);
96
97 5
        return $this;
98
    }
99 5
100
    /**
101 5
     * Allow overriding gacela factory suffixes.
102
     */
103
    public function addSuffixTypeFactory(string $suffix): self
104
    {
105
        $this->suffixTypesBuilder->addFactory($suffix);
106
107 5
        return $this;
108
    }
109 5
110
    /**
111 5
     * Allow overriding gacela config suffixes.
112
     */
113
    public function addSuffixTypeConfig(string $suffix): self
114
    {
115
        $this->suffixTypesBuilder->addConfig($suffix);
116
117 5
        return $this;
118
    }
119 5
120
    /**
121 5
     * Allow overriding gacela dependency provider suffixes.
122
     */
123
    public function addSuffixTypeProvider(string $suffix): self
124
    {
125
        $this->suffixTypesBuilder->addProvider($suffix);
126
127 6
        return $this;
128
    }
129 6
130
    /**
131 6
     * @deprecated in favor of `$this->addBinding(key, value)`
132
     * It will be removed in the next release
133
     *
134
     * @param class-string $key
135
     * @param class-string|object|callable $value
136
     */
137
    public function addMappingInterface(string $key, string|object|callable $value): self
138
    {
139
        return $this->addBinding($key, $value);
140
    }
141 1
142
    /**
143 1
     * Bind a key class or interface name to be resolved by Gacela automatically.
144
     *
145
     * @param class-string $key
146
     * @param class-string|object|callable $value
147
     */
148
    public function addBinding(string $key, string|object|callable $value): self
149
    {
150
        $this->bindingsBuilder->bind($key, $value);
151
152 11
        return $this;
153
    }
154 11
155
    /**
156 11
     * Useful to pass services while bootstrapping Gacela to the gacela.php config file.
157
     *
158
     * @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...
159
     */
160
    public function addExternalService(string $key, $value): self
161
    {
162
        $this->externalServices[$key] = $value;
163
164 3
        return $this;
165
    }
166 3
167
    /**
168 3
     * Get an external service from its defined key, previously added using `addExternalService()`.
169
     *
170
     * @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...
171
     */
172
    public function getExternalService(string $key)
173
    {
174
        return $this->externalServices[$key];
175
    }
176 4
177
    /**
178 4
     * Enable resetting the memory cache on each setup. Useful for functional tests.
179
     */
180
    public function resetInMemoryCache(): self
181
    {
182
        $this->shouldResetInMemoryCache = true;
183
184 59
        return $this;
185
    }
186 59
187
    /**
188 59
     * Shortcut to setFileCache(true)
189
     */
190
    public function enableFileCache(?string $dir = null): self
191
    {
192
        return $this->setFileCache(true, $dir);
193
    }
194 2
195
    /**
196 2
     * Define whether the file cache flag is enabled,
197
     * and the file cache directory.
198
     */
199
    public function setFileCache(bool $enabled, ?string $dir = null): self
200
    {
201
        $this->fileCacheEnabled = $enabled;
202
        $this->fileCacheDirectory = $dir;
203 17
204
        return $this;
205 17
    }
206 17
207
    /**
208 17
     * Define a list of project namespaces.
209
     *
210
     * @param list<string> $list
211
     */
212
    public function setProjectNamespaces(array $list): self
213
    {
214
        $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...
215
216 4
        return $this;
217
    }
218 4
219
    /**
220 4
     * Add/replace an existent configuration key with a specific value.
221
     */
222
    public function addAppConfigKeyValue(string $key, mixed $value): self
223
    {
224
        $this->configKeyValues[$key] = $value;
225
226
        return $this;
227
    }
228 8
229
    /**
230 8
     * Add/replace a list of existent configuration keys with a specific value.
231
     *
232 8
     * @param array<string, mixed> $config
233
     */
234
    public function addAppConfigKeyValues(array $config): self
235
    {
236
        $this->configKeyValues = array_merge($this->configKeyValues ?? [], $config);
237
238
        return $this;
239
    }
240 2
241
    /**
242 2
     * Do not dispatch any event in the application.
243
     */
244 2
    public function disableEventListeners(): self
245
    {
246
        $this->areEventListenersEnabled = false;
247
248
        return $this;
249
    }
250 1
251
    /**
252 1
     * Register a generic listener when any event happens.
253
     * The callable argument must be the type `GacelaEventInterface`.
254 1
     *
255
     * @param callable(GacelaEventInterface):void $listener
256
     */
257
    public function registerGenericListener(callable $listener): self
258
    {
259
        $this->genericListeners ??= [];
260
        $this->genericListeners[] = $listener;
261
262
        return $this;
263 11
    }
264
265 11
    /**
266 11
     * Register a listener when some event happens.
267
     *
268 11
     * @param class-string $event
269
     * @param callable(GacelaEventInterface):void $listener
270
     */
271
    public function registerSpecificListener(string $event, callable $listener): self
272
    {
273
        $this->specificListeners[$event] ??= [];
274
        $this->specificListeners[$event][] = $listener;
275
276
        return $this;
277 7
    }
278
279 7
    public function extendService(string $id, Closure $service): self
280 7
    {
281
        $this->servicesToExtend[$id] ??= [];
282 7
        $this->servicesToExtend[$id][] = $service;
283
284
        return $this;
285 3
    }
286
287 3
    /**
288 3
     * Add a new invokable class that can extend the GacelaConfig object.
289
     *
290 3
     * This configClass will receive the GacelaConfig object as argument to the __invoke() method.
291
     * ```
292
     * __invoke(GacelaConfig $config): void
293
     * ```
294
     *
295
     * @param class-string $className
296
     */
297
    public function extendGacelaConfig(string $className): self
298
    {
299
        $this->gacelaConfigsToExtend[] = $className;
300
301
        return $this;
302
    }
303 2
304
    /**
305 2
     * @param list<class-string> $list
306
     */
307 2
    public function extendGacelaConfigs(array $list): self
308
    {
309
        $this->gacelaConfigsToExtend = array_merge($this->gacelaConfigsToExtend ?? [], $list);
0 ignored issues
show
Documentation Bug introduced by
It seems like array_merge($this->gacel...tend ?? array(), $list) of type array is incompatible with the declared type Gacela\Framework\Bootstrap\list of property $gacelaConfigsToExtend.

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...
310
311
        return $this;
312
    }
313 2
314
    /**
315 2
     * @param class-string|callable $plugin
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string|callable at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string|callable.
Loading history...
316
     */
317 2
    public function addPlugin(string|callable $plugin): self
318
    {
319
        $this->plugins[] = $plugin;
320
321
        return $this;
322
    }
323 5
324
    /**
325 5
     * @param list<class-string|callable> $list
326
     */
327 5
    public function addPlugins(array $list): self
328
    {
329
        $this->plugins = array_merge($this->plugins ?? [], $list);
0 ignored issues
show
Documentation Bug introduced by
It seems like array_merge($this->plugins ?? array(), $list) of type array is incompatible with the declared type Gacela\Framework\Bootstrap\list of property $plugins.

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...
330
331
        return $this;
332
    }
333 1
334
    /**
335 1
     * @internal
336
     */
337 1
    public function toTransfer(): GacelaConfigTransfer
338
    {
339
        return new GacelaConfigTransfer(
340
            $this->appConfigBuilder,
341
            $this->suffixTypesBuilder,
342
            $this->bindingsBuilder,
343 93
            $this->externalServices,
344
            $this->shouldResetInMemoryCache,
345 93
            $this->fileCacheEnabled,
346 93
            $this->fileCacheDirectory,
347 93
            $this->projectNamespaces,
348 93
            $this->configKeyValues,
349 93
            $this->genericListeners,
350 93
            $this->specificListeners,
351 93
            $this->areEventListenersEnabled,
352 93
            $this->gacelaConfigsToExtend,
353 93
            $this->plugins,
354 93
            $this->servicesToExtend,
355 93
        );
356 93
    }
357
}
358