Passed
Branch master (609f2f)
by Dorian
08:59
created

Kernel::initializeContainer()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 33
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 13
c 0
b 0
f 0
nc 4
nop 0
dl 0
loc 33
rs 9.8333
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Gnutix\Kernel;
6
7
use Symfony\Component\Config\FileLocator;
8
use Symfony\Component\Config\Loader\LoaderInterface;
9
use Symfony\Component\DependencyInjection\ContainerBuilder;
10
use Symfony\Component\DependencyInjection\ContainerInterface;
11
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
12
use Symfony\Component\HttpKernel\HttpKernelInterface;
13
use Webmozart\Assert\Assert;
14
15
abstract class Kernel implements HttpKernelInterface
16
{
17
    private ?string $projectDir = null;
18
    private string $environment;
19
    private bool $debug;
20
    private ContainerInterface $container;
21
22
    public function __construct(string $environment = 'prod', bool $debug = false)
23
    {
24
        $this->environment = $environment;
25
        $this->debug = $debug;
26
27
        $this->initializeContainer();
28
    }
29
30
    public function getContainer(): ContainerInterface
31
    {
32
        return $this->container;
33
    }
34
35
    protected function getEnvironment(): string
36
    {
37
        return $this->environment;
38
    }
39
40
    protected function getDebug(): bool
41
    {
42
        return $this->debug;
43
    }
44
45
    protected function getApplicationRootDir(): string
46
    {
47
        if (null === $this->projectDir) {
48
            $r = new \ReflectionObject($this);
49
            /** @var string $dir */
50
            $dir = $r->getFileName();
51
            Assert::fileExists($dir);
52
53
            $dir = $rootDir = \dirname($dir);
54
            while (!file_exists($dir.'/composer.json')) {
55
                if ($dir === \dirname($dir)) {
56
                    return $this->projectDir = $rootDir;
57
                }
58
                $dir = \dirname($dir);
59
            }
60
            $this->projectDir = $dir;
61
        }
62
63
        return $this->projectDir;
64
    }
65
66
    protected function getConfigDir(): string
67
    {
68
        return $this->getApplicationRootDir().'/config';
69
    }
70
71
    protected function getCacheDir(): string
72
    {
73
        return $this->getApplicationRootDir().'/var/cache/'.$this->getEnvironment();
74
    }
75
76
    protected function getPublicDir(): string
77
    {
78
        return $this->getApplicationRootDir().'/public';
79
    }
80
81
    protected function getCharset(): string
82
    {
83
        return 'utf-8';
84
    }
85
86
    protected function getConfigFilesExtension(): string
87
    {
88
        return 'yml';
89
    }
90
91
    /**
92
     * @return \Symfony\Component\Config\Loader\LoaderInterface
93
     */
94
    protected function getConfigFilesLoader(ContainerBuilder $container)
95
    {
96
        return new YamlFileLoader($container, new FileLocator($this->getConfigDir()));
97
    }
98
99
    protected function addKernelParameters(ContainerBuilder $container): void
100
    {
101
        // Folder paths
102
        $container->setParameter('kernel.project_dir', $this->getApplicationRootDir());
103
        $container->setParameter('kernel.public_dir', $this->getPublicDir());
104
        $container->setParameter('kernel.cache_dir', $this->getCacheDir());
105
106
        // Configurations
107
        $container->setParameter('kernel.environment', $this->getEnvironment());
108
        $container->setParameter('kernel.debug', $this->getDebug());
109
        $container->setParameter('kernel.charset', $this->getCharset());
110
    }
111
112
    protected function initializeContainer(): void
113
    {
114
        // Create the container builder
115
        $container = new ContainerBuilder();
116
        $this->addKernelParameters($container);
117
118
        // Create a loader for the configuration files
119
        $configLoader = $this->getConfigFilesLoader($container);
120
        $configExtension = $this->getConfigFilesExtension();
121
122
        // Register the extensions before loading the configuration
123
        foreach ($this->getExtensions() as $extension) {
124
            $container->registerExtension($extension);
125
        }
126
127
        // Load the application's configuration files (so that it can configure the extensions)
128
        $this->loadConfigurationFile($configLoader, 'config', $configExtension);
129
130
        // Load the extensions configuration and services files
131
        foreach ($container->getExtensions() as $extension) {
132
            $extension->load($container->getExtensionConfig($extension->getAlias()), $container);
133
        }
134
135
        $this->addCompilerPasses($container);
136
137
        // Load the application's services files (so that it can override the extensions ones)
138
        $this->loadConfigurationFile($configLoader, 'services', $configExtension, false);
139
140
        // Compile everything
141
        $container->compile();
142
143
        // Store the container
144
        $this->container = $container;
145
    }
146
147
    protected function addCompilerPasses(ContainerBuilder $container): void
1 ignored issue
show
Unused Code introduced by
The parameter $container is not used and could be removed. ( Ignorable by Annotation )

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

147
    protected function addCompilerPasses(/** @scrutinizer ignore-unused */ ContainerBuilder $container): void

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
148
    {
149
    }
150
151
    protected function loadConfigurationFile(
152
        LoaderInterface $loader,
153
        string $fileNamePrefix,
154
        string $fileNameExtension,
155
        bool $throwException = true
156
    ): void {
157
        // Try to load the environment specific configuration files
158
        try {
159
            $loader->load($fileNamePrefix.'_'.$this->getEnvironment().'.'.$fileNameExtension);
160
        } catch (\InvalidArgumentException $e) {
161
            // Try to load the environment agnostic configuration file
162
            try {
163
                $loader->load($fileNamePrefix.'.'.$fileNameExtension);
164
            } catch (\InvalidArgumentException $e) {
165
                // If the application can't work without this file, we throw the exception
166
                if ($throwException) {
167
                    throw $e;
168
                }
169
            }
170
        }
171
    }
172
173
    /**
174
     * @return \Symfony\Component\DependencyInjection\Extension\ExtensionInterface[]
175
     */
176
    protected function getExtensions(): array
177
    {
178
        return [];
179
    }
180
}
181