Test Failed
Push — feat/gacela-config-improvemets... ( c62042 )
by Chema
05:18
created

GacelaConfig::resetInMemoryCache()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 2
c 0
b 0
f 0
dl 0
loc 5
rs 10
cc 1
nc 1
nop 0
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
    /** @var array<string,Closure> */
53
    private array $factories = [];
54
55
    /** @var array<string,Closure> */
56
    private array $protectedServices = [];
57
58
    /** @var array<string,string> */
59
    private array $aliases = [];
60
61
    /**
62
     * @param array<string,class-string|object|callable> $externalServices
63
     */
64
    public function __construct(private array $externalServices = [])
65
    {
66
        $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...
67
        $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...
68
        $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...
69
    }
70
71
    /**
72
     * Define 'config/*.php' as path, and 'config/local.php' as local path for the configuration.
73
     *
74
     * @codeCoverageIgnore
75
     *
76
     * @return Closure(GacelaConfig):void
77
     */
78
    public static function defaultPhpConfig(): callable
79
    {
80
        return static function (self $config): void {
81
            $config->addAppConfig('config/*.php', 'config/local.php');
82
        };
83
    }
84
85
    /**
86
     * Define the path where the configuration will be stored.
87
     *
88
     * @param string $path define the path where Gacela will read all the config files
89
     * @param string $pathLocal define the path where Gacela will read the local config file
90
     * @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...
91
     */
92
    public function addAppConfig(string $path, string $pathLocal = '', string|ConfigReaderInterface|null $reader = null): self
93
    {
94
        $this->appConfigBuilder->add($path, $pathLocal, $reader);
95
96
        return $this;
97
    }
98
99
    /**
100
     * Allow overriding gacela facade suffixes.
101
     */
102
    public function addSuffixTypeFacade(string $suffix): self
103
    {
104
        $this->suffixTypesBuilder->addFacade($suffix);
105
106
        return $this;
107
    }
108
109
    /**
110
     * Allow overriding gacela factory suffixes.
111
     */
112
    public function addSuffixTypeFactory(string $suffix): self
113
    {
114
        $this->suffixTypesBuilder->addFactory($suffix);
115
116
        return $this;
117
    }
118
119
    /**
120
     * Allow overriding gacela config suffixes.
121
     */
122
    public function addSuffixTypeConfig(string $suffix): self
123
    {
124
        $this->suffixTypesBuilder->addConfig($suffix);
125
126
        return $this;
127
    }
128
129
    /**
130
     * Allow overriding gacela dependency provider suffixes.
131
     */
132
    public function addSuffixTypeProvider(string $suffix): self
133
    {
134
        $this->suffixTypesBuilder->addProvider($suffix);
135
136
        return $this;
137
    }
138
139
    /**
140
     * @deprecated in favor of `$this->addBinding(key, value)`
141
     * It will be removed in the next release
142
     *
143
     * @param class-string $key
144
     * @param class-string|object|callable $value
145
     */
146
    public function addMappingInterface(string $key, string|object|callable $value): self
147
    {
148
        return $this->addBinding($key, $value);
149
    }
150
151
    /**
152
     * Bind a key class or interface name to be resolved by Gacela automatically.
153
     *
154
     * @param class-string $key
155
     * @param class-string|object|callable $value
156
     */
157
    public function addBinding(string $key, string|object|callable $value): self
158
    {
159
        $this->bindingsBuilder->bind($key, $value);
160
161
        return $this;
162
    }
163
164
    /**
165
     * Useful to pass services while bootstrapping Gacela to the gacela.php config file.
166
     *
167
     * @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...
168
     */
169
    public function addExternalService(string $key, $value): self
170
    {
171
        $this->externalServices[$key] = $value;
172
173
        return $this;
174
    }
175
176
    /**
177
     * Get an external service from its defined key, previously added using `addExternalService()`.
178
     *
179
     * @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...
180
     */
181
    public function getExternalService(string $key)
182
    {
183
        return $this->externalServices[$key];
184
    }
185
186
    /**
187
     * Enable resetting the memory cache on each setup. Useful for functional tests.
188
     */
189
    public function resetInMemoryCache(): self
190
    {
191
        $this->shouldResetInMemoryCache = true;
192
193
        return $this;
194
    }
195
196
    /**
197
     * Shortcut to setFileCache(true)
198
     */
199
    public function enableFileCache(?string $dir = null): self
200
    {
201
        return $this->setFileCache(true, $dir);
202
    }
203
204
    /**
205
     * Define whether the file cache flag is enabled,
206
     * and the file cache directory.
207
     */
208
    public function setFileCache(bool $enabled, ?string $dir = null): self
209
    {
210
        $this->fileCacheEnabled = $enabled;
211
        $this->fileCacheDirectory = $dir;
212
213
        return $this;
214
    }
215
216
    /**
217
     * Define a list of project namespaces.
218
     *
219
     * @param list<string> $list
220
     */
221
    public function setProjectNamespaces(array $list): self
222
    {
223
        $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...
224
225
        return $this;
226
    }
227
228
    /**
229
     * Add/replace an existent configuration key with a specific value.
230
     */
231
    public function addAppConfigKeyValue(string $key, mixed $value): self
232
    {
233
        $this->configKeyValues[$key] = $value;
234
235
        return $this;
236
    }
237
238
    /**
239
     * Add/replace a list of existent configuration keys with a specific value.
240
     *
241
     * @param array<string, mixed> $config
242
     */
243
    public function addAppConfigKeyValues(array $config): self
244
    {
245
        $this->configKeyValues = array_merge($this->configKeyValues ?? [], $config);
246
247
        return $this;
248
    }
249
250
    /**
251
     * Do not dispatch any event in the application.
252
     */
253
    public function disableEventListeners(): self
254
    {
255
        $this->areEventListenersEnabled = false;
256
257
        return $this;
258
    }
259
260
    /**
261
     * Register a generic listener when any event happens.
262
     * The callable argument must be the type `GacelaEventInterface`.
263
     *
264
     * @param callable(GacelaEventInterface):void $listener
265
     */
266
    public function registerGenericListener(callable $listener): self
267
    {
268
        $this->genericListeners ??= [];
269
        $this->genericListeners[] = $listener;
270
271
        return $this;
272
    }
273
274
    /**
275
     * Register a listener when some event happens.
276
     *
277
     * @param class-string $event
278
     * @param callable(GacelaEventInterface):void $listener
279
     */
280
    public function registerSpecificListener(string $event, callable $listener): self
281
    {
282
        $this->specificListeners[$event] ??= [];
283
        $this->specificListeners[$event][] = $listener;
284
285
        return $this;
286
    }
287
288
    public function extendService(string $id, Closure $service): self
289
    {
290
        $this->servicesToExtend[$id] ??= [];
291
        $this->servicesToExtend[$id][] = $service;
292
293
        return $this;
294
    }
295
296
    /**
297
     * Register a factory service that creates a new instance on each call.
298
     * Unlike regular services (which are singletons), factory services return
299
     * a new instance every time they are resolved from the container.
300
     *
301
     * @param string $id The service identifier (usually a class name or interface)
302
     * @param Closure $factory The factory closure that creates the service instance
303
     *
304
     * @return $this
305
     */
306
    public function addFactory(string $id, Closure $factory): self
307
    {
308
        $this->factories[$id] = $factory;
309
310
        return $this;
311
    }
312
313
    /**
314
     * Register a protected service that cannot be extended.
315
     * Protected services are stored as closures and won't be invoked by the container,
316
     * making them useful for storing callable configurations.
317
     *
318
     * @param string $id The service identifier
319
     * @param Closure $service The closure to protect
320
     *
321
     * @return $this
322
     */
323
    public function addProtected(string $id, Closure $service): self
324
    {
325
        $this->protectedServices[$id] = $service;
326
327
        return $this;
328
    }
329
330
    /**
331
     * Create an alias for a service.
332
     * This allows you to reference the same service with different names.
333
     *
334
     * @param string $alias The alias name
335
     * @param string $id The actual service identifier
336
     *
337
     * @return $this
338
     */
339
    public function addAlias(string $alias, string $id): self
340
    {
341
        $this->aliases[$alias] = $id;
342
343
        return $this;
344
    }
345
346
    /**
347
     * Add a new invokable class that can extend the GacelaConfig object.
348
     *
349
     * This configClass will receive the GacelaConfig object as argument to the __invoke() method.
350
     * ```
351
     * __invoke(GacelaConfig $config): void
352
     * ```
353
     *
354
     * @param class-string $className
355
     */
356
    public function extendGacelaConfig(string $className): self
357
    {
358
        $this->gacelaConfigsToExtend[] = $className;
359
360
        return $this;
361
    }
362
363
    /**
364
     * @param list<class-string> $list
365
     */
366
    public function extendGacelaConfigs(array $list): self
367
    {
368
        $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...
369
370
        return $this;
371
    }
372
373
    /**
374
     * @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...
375
     */
376
    public function addPlugin(string|callable $plugin): self
377
    {
378
        $this->plugins[] = $plugin;
379
380
        return $this;
381
    }
382
383
    /**
384
     * @param list<class-string|callable> $list
385
     */
386
    public function addPlugins(array $list): self
387
    {
388
        $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...
389
390
        return $this;
391
    }
392
393
    /**
394
     * @internal
395
     */
396
    public function toTransfer(): GacelaConfigTransfer
397
    {
398
        return new GacelaConfigTransfer(
399
            $this->appConfigBuilder,
400
            $this->suffixTypesBuilder,
401
            $this->bindingsBuilder,
402
            $this->externalServices,
403
            $this->shouldResetInMemoryCache,
404
            $this->fileCacheEnabled,
405
            $this->fileCacheDirectory,
406
            $this->projectNamespaces,
407
            $this->configKeyValues,
408
            $this->genericListeners,
409
            $this->specificListeners,
410
            $this->areEventListenersEnabled,
411
            $this->gacelaConfigsToExtend,
412
            $this->plugins,
413
            $this->servicesToExtend,
414
            $this->factories,
415
            $this->protectedServices,
416
            $this->aliases,
417
        );
418
    }
419
}
420