Skip to content

Commit 1ec2804

Browse files
Merge branch '3.4' into 4.0
* 3.4: Fix lock strategy tests [travis] cache compiled php extensions fix merge Allow remember-me factory creation when multiple user providers are configured. Add tests for glob loaders Improve assertions [DI][Routing] Fix tracking of globbed resources [Config] Handle Service/EventSubscriberInterface in ReflectionClassResource always call the parent class' constructor
2 parents 5535e6f + c5e8769 commit 1ec2804

13 files changed

+406
-8
lines changed

Compiler/RegisterServiceSubscribersPass.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,14 @@ protected function processValue($value, $isRoot = false)
5656
}
5757
$class = $value->getClass();
5858

59-
if (!is_subclass_of($class, ServiceSubscriberInterface::class)) {
60-
if (!class_exists($class, false)) {
61-
throw new InvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.', $class, $this->currentId));
62-
}
63-
59+
if (!$r = $this->container->getReflectionClass($class)) {
60+
throw new InvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.', $class, $this->currentId));
61+
}
62+
if (!$r->isSubclassOf(ServiceSubscriberInterface::class)) {
6463
throw new InvalidArgumentException(sprintf('Service "%s" must implement interface "%s".', $this->currentId, ServiceSubscriberInterface::class));
6564
}
66-
$this->container->addObjectResource($class);
65+
$class = $r->name;
66+
6767
$subscriberMap = array();
6868
$declaringClass = (new \ReflectionMethod($class, 'getSubscribedServices'))->class;
6969

Dumper/PhpDumper.php

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,11 @@ public function dump(array $options = array())
129129

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

134139
$this->initializeMethodNamesMap('Container' === $baseClass ? Container::class : $baseClass);
@@ -170,7 +175,7 @@ public function dump(array $options = array())
170175
}
171176

172177
$code =
173-
$this->startClass($options['class'], $baseClass).
178+
$this->startClass($options['class'], $baseClass, $baseClassWithNamespace).
174179
$this->addServices().
175180
$this->addDefaultParametersMethod().
176181
$this->endClass()
@@ -861,7 +866,7 @@ private function addNewInstance(Definition $definition, $return, $instantiation,
861866
return $return.sprintf("new %s(%s);\n", $this->dumpLiteralClass($class), implode(', ', $arguments));
862867
}
863868

864-
private function startClass(string $class, string $baseClass): string
869+
private function startClass(string $class, string $baseClass, string $baseClassWithNamespace): string
865870
{
866871
$namespaceLine = !$this->asFiles && $this->namespace ? "\nnamespace {$this->namespace};\n" : '';
867872

@@ -912,6 +917,14 @@ public function __construct()
912917
$code .= " \$this->buildParameters = \$buildParameters;\n";
913918
}
914919

920+
if (Container::class !== $baseClassWithNamespace) {
921+
$r = $this->container->getReflectionClass($baseClassWithNamespace, false);
922+
923+
if (null !== $r && (null !== $constructor = $r->getConstructor()) && 0 === $constructor->getNumberOfRequiredParameters()) {
924+
$code .= " parent::__construct();\n\n";
925+
}
926+
}
927+
915928
if ($this->container->getParameterBag()->all()) {
916929
$code .= " \$this->parameters = \$this->getDefaultParameters();\n\n";
917930
}

Loader/GlobFileLoader.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
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\Component\DependencyInjection\Loader;
13+
14+
/**
15+
* GlobFileLoader loads files from a glob pattern.
16+
*
17+
* @author Nicolas Grekas <[email protected]>
18+
*/
19+
class GlobFileLoader extends FileLoader
20+
{
21+
/**
22+
* {@inheritdoc}
23+
*/
24+
public function load($resource, $type = null)
25+
{
26+
foreach ($this->glob($resource, false, $globResource) as $path => $info) {
27+
$this->import($path);
28+
}
29+
30+
$this->container->addResource($globResource);
31+
}
32+
33+
/**
34+
* {@inheritdoc}
35+
*/
36+
public function supports($resource, $type = null)
37+
{
38+
return 'glob' === $type;
39+
}
40+
}

Tests/Dumper/PhpDumperTest.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,46 @@ public function testDumpRelativeDir()
106106
$this->assertStringEqualsFile(self::$fixturesPath.'/php/services12.php', $dumper->dump(array('file' => __FILE__)), '->dump() dumps __DIR__ relative strings');
107107
}
108108

109+
public function testDumpCustomContainerClassWithoutConstructor()
110+
{
111+
$container = new ContainerBuilder();
112+
$container->compile();
113+
114+
$dumper = new PhpDumper($container);
115+
116+
$this->assertStringEqualsFile(self::$fixturesPath.'/php/custom_container_class_without_constructor.php', $dumper->dump(array('base_class' => 'NoConstructorContainer', 'namespace' => 'Symfony\Component\DependencyInjection\Tests\Fixtures\Container')));
117+
}
118+
119+
public function testDumpCustomContainerClassConstructorWithoutArguments()
120+
{
121+
$container = new ContainerBuilder();
122+
$container->compile();
123+
124+
$dumper = new PhpDumper($container);
125+
126+
$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')));
127+
}
128+
129+
public function testDumpCustomContainerClassWithOptionalArgumentLessConstructor()
130+
{
131+
$container = new ContainerBuilder();
132+
$container->compile();
133+
134+
$dumper = new PhpDumper($container);
135+
136+
$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')));
137+
}
138+
139+
public function testDumpCustomContainerClassWithMandatoryArgumentLessConstructor()
140+
{
141+
$container = new ContainerBuilder();
142+
$container->compile();
143+
144+
$dumper = new PhpDumper($container);
145+
146+
$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')));
147+
}
148+
109149
/**
110150
* @dataProvider provideInvalidParameters
111151
* @expectedException \InvalidArgumentException
Lines changed: 10 additions & 0 deletions
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+
}
Lines changed: 10 additions & 0 deletions
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+
}
Lines changed: 10 additions & 0 deletions
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+
}
Lines 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+
}
Lines changed: 57 additions & 0 deletions
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+
}
Lines changed: 55 additions & 0 deletions
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+
}

0 commit comments

Comments
 (0)