Kernel::loadExtensions()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 3.0123

Importance

Changes 0
Metric Value
eloc 8
c 0
b 0
f 0
dl 0
loc 14
ccs 8
cts 9
cp 0.8889
rs 10
cc 3
nc 3
nop 0
crap 3.0123
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Thunder micro CLI framework.
7
 * (c) Jérémy Marodon <[email protected]>
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace RxThunder\Core\Kernel;
13
14
use RxThunder\Core\Kernel\Exception\KernelNotBootedException;
15
use Symfony\Component\Config\FileLocator;
16
use Symfony\Component\DependencyInjection\ContainerBuilder;
17
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
18
use Symfony\Component\Dotenv\Dotenv;
19
20
class Kernel implements KernelInterface
21
{
22
    public const NAME            = 'Thunder';
23
    public const VERSION         = '1.1.0';
24
    public const VERSION_ID      = 10100;
25
    public const MAJOR_VERSION   = 1;
26
    public const MINOR_VERSION   = 1;
27
    public const RELEASE_VERSION = 0;
28
    public const EXTRA_VERSION   = '';
29
30
    protected string $environment;
31
    protected ContainerBuilder $container;
32
    protected bool $booted = false;
33
    protected bool $debug;
34
    protected string $project_dir;
35
36 5
    public function __construct(string $environment, bool $debug = false)
37
    {
38 5
        $this->environment = $environment;
39 5
        $this->debug       = $debug;
40 5
        $this->project_dir = $this->initiateProjectDir();
41 5
        $this->container   = new ContainerBuilder();
42 5
    }
43
44 2
    public function boot(): void
45
    {
46 2
        if ($this->booted) {
47 1
            return;
48
        }
49
50 2
        $this->initializeContainer();
51
52 2
        $this->booted = true;
53 2
    }
54
55 2
    protected function initializeContainer(): void
56
    {
57 2
        $this->loadEnvironment();
58 2
        $this->loadExtensions();
59 2
        $this->loadDefinitions();
60
61 2
        $this->container->compile();
62 2
    }
63
64 2
    protected function loadEnvironment(): void
65
    {
66 2
        (new Dotenv())->populate(['APP_ENV' => $this->getEnvironment()]);
67 2
        (new Dotenv())->loadEnv($this->getProjectDir() . '/.env');
68 2
    }
69
70 2
    protected function loadDefinitions(): void
71
    {
72 2
        $this->container->setParameter('thunder.environment', $this->getEnvironment());
73 2
        $this->container->setParameter('thunder.debug', $this->debugActivated());
74 2
        $this->container->setParameter('thunder.project_dir', $this->getProjectDir());
75 2
        $this->container->setParameter('thunder.config_dir', $this->getConfigDir());
76
77
        $internal_loader =
78 2
            new PhpFileLoader(
79 2
                $this->container,
80 2
                new FileLocator(__DIR__ . '/../../config')
81
            );
82
83
        $personal_loader =
84 2
            new PhpFileLoader(
85 2
                $this->container,
86 2
                new FileLocator($this->getConfigDir())
87
            );
88
89 2
        $internal_loader->load('console.php');
90 2
        $internal_loader->load('container.php');
91 2
        $internal_loader->load('router.php');
92 2
        $internal_loader->load('logger.php');
93
94 2
        $personal_loader->load('parameters.php');
95 2
        $personal_loader->load('services.php');
96 2
    }
97
98 2
    protected function loadExtensions(): void
99
    {
100 2
        $extension_file_path = $this->getConfigDir() . '/extensions.php';
101 2
        if (!file_exists($extension_file_path)) {
102
            return;
103
        }
104
105
        /** @var array<class-string> $extensions */
106 2
        $extensions = require $extension_file_path;
107
108 2
        foreach ($extensions as $extension) {
109 2
            $extension = new $extension();
110 2
            $this->container->registerExtension($extension);
111 2
            $this->container->loadFromExtension($extension->getAlias());
112
        }
113 2
    }
114
115 5
    protected function initiateProjectDir(): string
116
    {
117 5
        if (isset($this->project_dir)) {
118 1
            throw new \LogicException('Project directory is already defined');
119
        }
120
121 5
        $reflected = new \ReflectionObject($this);
122 5
        if (!$dir = $reflected->getFileName()) {
123
            throw new \LogicException(sprintf('Cannot get filename of class "%s".', $reflected->name));
124
        }
125
126 5
        if (!file_exists($dir)) {
127
            throw new \LogicException(sprintf('File of class donʼt exists "%s".', $reflected->name));
128
        }
129
130 5
        $dir = $root_dir = \dirname($dir);
131 5
        while (!file_exists($dir . '/composer.lock')) {
132 5
            if ($dir === \dirname($dir)) {
133
                return $root_dir;
134
            }
135
136 5
            $dir = \dirname($dir);
137
        }
138
139 5
        return $dir;
140
    }
141
142 1
    public function getProjectDir(): string
143
    {
144 1
        return $this->project_dir;
145
    }
146
147 1
    public function getConfigDir(): string
148
    {
149 1
        return $this->project_dir . '/config';
150
    }
151
152 2
    public function getEnvironment(): string
153
    {
154 2
        return $this->environment;
155
    }
156
157
    /**
158
     * @throws KernelNotBootedException
159
     */
160 2
    public function getContainer(): ContainerBuilder
161
    {
162 2
        if (!$this->booted) {
163 1
            throw new KernelNotBootedException();
0 ignored issues
show
Deprecated Code introduced by
The class RxThunder\Core\Kernel\Ex...ernelNotBootedException has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

163
            throw /** @scrutinizer ignore-deprecated */ new KernelNotBootedException();
Loading history...
164
        }
165
166 1
        return $this->container;
167
    }
168
169 2
    public function debugActivated(): bool
170
    {
171 2
        return $this->debug;
172
    }
173
174 1
    public function booted(): bool
175
    {
176 1
        return $this->booted;
177
    }
178
}
179