Skip to content

Commit cfdc145

Browse files
Merge branch '4.0'
* 4.0: [Form] Fixed ContextErrorException in FileType [DI] Fix handling of inlined definitions by ContainerBuilder [Security] remove unused variable [DI] Fix infinite loop when analyzing references [Lock][Process][FrameworkBundle] fix tests Display a nice error message if the form/serializer component is missing. [SecurityBundle] providerIds is undefined error when firewall provider is not specified [SecurityBundle] providerIds is undefined error when firewall provider is not specified [SecurityBundle] providerIds is undefined error when firewall provider is not specified Force phpunit-bridge update (bis) [Bridge/PhpUnit] Fix disabling global state preservation Incorrect dot on method loadChoices in upgrade doc
2 parents 82b36e4 + 38ddcef commit cfdc145

File tree

13 files changed

+100
-48
lines changed

13 files changed

+100
-48
lines changed

phpunit

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#!/usr/bin/env php
22
<?php
33

4-
// Cache-Id: https://github.com/symfony/phpunit-bridge/commit/3646664aa952fe13e9a612a726cbb38e02249793
4+
// Cache-Id: https://github.com/symfony/phpunit-bridge/commit/66ffffcd8a6bb23aec847c8bdfb918610399499a
55

66
if (!file_exists(__DIR__.'/vendor/symfony/phpunit-bridge/bin/simple-phpunit')) {
77
echo "Unable to find the `simple-phpunit` script in `vendor/symfony/phpunit-bridge/bin/`.\nPlease run `composer update` before running this command.\n";

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -137,10 +137,6 @@ public function load(array $configs, ContainerBuilder $container)
137137
throw new LogicException('Translation support cannot be enabled as the Translation component is not installed.');
138138
}
139139

140-
if (!class_exists('Symfony\Component\Translation\Translator') && $this->isConfigEnabled($container, $config['validation'])) {
141-
throw new LogicException('Validation support cannot be enabled as the Translation component is not installed.');
142-
}
143-
144140
if (class_exists(Translator::class)) {
145141
$loader->load('identity_translator.xml');
146142
}
@@ -184,6 +180,10 @@ public function load(array $configs, ContainerBuilder $container)
184180
}
185181

186182
if ($this->isConfigEnabled($container, $config['form'])) {
183+
if (!class_exists('Symfony\Component\Form\Form')) {
184+
throw new LogicException('Form support cannot be enabled as the Form component is not installed.');
185+
}
186+
187187
$this->formConfigEnabled = true;
188188
$this->registerFormConfiguration($config, $container, $loader);
189189

@@ -231,6 +231,10 @@ public function load(array $configs, ContainerBuilder $container)
231231
$this->registerPropertyAccessConfiguration($config['property_access'], $container, $loader);
232232

233233
if ($this->isConfigEnabled($container, $config['serializer'])) {
234+
if (!class_exists('Symfony\Component\Serializer\Serializer')) {
235+
throw new LogicException('Serializer support cannot be enabled as the Serializer component is not installed.');
236+
}
237+
234238
$this->registerSerializerConfiguration($config['serializer'], $container, $loader);
235239
}
236240

@@ -923,6 +927,7 @@ private function registerTranslatorConfiguration(array $config, ContainerBuilder
923927
return 2 === substr_count($file->getBasename(), '.') && preg_match('/\.\w+$/', $file->getBasename());
924928
})
925929
->in($dirs)
930+
->sortByName()
926931
;
927932

928933
foreach ($finder as $file) {
@@ -1032,7 +1037,7 @@ private function registerValidatorMapping(ContainerBuilder $container, array $co
10321037

10331038
private function registerMappingFilesFromDir($dir, callable $fileRecorder)
10341039
{
1035-
foreach (Finder::create()->followLinks()->files()->in($dir)->name('/\.(xml|ya?ml)$/') as $file) {
1040+
foreach (Finder::create()->followLinks()->files()->in($dir)->name('/\.(xml|ya?ml)$/')->sortByName() as $file) {
10361041
$fileRecorder($file->getExtension(), $file->getRealPath());
10371042
}
10381043
}

src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ private function createFirewall(ContainerBuilder $container, $id, $firewall, &$a
349349
// Switch user listener
350350
if (isset($firewall['switch_user'])) {
351351
$listenerKeys[] = 'switch_user';
352-
$listeners[] = new Reference($this->createSwitchUserListener($container, $id, $firewall['switch_user'], $defaultProvider, $firewall['stateless']));
352+
$listeners[] = new Reference($this->createSwitchUserListener($container, $id, $firewall['switch_user'], $defaultProvider, $firewall['stateless'], $providerIds));
353353
}
354354

355355
// Access listener
@@ -594,7 +594,7 @@ private function createExceptionListener($container, $config, $id, $defaultEntry
594594
return $exceptionListenerId;
595595
}
596596

597-
private function createSwitchUserListener($container, $id, $config, $defaultProvider = null, $stateless)
597+
private function createSwitchUserListener($container, $id, $config, $defaultProvider, $stateless, $providerIds)
598598
{
599599
$userProvider = isset($config['provider']) ? $this->getUserProviderId($config['provider']) : $defaultProvider;
600600

src/Symfony/Bundle/SecurityBundle/composer.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
"symfony/dom-crawler": "~3.4|~4.0",
3131
"symfony/event-dispatcher": "~3.4|~4.0",
3232
"symfony/form": "~3.4|~4.0",
33-
"symfony/framework-bundle": "~3.4|~4.0",
33+
"symfony/framework-bundle": "~3.4-rc1|~4.0-rc1",
3434
"symfony/http-foundation": "~3.4|~4.0",
3535
"symfony/translation": "~3.4|~4.0",
3636
"symfony/twig-bundle": "~3.4|~4.0",
@@ -40,7 +40,7 @@
4040
"symfony/var-dumper": "~3.4|~4.0",
4141
"symfony/yaml": "~3.4|~4.0",
4242
"symfony/expression-language": "~3.4|~4.0",
43-
"doctrine/doctrine-bundle": "~1.4",
43+
"doctrine/doctrine-bundle": "~1.5",
4444
"twig/twig": "~1.34|~2.4"
4545
},
4646
"conflict": {

src/Symfony/Component/DependencyInjection/ContainerBuilder.php

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -544,7 +544,7 @@ public function get($id, $invalidBehavior = ContainerInterface::EXCEPTION_ON_INV
544544
$this->{$loading}[$id] = true;
545545

546546
try {
547-
$service = $this->createService($definition, $id);
547+
$service = $this->createService($definition, new \SplObjectStorage(), $id);
548548
} finally {
549549
unset($this->{$loading}[$id]);
550550
}
@@ -978,8 +978,12 @@ public function findDefinition($id)
978978
* @throws RuntimeException When the service is a synthetic service
979979
* @throws InvalidArgumentException When configure callable is not callable
980980
*/
981-
private function createService(Definition $definition, $id, $tryProxy = true)
981+
private function createService(Definition $definition, \SplObjectStorage $inlinedDefinitions, $id = null, $tryProxy = true)
982982
{
983+
if (null === $id && isset($inlinedDefinitions[$definition])) {
984+
return $inlinedDefinitions[$definition];
985+
}
986+
983987
if ($definition instanceof ChildDefinition) {
984988
throw new RuntimeException(sprintf('Constructing service "%s" from a parent definition is not supported at build time.', $id));
985989
}
@@ -998,11 +1002,11 @@ private function createService(Definition $definition, $id, $tryProxy = true)
9981002
->instantiateProxy(
9991003
$this,
10001004
$definition,
1001-
$id, function () use ($definition, $id) {
1002-
return $this->createService($definition, $id, false);
1005+
$id, function () use ($definition, $inlinedDefinitions, $id) {
1006+
return $this->createService($definition, $inlinedDefinitions, $id, false);
10031007
}
10041008
);
1005-
$this->shareService($definition, $proxy, $id);
1009+
$this->shareService($definition, $proxy, $id, $inlinedDefinitions);
10061010

10071011
return $proxy;
10081012
}
@@ -1013,15 +1017,15 @@ private function createService(Definition $definition, $id, $tryProxy = true)
10131017
require_once $parameterBag->resolveValue($definition->getFile());
10141018
}
10151019

1016-
$arguments = $this->resolveServices($parameterBag->unescapeValue($parameterBag->resolveValue($definition->getArguments())));
1020+
$arguments = $this->doResolveServices($parameterBag->unescapeValue($parameterBag->resolveValue($definition->getArguments())), $inlinedDefinitions);
10171021

10181022
if (null !== $id && $definition->isShared() && isset($this->services[$id]) && ($tryProxy || !$definition->isLazy())) {
10191023
return $this->services[$id];
10201024
}
10211025

10221026
if (null !== $factory = $definition->getFactory()) {
10231027
if (is_array($factory)) {
1024-
$factory = array($this->resolveServices($parameterBag->resolveValue($factory[0])), $factory[1]);
1028+
$factory = array($this->doResolveServices($parameterBag->resolveValue($factory[0]), $inlinedDefinitions), $factory[1]);
10251029
} elseif (!is_string($factory)) {
10261030
throw new RuntimeException(sprintf('Cannot create service "%s" because of invalid factory', $id));
10271031
}
@@ -1047,16 +1051,16 @@ private function createService(Definition $definition, $id, $tryProxy = true)
10471051

10481052
if ($tryProxy || !$definition->isLazy()) {
10491053
// share only if proxying failed, or if not a proxy
1050-
$this->shareService($definition, $service, $id);
1054+
$this->shareService($definition, $service, $id, $inlinedDefinitions);
10511055
}
10521056

1053-
$properties = $this->resolveServices($parameterBag->unescapeValue($parameterBag->resolveValue($definition->getProperties())));
1057+
$properties = $this->doResolveServices($parameterBag->unescapeValue($parameterBag->resolveValue($definition->getProperties())), $inlinedDefinitions);
10541058
foreach ($properties as $name => $value) {
10551059
$service->$name = $value;
10561060
}
10571061

10581062
foreach ($definition->getMethodCalls() as $call) {
1059-
$this->callMethod($service, $call);
1063+
$this->callMethod($service, $call, $inlinedDefinitions);
10601064
}
10611065

10621066
if ($callable = $definition->getConfigurator()) {
@@ -1066,7 +1070,7 @@ private function createService(Definition $definition, $id, $tryProxy = true)
10661070
if ($callable[0] instanceof Reference) {
10671071
$callable[0] = $this->get((string) $callable[0], $callable[0]->getInvalidBehavior());
10681072
} elseif ($callable[0] instanceof Definition) {
1069-
$callable[0] = $this->createService($callable[0], null);
1073+
$callable[0] = $this->createService($callable[0], $inlinedDefinitions);
10701074
}
10711075
}
10721076

@@ -1089,10 +1093,15 @@ private function createService(Definition $definition, $id, $tryProxy = true)
10891093
* the real service instances and all expressions evaluated
10901094
*/
10911095
public function resolveServices($value)
1096+
{
1097+
return $this->doResolveServices($value, new \SplObjectStorage());
1098+
}
1099+
1100+
private function doResolveServices($value, \SplObjectStorage $inlinedDefinitions)
10921101
{
10931102
if (is_array($value)) {
10941103
foreach ($value as $k => $v) {
1095-
$value[$k] = $this->resolveServices($v);
1104+
$value[$k] = $this->doResolveServices($v, $inlinedDefinitions);
10961105
}
10971106
} elseif ($value instanceof ServiceClosureArgument) {
10981107
$reference = $value->getValues()[0];
@@ -1137,7 +1146,7 @@ public function resolveServices($value)
11371146
} elseif ($value instanceof Reference) {
11381147
$value = $this->get((string) $value, $value->getInvalidBehavior());
11391148
} elseif ($value instanceof Definition) {
1140-
$value = $this->createService($value, null);
1149+
$value = $this->createService($value, $inlinedDefinitions);
11411150
} elseif ($value instanceof Expression) {
11421151
$value = $this->getExpressionLanguage()->evaluate($value, array('container' => $this));
11431152
}
@@ -1434,7 +1443,7 @@ private function getProxyInstantiator(): InstantiatorInterface
14341443
return $this->proxyInstantiator;
14351444
}
14361445

1437-
private function callMethod($service, $call)
1446+
private function callMethod($service, $call, \SplObjectStorage $inlinedDefinitions)
14381447
{
14391448
foreach (self::getServiceConditionals($call[1]) as $s) {
14401449
if (!$this->has($s)) {
@@ -1447,7 +1456,7 @@ private function callMethod($service, $call)
14471456
}
14481457
}
14491458

1450-
call_user_func_array(array($service, $call[0]), $this->resolveServices($this->getParameterBag()->unescapeValue($this->getParameterBag()->resolveValue($call[1]))));
1459+
call_user_func_array(array($service, $call[0]), $this->doResolveServices($this->getParameterBag()->unescapeValue($this->getParameterBag()->resolveValue($call[1])), $inlinedDefinitions));
14511460
}
14521461

14531462
/**
@@ -1457,9 +1466,14 @@ private function callMethod($service, $call)
14571466
* @param object $service
14581467
* @param string|null $id
14591468
*/
1460-
private function shareService(Definition $definition, $service, $id)
1469+
private function shareService(Definition $definition, $service, $id, \SplObjectStorage $inlinedDefinitions)
14611470
{
1462-
if (null !== $id && $definition->isShared()) {
1471+
if (!$definition->isShared()) {
1472+
return;
1473+
}
1474+
if (null === $id) {
1475+
$inlinedDefinitions[$definition] = $service;
1476+
} else {
14631477
$this->services[$id] = $service;
14641478
unset($this->loading[$id], $this->alreadyLoading[$id]);
14651479
}

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,7 @@ private function analyzeCircularReferences(array $edges, &$checkedNodes, &$curre
353353
if (isset($checkedNodes[$id])) {
354354
continue;
355355
}
356+
$checkedNodes[$id] = true;
356357

357358
if ($node->getValue() && ($edge->isLazy() || $edge->isWeak())) {
358359
// no-op
@@ -364,10 +365,8 @@ private function analyzeCircularReferences(array $edges, &$checkedNodes, &$curre
364365
} else {
365366
$currentPath[$id] = $id;
366367
$this->analyzeCircularReferences($node->getOutEdges(), $checkedNodes, $currentPath);
368+
array_pop($currentPath);
367369
}
368-
369-
$checkedNodes[$id] = true;
370-
array_pop($currentPath);
371370
}
372371
}
373372

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1051,6 +1051,28 @@ public function testLazyLoadedService()
10511051
$this->assertTrue($classInList);
10521052
}
10531053

1054+
public function testInlinedDefinitions()
1055+
{
1056+
$container = new ContainerBuilder();
1057+
1058+
$definition = new Definition('BarClass');
1059+
1060+
$container->register('bar_user', 'BarUserClass')
1061+
->addArgument($definition)
1062+
->setProperty('foo', $definition);
1063+
1064+
$container->register('bar', 'BarClass')
1065+
->setProperty('foo', $definition)
1066+
->addMethodCall('setBaz', array($definition));
1067+
1068+
$barUser = $container->get('bar_user');
1069+
$bar = $container->get('bar');
1070+
1071+
$this->assertSame($barUser->foo, $barUser->bar);
1072+
$this->assertSame($bar->foo, $bar->getBaz());
1073+
$this->assertNotSame($bar->foo, $barUser->foo);
1074+
}
1075+
10541076
public function testInitializePropertiesBeforeMethodCalls()
10551077
{
10561078
$container = new ContainerBuilder();

src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/classes.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ function sc_configure($instance)
99
$instance->configure();
1010
}
1111

12-
class BarClass
12+
class BarClass extends BazClass
1313
{
1414
protected $baz;
1515
public $foo = 'foo';

src/Symfony/Component/Form/Extension/Core/Type/FileType.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,13 @@ public function buildForm(FormBuilderInterface $builder, array $options)
3434

3535
if ($options['multiple']) {
3636
$data = array();
37+
$files = $event->getData();
3738

38-
foreach ($event->getData() as $file) {
39+
if (!is_array($files)) {
40+
$files = array();
41+
}
42+
43+
foreach ($files as $file) {
3944
if ($requestHandler->isFileUpload($file)) {
4045
$data[] = $file;
4146
}

src/Symfony/Component/Form/Tests/Extension/Core/Type/FileTypeTest.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,24 @@ public function testMultipleSubmittedFilePathsAreDropped(RequestHandlerInterface
159159
$this->assertCount(1, $form->getData());
160160
}
161161

162+
/**
163+
* @dataProvider requestHandlerProvider
164+
*/
165+
public function testSubmitNonArrayValueWhenMultiple(RequestHandlerInterface $requestHandler)
166+
{
167+
$form = $this->factory
168+
->createBuilder(static::TESTED_TYPE, null, array(
169+
'multiple' => true,
170+
))
171+
->setRequestHandler($requestHandler)
172+
->getForm();
173+
$form->submit(null);
174+
175+
$this->assertSame(array(), $form->getData());
176+
$this->assertSame(array(), $form->getNormData());
177+
$this->assertSame(array(), $form->getViewData());
178+
}
179+
162180
public function requestHandlerProvider()
163181
{
164182
return array(

0 commit comments

Comments
 (0)