Skip to content

Commit cfc4879

Browse files
committed
[DependencyInjection] Properly ignore invalid reference arguments in collection arguments
1 parent 03c4276 commit cfc4879

File tree

2 files changed

+62
-4
lines changed

2 files changed

+62
-4
lines changed

src/Symfony/Component/DependencyInjection/Compiler/ResolveInvalidReferencesPass.php

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,16 +71,19 @@ public function process(ContainerBuilder $container)
7171
*
7272
* @param array $arguments An array of Reference objects
7373
* @param bool $inMethodCall
74+
* @param bool $inCollection
7475
*
7576
* @return array
7677
*
7778
* @throws RuntimeException When the config is invalid
7879
*/
79-
private function processArguments(array $arguments, $inMethodCall = false)
80+
private function processArguments(array $arguments, $inMethodCall = false, $inCollection = false)
8081
{
82+
$isNumeric = array_keys($arguments) === range(0, count($arguments) - 1);
83+
8184
foreach ($arguments as $k => $argument) {
8285
if (is_array($argument)) {
83-
$arguments[$k] = $this->processArguments($argument, $inMethodCall);
86+
$arguments[$k] = $this->processArguments($argument, $inMethodCall, true);
8487
} elseif ($argument instanceof Reference) {
8588
$id = (string) $argument;
8689

@@ -91,6 +94,10 @@ private function processArguments(array $arguments, $inMethodCall = false)
9194
if (!$exists && ContainerInterface::NULL_ON_INVALID_REFERENCE === $invalidBehavior) {
9295
$arguments[$k] = null;
9396
} elseif (!$exists && ContainerInterface::IGNORE_ON_INVALID_REFERENCE === $invalidBehavior) {
97+
if ($inCollection) {
98+
unset($arguments[$k]);
99+
continue;
100+
}
94101
if ($inMethodCall) {
95102
throw new RuntimeException('Method shouldn\'t be called.');
96103
}
@@ -100,6 +107,11 @@ private function processArguments(array $arguments, $inMethodCall = false)
100107
}
101108
}
102109

110+
// Ensure numerically indexed arguments have sequential numeric keys.
111+
if ($isNumeric) {
112+
$arguments = array_values($arguments);
113+
}
114+
103115
return $arguments;
104116
}
105117
}

src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveInvalidReferencesPassTest.php

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,63 @@ public function testProcess()
2323
$container = new ContainerBuilder();
2424
$def = $container
2525
->register('foo')
26-
->setArguments(array(new Reference('bar', ContainerInterface::NULL_ON_INVALID_REFERENCE)))
26+
->setArguments(array(
27+
new Reference('bar', ContainerInterface::NULL_ON_INVALID_REFERENCE),
28+
new Reference('baz', ContainerInterface::IGNORE_ON_INVALID_REFERENCE),
29+
))
2730
->addMethodCall('foo', array(new Reference('moo', ContainerInterface::IGNORE_ON_INVALID_REFERENCE)))
2831
;
2932

3033
$this->process($container);
3134

3235
$arguments = $def->getArguments();
33-
$this->assertNull($arguments[0]);
36+
$this->assertSame(array(null, null), $arguments);
3437
$this->assertCount(0, $def->getMethodCalls());
3538
}
3639

40+
public function testProcessIgnoreInvalidArgumentInCollectionArgument()
41+
{
42+
$container = new ContainerBuilder();
43+
$container->register('baz');
44+
$def = $container
45+
->register('foo')
46+
->setArguments(array(
47+
array(
48+
new Reference('bar', ContainerInterface::IGNORE_ON_INVALID_REFERENCE),
49+
$baz = new Reference('baz', ContainerInterface::IGNORE_ON_INVALID_REFERENCE),
50+
new Reference('moo', ContainerInterface::NULL_ON_INVALID_REFERENCE),
51+
),
52+
))
53+
;
54+
55+
$this->process($container);
56+
57+
$arguments = $def->getArguments();
58+
$this->assertSame(array($baz, null), $arguments[0]);
59+
}
60+
61+
public function testProcessKeepMethodCallOnInvalidArgumentInCollectionArgument()
62+
{
63+
$container = new ContainerBuilder();
64+
$container->register('baz');
65+
$def = $container
66+
->register('foo')
67+
->addMethodCall('foo', array(
68+
array(
69+
new Reference('bar', ContainerInterface::IGNORE_ON_INVALID_REFERENCE),
70+
$baz = new Reference('baz', ContainerInterface::IGNORE_ON_INVALID_REFERENCE),
71+
new Reference('moo', ContainerInterface::NULL_ON_INVALID_REFERENCE),
72+
),
73+
))
74+
;
75+
76+
$this->process($container);
77+
78+
$calls = $def->getMethodCalls();
79+
$this->assertCount(1, $def->getMethodCalls());
80+
$this->assertSame(array($baz, null), $calls[0][1][0]);
81+
}
82+
3783
public function testProcessIgnoreNonExistentServices()
3884
{
3985
$container = new ContainerBuilder();

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy