Completed
Push — master ( 866487...6bcace )
by Dorian
04:50
created

Kernel::getPublicDir()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
namespace Gnutix\Kernel;
4
5
use Symfony\Bundle\TwigBundle\DependencyInjection\Compiler\TwigEnvironmentPass as SymfonyTwigEnvironmentPass;
6
use Symfony\Component\Config\FileLocator;
7
use Symfony\Component\Config\Loader\LoaderInterface;
8
use Symfony\Component\DependencyInjection\ContainerBuilder;
9
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
10
use Symfony\Component\HttpKernel\HttpKernelInterface;
11
12
/**
13
 * Kernel
14
 */
15
abstract class Kernel implements HttpKernelInterface
16
{
17
    /** @var string */
18
    protected $projectDir;
19
20
    /** @var string */
21
    protected $environment;
22
23
    /** @var bool */
24
    protected $debug;
25
26
    /** @var \Symfony\Component\DependencyInjection\ContainerInterface */
27
    protected $container;
28
29
    /**
30
     * @param string $environment
31
     * @param bool   $debug
32
     */
33
    public function __construct($environment = 'prod', $debug = false)
34
    {
35
        $this->environment = $environment;
36
        $this->debug = $debug;
37
38
        $this->initializeContainer();
39
    }
40
41
    /**
42
     * @return \Symfony\Component\DependencyInjection\ContainerInterface
43
     */
44
    public function getContainer()
45
    {
46
        return $this->container;
47
    }
48
49
    /**
50
     * @return string
51
     */
52
    protected function getEnvironment()
53
    {
54
        return $this->environment;
55
    }
56
57
    /**
58
     * @return bool
59
     */
60
    protected function getDebug()
61
    {
62
        return $this->debug;
63
    }
64
65
    /**
66
     * @return string
67
     */
68
    protected function getApplicationRootDir()
69
    {
70
        if (null === $this->projectDir) {
71
            $r = new \ReflectionObject($this);
72
73
            if (!file_exists($dir = $r->getFileName())) {
74
                throw new \LogicException(sprintf(
75
                    'Cannot auto-detect project dir for kernel of class "%s".',
76
                    $r->name
77
                ));
78
            }
79
80
            $dir = $rootDir = \dirname($dir);
81
            while (!file_exists($dir.'/composer.json')) {
82
                if ($dir === \dirname($dir)) {
83
                    return $this->projectDir = $rootDir;
84
                }
85
                $dir = \dirname($dir);
86
            }
87
            $this->projectDir = $dir;
88
        }
89
90
        return $this->projectDir;
91
    }
92
93
    /**
94
     * @return string
95
     */
96
    protected function getConfigDir()
97
    {
98
        return $this->getApplicationRootDir().'/config';
99
    }
100
101
    /**
102
     * @return string
103
     */
104
    protected function getCacheDir()
105
    {
106
        return $this->getApplicationRootDir().'/var/cache/'.$this->getEnvironment();
107
    }
108
109
    /**
110
     * @return string
111
     */
112
    protected function getPublicDir()
113
    {
114
        return $this->getApplicationRootDir().'/public';
115
    }
116
117
    /**
118
     * @return string
119
     */
120
    protected function getCharset()
121
    {
122
        return 'utf-8';
123
    }
124
125
    /**
126
     * @return string
127
     */
128
    protected function getConfigFilesExtension()
129
    {
130
        return 'yml';
131
    }
132
133
    /**
134
     * @return \Symfony\Component\Config\Loader\LoaderInterface
135
     */
136
    protected function getConfigFilesLoader(ContainerBuilder $container)
137
    {
138
        return new YamlFileLoader($container, new FileLocator($this->getConfigDir()));
139
    }
140
141
    protected function addKernelParameters(ContainerBuilder $container): void
142
    {
143
        // Folder paths
144
        $container->setParameter('kernel.project_dir', $this->getApplicationRootDir());
145
        $container->setParameter('kernel.public_dir', $this->getPublicDir());
146
        $container->setParameter('kernel.cache_dir', $this->getCacheDir());
147
148
        // Configurations
149
        $container->setParameter('kernel.environment', $this->getEnvironment());
150
        $container->setParameter('kernel.debug', $this->getDebug());
151
        $container->setParameter('kernel.charset', $this->getCharset());
152
    }
153
154
    /**
155
     * Create the container
156
     */
157
    protected function initializeContainer(): void
158
    {
159
        // Create the container builder
160
        $container = new ContainerBuilder();
161
        $this->addKernelParameters($container);
162
163
        // Create a loader for the configuration files
164
        $configLoader = $this->getConfigFilesLoader($container);
165
        $configExtension = $this->getConfigFilesExtension();
166
167
        // Register the extensions before loading the configuration
168
        foreach ($this->getExtensions() as $extension) {
169
            $container->registerExtension($extension);
170
        }
171
172
        // Load the application's configuration files (so that it can configure the extensions)
173
        $this->loadConfigurationFile($configLoader, 'config', $configExtension);
174
175
        // Load the extensions configuration and services files
176
        foreach ($container->getExtensions() as $extension) {
177
            $extension->load($container->getExtensionConfig($extension->getAlias()), $container);
178
        }
179
180
        $container->addCompilerPass(new SymfonyTwigEnvironmentPass());
181
182
        // Load the application's services files (so that it can override the extensions ones)
183
        $this->loadConfigurationFile($configLoader, 'services', $configExtension, false);
184
185
        // Compile everything
186
        $container->compile();
187
188
        // Store the container
189
        $this->container = $container;
190
    }
191
192
    /**
193
     * @param string                                           $fileNamePrefix
194
     * @param string                                           $fileNameExtension
195
     * @param bool                                             $throwException
196
     *
197
     * @throws \InvalidArgumentException
198
     */
199
    protected function loadConfigurationFile(
200
        LoaderInterface $loader,
201
        $fileNamePrefix,
202
        $fileNameExtension,
203
        $throwException = true
204
    ): void {
205
        // Try to load the environment specific configuration files
206
        try {
207
            $loader->load($fileNamePrefix.'_'.$this->getEnvironment().'.'.$fileNameExtension);
208
        } catch (\InvalidArgumentException $e) {
209
            // Try to load the environment agnostic configuration file
210
            try {
211
                $loader->load($fileNamePrefix.'.'.$fileNameExtension);
212
            } catch (\InvalidArgumentException $e) {
213
                // If the application can't work without this file, we throw the exception
214
                if ($throwException) {
215
                    throw $e;
216
                }
217
            }
218
        }
219
    }
220
221
    /**
222
     * @return \Symfony\Component\DependencyInjection\Extension\ExtensionInterface[]
223
     */
224
    protected function getExtensions()
225
    {
226
        return [];
227
    }
228
}
229