|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
/* |
|
4
|
|
|
* This file is part of the SymfonyExtension package. |
|
5
|
|
|
* |
|
6
|
|
|
* (c) Kamil Kokot <[email protected]> |
|
7
|
|
|
* |
|
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 FriendsOfBehat\SymfonyExtension\ServiceContainer; |
|
13
|
|
|
|
|
14
|
|
|
use Behat\MinkExtension\ServiceContainer\MinkExtension; |
|
15
|
|
|
use Behat\Testwork\EventDispatcher\ServiceContainer\EventDispatcherExtension; |
|
16
|
|
|
use Behat\Testwork\ServiceContainer\Exception\ProcessingException; |
|
17
|
|
|
use Behat\Testwork\ServiceContainer\Extension; |
|
18
|
|
|
use Behat\Testwork\ServiceContainer\ExtensionManager; |
|
19
|
|
|
use FriendsOfBehat\SymfonyExtension\Driver\Factory\SymfonyDriverFactory; |
|
20
|
|
|
use FriendsOfBehat\SymfonyExtension\Listener\KernelRebooter; |
|
21
|
|
|
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; |
|
22
|
|
|
use Symfony\Component\DependencyInjection\Container; |
|
23
|
|
|
use Symfony\Component\DependencyInjection\ContainerBuilder; |
|
24
|
|
|
use Symfony\Component\DependencyInjection\Definition; |
|
25
|
|
|
use Symfony\Component\DependencyInjection\Reference; |
|
26
|
|
|
|
|
27
|
|
|
final class SymfonyExtension implements Extension |
|
28
|
|
|
{ |
|
29
|
|
|
/** |
|
30
|
|
|
* Kernel used inside Behat contexts or to create services injected to them. |
|
31
|
|
|
* Container is built before every scenario. |
|
32
|
|
|
*/ |
|
33
|
|
|
const KERNEL_ID = 'sylius_symfony_extension.kernel'; |
|
34
|
|
|
|
|
35
|
|
|
/** |
|
36
|
|
|
* The current container used in scenario contexts. |
|
37
|
|
|
* To be used as a factory for current injected application services. |
|
38
|
|
|
*/ |
|
39
|
|
|
const KERNEL_CONTAINER_ID = 'sylius_symfony_extension.kernel.container'; |
|
40
|
|
|
|
|
41
|
|
|
/** |
|
42
|
|
|
* Kernel used by Symfony2 driver to isolate web container from contexts' container. |
|
43
|
|
|
* Container is built before every request. |
|
44
|
|
|
*/ |
|
45
|
|
|
const DRIVER_KERNEL_ID = 'sylius_symfony_extension.driver_kernel'; |
|
46
|
|
|
|
|
47
|
|
|
/** |
|
48
|
|
|
* Kernel that should be used by extensions only. |
|
49
|
|
|
* Container is built only once at the first use. |
|
50
|
|
|
*/ |
|
51
|
|
|
const SHARED_KERNEL_ID = 'sylius_symfony_extension.shared_kernel'; |
|
52
|
|
|
|
|
53
|
|
|
/** |
|
54
|
|
|
* The only container built by shared kernel. |
|
55
|
|
|
* To be used as a factory for shared injected application services. |
|
56
|
|
|
*/ |
|
57
|
|
|
const SHARED_KERNEL_CONTAINER_ID = 'sylius_symfony_extension.shared_kernel.container'; |
|
58
|
|
|
|
|
59
|
|
|
/** |
|
60
|
|
|
* {@inheritdoc} |
|
61
|
|
|
*/ |
|
62
|
|
|
public function getConfigKey() |
|
63
|
|
|
{ |
|
64
|
|
|
return 'fob_symfony'; |
|
65
|
|
|
} |
|
66
|
|
|
|
|
67
|
|
|
/** |
|
68
|
|
|
* {@inheritdoc} |
|
69
|
|
|
*/ |
|
70
|
|
|
public function initialize(ExtensionManager $extensionManager) |
|
71
|
|
|
{ |
|
72
|
|
|
$this->registerSymfonyDriverFactory($extensionManager); |
|
73
|
|
|
} |
|
74
|
|
|
|
|
75
|
|
|
/** |
|
76
|
|
|
* {@inheritdoc} |
|
77
|
|
|
*/ |
|
78
|
|
|
public function configure(ArrayNodeDefinition $builder) |
|
79
|
|
|
{ |
|
80
|
|
|
$builder |
|
81
|
|
|
->addDefaultsIfNotSet() |
|
82
|
|
|
->children() |
|
83
|
|
|
->arrayNode('kernel') |
|
84
|
|
|
->addDefaultsIfNotSet() |
|
85
|
|
|
->children() |
|
86
|
|
|
->scalarNode('bootstrap')->defaultValue('app/autoload.php')->end() |
|
87
|
|
|
->scalarNode('path')->defaultValue('app/AppKernel.php')->end() |
|
88
|
|
|
->scalarNode('class')->defaultValue('AppKernel')->end() |
|
89
|
|
|
->scalarNode('env')->defaultValue('test')->end() |
|
90
|
|
|
->booleanNode('debug')->defaultTrue()->end() |
|
91
|
|
|
; |
|
92
|
|
|
} |
|
93
|
|
|
|
|
94
|
|
|
/** |
|
95
|
|
|
* {@inheritdoc} |
|
96
|
|
|
*/ |
|
97
|
|
|
public function load(ContainerBuilder $container, array $config) |
|
98
|
|
|
{ |
|
99
|
|
|
$this->loadKernel($container, $config['kernel']); |
|
100
|
|
|
$this->loadKernelContainer($container); |
|
101
|
|
|
|
|
102
|
|
|
$this->loadDriverKernel($container); |
|
103
|
|
|
|
|
104
|
|
|
$this->loadSharedKernel($container); |
|
105
|
|
|
$this->loadSharedKernelContainer($container); |
|
106
|
|
|
|
|
107
|
|
|
$this->loadKernelRebooter($container); |
|
108
|
|
|
} |
|
109
|
|
|
|
|
110
|
|
|
/** |
|
111
|
|
|
* {@inheritdoc} |
|
112
|
|
|
*/ |
|
113
|
|
|
public function process(ContainerBuilder $container) |
|
114
|
|
|
{ |
|
115
|
|
|
} |
|
116
|
|
|
|
|
117
|
|
|
/** |
|
118
|
|
|
* @param ContainerBuilder $container |
|
119
|
|
|
*/ |
|
120
|
|
|
private function loadKernel(ContainerBuilder $container, array $config) |
|
121
|
|
|
{ |
|
122
|
|
|
$definition = new Definition($config['class'], array( |
|
123
|
|
|
$config['env'], |
|
124
|
|
|
$config['debug'], |
|
125
|
|
|
)); |
|
126
|
|
|
$definition->addMethodCall('boot'); |
|
127
|
|
|
$definition->setFile($this->getKernelFile($container->getParameter('paths.base'), $config['path'])); |
|
128
|
|
|
|
|
129
|
|
|
$container->setDefinition(self::KERNEL_ID, $definition); |
|
130
|
|
|
|
|
131
|
|
|
$this->requireKernelBootstrapFile($container->getParameter('paths.base'), $config['bootstrap']); |
|
132
|
|
|
} |
|
133
|
|
|
|
|
134
|
|
|
/** |
|
135
|
|
|
* @param ContainerBuilder $container |
|
136
|
|
|
*/ |
|
137
|
|
View Code Duplication |
private function loadKernelContainer(ContainerBuilder $container) |
|
|
|
|
|
|
138
|
|
|
{ |
|
139
|
|
|
$containerDefinition = new Definition(Container::class); |
|
140
|
|
|
$containerDefinition->setFactory([ |
|
141
|
|
|
new Reference(self::KERNEL_ID), |
|
142
|
|
|
'getContainer', |
|
143
|
|
|
]); |
|
144
|
|
|
|
|
145
|
|
|
$container->setDefinition(self::KERNEL_CONTAINER_ID, $containerDefinition); |
|
146
|
|
|
} |
|
147
|
|
|
|
|
148
|
|
|
/** |
|
149
|
|
|
* @param ContainerBuilder $container |
|
150
|
|
|
*/ |
|
151
|
|
|
private function loadDriverKernel(ContainerBuilder $container) |
|
152
|
|
|
{ |
|
153
|
|
|
$container->setDefinition(self::DRIVER_KERNEL_ID, $container->findDefinition(self::KERNEL_ID)); |
|
154
|
|
|
} |
|
155
|
|
|
|
|
156
|
|
|
/** |
|
157
|
|
|
* @param ContainerBuilder $container |
|
158
|
|
|
*/ |
|
159
|
|
|
private function loadSharedKernel(ContainerBuilder $container) |
|
160
|
|
|
{ |
|
161
|
|
|
$container->setDefinition(self::SHARED_KERNEL_ID, $container->findDefinition(self::KERNEL_ID)); |
|
162
|
|
|
} |
|
163
|
|
|
|
|
164
|
|
|
/** |
|
165
|
|
|
* @param ContainerBuilder $container |
|
166
|
|
|
*/ |
|
167
|
|
View Code Duplication |
private function loadSharedKernelContainer(ContainerBuilder $container) |
|
|
|
|
|
|
168
|
|
|
{ |
|
169
|
|
|
$containerDefinition = new Definition(Container::class); |
|
170
|
|
|
$containerDefinition->setFactory([ |
|
171
|
|
|
new Reference(self::SHARED_KERNEL_ID), |
|
172
|
|
|
'getContainer', |
|
173
|
|
|
]); |
|
174
|
|
|
|
|
175
|
|
|
$container->setDefinition(self::SHARED_KERNEL_CONTAINER_ID, $containerDefinition); |
|
176
|
|
|
} |
|
177
|
|
|
|
|
178
|
|
|
/** |
|
179
|
|
|
* @param ContainerBuilder $container |
|
180
|
|
|
*/ |
|
181
|
|
View Code Duplication |
private function loadKernelRebooter(ContainerBuilder $container) |
|
|
|
|
|
|
182
|
|
|
{ |
|
183
|
|
|
$definition = new Definition(KernelRebooter::class, [new Reference(self::KERNEL_ID)]); |
|
184
|
|
|
$definition->addTag(EventDispatcherExtension::SUBSCRIBER_TAG); |
|
185
|
|
|
|
|
186
|
|
|
$container->setDefinition(self::KERNEL_ID . '.rebooter', $definition); |
|
187
|
|
|
} |
|
188
|
|
|
|
|
189
|
|
|
/** |
|
190
|
|
|
* @param ExtensionManager $extensionManager |
|
191
|
|
|
*/ |
|
192
|
|
|
private function registerSymfonyDriverFactory(ExtensionManager $extensionManager) |
|
193
|
|
|
{ |
|
194
|
|
|
/** @var MinkExtension $minkExtension */ |
|
195
|
|
|
$minkExtension = $extensionManager->getExtension('mink'); |
|
196
|
|
|
if (null === $minkExtension) { |
|
197
|
|
|
return; |
|
198
|
|
|
} |
|
199
|
|
|
|
|
200
|
|
|
$minkExtension->registerDriverFactory(new SymfonyDriverFactory( |
|
201
|
|
|
'symfony', |
|
202
|
|
|
new Reference(self::DRIVER_KERNEL_ID) |
|
203
|
|
|
)); |
|
204
|
|
|
} |
|
205
|
|
|
|
|
206
|
|
|
/** |
|
207
|
|
|
* @param string $basePath |
|
208
|
|
|
* @param string $kernelPath |
|
209
|
|
|
* |
|
210
|
|
|
* @return string|null |
|
211
|
|
|
*/ |
|
212
|
|
|
private function getKernelFile($basePath, $kernelPath) |
|
213
|
|
|
{ |
|
214
|
|
|
$possibleFiles = [ |
|
215
|
|
|
sprintf('%s/%s', $basePath, $kernelPath), |
|
216
|
|
|
$kernelPath, |
|
217
|
|
|
]; |
|
218
|
|
|
|
|
219
|
|
|
foreach ($possibleFiles as $possibleFile) { |
|
220
|
|
|
if (file_exists($possibleFile)) { |
|
221
|
|
|
return $possibleFile; |
|
222
|
|
|
} |
|
223
|
|
|
} |
|
224
|
|
|
|
|
225
|
|
|
return null; |
|
226
|
|
|
} |
|
227
|
|
|
|
|
228
|
|
|
/** |
|
229
|
|
|
* @param string $basePath |
|
230
|
|
|
* @param string|null $bootstrapPath |
|
231
|
|
|
* |
|
232
|
|
|
* @throws \DomainException |
|
233
|
|
|
*/ |
|
234
|
|
|
private function requireKernelBootstrapFile($basePath, $bootstrapPath) |
|
235
|
|
|
{ |
|
236
|
|
|
if (null === $bootstrapPath) { |
|
237
|
|
|
return; |
|
238
|
|
|
} |
|
239
|
|
|
|
|
240
|
|
|
$possiblePaths = [ |
|
241
|
|
|
sprintf('%s/%s', $basePath, $bootstrapPath), |
|
242
|
|
|
$bootstrapPath, |
|
243
|
|
|
]; |
|
244
|
|
|
|
|
245
|
|
|
foreach ($possiblePaths as $possiblePath) { |
|
246
|
|
|
if (file_exists($possiblePath)) { |
|
247
|
|
|
require_once $possiblePath; |
|
248
|
|
|
|
|
249
|
|
|
return; |
|
250
|
|
|
} |
|
251
|
|
|
} |
|
252
|
|
|
|
|
253
|
|
|
throw new \DomainException('Could not load bootstrap file.'); |
|
254
|
|
|
} |
|
255
|
|
|
} |
|
256
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.