Passed
Pull Request — master (#215)
by Jesús
06:56 queued 03:36
created

GacelaConfig   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 263
Duplicated Lines 0 %

Test Coverage

Coverage 95.45%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 60
c 1
b 0
f 0
dl 0
loc 263
rs 10
wmc 19
ccs 63
cts 66
cp 0.9545

19 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A addAppConfigKeyValue() 0 5 1
A build() 0 14 1
A getExternalService() 0 3 1
A addAppConfig() 0 5 1
A addExternalService() 0 5 1
A addSuffixTypeFacade() 0 5 1
A registerListener() 0 3 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 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
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
14
final class GacelaConfig
15
{
16
    private ConfigBuilder $configBuilder;
17
18
    private SuffixTypesBuilder $suffixTypesBuilder;
19
20
    private MappingInterfacesBuilder $mappingInterfacesBuilder;
21
22
    /** @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...
23
    private array $externalServices;
24
25
    private bool $shouldResetInMemoryCache = false;
26
27
    private bool $fileCacheEnabled = GacelaFileCache::DEFAULT_ENABLED_VALUE;
28
29
    private string $fileCacheDirectory = GacelaFileCache::DEFAULT_DIRECTORY_VALUE;
30
31
    /** @var list<string> */
32
    private array $projectNamespaces = [];
33
34
    /** @var array<string,mixed> */
35
    private array $configKeyValues = [];
36
37
    private bool $areEventListenersEnabled = true;
38
39
    /** @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...
40
    private array $listenersPerEvent = [];
41
42
    /**
43
     * @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...
44
     */
45 51
    public function __construct(array $externalServices = [])
46
    {
47 51
        $this->externalServices = $externalServices;
48 51
        $this->configBuilder = new ConfigBuilder();
49 51
        $this->suffixTypesBuilder = new SuffixTypesBuilder();
50 51
        $this->mappingInterfacesBuilder = new MappingInterfacesBuilder();
51
    }
52
53
    /**
54
     * Define 'config/*.php' as path, and 'config/local.php' as local path for the configuration.
55
     *
56
     * @return Closure(GacelaConfig):void
57
     */
58 7
    public static function withPhpConfigDefault(): callable
59
    {
60 7
        return static function (self $config): void {
61 7
            $config->addAppConfig('config/*.php', 'config/local.php');
62
        };
63
    }
64
65
    /**
66
     * Define the path where the configuration will be stored.
67
     *
68
     * @param string $path define the path where Gacela will read all the config files
69
     * @param string $pathLocal define the path where Gacela will read the local config file
70
     * @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...
71
     */
72 23
    public function addAppConfig(string $path, string $pathLocal = '', $reader = null): self
73
    {
74 23
        $this->configBuilder->add($path, $pathLocal, $reader);
75
76 23
        return $this;
77
    }
78
79
    /**
80
     * Allow overriding gacela facade suffixes.
81
     */
82 5
    public function addSuffixTypeFacade(string $suffix): self
83
    {
84 5
        $this->suffixTypesBuilder->addFacade($suffix);
85
86 5
        return $this;
87
    }
88
89
    /**
90
     * Allow overriding gacela factory suffixes.
91
     */
92 5
    public function addSuffixTypeFactory(string $suffix): self
93
    {
94 5
        $this->suffixTypesBuilder->addFactory($suffix);
95
96 5
        return $this;
97
    }
98
99
    /**
100
     * Allow overriding gacela config suffixes.
101
     */
102 5
    public function addSuffixTypeConfig(string $suffix): self
103
    {
104 5
        $this->suffixTypesBuilder->addConfig($suffix);
105
106 5
        return $this;
107
    }
108
109
    /**
110
     * Allow overriding gacela dependency provider suffixes.
111
     */
112 6
    public function addSuffixTypeDependencyProvider(string $suffix): self
113
    {
114 6
        $this->suffixTypesBuilder->addDependencyProvider($suffix);
115
116 6
        return $this;
117
    }
118
119
    /**
120
     * Define the mapping between interfaces and concretions, so Gacela services will auto-resolve them automatically.
121
     *
122
     * @param class-string $key
123
     * @param class-string|object|callable $value
124
     */
125 9
    public function addMappingInterface(string $key, $value): self
126
    {
127 9
        $this->mappingInterfacesBuilder->bind($key, $value);
128
129 9
        return $this;
130
    }
131
132
    /**
133
     * Useful to pass services while bootstrapping Gacela to the gacela.php config file.
134
     *
135
     * @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...
136
     */
137 2
    public function addExternalService(string $key, $value): self
138
    {
139 2
        $this->externalServices[$key] = $value;
140
141 2
        return $this;
142
    }
143
144
    /**
145
     * Get an external service from its defined key, previously added using `addExternalService()`.
146
     *
147
     * @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...
148
     */
149 4
    public function getExternalService(string $key)
150
    {
151 4
        return $this->externalServices[$key];
152
    }
153
154
    /**
155
     * Enable resetting the memory cache on each setup. Useful for functional tests.
156
     */
157 11
    public function resetInMemoryCache(): self
158
    {
159 11
        $this->shouldResetInMemoryCache = true;
160
161 11
        return $this;
162
    }
163
164
    /**
165
     * Define whether the file cache flag is enabled.
166
     */
167 14
    public function setFileCacheEnabled(bool $flag): self
168
    {
169 14
        $this->fileCacheEnabled = $flag;
170
171 14
        return $this;
172
    }
173
174
    /**
175
     * Define the file cache directory.
176
     */
177 2
    public function setFileCacheDirectory(string $dir): self
178
    {
179 2
        $this->fileCacheDirectory = $dir;
180
181 2
        return $this;
182
    }
183
184
    /**
185
     * Define a list of project namespaces.
186
     *
187
     * @param list<string> $list
188
     */
189 3
    public function setProjectNamespaces(array $list): self
190
    {
191 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...
192
193 3
        return $this;
194
    }
195
196
    /**
197
     * Add/replace an existent configuration key with a specific value.
198
     *
199
     * @param mixed $value
200
     */
201 1
    public function addAppConfigKeyValue(string $key, $value): self
202
    {
203 1
        $this->configKeyValues[$key] = $value;
204
205 1
        return $this;
206
    }
207
208
    /**
209
     * Add/replace a list of existent configuration keys with a specific value.
210
     *
211
     * @param array<string, mixed> $config
212
     */
213 1
    public function addAppConfigKeyValues(array $config): self
214
    {
215 1
        $this->configKeyValues = array_merge($this->configKeyValues, $config);
216
217 1
        return $this;
218
    }
219
220
    /**
221
     * Do not dispatch any event in the application.
222
     */
223
    public function disableEventListeners(): self
224
    {
225
        $this->areEventListenersEnabled = false;
226
227
        return $this;
228
    }
229
230
    /**
231
     * Register a listener when some event happens.
232
     *
233
     * Available events:
234
     * - ResolvedClassCachedEvent::class
235
     * - ResolvedClassCreatedEvent::class
236
     * - ResolvedClassTriedFromParentEvent::class
237
     * - ResolvedCreatedDefaultClassEvent::class
238
     *
239
     * @param class-string $event
240
     */
241 3
    public function registerListener(string $event, callable $listener): void
242
    {
243 3
        $this->listenersPerEvent[$event][] = $listener;
244
    }
245
246
    /**
247
     * @internal
248
     *
249
     * @return array{
250
     *     external-services: array<string,class-string|object|callable>,
251
     *     config-builder: ConfigBuilder,
252
     *     suffix-types-builder: SuffixTypesBuilder,
253
     *     mapping-interfaces-builder: MappingInterfacesBuilder,
254
     *     should-reset-in-memory-cache: bool,
255
     *     file-cache-enabled: bool,
256
     *     file-cache-directory: string,
257
     *     project-namespaces: list<string>,
258
     *     config-key-values: array<string,mixed>,
259
     *     are-event-listeners-enabled: bool,
260
     *     listeners-per-event: array<class-string,list<callable>>,
261
     * }
262
     */
263 50
    public function build(): array
264
    {
265
        return [
266 50
            'external-services' => $this->externalServices,
267 50
            'config-builder' => $this->configBuilder,
268 50
            'suffix-types-builder' => $this->suffixTypesBuilder,
269 50
            'mapping-interfaces-builder' => $this->mappingInterfacesBuilder,
270 50
            'should-reset-in-memory-cache' => $this->shouldResetInMemoryCache,
271 50
            'file-cache-enabled' => $this->fileCacheEnabled,
272 50
            'file-cache-directory' => $this->fileCacheDirectory,
273 50
            'project-namespaces' => $this->projectNamespaces,
274 50
            'config-key-values' => $this->configKeyValues,
275 50
            'are-event-listeners-enabled' => $this->areEventListenersEnabled,
276 50
            'listeners-per-event' => $this->listenersPerEvent,
277
        ];
278
    }
279
}
280