Skip to content

Commit faaa406

Browse files
Merge branch '3.4' into 4.1
* 3.4: (21 commits) Added the Code of Conduct file do not override custom access decision configs [Security] Do not deauthenticate user when the first refreshed user has changed invalidate stale commits for PRs too add missing cache prefix seed attribute to XSD fix command description Fix class documentation [Validator] Add a missing translation [FrameworkBundle] Fix 3.4 tests [DI] fix dumping inline services again Fix phpdocs [EventDispatcher] Remove template method in test case Added LB translation for #27993 (UUID validator message translation) Replace deprecated validateValue with validate [FWBundle] Automatically enable PropertyInfo when using Flex [Process] fix locking of pipe files on Windows Correct PHPDoc type for float ttl bumped Symfony version to 3.4.18 updated VERSION for 3.4.17 updated CHANGELOG for 3.4.17 ...
2 parents f6b9d89 + 14c75bd commit faaa406

File tree

7 files changed

+368
-34
lines changed

7 files changed

+368
-34
lines changed

Dumper/PhpDumper.php

Lines changed: 22 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -489,10 +489,6 @@ private function isTrivialInstance(Definition $definition): bool
489489
}
490490
}
491491

492-
if (false !== strpos($this->dumpLiteralClass($this->dumpValue($definition->getClass())), '$')) {
493-
return false;
494-
}
495-
496492
return true;
497493
}
498494

@@ -559,18 +555,16 @@ private function addService(string $id, Definition $definition, string &$file =
559555
$return = array();
560556

561557
if ($class = $definition->getClass()) {
562-
$class = $this->container->resolveEnvPlaceholders($class);
558+
$class = $class instanceof Parameter ? '%'.$class.'%' : $this->container->resolveEnvPlaceholders($class);
563559
$return[] = sprintf(0 === strpos($class, '%') ? '@return object A %1$s instance' : '@return \%s', ltrim($class, '\\'));
564560
} elseif ($definition->getFactory()) {
565561
$factory = $definition->getFactory();
566562
if (\is_string($factory)) {
567563
$return[] = sprintf('@return object An instance returned by %s()', $factory);
568564
} elseif (\is_array($factory) && (\is_string($factory[0]) || $factory[0] instanceof Definition || $factory[0] instanceof Reference)) {
569-
if (\is_string($factory[0]) || $factory[0] instanceof Reference) {
570-
$return[] = sprintf('@return object An instance returned by %s::%s()', (string) $factory[0], $factory[1]);
571-
} elseif ($factory[0] instanceof Definition) {
572-
$return[] = sprintf('@return object An instance returned by %s::%s()', $factory[0]->getClass(), $factory[1]);
573-
}
565+
$class = $factory[0] instanceof Definition ? $factory[0]->getClass() : (string) $factory[0];
566+
$class = $class instanceof Parameter ? '%'.$class.'%' : $this->container->resolveEnvPlaceholders($class);
567+
$return[] = sprintf('@return object An instance returned by %s::%s()', $class, $factory[1]);
574568
}
575569
}
576570

@@ -671,7 +665,7 @@ private function addInlineVariables(string &$head, string &$tail, string $id, ar
671665
if (\is_array($argument)) {
672666
$hasSelfRef = $this->addInlineVariables($head, $tail, $id, $argument, $forConstructor) || $hasSelfRef;
673667
} elseif ($argument instanceof Reference) {
674-
$hasSelfRef = $this->addInlineReference($head, $tail, $id, $argument, $forConstructor) || $hasSelfRef;
668+
$hasSelfRef = $this->addInlineReference($head, $id, $argument, $forConstructor) || $hasSelfRef;
675669
} elseif ($argument instanceof Definition) {
676670
$hasSelfRef = $this->addInlineService($head, $tail, $id, $argument, $forConstructor) || $hasSelfRef;
677671
}
@@ -680,37 +674,31 @@ private function addInlineVariables(string &$head, string &$tail, string $id, ar
680674
return $hasSelfRef;
681675
}
682676

683-
private function addInlineReference(string &$head, string &$tail, string $id, string $targetId, bool $forConstructor): bool
677+
private function addInlineReference(string &$code, string $id, string $targetId, bool $forConstructor): bool
684678
{
679+
$hasSelfRef = isset($this->circularReferences[$id][$targetId]);
680+
685681
if ('service_container' === $targetId || isset($this->referenceVariables[$targetId])) {
686-
return isset($this->circularReferences[$id][$targetId]);
682+
return $hasSelfRef;
687683
}
688684

689685
list($callCount, $behavior) = $this->serviceCalls[$targetId];
690686

691-
if (2 > $callCount && (!$forConstructor || !isset($this->circularReferences[$id][$targetId]))) {
692-
return isset($this->circularReferences[$id][$targetId]);
687+
if (2 > $callCount && (!$hasSelfRef || !$forConstructor)) {
688+
return $hasSelfRef;
693689
}
694690

695691
$name = $this->getNextVariableName();
696692
$this->referenceVariables[$targetId] = new Variable($name);
697693

698694
$reference = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE >= $behavior ? new Reference($targetId, $behavior) : null;
699-
$code = sprintf(" \$%s = %s;\n", $name, $this->getServiceCall($targetId, $reference));
700-
701-
if (!isset($this->circularReferences[$id][$targetId])) {
702-
$head .= $code;
695+
$code .= sprintf(" \$%s = %s;\n", $name, $this->getServiceCall($targetId, $reference));
703696

704-
return false;
697+
if (!$hasSelfRef || !$forConstructor) {
698+
return $hasSelfRef;
705699
}
706700

707-
if (!$forConstructor) {
708-
$tail .= $code;
709-
710-
return true;
711-
}
712-
713-
$head .= $code.sprintf(<<<'EOTXT'
701+
$code .= sprintf(<<<'EOTXT'
714702
715703
if (isset($this->%s['%s'])) {
716704
return $this->%1$s['%2$s'];
@@ -733,17 +721,21 @@ private function addInlineService(string &$head, string &$tail, string $id, Defi
733721

734722
$arguments = array($definition->getArguments(), $definition->getFactory());
735723

736-
if (2 > $this->inlinedDefinitions[$definition] && !$definition->getMethodCalls() && !$definition->getProperties() && !$definition->getConfigurator() && false === strpos($this->dumpValue($definition->getClass()), '$')) {
724+
if (2 > $this->inlinedDefinitions[$definition] && !$definition->getMethodCalls() && !$definition->getProperties() && !$definition->getConfigurator()) {
737725
return $this->addInlineVariables($head, $tail, $id, $arguments, $forConstructor);
738726
}
739727

740728
$name = $this->getNextVariableName();
741729
$this->definitionVariables[$definition] = new Variable($name);
742730

743731
$code = '';
744-
$hasSelfRef = $this->addInlineVariables($code, $tail, $id, $arguments, $forConstructor);
732+
if ($forConstructor) {
733+
$hasSelfRef = $this->addInlineVariables($code, $tail, $id, $arguments, $forConstructor);
734+
} else {
735+
$hasSelfRef = $this->addInlineVariables($code, $code, $id, $arguments, $forConstructor);
736+
}
745737
$code .= $this->addNewInstance($definition, '$'.$name, ' = ', $id);
746-
$hasSelfRef ? $tail .= ('' !== $tail ? "\n" : '').$code : $head .= ('' !== $head ? "\n" : '').$code;
738+
$hasSelfRef && !$forConstructor ? $tail .= ('' !== $tail ? "\n" : '').$code : $head .= ('' !== $head ? "\n" : '').$code;
747739

748740
$code = '';
749741
$arguments = array($definition->getProperties(), $definition->getMethodCalls(), $definition->getConfigurator());

Tests/Dumper/PhpDumperTest.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -903,6 +903,28 @@ public function testDeepServiceGraph()
903903
$this->assertEquals((object) array('p2' => (object) array('p3' => (object) array())), $container->get('foo')->bClone);
904904
}
905905

906+
public function testInlineSelfRef()
907+
{
908+
$container = new ContainerBuilder();
909+
910+
$bar = (new Definition('App\Bar'))
911+
->setProperty('foo', new Reference('App\Foo'));
912+
913+
$baz = (new Definition('App\Baz'))
914+
->setProperty('bar', $bar)
915+
->addArgument($bar);
916+
917+
$container->register('App\Foo')
918+
->setPublic(true)
919+
->addArgument($baz);
920+
921+
$passConfig = $container->getCompiler()->getPassConfig();
922+
$container->compile();
923+
924+
$dumper = new PhpDumper($container);
925+
$this->assertStringEqualsFile(self::$fixturesPath.'/php/services_inline_self_ref.php', $dumper->dump(array('class' => 'Symfony_DI_PhpDumper_Test_Inline_Self_Ref')));
926+
}
927+
906928
public function testHotPathOptimizations()
907929
{
908930
$container = include self::$fixturesPath.'/containers/container_inline_requires.php';
@@ -980,6 +1002,18 @@ public function testUninitializedSyntheticReference()
9801002
$this->assertEquals((object) array('foo' => (object) array(123)), $container->get('bar'));
9811003
}
9821004

1005+
public function testAdawsonContainer()
1006+
{
1007+
$container = new ContainerBuilder();
1008+
$loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml'));
1009+
$loader->load('services_adawson.yml');
1010+
$container->compile();
1011+
1012+
$dumper = new PhpDumper($container);
1013+
$dump = $dumper->dump();
1014+
$this->assertStringEqualsFile(self::$fixturesPath.'/php/services_adawson.php', $dumper->dump());
1015+
}
1016+
9831017
/**
9841018
* This test checks the trigger of a deprecation note and should not be removed in major releases.
9851019
*

Tests/Fixtures/containers/container19.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,12 @@
77

88
$container = new ContainerBuilder();
99

10+
$container->setParameter('env(FOO)', 'Bar\FaooClass');
11+
$container->setParameter('foo', '%env(FOO)%');
12+
1013
$container
11-
->register('service_from_anonymous_factory', 'Bar\FooClass')
12-
->setFactory(array(new Definition('Bar\FooClass'), 'getInstance'))
14+
->register('service_from_anonymous_factory', '%foo%')
15+
->setFactory(array(new Definition('%foo%'), 'getInstance'))
1316
->setPublic(true)
1417
;
1518

Tests/Fixtures/php/services19.php

Lines changed: 80 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ class ProjectServiceContainer extends Container
2626

2727
public function __construct()
2828
{
29+
$this->parameters = $this->getDefaultParameters();
30+
2931
$this->services = $this->privates = array();
3032
$this->methodMap = array(
3133
'service_from_anonymous_factory' => 'getServiceFromAnonymousFactoryService',
@@ -62,11 +64,11 @@ public function getRemovedIds()
6264
/**
6365
* Gets the public 'service_from_anonymous_factory' shared service.
6466
*
65-
* @return \Bar\FooClass
67+
* @return object A %env(FOO)% instance
6668
*/
6769
protected function getServiceFromAnonymousFactoryService()
6870
{
69-
return $this->services['service_from_anonymous_factory'] = (new \Bar\FooClass())->getInstance();
71+
return $this->services['service_from_anonymous_factory'] = (new ${($_ = $this->getEnv('FOO')) && false ?: "_"}())->getInstance();
7072
}
7173

7274
/**
@@ -82,4 +84,80 @@ protected function getServiceWithMethodCallAndFactoryService()
8284

8385
return $instance;
8486
}
87+
88+
public function getParameter($name)
89+
{
90+
$name = (string) $name;
91+
92+
if (!(isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters))) {
93+
throw new InvalidArgumentException(sprintf('The parameter "%s" must be defined.', $name));
94+
}
95+
if (isset($this->loadedDynamicParameters[$name])) {
96+
return $this->loadedDynamicParameters[$name] ? $this->dynamicParameters[$name] : $this->getDynamicParameter($name);
97+
}
98+
99+
return $this->parameters[$name];
100+
}
101+
102+
public function hasParameter($name)
103+
{
104+
$name = (string) $name;
105+
106+
return isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters);
107+
}
108+
109+
public function setParameter($name, $value)
110+
{
111+
throw new LogicException('Impossible to call set() on a frozen ParameterBag.');
112+
}
113+
114+
public function getParameterBag()
115+
{
116+
if (null === $this->parameterBag) {
117+
$parameters = $this->parameters;
118+
foreach ($this->loadedDynamicParameters as $name => $loaded) {
119+
$parameters[$name] = $loaded ? $this->dynamicParameters[$name] : $this->getDynamicParameter($name);
120+
}
121+
$this->parameterBag = new FrozenParameterBag($parameters);
122+
}
123+
124+
return $this->parameterBag;
125+
}
126+
127+
private $loadedDynamicParameters = array(
128+
'foo' => false,
129+
);
130+
private $dynamicParameters = array();
131+
132+
/**
133+
* Computes a dynamic parameter.
134+
*
135+
* @param string The name of the dynamic parameter to load
136+
*
137+
* @return mixed The value of the dynamic parameter
138+
*
139+
* @throws InvalidArgumentException When the dynamic parameter does not exist
140+
*/
141+
private function getDynamicParameter($name)
142+
{
143+
switch ($name) {
144+
case 'foo': $value = $this->getEnv('FOO'); break;
145+
default: throw new InvalidArgumentException(sprintf('The dynamic parameter "%s" must be defined.', $name));
146+
}
147+
$this->loadedDynamicParameters[$name] = true;
148+
149+
return $this->dynamicParameters[$name] = $value;
150+
}
151+
152+
/**
153+
* Gets the default parameters.
154+
*
155+
* @return array An array of the default parameters
156+
*/
157+
protected function getDefaultParameters()
158+
{
159+
return array(
160+
'env(FOO)' => 'Bar\\FaooClass',
161+
);
162+
}
85163
}

0 commit comments

Comments
 (0)