Valkyrja   A
last analyzed

Complexity

Total Complexity 35

Size/Duplication

Total Lines 335
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 35
eloc 97
dl 0
loc 335
rs 9.6
c 0
b 0
f 0

24 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 12 2
A addComponent() 0 15 2
A addComponentContainerAliases() 0 5 1
A setEnv() 0 7 1
A bootstrapOptionalComponents() 0 7 2
A bootstrapComponents() 0 6 1
A bootstrapRequiredComponents() 0 7 2
A addComponentEventListeners() 0 6 2
A bootstrapData() 0 3 1
A getContainer() 0 4 1
A getVersion() 0 7 1
A bootstrapCoreComponents() 0 7 2
A addComponentContainerProviders() 0 5 1
A getEnv() 0 4 1
A getDebugMode() 0 7 1
A getEnvironment() 0 7 1
A bootstrapCustomComponents() 0 7 2
A bootstrapServices() 0 22 3
A setContainer() 0 6 1
A addComponentContainerServices() 0 5 1
A addComponentHttpControllers() 0 6 2
A addComponentCliControllers() 0 6 2
A bootstrapTimezone() 0 6 1
A bootstrapConfig() 0 5 1
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Valkyrja Framework package.
7
 *
8
 * (c) Melech Mizrachi <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Valkyrja\Application\Kernel;
15
16
use Override;
0 ignored issues
show
Bug introduced by
The type Override was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
17
use Valkyrja\Application\Data\Config;
18
use Valkyrja\Application\Data\Data;
19
use Valkyrja\Application\Env\Env;
0 ignored issues
show
Bug introduced by
The type Valkyrja\Application\Env\Env was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
20
use Valkyrja\Application\Kernel\Contract\ApplicationContract;
0 ignored issues
show
Bug introduced by
The type Valkyrja\Application\Ker...act\ApplicationContract was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
21
use Valkyrja\Application\Provider\Provider;
22
use Valkyrja\Application\Throwable\Exception\RuntimeException;
23
use Valkyrja\Cli\Routing\Data\Data as CliData;
24
use Valkyrja\Container\Data\Data as ContainerData;
25
use Valkyrja\Container\Manager\Contract\ContainerContract;
26
use Valkyrja\Event\Data\Data as EventData;
27
use Valkyrja\Http\Routing\Data\Data as HttpData;
28
29
class Valkyrja implements ApplicationContract
30
{
31
    /**
32
     * Application env.
33
     */
34
    protected Env $env;
35
36
    /**
37
     * Application config.
38
     */
39
    protected Config|null $config = null;
40
41
    /**
42
     * Application data.
43
     */
44
    protected Data|null $data = null;
45
46
    /**
47
     * Get the instance of the container.
48
     */
49
    protected ContainerContract $container;
50
51
    public function __construct(ContainerContract $container, Env $env, Config|Data $configData = new Config())
52
    {
53
        $this->setEnv(env: $env);
54
        $this->setContainer($container);
55
56
        if ($configData instanceof Config) {
57
            $this->bootstrapConfig(config: $configData);
58
        } else {
59
            $this->bootstrapData(data: $configData);
60
        }
61
62
        $this->bootstrapServices();
63
    }
64
65
    /**
66
     * @inheritDoc
67
     */
68
    #[Override]
69
    public function addComponent(string $component): void
70
    {
71
        if ($this->config === null) {
72
            throw new RuntimeException('Cannot add components to an app setup with Data');
73
        }
74
75
        $config = $this->config;
76
77
        $this->addComponentContainerAliases($config, $component);
78
        $this->addComponentContainerServices($config, $component);
79
        $this->addComponentContainerProviders($component);
80
        $this->addComponentEventListeners($config, $component);
81
        $this->addComponentCliControllers($config, $component);
82
        $this->addComponentHttpControllers($config, $component);
83
    }
84
85
    /**
86
     * @inheritDoc
87
     */
88
    #[Override]
89
    public function getEnv(): Env
90
    {
91
        return $this->env;
92
    }
93
94
    /**
95
     * @inheritDoc
96
     */
97
    #[Override]
98
    public function setEnv(Env $env): void
99
    {
100
        // Set the env class to use
101
        $this->env = $env;
102
103
        $this->bootstrapTimezone();
104
    }
105
106
    /**
107
     * @inheritDoc
108
     */
109
    #[Override]
110
    public function getContainer(): ContainerContract
111
    {
112
        return $this->container;
113
    }
114
115
    /**
116
     * @inheritDoc
117
     */
118
    #[Override]
119
    public function setContainer(ContainerContract $container): static
120
    {
121
        $this->container = $container;
122
123
        return $this;
124
    }
125
126
    /**
127
     * @inheritDoc
128
     */
129
    #[Override]
130
    public function getDebugMode(): bool
131
    {
132
        /** @var bool $debugMode */
133
        $debugMode = $this->env::APP_DEBUG_MODE;
134
135
        return $debugMode;
136
    }
137
138
    /**
139
     * @inheritDoc
140
     */
141
    #[Override]
142
    public function getEnvironment(): string
143
    {
144
        /** @var non-empty-string $env */
145
        $env = $this->env::APP_ENV;
146
147
        return $env;
148
    }
149
150
    /**
151
     * @inheritDoc
152
     */
153
    #[Override]
154
    public function getVersion(): string
155
    {
156
        /** @var non-empty-string $version */
157
        $version = $this->env::APP_VERSION;
158
159
        return $version;
160
    }
161
162
    /**
163
     * Bootstrap the config.
164
     */
165
    protected function bootstrapConfig(Config $config): void
166
    {
167
        $this->config = $config;
168
169
        $this->bootstrapComponents();
170
    }
171
172
    /**
173
     * Bootstrap all the components types for the application.
174
     */
175
    protected function bootstrapComponents(): void
176
    {
177
        $this->bootstrapRequiredComponents();
178
        $this->bootstrapCoreComponents();
179
        $this->bootstrapOptionalComponents();
180
        $this->bootstrapCustomComponents();
181
    }
182
183
    /**
184
     * Bootstrap all the required components for the application to run.
185
     */
186
    protected function bootstrapRequiredComponents(): void
187
    {
188
        /** @var class-string<Provider>[] $components */
189
        $components = $this->env::APP_REQUIRED_COMPONENTS;
190
191
        foreach ($components as $component) {
192
            $this->addComponent(component: $component);
193
        }
194
    }
195
196
    /**
197
     * Bootstrap all the core components to run specific parts of the application.
198
     */
199
    protected function bootstrapCoreComponents(): void
200
    {
201
        /** @var class-string<Provider>[] $components */
202
        $components = $this->env::APP_CORE_COMPONENTS;
203
204
        foreach ($components as $component) {
205
            $this->addComponent(component: $component);
206
        }
207
    }
208
209
    /**
210
     * Bootstrap all the optional components.
211
     */
212
    protected function bootstrapOptionalComponents(): void
213
    {
214
        /** @var class-string<Provider>[] $components */
215
        $components = $this->env::APP_COMPONENTS;
216
217
        foreach ($components as $component) {
218
            $this->addComponent(component: $component);
219
        }
220
    }
221
222
    /**
223
     * Bootstrap all the custom components.
224
     */
225
    protected function bootstrapCustomComponents(): void
226
    {
227
        /** @var class-string<Provider>[] $components */
228
        $components = $this->env::APP_CUSTOM_COMPONENTS;
229
230
        foreach ($components as $component) {
231
            $this->addComponent(component: $component);
232
        }
233
    }
234
235
    /**
236
     * Add a component's container aliases.
237
     *
238
     * @param class-string<Provider> $component The component class
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<Provider> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<Provider>.
Loading history...
239
     */
240
    protected function addComponentContainerAliases(Config $config, string $component): void
241
    {
242
        $config->aliases = [
243
            ...$config->aliases,
244
            ...$component::getContainerAliases(),
245
        ];
246
    }
247
248
    /**
249
     * Add a component's container services.
250
     *
251
     * @param class-string<Provider> $component The component class
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<Provider> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<Provider>.
Loading history...
252
     */
253
    protected function addComponentContainerServices(Config $config, string $component): void
254
    {
255
        $config->services = [
256
            ...$config->services,
257
            ...$component::getContainerServices(),
258
        ];
259
    }
260
261
    /**
262
     * Add a component's container services.
263
     *
264
     * @param class-string<Provider> $component The component class
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<Provider> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<Provider>.
Loading history...
265
     */
266
    protected function addComponentContainerProviders(string $component): void
267
    {
268
        array_map(
269
            [$this->container, 'register'],
270
            $component::getContainerProviders(),
271
        );
272
    }
273
274
    /**
275
     * Add a component's event listeners.
276
     *
277
     * @param class-string<Provider> $component The component class
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<Provider> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<Provider>.
Loading history...
278
     */
279
    protected function addComponentEventListeners(Config $config, string $component): void
280
    {
281
        if ($this->env::APP_ADD_EVENT_LISTENERS) {
282
            $config->listeners = [
283
                ...$config->listeners,
284
                ...$component::getEventListeners(),
285
            ];
286
        }
287
    }
288
289
    /**
290
     * Add a component's cli controllers.
291
     *
292
     * @param class-string<Provider> $component The component class
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<Provider> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<Provider>.
Loading history...
293
     */
294
    protected function addComponentCliControllers(Config $config, string $component): void
295
    {
296
        if ($this->env::APP_ADD_CLI_CONTROLLERS) {
297
            $config->commands = [
298
                ...$config->commands,
299
                ...$component::getCliControllers(),
300
            ];
301
        }
302
    }
303
304
    /**
305
     * Add a component's http controllers.
306
     *
307
     * @param class-string<Provider> $component The component class
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<Provider> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<Provider>.
Loading history...
308
     */
309
    protected function addComponentHttpControllers(Config $config, string $component): void
310
    {
311
        if ($this->env::APP_ADD_HTTP_CONTROLLERS) {
312
            $config->controllers = [
313
                ...$config->controllers,
314
                ...$component::getHttpControllers(),
315
            ];
316
        }
317
    }
318
319
    /**
320
     * Bootstrap the data.
321
     */
322
    protected function bootstrapData(Data $data): void
323
    {
324
        $this->data = $data;
325
    }
326
327
    /**
328
     * Bootstrap container services.
329
     */
330
    protected function bootstrapServices(): void
331
    {
332
        $container = $this->container;
333
334
        $container->setSingleton(ApplicationContract::class, $this);
335
        $container->setSingleton(Env::class, $this->env);
336
        $container->setSingleton(ContainerContract::class, $container);
337
338
        if ($this->data !== null) {
339
            $container->setSingleton(ContainerData::class, $this->data->container);
340
            $container->setSingleton(EventData::class, $this->data->event);
341
            $container->setSingleton(CliData::class, $this->data->cli);
342
            $container->setSingleton(HttpData::class, $this->data->http);
343
344
            $container->setFromData($this->data->container);
345
        }
346
347
        if ($this->config !== null) {
348
            $container->setSingleton(Config::class, $this->config);
349
350
            $data = $container->getSingleton(ContainerData::class);
351
            $container->setFromData($data);
352
        }
353
    }
354
355
    /**
356
     * Bootstrap the timezone.
357
     */
358
    protected function bootstrapTimezone(): void
359
    {
360
        /** @var non-empty-string $timezone */
361
        $timezone = $this->env::APP_TIMEZONE;
362
363
        date_default_timezone_set($timezone);
364
    }
365
}
366