Skip to content

Commit 413c495

Browse files
committed
[FrameworkBundle] Fix config builder with extensions extended in build()
1 parent 8306a88 commit 413c495

File tree

2 files changed

+237
-20
lines changed

2 files changed

+237
-20
lines changed

src/Symfony/Bundle/FrameworkBundle/CacheWarmer/ConfigBuilderCacheWarmer.php

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,17 @@ public function __construct(KernelInterface $kernel, ?LoggerInterface $logger =
4747
*/
4848
public function warmUp(string $cacheDir)
4949
{
50-
$generator = new ConfigBuilderGenerator($this->kernel->getBuildDir());
50+
/** @var ContainerBuilder $container */
51+
$container = \Closure::bind(function (KernelInterface $kernel) {
52+
$containerBuilder = $kernel->getContainerBuilder();
53+
$kernel->prepareContainer($containerBuilder);
5154

52-
foreach ($this->kernel->getBundles() as $bundle) {
53-
$extension = $bundle->getContainerExtension();
54-
if (null === $extension) {
55-
continue;
56-
}
55+
return $containerBuilder;
56+
}, null, $this->kernel)($this->kernel);
57+
58+
$generator = new ConfigBuilderGenerator($this->kernel->getBuildDir());
5759

60+
foreach ($container->getExtensions() as $extension) {
5861
try {
5962
$this->dumpExtension($extension, $generator);
6063
} catch (\Exception $e) {

src/Symfony/Bundle/FrameworkBundle/Tests/CacheWarmer/ConfigBuilderCacheWarmerTest.php

Lines changed: 228 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,15 @@
1414
use Symfony\Bundle\FrameworkBundle\CacheWarmer\ConfigBuilderCacheWarmer;
1515
use Symfony\Bundle\FrameworkBundle\FrameworkBundle;
1616
use Symfony\Bundle\FrameworkBundle\Tests\TestCase;
17+
use Symfony\Component\Config\Definition\Builder\NodeDefinition;
18+
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
19+
use Symfony\Component\Config\Definition\ConfigurationInterface;
1720
use Symfony\Component\Config\Loader\LoaderInterface;
21+
use Symfony\Component\DependencyInjection\ContainerBuilder;
22+
use Symfony\Component\DependencyInjection\Extension\Extension;
23+
use Symfony\Component\DependencyInjection\Extension\ExtensionInterface;
1824
use Symfony\Component\Filesystem\Filesystem;
25+
use Symfony\Component\HttpKernel\Bundle\Bundle;
1926
use Symfony\Component\HttpKernel\Kernel;
2027

2128
class ConfigBuilderCacheWarmerTest extends TestCase
@@ -38,41 +45,248 @@ protected function tearDown(): void
3845

3946
public function testBuildDirIsUsedAsConfigBuilderOutputDir()
4047
{
41-
$kernel = new class($this->varDir) extends Kernel {
42-
private $varDir;
48+
$kernel = new TestKernel($this->varDir);
49+
$kernel->boot();
50+
51+
$warmer = new ConfigBuilderCacheWarmer($kernel);
52+
$warmer->warmUp($kernel->getCacheDir());
53+
54+
self::assertDirectoryExists($kernel->getBuildDir().'/Symfony');
55+
self::assertDirectoryDoesNotExist($kernel->getCacheDir().'/Symfony');
56+
}
4357

44-
public function __construct(string $varDir)
58+
public function testExtensionAddedInKernel()
59+
{
60+
$kernel = new class($this->varDir) extends TestKernel {
61+
protected function build(ContainerBuilder $container): void
4562
{
46-
parent::__construct('test', false);
63+
$container->registerExtension(new class() extends Extension implements ConfigurationInterface {
64+
public function load(array $configs, ContainerBuilder $container): void
65+
{
66+
}
67+
68+
public function getConfigTreeBuilder(): TreeBuilder
69+
{
70+
$treeBuilder = new TreeBuilder('app');
71+
$rootNode = $treeBuilder->getRootNode();
72+
73+
$rootNode
74+
->children()
75+
->scalarNode('provider')->end()
76+
->end()
77+
;
78+
79+
return $treeBuilder;
80+
}
4781

48-
$this->varDir = $varDir;
82+
public function getAlias(): string
83+
{
84+
return 'app';
85+
}
86+
});
4987
}
88+
};
89+
$kernel->boot();
5090

51-
public function registerBundles(): iterable
91+
$warmer = new ConfigBuilderCacheWarmer($kernel);
92+
$warmer->warmUp($kernel->getCacheDir());
93+
94+
self::assertFileExists($kernel->getBuildDir().'/Symfony/Config/FrameworkConfig.php');
95+
self::assertFileExists($kernel->getBuildDir().'/Symfony/Config/AppConfig.php');
96+
}
97+
98+
public function testKernelAsExtension()
99+
{
100+
$kernel = new class($this->varDir) extends TestKernel implements ExtensionInterface, ConfigurationInterface {
101+
public function load(array $configs, ContainerBuilder $container): void
52102
{
53-
yield new FrameworkBundle();
54103
}
55104

56-
public function getBuildDir(): string
105+
public function getXsdValidationBasePath()
57106
{
58-
return $this->varDir.'/build';
107+
return false;
59108
}
60109

61-
public function getCacheDir(): string
110+
public function getNamespace(): string
62111
{
63-
return $this->varDir.'/cache';
112+
return 'http://www.example.com/schema/acme';
64113
}
65114

66-
public function registerContainerConfiguration(LoaderInterface $loader)
115+
public function getAlias(): string
67116
{
117+
return 'kernel';
118+
}
119+
120+
public function getConfigTreeBuilder(): TreeBuilder
121+
{
122+
$treeBuilder = new TreeBuilder('kernel');
123+
$rootNode = $treeBuilder->getRootNode();
124+
125+
$rootNode
126+
->children()
127+
->scalarNode('provider')->end()
128+
->end()
129+
;
130+
131+
return $treeBuilder;
68132
}
69133
};
70134
$kernel->boot();
71135

72136
$warmer = new ConfigBuilderCacheWarmer($kernel);
73137
$warmer->warmUp($kernel->getCacheDir());
74138

75-
self::assertDirectoryExists($kernel->getBuildDir().'/Symfony');
76-
self::assertDirectoryDoesNotExist($kernel->getCacheDir().'/Symfony');
139+
self::assertFileExists($kernel->getBuildDir().'/Symfony/Config/FrameworkConfig.php');
140+
self::assertFileExists($kernel->getBuildDir().'/Symfony/Config/KernelConfig.php');
141+
}
142+
143+
public function testExtensionsExtendedInBuildMethods()
144+
{
145+
$kernel = new class($this->varDir) extends TestKernel {
146+
protected function build(ContainerBuilder $container): void
147+
{
148+
/** @var TestSecurityExtension $extension */
149+
$extension = $container->getExtension('test_security');
150+
$extension->addAuthenticatorFactory(new class() implements TestAuthenticatorFactoryInterface {
151+
public function getKey(): string
152+
{
153+
return 'token';
154+
}
155+
156+
public function addConfiguration(NodeDefinition $node): void
157+
{
158+
}
159+
});
160+
}
161+
162+
public function registerBundles(): iterable
163+
{
164+
yield from parent::registerBundles();
165+
166+
yield new class() extends Bundle {
167+
public function getContainerExtension(): ExtensionInterface
168+
{
169+
return new TestSecurityExtension();
170+
}
171+
};
172+
173+
yield new class() extends Bundle {
174+
public function build(ContainerBuilder $container): void
175+
{
176+
/** @var TestSecurityExtension $extension */
177+
$extension = $container->getExtension('test_security');
178+
$extension->addAuthenticatorFactory(new class() implements TestAuthenticatorFactoryInterface {
179+
public function getKey(): string
180+
{
181+
return 'form-login';
182+
}
183+
184+
public function addConfiguration(NodeDefinition $node): void
185+
{
186+
$node
187+
->children()
188+
->scalarNode('provider')->end()
189+
->end()
190+
;
191+
}
192+
});
193+
}
194+
};
195+
}
196+
};
197+
$kernel->boot();
198+
199+
$warmer = new ConfigBuilderCacheWarmer($kernel);
200+
$warmer->warmUp($kernel->getCacheDir());
201+
202+
self::assertFileExists($kernel->getBuildDir().'/Symfony/Config/FrameworkConfig.php');
203+
self::assertFileExists($kernel->getBuildDir().'/Symfony/Config/SecurityConfig.php');
204+
self::assertFileExists($kernel->getBuildDir().'/Symfony/Config/Security/FirewallConfig.php');
205+
self::assertFileExists($kernel->getBuildDir().'/Symfony/Config/Security/FirewallConfig/FormLoginConfig.php');
206+
self::assertFileExists($kernel->getBuildDir().'/Symfony/Config/Security/FirewallConfig/TokenConfig.php');
207+
}
208+
}
209+
210+
class TestKernel extends Kernel
211+
{
212+
private $varDir;
213+
214+
public function __construct(string $varDir)
215+
{
216+
parent::__construct('test', false);
217+
218+
$this->varDir = $varDir;
219+
}
220+
221+
public function registerBundles(): iterable
222+
{
223+
yield new FrameworkBundle();
224+
}
225+
226+
public function getBuildDir(): string
227+
{
228+
return $this->varDir.'/build';
229+
}
230+
231+
public function getCacheDir(): string
232+
{
233+
return $this->varDir.'/cache';
234+
}
235+
236+
public function registerContainerConfiguration(LoaderInterface $loader): void
237+
{
238+
}
239+
}
240+
241+
interface TestAuthenticatorFactoryInterface
242+
{
243+
public function getKey(): string;
244+
245+
public function addConfiguration(NodeDefinition $builder): void;
246+
}
247+
248+
class TestSecurityExtension extends Extension implements ConfigurationInterface
249+
{
250+
/** @var TestAuthenticatorFactoryInterface[] */
251+
private $factories;
252+
253+
public function load(array $configs, ContainerBuilder $container): void
254+
{
255+
}
256+
257+
public function getConfiguration(array $config, ContainerBuilder $container): ConfigurationInterface
258+
{
259+
return $this;
260+
}
261+
262+
public function addAuthenticatorFactory(TestAuthenticatorFactoryInterface $factory): void
263+
{
264+
$this->factories[] = $factory;
265+
}
266+
267+
public function getConfigTreeBuilder(): TreeBuilder
268+
{
269+
$treeBuilder = new TreeBuilder('security');
270+
$rootNode = $treeBuilder->getRootNode();
271+
272+
$firewallNodeBuilder = $rootNode
273+
->fixXmlConfig('firewall')
274+
->children()
275+
->arrayNode('firewalls')
276+
->isRequired()
277+
->requiresAtLeastOneElement()
278+
->useAttributeAsKey('name')
279+
->prototype('array')
280+
->children()
281+
;
282+
283+
foreach ($this->factories as $factory) {
284+
$name = str_replace('-', '_', $factory->getKey());
285+
$factoryNode = $firewallNodeBuilder->arrayNode($name);
286+
287+
$factory->addConfiguration($factoryNode);
288+
}
289+
290+
return $treeBuilder;
77291
}
78292
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy