Passed
Pull Request — master (#41)
by Thomas
04:16
created

DebugKernel::attachSynthetic()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 1
dl 0
loc 7
ccs 0
cts 4
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the ekino Drupal Debug project.
7
 *
8
 * (c) ekino
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 Ekino\Drupal\Debug\Kernel;
15
16
use Drupal\Core\DependencyInjection\ContainerBuilder;
17
use Drupal\Core\DrupalKernelInterface;
18
use Drupal\Core\OriginalDrupalKernel;
19
use Ekino\Drupal\Debug\Action\ActionManager;
20
use Ekino\Drupal\Debug\Kernel\Event\AfterAttachSyntheticEvent;
21
use Ekino\Drupal\Debug\Kernel\Event\AfterContainerInitializationEvent;
22
use Ekino\Drupal\Debug\Kernel\Event\AfterRequestPreHandleEvent;
23
use Ekino\Drupal\Debug\Kernel\Event\AfterSettingsInitializationEvent;
24
use Ekino\Drupal\Debug\Kernel\Event\DebugKernelEvents;
25
use Ekino\Drupal\Debug\Option\OptionsStack;
26
use Symfony\Component\DependencyInjection\ContainerInterface;
27
use Symfony\Component\EventDispatcher\EventDispatcher;
28
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
29
use Symfony\Component\HttpFoundation\Request;
30
31
class DebugKernel extends OriginalDrupalKernel
32
{
33
    /**
34
     * @var EventDispatcher
35
     */
36
    private $eventDispatcher;
37
38
    /**
39
     * @var ActionManager
40
     */
41
    private $actionManager;
42
43
    /**
44
     * @var array
45
     */
46
    private $enabledModules;
47
48
    /**
49
     * @var array
50
     */
51
    private $enabledThemes;
52
53
    /**
54
     * @var bool
55
     */
56
    private $settingsWereInitializedWithTheDedicatedDrupalKernelMethod;
57
58
    /**
59
     * @param string            $environment
60
     * @param object            $classLoader
61
     * @param bool              $allowDumping
62
     * @param string|null       $appRoot
63
     * @param OptionsStack|null $optionsStack
64
     */
65
    public function __construct($environment, $classLoader, $allowDumping = true, $appRoot = null, OptionsStack $optionsStack = null)
66
    {
67
        $this->eventDispatcher = $this->getEventDispatcher();
68
69
        if (!\is_string($appRoot)) {
70
            $appRoot = static::guessApplicationRoot();
71
        }
72
73
        $this->actionManager = $this->getActionManager($appRoot, $optionsStack instanceof OptionsStack ? $optionsStack : OptionsStack::create());
74
75
        $this->actionManager->addEventSubscriberActionsToEventDispatcher($this->eventDispatcher);
76
77
        $this->eventDispatcher->dispatch(DebugKernelEvents::ON_KERNEL_INSTANTIATION);
78
79
        static::bootEnvironment();
80
81
        $this->eventDispatcher->dispatch(DebugKernelEvents::AFTER_ENVIRONMENT_BOOT);
82
83
        $this->enabledModules = array();
84
        $this->enabledThemes = array();
85
        $this->settingsWereInitializedWithTheDedicatedDrupalKernelMethod = false;
86
87
        parent::__construct($environment, $classLoader, $allowDumping, $appRoot);
88
    }
89
90
    /**
91
     * @return DebugKernel
92
     */
93
    public function boot()
94
    {
95
        // The kernel cannot be booted without settings.
96
        //
97
        // If the kernel is going to be booted, but that the
98
        // initializeSettings() method was never called, it means that the
99
        // settings were initialized in another way. If it is not the case, the
100
        // booting is going to fail anyway.
101
        //
102
        // Whatever... Since the settings were not initialized in the traditional
103
        // way, the things we want to do after the settings initialization
104
        // were not done. So we do them now.
105
        if (!$this->settingsWereInitializedWithTheDedicatedDrupalKernelMethod) {
106
            $this->afterSettingsInitialization();
107
        }
108
109
        return parent::boot();
110
    }
111
112
    /**
113
     * {@inheritdoc}
114
     */
115
    public function preHandle(Request $request)
116
    {
117
        parent::preHandle($request);
118
119
        $this->eventDispatcher->dispatch(DebugKernelEvents::AFTER_REQUEST_PRE_HANDLE, new AfterRequestPreHandleEvent($this->container, $this->enabledModules, $this->enabledThemes));
120
    }
121
122
    /**
123
     * {@inheritdoc}
124
     */
125
    protected function getKernelParameters()
126
    {
127
        return \array_merge(parent::getKernelParameters(), array(
128
            'kernel.debug' => true,
129
        ));
130
    }
131
132
    /**
133
     * {@inheritdoc}
134
     */
135
    protected function initializeContainer()
136
    {
137
        $container = parent::initializeContainer();
138
139
        $this->eventDispatcher->dispatch(DebugKernelEvents::AFTER_CONTAINER_INITIALIZATION, new AfterContainerInitializationEvent($container, $this->enabledModules, $this->enabledThemes));
140
141
        return $container;
142
    }
143
144
    /**
145
     * {@inheritdoc}
146
     */
147
    protected function initializeSettings(Request $request)
148
    {
149
        parent::initializeSettings($request);
150
151
        $this->settingsWereInitializedWithTheDedicatedDrupalKernelMethod = true;
152
153
        $this->afterSettingsInitialization();
154
    }
155
156
    /**
157
     * {@inheritdoc}
158
     */
159
    protected function attachSynthetic(ContainerInterface $container)
160
    {
161
        $container = parent::attachSynthetic($container);
162
163
        $this->eventDispatcher->dispatch(DebugKernelEvents::AFTER_ATTACH_SYNTHETIC, new AfterAttachSyntheticEvent($container, $this->enabledModules, $this->enabledThemes));
164
165
        return $container;
166
    }
167
168
    /**
169
     * {@inheritdoc}
170
     */
171
    protected function getContainerBuilder()
172
    {
173
        $containerBuilder = parent::getContainerBuilder();
174
175
        $this->actionManager->addCompilerPassActionsToContainerBuilder($containerBuilder);
176
177
        return $containerBuilder;
178
    }
179
180
    /**
181
     * @return EventDispatcher
182
     */
183
    protected function getEventDispatcher(): EventDispatcherInterface
184
    {
185
        return new EventDispatcher();
186
    }
187
188
    /**
189
     * @param string       $appRoot
190
     * @param OptionsStack $optionsStack
191
     *
192
     * @return ActionManager
193
     */
194
    protected function getActionManager(string $appRoot, OptionsStack $optionsStack): ActionManager
195
    {
196
        return new ActionManager($appRoot, $optionsStack);
197
    }
198
199
    private function afterSettingsInitialization(): void
200
    {
201
        $coreExtensionConfig = $this->getConfigStorage()->read('core.extension');
202
        if (isset($coreExtensionConfig['module'])) {
203
            $this->enabledModules = \array_keys($coreExtensionConfig['module']);
204
        }
205
206
        if (isset($coreExtensionConfig['theme'])) {
207
            $this->enabledThemes = \array_keys($coreExtensionConfig['theme']);
208
        }
209
210
        $this->eventDispatcher->dispatch(DebugKernelEvents::AFTER_SETTINGS_INITIALIZATION, new AfterSettingsInitializationEvent($this->enabledModules, $this->enabledThemes));
211
    }
212
}
213