Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit c026ec6

Browse filesBrowse files
bug #25762 [DependencyInjection] always call the parent class' constructor (xabbuh)
This PR was merged into the 3.4 branch. Discussion ---------- [DependencyInjection] always call the parent class' constructor | Q | A | ------------- | --- | Branch? | 2.7 | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #25343 | License | MIT | Doc PR | Commits ------- a1b1484 always call the parent class' constructor
2 parents a469490 + a1b1484 commit c026ec6
Copy full SHA for c026ec6

10 files changed

+320
-4
lines changed

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php
+19-4Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,11 @@ public function dump(array $options = array())
128128

129129
if (0 !== strpos($baseClass = $options['base_class'], '\\') && 'Container' !== $baseClass) {
130130
$baseClass = sprintf('%s\%s', $options['namespace'] ? '\\'.$options['namespace'] : '', $baseClass);
131+
$baseClassWithNamespace = $baseClass;
132+
} elseif ('Container' === $baseClass) {
133+
$baseClassWithNamespace = Container::class;
134+
} else {
135+
$baseClassWithNamespace = $baseClass;
131136
}
132137

133138
$this->initializeMethodNamesMap('Container' === $baseClass ? Container::class : $baseClass);
@@ -169,7 +174,7 @@ public function dump(array $options = array())
169174
}
170175

171176
$code =
172-
$this->startClass($options['class'], $baseClass).
177+
$this->startClass($options['class'], $baseClass, $baseClassWithNamespace).
173178
$this->addServices().
174179
$this->addDefaultParametersMethod().
175180
$this->endClass()
@@ -919,12 +924,13 @@ private function addNewInstance(Definition $definition, $return, $instantiation,
919924
/**
920925
* Adds the class headers.
921926
*
922-
* @param string $class Class name
923-
* @param string $baseClass The name of the base class
927+
* @param string $class Class name
928+
* @param string $baseClass The name of the base class
929+
* @param string $baseClassWithNamespace Fully qualified base class name
924930
*
925931
* @return string
926932
*/
927-
private function startClass($class, $baseClass)
933+
private function startClass($class, $baseClass, $baseClassWithNamespace)
928934
{
929935
$bagClass = $this->container->isCompiled() ? 'use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;' : 'use Symfony\Component\DependencyInjection\ParameterBag\\ParameterBag;';
930936
$namespaceLine = !$this->asFiles && $this->namespace ? "\nnamespace {$this->namespace};\n" : '';
@@ -972,9 +978,18 @@ public function __construct()
972978
}
973979

974980
if ($this->container->isCompiled()) {
981+
if (Container::class !== $baseClassWithNamespace) {
982+
$r = $this->container->getReflectionClass($baseClassWithNamespace, false);
983+
984+
if (null !== $r && (null !== $constructor = $r->getConstructor()) && 0 === $constructor->getNumberOfRequiredParameters()) {
985+
$code .= " parent::__construct();\n\n";
986+
}
987+
}
988+
975989
if ($this->container->getParameterBag()->all()) {
976990
$code .= " \$this->parameters = \$this->getDefaultParameters();\n\n";
977991
}
992+
978993
$code .= " \$this->services = array();\n";
979994
} else {
980995
$arguments = $this->container->getParameterBag()->all() ? 'new ParameterBag($this->getDefaultParameters())' : null;

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php
+40Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,46 @@ public function testDumpRelativeDir()
107107
$this->assertStringEqualsFile(self::$fixturesPath.'/php/services12.php', $dumper->dump(array('file' => __FILE__)), '->dump() dumps __DIR__ relative strings');
108108
}
109109

110+
public function testDumpCustomContainerClassWithoutConstructor()
111+
{
112+
$container = new ContainerBuilder();
113+
$container->compile();
114+
115+
$dumper = new PhpDumper($container);
116+
117+
$this->assertStringEqualsFile(self::$fixturesPath.'/php/custom_container_class_without_constructor.php', $dumper->dump(array('base_class' => 'NoConstructorContainer', 'namespace' => 'Symfony\Component\DependencyInjection\Tests\Fixtures\Container')));
118+
}
119+
120+
public function testDumpCustomContainerClassConstructorWithoutArguments()
121+
{
122+
$container = new ContainerBuilder();
123+
$container->compile();
124+
125+
$dumper = new PhpDumper($container);
126+
127+
$this->assertStringEqualsFile(self::$fixturesPath.'/php/custom_container_class_constructor_without_arguments.php', $dumper->dump(array('base_class' => 'ConstructorWithoutArgumentsContainer', 'namespace' => 'Symfony\Component\DependencyInjection\Tests\Fixtures\Container')));
128+
}
129+
130+
public function testDumpCustomContainerClassWithOptionalArgumentLessConstructor()
131+
{
132+
$container = new ContainerBuilder();
133+
$container->compile();
134+
135+
$dumper = new PhpDumper($container);
136+
137+
$this->assertStringEqualsFile(self::$fixturesPath.'/php/custom_container_class_with_optional_constructor_arguments.php', $dumper->dump(array('base_class' => 'ConstructorWithOptionalArgumentsContainer', 'namespace' => 'Symfony\Component\DependencyInjection\Tests\Fixtures\Container')));
138+
}
139+
140+
public function testDumpCustomContainerClassWithMandatoryArgumentLessConstructor()
141+
{
142+
$container = new ContainerBuilder();
143+
$container->compile();
144+
145+
$dumper = new PhpDumper($container);
146+
147+
$this->assertStringEqualsFile(self::$fixturesPath.'/php/custom_container_class_with_mandatory_constructor_arguments.php', $dumper->dump(array('base_class' => 'ConstructorWithMandatoryArgumentsContainer', 'namespace' => 'Symfony\Component\DependencyInjection\Tests\Fixtures\Container')));
148+
}
149+
110150
/**
111151
* @dataProvider provideInvalidParameters
112152
* @expectedException \InvalidArgumentException
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
namespace Symfony\Component\DependencyInjection\Tests\Fixtures\Container;
4+
5+
class ConstructorWithMandatoryArgumentsContainer
6+
{
7+
public function __construct($mandatoryArgument)
8+
{
9+
}
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
namespace Symfony\Component\DependencyInjection\Tests\Fixtures\Container;
4+
5+
class ConstructorWithOptionalArgumentsContainer
6+
{
7+
public function __construct($optionalArgument = 'foo')
8+
{
9+
}
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
namespace Symfony\Component\DependencyInjection\Tests\Fixtures\Container;
4+
5+
class ConstructorWithoutArgumentsContainer
6+
{
7+
public function __construct()
8+
{
9+
}
10+
}
+7Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
namespace Symfony\Component\DependencyInjection\Tests\Fixtures\Container;
4+
5+
class NoConstructorContainer
6+
{
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<?php
2+
3+
namespace Symfony\Component\DependencyInjection\Tests\Fixtures\Container;
4+
5+
use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
6+
use Symfony\Component\DependencyInjection\ContainerInterface;
7+
use Symfony\Component\DependencyInjection\Container;
8+
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
9+
use Symfony\Component\DependencyInjection\Exception\LogicException;
10+
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
11+
use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;
12+
13+
/**
14+
* This class has been auto-generated
15+
* by the Symfony Dependency Injection Component.
16+
*
17+
* @final since Symfony 3.3
18+
*/
19+
class ProjectServiceContainer extends \Symfony\Component\DependencyInjection\Tests\Fixtures\Container\ConstructorWithoutArgumentsContainer
20+
{
21+
private $parameters;
22+
private $targetDirs = array();
23+
24+
public function __construct()
25+
{
26+
parent::__construct();
27+
28+
$this->services = array();
29+
30+
$this->aliases = array();
31+
}
32+
33+
public function getRemovedIds()
34+
{
35+
return array(
36+
'Psr\\Container\\ContainerInterface' => true,
37+
'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true,
38+
);
39+
}
40+
41+
public function compile()
42+
{
43+
throw new LogicException('You cannot compile a dumped container that was already compiled.');
44+
}
45+
46+
public function isCompiled()
47+
{
48+
return true;
49+
}
50+
51+
public function isFrozen()
52+
{
53+
@trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the isCompiled() method instead.', __METHOD__), E_USER_DEPRECATED);
54+
55+
return true;
56+
}
57+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?php
2+
3+
namespace Symfony\Component\DependencyInjection\Tests\Fixtures\Container;
4+
5+
use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
6+
use Symfony\Component\DependencyInjection\ContainerInterface;
7+
use Symfony\Component\DependencyInjection\Container;
8+
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
9+
use Symfony\Component\DependencyInjection\Exception\LogicException;
10+
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
11+
use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;
12+
13+
/**
14+
* This class has been auto-generated
15+
* by the Symfony Dependency Injection Component.
16+
*
17+
* @final since Symfony 3.3
18+
*/
19+
class ProjectServiceContainer extends \Symfony\Component\DependencyInjection\Tests\Fixtures\Container\ConstructorWithMandatoryArgumentsContainer
20+
{
21+
private $parameters;
22+
private $targetDirs = array();
23+
24+
public function __construct()
25+
{
26+
$this->services = array();
27+
28+
$this->aliases = array();
29+
}
30+
31+
public function getRemovedIds()
32+
{
33+
return array(
34+
'Psr\\Container\\ContainerInterface' => true,
35+
'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true,
36+
);
37+
}
38+
39+
public function compile()
40+
{
41+
throw new LogicException('You cannot compile a dumped container that was already compiled.');
42+
}
43+
44+
public function isCompiled()
45+
{
46+
return true;
47+
}
48+
49+
public function isFrozen()
50+
{
51+
@trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the isCompiled() method instead.', __METHOD__), E_USER_DEPRECATED);
52+
53+
return true;
54+
}
55+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<?php
2+
3+
namespace Symfony\Component\DependencyInjection\Tests\Fixtures\Container;
4+
5+
use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
6+
use Symfony\Component\DependencyInjection\ContainerInterface;
7+
use Symfony\Component\DependencyInjection\Container;
8+
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
9+
use Symfony\Component\DependencyInjection\Exception\LogicException;
10+
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
11+
use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;
12+
13+
/**
14+
* This class has been auto-generated
15+
* by the Symfony Dependency Injection Component.
16+
*
17+
* @final since Symfony 3.3
18+
*/
19+
class ProjectServiceContainer extends \Symfony\Component\DependencyInjection\Tests\Fixtures\Container\ConstructorWithOptionalArgumentsContainer
20+
{
21+
private $parameters;
22+
private $targetDirs = array();
23+
24+
public function __construct()
25+
{
26+
parent::__construct();
27+
28+
$this->services = array();
29+
30+
$this->aliases = array();
31+
}
32+
33+
public function getRemovedIds()
34+
{
35+
return array(
36+
'Psr\\Container\\ContainerInterface' => true,
37+
'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true,
38+
);
39+
}
40+
41+
public function compile()
42+
{
43+
throw new LogicException('You cannot compile a dumped container that was already compiled.');
44+
}
45+
46+
public function isCompiled()
47+
{
48+
return true;
49+
}
50+
51+
public function isFrozen()
52+
{
53+
@trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the isCompiled() method instead.', __METHOD__), E_USER_DEPRECATED);
54+
55+
return true;
56+
}
57+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?php
2+
3+
namespace Symfony\Component\DependencyInjection\Tests\Fixtures\Container;
4+
5+
use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
6+
use Symfony\Component\DependencyInjection\ContainerInterface;
7+
use Symfony\Component\DependencyInjection\Container;
8+
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
9+
use Symfony\Component\DependencyInjection\Exception\LogicException;
10+
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
11+
use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;
12+
13+
/**
14+
* This class has been auto-generated
15+
* by the Symfony Dependency Injection Component.
16+
*
17+
* @final since Symfony 3.3
18+
*/
19+
class ProjectServiceContainer extends \Symfony\Component\DependencyInjection\Tests\Fixtures\Container\NoConstructorContainer
20+
{
21+
private $parameters;
22+
private $targetDirs = array();
23+
24+
public function __construct()
25+
{
26+
$this->services = array();
27+
28+
$this->aliases = array();
29+
}
30+
31+
public function getRemovedIds()
32+
{
33+
return array(
34+
'Psr\\Container\\ContainerInterface' => true,
35+
'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true,
36+
);
37+
}
38+
39+
public function compile()
40+
{
41+
throw new LogicException('You cannot compile a dumped container that was already compiled.');
42+
}
43+
44+
public function isCompiled()
45+
{
46+
return true;
47+
}
48+
49+
public function isFrozen()
50+
{
51+
@trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the isCompiled() method instead.', __METHOD__), E_USER_DEPRECATED);
52+
53+
return true;
54+
}
55+
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.