Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 1abfaba

Browse files
committed
feature #13761 Automatically process extensions when they implement CompilerPassInterface (WouterJ)
This PR was merged into the 2.7 branch. Discussion ---------- Automatically process extensions when they implement CompilerPassInterface | Q | A | ------------- | --- | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | - | License | MIT | Doc PR | todo (if people are in favor of this PR) Compiler passes are very powerfull, but also quite strange to work with. Especially when you just need a very simple compiler pass (like https://github.com/symfony-cmf/RoutingBundle/blob/master/DependencyInjection/Compiler/SetRouterPass.php). For 3 lines of code, you need to tweak your bundle class and create a new class. When using the DI component standalone, compiler passes are even harder to work with, as DI extensions can't register them. I believe that's why libraries like Behat make their extensions compiler passes by default. I think it would be very easy to just implement an interface and have a `compile` method for the simple compiler pass stuff. If a bundle needs multiple compiler passes or need compiler passes to be executed at other times in the compile process, a bundle can use the normal compiler passes. But if it's just one simple thing, like replacing a definition or getting services with a specific tag, I think this method will be very usefull. Commits ------- 6c50013 Allowed extensions to inline compiler passes
2 parents c38326c + 6c50013 commit 1abfaba

File tree

3 files changed

+75
-0
lines changed

3 files changed

+75
-0
lines changed
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
namespace Symfony\Component\DependencyInjection\Compiler;
4+
5+
use Symfony\Component\DependencyInjection\ContainerBuilder;
6+
7+
/**
8+
* A pass to automatically process extensions if they implement
9+
* CompilerPassInterface.
10+
*
11+
* @author Wouter J <[email protected]>
12+
*/
13+
class ExtensionCompilerPass implements CompilerPassInterface
14+
{
15+
/**
16+
* {@inheritdoc}
17+
*/
18+
public function process(ContainerBuilder $container)
19+
{
20+
foreach ($container->getExtensions() as $extension) {
21+
if (!$extension instanceof CompilerPassInterface) {
22+
continue;
23+
}
24+
25+
$extension->process($container);
26+
}
27+
}
28+
}

src/Symfony/Component/DependencyInjection/Compiler/PassConfig.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ public function __construct()
4545
$this->mergePass = new MergeExtensionConfigurationPass();
4646

4747
$this->optimizationPasses = array(
48+
new ExtensionCompilerPass(),
4849
new ResolveDefinitionTemplatesPass(),
4950
new DecoratorServicePass(),
5051
new ResolveParameterPlaceHoldersPass(),
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?php
2+
3+
namespace Symfony\Component\DependencyInjection\Tests\Compiler;
4+
5+
use Symfony\Component\DependencyInjection\Compiler\ExtensionCompilerPass;
6+
7+
/**
8+
* @author Wouter J <[email protected]>
9+
*/
10+
class ExtensionCompilerPassTest extends \PHPUnit_Framework_TestCase
11+
{
12+
private $container;
13+
private $pass;
14+
15+
public function setUp()
16+
{
17+
$this->container = $this->getMock('Symfony\Component\DependencyInjection\ContainerBuilder');
18+
$this->pass = new ExtensionCompilerPass();
19+
}
20+
21+
public function testProcess()
22+
{
23+
$extension1 = $this->createExtensionMock(true);
24+
$extension1->expects($this->once())->method('process');
25+
$extension2 = $this->createExtensionMock(false);
26+
$extension3 = $this->createExtensionMock(false);
27+
$extension4 = $this->createExtensionMock(true);
28+
$extension4->expects($this->once())->method('process');
29+
30+
$this->container->expects($this->any())
31+
->method('getExtensions')
32+
->will($this->returnValue(array($extension1, $extension2, $extension3, $extension4)))
33+
;
34+
35+
$this->pass->process($this->container);
36+
}
37+
38+
private function createExtensionMock($hasInlineCompile)
39+
{
40+
return $this->getMock('Symfony\Component\DependencyInjection\\'.(
41+
$hasInlineCompile
42+
? 'Compiler\CompilerPassInterface'
43+
: 'Extension\ExtensionInterface'
44+
));
45+
}
46+
}

0 commit comments

Comments
 (0)