Skip to content

Commit 10ec39e

Browse files
Merge branch '2.7' into 2.8
* 2.7: [Form] Fixed ContextErrorException in FileType [DI] Fix handling of inlined definitions by ContainerBuilder
2 parents caad854 + a809ab2 commit 10ec39e

File tree

5 files changed

+80
-21
lines changed

5 files changed

+80
-21
lines changed

src/Symfony/Component/DependencyInjection/ContainerBuilder.php

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,7 @@ public function get($id, $invalidBehavior = ContainerInterface::EXCEPTION_ON_INV
460460
$this->loading[$id] = true;
461461

462462
try {
463-
$service = $this->createService($definition, $id);
463+
$service = $this->createService($definition, new \SplObjectStorage(), $id);
464464
} catch (\Exception $e) {
465465
unset($this->loading[$id]);
466466

@@ -846,8 +846,12 @@ public function findDefinition($id)
846846
*
847847
* @internal this method is public because of PHP 5.3 limitations, do not use it explicitly in your code
848848
*/
849-
public function createService(Definition $definition, $id, $tryProxy = true)
849+
public function createService(Definition $definition, \SplObjectStorage $inlinedDefinitions, $id = null, $tryProxy = true)
850850
{
851+
if (null === $id && isset($inlinedDefinitions[$definition])) {
852+
return $inlinedDefinitions[$definition];
853+
}
854+
851855
if ($definition instanceof DefinitionDecorator) {
852856
throw new RuntimeException(sprintf('Constructing service "%s" from a parent definition is not supported at build time.', $id));
853857
}
@@ -868,11 +872,11 @@ public function createService(Definition $definition, $id, $tryProxy = true)
868872
->instantiateProxy(
869873
$container,
870874
$definition,
871-
$id, function () use ($definition, $id, $container) {
872-
return $container->createService($definition, $id, false);
875+
$id, function () use ($definition, $inlinedDefinitions, $id, $container) {
876+
return $container->createService($definition, $inlinedDefinitions, $id, false);
873877
}
874878
);
875-
$this->shareService($definition, $proxy, $id);
879+
$this->shareService($definition, $proxy, $id, $inlinedDefinitions);
876880

877881
return $proxy;
878882
}
@@ -883,11 +887,11 @@ public function createService(Definition $definition, $id, $tryProxy = true)
883887
require_once $parameterBag->resolveValue($definition->getFile());
884888
}
885889

886-
$arguments = $this->resolveServices($parameterBag->unescapeValue($parameterBag->resolveValue($definition->getArguments())));
890+
$arguments = $this->doResolveServices($parameterBag->unescapeValue($parameterBag->resolveValue($definition->getArguments())), $inlinedDefinitions);
887891

888892
if (null !== $factory = $definition->getFactory()) {
889893
if (is_array($factory)) {
890-
$factory = array($this->resolveServices($parameterBag->resolveValue($factory[0])), $factory[1]);
894+
$factory = array($this->doResolveServices($parameterBag->resolveValue($factory[0]), $inlinedDefinitions), $factory[1]);
891895
} elseif (!is_string($factory)) {
892896
throw new RuntimeException(sprintf('Cannot create service "%s" because of invalid factory', $id));
893897
}
@@ -923,16 +927,16 @@ public function createService(Definition $definition, $id, $tryProxy = true)
923927

924928
if ($tryProxy || !$definition->isLazy()) {
925929
// share only if proxying failed, or if not a proxy
926-
$this->shareService($definition, $service, $id);
930+
$this->shareService($definition, $service, $id, $inlinedDefinitions);
927931
}
928932

929-
$properties = $this->resolveServices($parameterBag->unescapeValue($parameterBag->resolveValue($definition->getProperties())));
933+
$properties = $this->doResolveServices($parameterBag->unescapeValue($parameterBag->resolveValue($definition->getProperties())), $inlinedDefinitions);
930934
foreach ($properties as $name => $value) {
931935
$service->$name = $value;
932936
}
933937

934938
foreach ($definition->getMethodCalls() as $call) {
935-
$this->callMethod($service, $call);
939+
$this->callMethod($service, $call, $inlinedDefinitions);
936940
}
937941

938942
if ($callable = $definition->getConfigurator()) {
@@ -942,7 +946,7 @@ public function createService(Definition $definition, $id, $tryProxy = true)
942946
if ($callable[0] instanceof Reference) {
943947
$callable[0] = $this->get((string) $callable[0], $callable[0]->getInvalidBehavior());
944948
} elseif ($callable[0] instanceof Definition) {
945-
$callable[0] = $this->createService($callable[0], null);
949+
$callable[0] = $this->createService($callable[0], $inlinedDefinitions);
946950
}
947951
}
948952

@@ -965,15 +969,20 @@ public function createService(Definition $definition, $id, $tryProxy = true)
965969
* the real service instances and all expressions evaluated
966970
*/
967971
public function resolveServices($value)
972+
{
973+
return $this->doResolveServices($value, new \SplObjectStorage());
974+
}
975+
976+
private function doResolveServices($value, \SplObjectStorage $inlinedDefinitions)
968977
{
969978
if (is_array($value)) {
970979
foreach ($value as $k => $v) {
971-
$value[$k] = $this->resolveServices($v);
980+
$value[$k] = $this->doResolveServices($v, $inlinedDefinitions);
972981
}
973982
} elseif ($value instanceof Reference) {
974983
$value = $this->get((string) $value, $value->getInvalidBehavior());
975984
} elseif ($value instanceof Definition) {
976-
$value = $this->createService($value, null);
985+
$value = $this->createService($value, $inlinedDefinitions);
977986
} elseif ($value instanceof Expression) {
978987
$value = $this->getExpressionLanguage()->evaluate($value, array('container' => $this));
979988
}
@@ -1111,14 +1120,14 @@ private function synchronize($id)
11111120
foreach ($definition->getMethodCalls() as $call) {
11121121
foreach ($call[1] as $argument) {
11131122
if ($argument instanceof Reference && $id == (string) $argument) {
1114-
$this->callMethod($this->get($definitionId), $call);
1123+
$this->callMethod($this->get($definitionId), $call, new \SplObjectStorage());
11151124
}
11161125
}
11171126
}
11181127
}
11191128
}
11201129

1121-
private function callMethod($service, $call)
1130+
private function callMethod($service, $call, \SplObjectStorage $inlinedDefinitions)
11221131
{
11231132
$services = self::getServiceConditionals($call[1]);
11241133

@@ -1128,7 +1137,7 @@ private function callMethod($service, $call)
11281137
}
11291138
}
11301139

1131-
call_user_func_array(array($service, $call[0]), $this->resolveServices($this->getParameterBag()->unescapeValue($this->getParameterBag()->resolveValue($call[1]))));
1140+
call_user_func_array(array($service, $call[0]), $this->doResolveServices($this->getParameterBag()->unescapeValue($this->getParameterBag()->resolveValue($call[1])), $inlinedDefinitions));
11321141
}
11331142

11341143
/**
@@ -1140,9 +1149,14 @@ private function callMethod($service, $call)
11401149
*
11411150
* @throws InactiveScopeException
11421151
*/
1143-
private function shareService(Definition $definition, $service, $id)
1152+
private function shareService(Definition $definition, $service, $id, \SplObjectStorage $inlinedDefinitions)
11441153
{
1145-
if (null !== $id && $definition->isShared() && self::SCOPE_PROTOTYPE !== $scope = $definition->getScope(false)) {
1154+
if (!$definition->isShared() || self::SCOPE_PROTOTYPE === $scope = $definition->getScope()) {
1155+
return;
1156+
}
1157+
if (null === $id) {
1158+
$inlinedDefinitions[$definition] = $service;
1159+
} else {
11461160
if (self::SCOPE_CONTAINER !== $scope && !isset($this->scopedServices[$scope])) {
11471161
throw new InactiveScopeException($id, $scope);
11481162
}

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

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ public function testCreateDeprecatedService()
7272
$definition->setDeprecated(true);
7373

7474
$builder = new ContainerBuilder();
75-
$builder->createService($definition, 'deprecated_foo');
75+
$builder->createService($definition, new \SplObjectStorage(), 'deprecated_foo');
7676
}
7777

7878
public function testRegister()
@@ -865,6 +865,28 @@ public function testLazyLoadedService()
865865
$this->assertTrue($classInList);
866866
}
867867

868+
public function testInlinedDefinitions()
869+
{
870+
$container = new ContainerBuilder();
871+
872+
$definition = new Definition('BarClass');
873+
874+
$container->register('bar_user', 'BarUserClass')
875+
->addArgument($definition)
876+
->setProperty('foo', $definition);
877+
878+
$container->register('bar', 'BarClass')
879+
->setProperty('foo', $definition)
880+
->addMethodCall('setBaz', array($definition));
881+
882+
$barUser = $container->get('bar_user');
883+
$bar = $container->get('bar');
884+
885+
$this->assertSame($barUser->foo, $barUser->bar);
886+
$this->assertSame($bar->foo, $bar->getBaz());
887+
$this->assertNotSame($bar->foo, $barUser->foo);
888+
}
889+
868890
public function testInitializePropertiesBeforeMethodCalls()
869891
{
870892
$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
@@ -8,7 +8,7 @@ function sc_configure($instance)
88
$instance->configure();
99
}
1010

11-
class BarClass
11+
class BarClass extends BazClass
1212
{
1313
protected $baz;
1414
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
@@ -169,6 +169,24 @@ public function testMultipleSubmittedFilePathsAreDropped(RequestHandlerInterface
169169
$this->assertCount(1, $form->getData());
170170
}
171171

172+
/**
173+
* @dataProvider requestHandlerProvider
174+
*/
175+
public function testSubmitNonArrayValueWhenMultiple(RequestHandlerInterface $requestHandler)
176+
{
177+
$form = $this->factory
178+
->createBuilder(static::TESTED_TYPE, null, array(
179+
'multiple' => true,
180+
))
181+
->setRequestHandler($requestHandler)
182+
->getForm();
183+
$form->submit(null);
184+
185+
$this->assertSame(array(), $form->getData());
186+
$this->assertSame(array(), $form->getNormData());
187+
$this->assertSame(array(), $form->getViewData());
188+
}
189+
172190
public function requestHandlerProvider()
173191
{
174192
return array(

0 commit comments

Comments
 (0)