Passed
Push — add-with-all-to-modules-list ( 82b81d...0edb38 )
by Chema
03:40
created

GacelaConfig::extendGacelaConfigs()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

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