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

Skip to content

Commit dee1e09

Browse files
committed
added a Twig runtime loader
1 parent 2e35a01 commit dee1e09

File tree

5 files changed

+124
-9
lines changed

5 files changed

+124
-9
lines changed
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[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 Symfony\Bundle\TwigBundle;
13+
14+
use Symfony\Component\DependencyInjection\ContainerInterface;
15+
16+
/**
17+
* Loads Twig extension runtimes.
18+
*
19+
* @author Fabien Potencier <[email protected]>
20+
*/
21+
class ContainerAwareRuntimeLoader implements \Twig_RuntimeLoaderInterface
22+
{
23+
private $container;
24+
private $mapping;
25+
26+
public function __construct(ContainerInterface $container, array $mapping)
27+
{
28+
$this->mapping = $mapping;
29+
}
30+
31+
/**
32+
* {@inheritdoc}
33+
*/
34+
public function load($class)
35+
{
36+
if (!isset($this->mapping[$class])) {
37+
throw new \LogicException(sprintf('Class "%s" is not configured as a Twig runtime. Add the "twig.runtime" tag to the related service in the container.', $class));
38+
}
39+
40+
return $this->container->get($this->mapping[$class]);
41+
}
42+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[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 Symfony\Bundle\TwigBundle\DependencyInjection\Compiler;
13+
14+
use Symfony\Component\DependencyInjection\ContainerBuilder;
15+
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
16+
17+
/**
18+
* Registers Twig runtime services.
19+
*/
20+
class RuntimeLoaderPass implements CompilerPassInterface
21+
{
22+
public function process(ContainerBuilder $container)
23+
{
24+
if (!$container->hasDefinition('twig.runtime_loader')) {
25+
return;
26+
}
27+
28+
$definition = $container->getDefinition('twig.runtime_loader');
29+
$mapping = array();
30+
foreach ($container->findTaggedServiceIds('twig.runtime') as $id => $attributes) {
31+
$mapping[$container->getDefinition($id)->getClass()] = $id;
32+
}
33+
34+
$definition->replaceArgument(1, $mapping);
35+
}
36+
}

src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
<argument>app</argument>
1313
<argument type="service" id="twig.app_variable" />
1414
</call>
15+
<call method="addRuntimeLoader">
16+
<argument type="service" id="twig.runtime_loader" />
17+
</call>
1518
<configurator service="twig.configurator.environment" method="configure" />
1619
</service>
1720

@@ -128,6 +131,7 @@
128131
<service id="twig.form.renderer" class="Symfony\Bridge\Twig\Form\TwigRenderer" public="false">
129132
<argument type="service" id="twig.form.engine" />
130133
<argument type="service" id="security.csrf.token_manager" on-invalid="null" />
134+
<tag name="twig.runtime" />
131135
</service>
132136

133137
<service id="twig.translation.extractor" class="Symfony\Bridge\Twig\Translation\TwigExtractor">
@@ -160,5 +164,10 @@
160164
<argument /> <!-- decimal point, set in TwigExtension -->
161165
<argument /> <!-- thousands separator, set in TwigExtension -->
162166
</service>
167+
168+
<service id="twig.runtime_loader" class="Symfony\Bundle\TwigBundle\ContainerAwareRuntimeLoader" public="false">
169+
<argument type="service" id="service_container" />
170+
<argument type="collection" /> <!-- the mapping between class names and service names -->
171+
</service>
163172
</services>
164173
</container>

src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/TwigExtensionTest.php

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@
1111

1212
namespace Symfony\Bundle\TwigBundle\Tests\DependencyInjection;
1313

14+
use Symfony\Bundle\TwigBundle\DependencyInjection\Compiler\RuntimeLoaderPass;
1415
use Symfony\Bundle\TwigBundle\DependencyInjection\TwigExtension;
1516
use Symfony\Bundle\TwigBundle\Tests\TestCase;
1617
use Symfony\Component\Config\FileLocator;
18+
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
1719
use Symfony\Component\DependencyInjection\ContainerBuilder;
1820
use Symfony\Component\DependencyInjection\Reference;
1921
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
@@ -62,17 +64,17 @@ public function testLoadFullConfiguration($format)
6264
$calls = $container->getDefinition('twig')->getMethodCalls();
6365
$this->assertEquals('app', $calls[0][1][0], '->load() registers services as Twig globals');
6466
$this->assertEquals(new Reference('twig.app_variable'), $calls[0][1][1]);
65-
$this->assertEquals('foo', $calls[1][1][0], '->load() registers services as Twig globals');
66-
$this->assertEquals(new Reference('bar'), $calls[1][1][1], '->load() registers services as Twig globals');
67-
$this->assertEquals('baz', $calls[2][1][0], '->load() registers variables as Twig globals');
68-
$this->assertEquals('@qux', $calls[2][1][1], '->load() allows escaping of service identifiers');
69-
$this->assertEquals('pi', $calls[3][1][0], '->load() registers variables as Twig globals');
70-
$this->assertEquals(3.14, $calls[3][1][1], '->load() registers variables as Twig globals');
67+
$this->assertEquals('foo', $calls[2][1][0], '->load() registers services as Twig globals');
68+
$this->assertEquals(new Reference('bar'), $calls[2][1][1], '->load() registers services as Twig globals');
69+
$this->assertEquals('baz', $calls[3][1][0], '->load() registers variables as Twig globals');
70+
$this->assertEquals('@qux', $calls[3][1][1], '->load() allows escaping of service identifiers');
71+
$this->assertEquals('pi', $calls[4][1][0], '->load() registers variables as Twig globals');
72+
$this->assertEquals(3.14, $calls[4][1][1], '->load() registers variables as Twig globals');
7173

7274
// Yaml and Php specific configs
7375
if (in_array($format, array('yml', 'php'))) {
74-
$this->assertEquals('bad', $calls[4][1][0], '->load() registers variables as Twig globals');
75-
$this->assertEquals(array('key' => 'foo'), $calls[4][1][1], '->load() registers variables as Twig globals');
76+
$this->assertEquals('bad', $calls[5][1][0], '->load() registers variables as Twig globals');
77+
$this->assertEquals(array('key' => 'foo'), $calls[5][1][1], '->load() registers variables as Twig globals');
7678
}
7779

7880
// Twig options
@@ -133,7 +135,7 @@ public function testGlobalsWithDifferentTypesAndValues()
133135
$this->compileContainer($container);
134136

135137
$calls = $container->getDefinition('twig')->getMethodCalls();
136-
foreach (array_slice($calls, 1) as $call) {
138+
foreach (array_slice($calls, 2) as $call) {
137139
list($name, $value) = each($globals);
138140
$this->assertEquals($name, $call[1][0]);
139141
$this->assertSame($value, $call[1][1]);
@@ -211,6 +213,29 @@ public function stopwatchExtensionAvailabilityProvider()
211213
);
212214
}
213215

216+
public function testRuntimeLoader()
217+
{
218+
$container = $this->createContainer();
219+
$container->registerExtension(new TwigExtension());
220+
$container->loadFromExtension('twig', array());
221+
$container->setParameter('kernel.environment', 'test');
222+
$container->setParameter('debug.file_link_format', 'test');
223+
$container->setParameter('foo', 'FooClass');
224+
$container->register('http_kernel', 'FooClass');
225+
$container->register('templating.locator', 'FooClass');
226+
$container->register('templating.name_parser', 'FooClass');
227+
$container->register('foo', '%foo%')->addTag('twig.runtime');
228+
$container->addCompilerPass(new RuntimeLoaderPass(), PassConfig::TYPE_BEFORE_REMOVING);
229+
$container->getCompilerPassConfig()->setRemovingPasses(array());
230+
$container->compile();
231+
232+
$loader = $container->getDefinition('twig.runtime_loader');
233+
$this->assertEquals(array(
234+
'Symfony\Bridge\Twig\Form\TwigRenderer' => 'twig.form.renderer',
235+
'FooClass' => 'foo',
236+
), $loader->getArgument(1));
237+
}
238+
214239
private function createContainer()
215240
{
216241
$container = new ContainerBuilder(new ParameterBag(array(

src/Symfony/Bundle/TwigBundle/TwigBundle.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@
1212
namespace Symfony\Bundle\TwigBundle;
1313

1414
use Symfony\Component\HttpKernel\Bundle\Bundle;
15+
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
1516
use Symfony\Component\DependencyInjection\ContainerBuilder;
1617
use Symfony\Bundle\TwigBundle\DependencyInjection\Compiler\TwigEnvironmentPass;
1718
use Symfony\Bundle\TwigBundle\DependencyInjection\Compiler\TwigLoaderPass;
1819
use Symfony\Bundle\TwigBundle\DependencyInjection\Compiler\ExceptionListenerPass;
1920
use Symfony\Bundle\TwigBundle\DependencyInjection\Compiler\ExtensionPass;
21+
use Symfony\Bundle\TwigBundle\DependencyInjection\Compiler\RuntimeLoaderPass;
2022

2123
/**
2224
* Bundle.
@@ -33,5 +35,6 @@ public function build(ContainerBuilder $container)
3335
$container->addCompilerPass(new TwigEnvironmentPass());
3436
$container->addCompilerPass(new TwigLoaderPass());
3537
$container->addCompilerPass(new ExceptionListenerPass());
38+
$container->addCompilerPass(new RuntimeLoaderPass(), PassConfig::TYPE_BEFORE_REMOVING);
3639
}
3740
}

0 commit comments

Comments
 (0)