Skip to content

Commit 7921255

Browse files
[DI] Dont resolve envs in service ids
1 parent db979e8 commit 7921255

File tree

8 files changed

+269
-27
lines changed

8 files changed

+269
-27
lines changed

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

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -77,16 +77,20 @@ public function process(ContainerBuilder $container)
7777
}
7878
}
7979

80-
$resolvedId = $container->resolveEnvPlaceholders($id, null, $usedEnvs);
81-
if (null !== $usedEnvs) {
82-
throw new EnvParameterException(array($resolvedId), null, 'A service name ("%s") cannot contain dynamic values.');
80+
if ($definition->isPublic()) {
81+
$resolvedId = $container->resolveEnvPlaceholders($id, null, $usedEnvs);
82+
if (null !== $usedEnvs) {
83+
throw new EnvParameterException(array($resolvedId), null, 'A service name ("%s") cannot contain dynamic values.');
84+
}
8385
}
8486
}
8587

8688
foreach ($container->getAliases() as $id => $alias) {
87-
$resolvedId = $container->resolveEnvPlaceholders($id, null, $usedEnvs);
88-
if (null !== $usedEnvs) {
89-
throw new EnvParameterException(array($resolvedId), null, 'An alias name ("%s") cannot contain dynamic values.');
89+
if ($alias->isPublic()) {
90+
$resolvedId = $container->resolveEnvPlaceholders($id, null, $usedEnvs);
91+
if (null !== $usedEnvs) {
92+
throw new EnvParameterException(array($resolvedId), null, 'An alias name ("%s") cannot contain dynamic values.');
93+
}
9094
}
9195
}
9296
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ protected function processValue($value, $isRoot = false)
3535

3636
$value = parent::processValue($value, $isRoot);
3737

38-
if ($value && is_array($value)) {
38+
if ($value && is_array($value) && !$isRoot) {
3939
$value = array_combine($this->container->resolveEnvPlaceholders(array_keys($value), true), $value);
4040
}
4141

src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -680,6 +680,7 @@ private function addServices()
680680
private function addNewInstance(Definition $definition, $return, $instantiation, $id)
681681
{
682682
$class = $this->dumpValue($definition->getClass());
683+
$return = ' '.$return.$instantiation;
683684

684685
$arguments = array();
685686
foreach ($definition->getArguments() as $value) {
@@ -695,7 +696,7 @@ private function addNewInstance(Definition $definition, $return, $instantiation,
695696

696697
if ($callable[0] instanceof Reference
697698
|| ($callable[0] instanceof Definition && $this->definitionVariables->contains($callable[0]))) {
698-
return sprintf(" $return{$instantiation}%s->%s(%s);\n", $this->dumpValue($callable[0]), $callable[1], $arguments ? implode(', ', $arguments) : '');
699+
return $return.sprintf("%s->%s(%s);\n", $this->dumpValue($callable[0]), $callable[1], $arguments ? implode(', ', $arguments) : '');
699700
}
700701

701702
$class = $this->dumpValue($callable[0]);
@@ -705,24 +706,24 @@ private function addNewInstance(Definition $definition, $return, $instantiation,
705706
throw new RuntimeException(sprintf('Cannot dump definition: The "%s" service is defined to be created by a factory but is missing the service reference, did you forget to define the factory service id or class?', $id));
706707
}
707708

708-
return sprintf(" $return{$instantiation}%s::%s(%s);\n", $this->dumpLiteralClass($class), $callable[1], $arguments ? implode(', ', $arguments) : '');
709+
return $return.sprintf("%s::%s(%s);\n", $this->dumpLiteralClass($class), $callable[1], $arguments ? implode(', ', $arguments) : '');
709710
}
710711

711712
if (0 === strpos($class, 'new ')) {
712-
return sprintf(" $return{$instantiation}(%s)->%s(%s);\n", $this->dumpValue($callable[0]), $callable[1], $arguments ? implode(', ', $arguments) : '');
713+
return $return.sprintf("(%s)->%s(%s);\n", $this->dumpValue($callable[0]), $callable[1], $arguments ? implode(', ', $arguments) : '');
713714
}
714715

715-
return sprintf(" $return{$instantiation}call_user_func(array(%s, '%s')%s);\n", $this->dumpValue($callable[0]), $callable[1], $arguments ? ', '.implode(', ', $arguments) : '');
716+
return $return.sprintf("call_user_func(array(%s, '%s')%s);\n", $this->dumpValue($callable[0]), $callable[1], $arguments ? ', '.implode(', ', $arguments) : '');
716717
}
717718

718-
return sprintf(" $return{$instantiation}%s(%s);\n", $this->dumpLiteralClass($this->dumpValue($callable)), $arguments ? implode(', ', $arguments) : '');
719+
return $return.sprintf("%s(%s);\n", $this->dumpLiteralClass($this->dumpValue($callable)), $arguments ? implode(', ', $arguments) : '');
719720
}
720721

721722
if (false !== strpos($class, '$')) {
722-
return sprintf(" \$class = %s;\n\n $return{$instantiation}new \$class(%s);\n", $class, implode(', ', $arguments));
723+
return sprintf(" \$class = %s;\n\n%snew \$class(%s);\n", $class, $return, implode(', ', $arguments));
723724
}
724725

725-
return sprintf(" $return{$instantiation}new %s(%s);\n", $this->dumpLiteralClass($class), implode(', ', $arguments));
726+
return $return.sprintf("new %s(%s);\n", $this->dumpLiteralClass($class), implode(', ', $arguments));
726727
}
727728

728729
/**
@@ -890,7 +891,7 @@ private function addNormalizedIds()
890891
ksort($normalizedIds);
891892
foreach ($normalizedIds as $id => $normalizedId) {
892893
if ($this->container->has($normalizedId)) {
893-
$code .= ' '.$this->export($id).' => '.$this->export($normalizedId).",\n";
894+
$code .= ' '.$this->doExport($id).' => '.$this->doExport($normalizedId).",\n";
894895
}
895896
}
896897

@@ -912,7 +913,7 @@ private function addMethodMap()
912913
$code = " \$this->methodMap = array(\n";
913914
ksort($definitions);
914915
foreach ($definitions as $id => $definition) {
915-
$code .= ' '.$this->export($id).' => '.$this->export($this->generateMethodName($id)).",\n";
916+
$code .= ' '.$this->doExport($id).' => '.$this->doExport($this->generateMethodName($id)).",\n";
916917
}
917918

918919
return $code." );\n";
@@ -933,7 +934,7 @@ private function addPrivateServices()
933934
ksort($definitions);
934935
foreach ($definitions as $id => $definition) {
935936
if (!$definition->isPublic()) {
936-
$code .= ' '.$this->export($id)." => true,\n";
937+
$code .= ' '.$this->doExport($id)." => true,\n";
937938
}
938939
}
939940

@@ -966,7 +967,7 @@ private function addAliases()
966967
while (isset($aliases[$id])) {
967968
$id = (string) $aliases[$id];
968969
}
969-
$code .= ' '.$this->export($alias).' => '.$this->export($id).",\n";
970+
$code .= ' '.$this->doExport($alias).' => '.$this->doExport($id).",\n";
970971
}
971972

972973
return $code." );\n";
@@ -1688,9 +1689,9 @@ private function exportTargetDirs()
16881689
private function export($value)
16891690
{
16901691
if (null !== $this->targetDirRegex && is_string($value) && preg_match($this->targetDirRegex, $value, $matches, PREG_OFFSET_CAPTURE)) {
1691-
$prefix = $matches[0][1] ? $this->doExport(substr($value, 0, $matches[0][1])).'.' : '';
1692+
$prefix = $matches[0][1] ? $this->doExport(substr($value, 0, $matches[0][1]), true).'.' : '';
16921693
$suffix = $matches[0][1] + strlen($matches[0][0]);
1693-
$suffix = isset($value[$suffix]) ? '.'.$this->doExport(substr($value, $suffix)) : '';
1694+
$suffix = isset($value[$suffix]) ? '.'.$this->doExport(substr($value, $suffix), true) : '';
16941695
$dirname = '__DIR__';
16951696

16961697
if (0 < $offset = 1 + $this->targetDirMaxMatches - count($matches)) {
@@ -1704,10 +1705,10 @@ private function export($value)
17041705
return $dirname;
17051706
}
17061707

1707-
return $this->doExport($value);
1708+
return $this->doExport($value, true);
17081709
}
17091710

1710-
private function doExport($value)
1711+
private function doExport($value, $resolveEnv = false)
17111712
{
17121713
if (is_string($value) && false !== strpos($value, "\n")) {
17131714
$cleanParts = explode("\n", $value);
@@ -1717,7 +1718,7 @@ private function doExport($value)
17171718
$export = var_export($value, true);
17181719
}
17191720

1720-
if ("'" === $export[0] && $export !== $resolvedExport = $this->container->resolveEnvPlaceholders($export, "'.\$this->getEnv('%s').'")) {
1721+
if ($resolveEnv && "'" === $export[0] && $export !== $resolvedExport = $this->container->resolveEnvPlaceholders($export, "'.\$this->getEnv('%s').'")) {
17211722
$export = $resolvedExport;
17221723
if ("'" === $export[1]) {
17231724
$export = substr($export, 3);

src/Symfony/Component/DependencyInjection/Tests/Compiler/CheckDefinitionValidityPassTest.php

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Component\DependencyInjection\Tests\Compiler;
1313

1414
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\DependencyInjection\Alias;
1516
use Symfony\Component\DependencyInjection\Compiler\CheckDefinitionValidityPass;
1617
use Symfony\Component\DependencyInjection\ContainerBuilder;
1718

@@ -79,27 +80,39 @@ public function testInvalidTags()
7980
/**
8081
* @expectedException \Symfony\Component\DependencyInjection\Exception\EnvParameterException
8182
*/
82-
public function testDynamicServiceName()
83+
public function testDynamicPublicServiceName()
8384
{
8485
$container = new ContainerBuilder();
8586
$env = $container->getParameterBag()->get('env(BAR)');
86-
$container->register("foo.$env", 'class');
87+
$container->register("foo.$env", 'class')->setPublic(true);
8788

8889
$this->process($container);
8990
}
9091

9192
/**
9293
* @expectedException \Symfony\Component\DependencyInjection\Exception\EnvParameterException
9394
*/
94-
public function testDynamicAliasName()
95+
public function testDynamicPublicAliasName()
9596
{
9697
$container = new ContainerBuilder();
9798
$env = $container->getParameterBag()->get('env(BAR)');
98-
$container->setAlias("foo.$env", 'class');
99+
$container->setAlias("foo.$env", new Alias('class', true));
99100

100101
$this->process($container);
101102
}
102103

104+
public function testDynamicPrivateName()
105+
{
106+
$container = new ContainerBuilder();
107+
$env = $container->getParameterBag()->get('env(BAR)');
108+
$container->register("foo.$env", 'class')->setPublic(false);
109+
$container->setAlias("bar.$env", new Alias('class', false));
110+
111+
$this->process($container);
112+
113+
$this->addToAssertionCount(1);
114+
}
115+
103116
protected function process(ContainerBuilder $container)
104117
{
105118
$pass = new CheckDefinitionValidityPass();

src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -665,6 +665,22 @@ public function testCompileWithResolveMissingEnv()
665665
$container->compile(true);
666666
}
667667

668+
public function testEnvInId()
669+
{
670+
$container = include __DIR__.'/Fixtures/containers/container_env_in_id.php';
671+
$container->compile(true);
672+
673+
$expected = array(
674+
'service_container',
675+
'foo',
676+
'bar',
677+
'bar_%env(BAR)%',
678+
);
679+
$this->assertSame($expected, array_keys($container->getDefinitions()));
680+
681+
$this->assertSame(array('baz_bar'), array_keys($container->getDefinition('foo')->getArgument(1)));
682+
}
683+
668684
/**
669685
* @expectedException \LogicException
670686
*/

src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,15 @@ public function testDumpAutowireData()
327327
$this->assertStringEqualsFile(self::$fixturesPath.'/php/services24.php', $dumper->dump());
328328
}
329329

330+
public function testEnvInId()
331+
{
332+
$container = include self::$fixturesPath.'/containers/container_env_in_id.php';
333+
$container->compile();
334+
$dumper = new PhpDumper($container);
335+
336+
$this->assertStringEqualsFile(self::$fixturesPath.'/php/services_env_in_id.php', $dumper->dump());
337+
}
338+
330339
public function testEnvParameter()
331340
{
332341
$container = new ContainerBuilder();
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
use Symfony\Component\DependencyInjection\ContainerBuilder;
4+
use Symfony\Component\DependencyInjection\Definition;
5+
use Symfony\Component\DependencyInjection\Dumper\PhpDumper;
6+
use Symfony\Component\DependencyInjection\Reference;
7+
8+
$container = new ContainerBuilder();
9+
10+
$container->setParameter('env(BAR)', 'bar');
11+
12+
$container->register('foo', 'stdClass')->setPublic(true)
13+
->addArgument(new Reference('bar_%env(BAR)%'))
14+
->addArgument(array('baz_%env(BAR)%' => new Reference('baz_%env(BAR)%')));
15+
16+
$container->register('bar', 'stdClass')->setPublic(true)
17+
->addArgument(new Reference('bar_%env(BAR)%'));
18+
19+
$container->register('bar_%env(BAR)%', 'stdClass')->setPublic(false);
20+
$container->register('baz_%env(BAR)%', 'stdClass')->setPublic(false);
21+
22+
return $container;

0 commit comments

Comments
 (0)