Skip to content

Commit c723a66

Browse files
committed
[TwigBundle] Replace container by service locator in ContainerAwareRuntimeLoader
1 parent d8ea88c commit c723a66

File tree

5 files changed

+36
-18
lines changed

5 files changed

+36
-18
lines changed

src/Symfony/Bundle/TwigBundle/ContainerAwareRuntimeLoader.php

+16-7
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111

1212
namespace Symfony\Bundle\TwigBundle;
1313

14+
use Psr\Container\ContainerInterface;
1415
use Psr\Log\LoggerInterface;
15-
use Symfony\Component\DependencyInjection\ContainerInterface;
1616

1717
/**
1818
* Loads Twig extension runtimes via the service container.
@@ -22,23 +22,32 @@
2222
class ContainerAwareRuntimeLoader implements \Twig_RuntimeLoaderInterface
2323
{
2424
private $container;
25-
private $mapping;
2625
private $logger;
2726

28-
public function __construct(ContainerInterface $container, array $mapping, LoggerInterface $logger = null)
27+
public function __construct(ContainerInterface $container, $logger = null)
2928
{
30-
$this->container = $container;
31-
$this->mapping = $mapping;
29+
// BC 3.x, to be removed in 4.0, re-adding the LoggerInterface typehint to the $logger argument
30+
if (is_array($logger)) {
31+
@trigger_error(sprintf('The second argument of %s() is deprecated since version 3.3 and will be removed, passing something else than a %s instance will trigger an error in 4.0.', __METHOD__, LoggerInterface::class), E_USER_DEPRECATED);
32+
33+
if (2 < func_num_args() && func_get_arg(3) instanceof LoggerInterface) {
34+
$logger = func_get_arg(3);
35+
} else {
36+
$logger = null;
37+
}
38+
}
39+
3240
$this->logger = $logger;
41+
$this->container = $container;
3342
}
3443

3544
/**
3645
* {@inheritdoc}
3746
*/
3847
public function load($class)
3948
{
40-
if (isset($this->mapping[$class])) {
41-
return $this->container->get($this->mapping[$class]);
49+
if ($this->container->has($class)) {
50+
return $this->container->get($class);
4251
}
4352

4453
if (null !== $this->logger) {

src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/RuntimeLoaderPass.php

+4-2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
use Symfony\Component\DependencyInjection\ContainerBuilder;
1515
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
1616
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
17+
use Symfony\Component\DependencyInjection\Reference;
18+
use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
1719

1820
/**
1921
* Registers Twig runtime services.
@@ -39,9 +41,9 @@ public function process(ContainerBuilder $container)
3941
throw new InvalidArgumentException(sprintf('The service "%s" must not be abstract as it can be lazy-loaded.', $id));
4042
}
4143

42-
$mapping[$def->getClass()] = $id;
44+
$mapping[$def->getClass()] = new Reference($id);
4345
}
4446

45-
$definition->replaceArgument(1, $mapping);
47+
$definition->replaceArgument(0, new ServiceLocatorArgument($mapping));
4648
}
4749
}

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

+1-2
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,7 @@
138138
</service>
139139

140140
<service id="twig.runtime_loader" class="Symfony\Bundle\TwigBundle\ContainerAwareRuntimeLoader" public="false">
141-
<argument type="service" id="service_container" />
142-
<argument type="collection" /> <!-- the mapping between class names and service names -->
141+
<argument /> <!-- runtime loader service locator -->
143142
<argument type="service" id="logger" on-invalid="null" />
144143
</service>
145144
</services>

src/Symfony/Bundle/TwigBundle/Tests/ContainerAwareRuntimeLoaderTest.php

+14-6
Original file line numberDiff line numberDiff line change
@@ -11,28 +11,36 @@
1111

1212
namespace Symfony\Bundle\TwigBundle\Tests;
1313

14+
use Psr\Container\ContainerInterface;
1415
use Psr\Log\LoggerInterface;
15-
use Symfony\Component\DependencyInjection\ContainerInterface;
1616
use Symfony\Bundle\TwigBundle\ContainerAwareRuntimeLoader;
1717

1818
class ContainerAwareRuntimeLoaderTest extends TestCase
1919
{
2020
public function testLoad()
2121
{
2222
$container = $this->getMockBuilder(ContainerInterface::class)->getMock();
23-
$container->expects($this->once())->method('get')->with('foo');
23+
$container->expects($this->once())->method('has')->with('FooClass')->willReturn(true);
24+
$container->expects($this->once())->method('get')->with('FooClass');
2425

25-
$loader = new ContainerAwareRuntimeLoader($container, array(
26-
'FooClass' => 'foo',
27-
));
26+
$loader = new ContainerAwareRuntimeLoader($container);
2827
$loader->load('FooClass');
2928
}
3029

3130
public function testLoadWithoutAMatch()
3231
{
3332
$logger = $this->getMockBuilder(LoggerInterface::class)->getMock();
3433
$logger->expects($this->once())->method('warning')->with('Class "BarClass" is not configured as a Twig runtime. Add the "twig.runtime" tag to the related service in the container.');
35-
$loader = new ContainerAwareRuntimeLoader($this->getMockBuilder(ContainerInterface::class)->getMock(), array(), $logger);
34+
$loader = new ContainerAwareRuntimeLoader($this->getMockBuilder(ContainerInterface::class)->getMock(), $logger);
3635
$this->assertNull($loader->load('BarClass'));
3736
}
37+
38+
/**
39+
* @group legacy
40+
* @expectedDeprecation The second argument of Symfony\Bundle\TwigBundle\ContainerAwareRuntimeLoader::__construct() is deprecated since version 3.3 and will be removed, passing something else than a Psr\Log\LoggerInterface instance will trigger an error in 4.0.
41+
*/
42+
public function testSecondConstructorArgumentIsDeprecated()
43+
{
44+
$loader = new ContainerAwareRuntimeLoader($this->getMockBuilder(ContainerInterface::class)->getMock(), array());
45+
}
3846
}

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ public function testRuntimeLoader()
244244
$container->compile();
245245

246246
$loader = $container->getDefinition('twig.runtime_loader');
247-
$args = $loader->getArgument(1);
247+
$args = $loader->getArgument(0)->getValues();
248248
$this->assertArrayHasKey('Symfony\Bridge\Twig\Form\TwigRenderer', $args);
249249
$this->assertArrayHasKey('FooClass', $args);
250250
$this->assertContains('twig.form.renderer', $args);

0 commit comments

Comments
 (0)