8000 [DependencyInjection] Fix order of arguments when mixing positional a… · symfony/symfony@eaac56b · GitHub
[go: up one dir, main page]

Skip to content

Commit eaac56b

Browse files
[DependencyInjection] Fix order of arguments when mixing positional and named ones
1 parent ef26e93 commit eaac56b

File tree

5 files changed

+62
-4
lines changed

5 files changed

+62
-4
lines changed

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,10 @@ private function autowireMethod(\ReflectionFunctionAbstract $reflectionMethod, a
240240
foreach ($parameters as $index => $parameter) {
241241
$this->defaultArgument->names[$index] = $parameter->name;
242242

243+
if (\array_key_exists($parameter->name, $arguments)) {
244+
$arguments[$index] = $arguments[$parameter->name];
245+
unset($arguments[$parameter->name]);
246+
}
243247
if (\array_key_exists($index, $arguments) && '' !== $arguments[$index]) {
244248
continue;
245249
}
@@ -341,7 +345,7 @@ private function autowireMethod(\ReflectionFunctionAbstract $reflectionMethod, a
341345

342346
// it's possible index 1 was set, then index 0, then 2, etc
343347
// make sure that we re-order so they're injected as expected
344-
ksort($arguments);
348+
ksort($arguments, \SORT_NATURAL);
345349

346350
return $arguments;
347351
}

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

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,10 +177,17 @@ protected function processValue($value, bool $isRoot = false)
177177
}
178178
}
179179

180+
$names = [];
181+
180182
foreach ($reflectionMethod->getParameters() as $key => $parameter) {
183+
$names[$key] = $parameter->name;
184+
181185
if (\array_key_exists($key, $arguments) && '' !== $arguments[$key]) {
182186
continue;
183187
}
188+
if (\array_key_exists($parameter->name, $arguments) && '' !== $arguments[$parameter->name]) {
189+
continue;
190+
}
184191

185192
$typeHint = ProxyHelper::getTypeHint($reflectionMethod, $parameter);
186193
$name = Target::parseName($parameter);
@@ -210,8 +217,15 @@ protected function processValue($value, bool $isRoot = false)
210217
}
211218
}
212219

220+
foreach ($names as $key => $name) {
221+
if (\array_key_exists($name, $arguments) && (\array_key_exists($key - 1, $arguments) || \array_key_exists($names[$key - 1] ?? '', $arguments))) {
222+
$arguments[$key] = $arguments[$name];
223+
unset($arguments[$name]);
224+
}
225+
}
226+
213227
if ($arguments !== $call[1]) {
214-
ksort($arguments);
228+
ksort($arguments, \SORT_NATURAL);
215229
$calls[$i][1] = $arguments;
216230
}
217231
}

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,11 +107,12 @@ protected function processValue($value, bool $isRoot = false)
107107
}
108108

109109
if ($resolvedArguments !== $call[1]) {
110-
ksort($resolvedArguments);
110+
ksort($resolvedArguments, \SORT_NATURAL);
111111

112112
if (!$value->isAutowired() && !array_is_list($resolvedArguments)) {
113-
ksort($resolvedKeys);
113+
ksort($resolvedKeys, \SORT_NATURAL);
114114
$resolvedArguments = array_combine($resolvedKeys, $resolvedArguments);
115+
ksort($resolvedArguments, \SORT_NATURAL);
115116
}
116117

117118
$calls[$i][1] = $resolvedArguments;

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1204,4 +1204,19 @@ public function testDecorationWithServiceAndAliasedInterface()
12041204
static::assertInstanceOf(DecoratedDecorator::class, $container->get(DecoratorInterface::class));
12051205
static::assertInstanceOf(DecoratedDecorator::class, $container->get(DecoratorImpl::class));
12061206
}
1207+
1208+
public function testAutowireWithNamedArgs()
1209+
{
1210+
$container = new ContainerBuilder();
1211+
1212+
$container->register('foo', MultipleArgumentsOptionalScalar::class)
1213+
->setArguments(['foo' => 'abc'])
1214+
->setAutowired(true)
1215+
->setPublic(true);
1216+
$container->register(A::class, A::class);
1217+
1218+
(new AutowirePass())->process($container);
1219+
1220+
$this->assertEquals([new TypedReference(A::class, A::class), 'abc'], $container->getDefinition('foo')->getArguments());
1221+
}
12071222
}

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

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,4 +249,28 @@ public function testBindWithTarget()
249249

250250
$this->assertSame('bar', (string) $container->getDefinition('with_target')->getArgument(0));
251251
}
252+
253+
public function testBindWithNamedArgs()
254+
{
255+
$container = new ContainerBuilder();
256+
257+
$bindings = [
258+
CaseSensitiveClass::class => new BoundArgument(new Reference('foo')),
259+
];
260+
261+
$definition = $container->register(NamedArgumentsDummy::class, NamedArgumentsDummy::class);
262+
$definition->setArguments(['apiKey' => '123']);
263+
$definition->setBindings($bindings);
264+
265+
$container->register('foo', CaseSensitiveClass::class);
266+
267+
$pass = new ResolveBindingsPass();
268+
$pass->process($container);
269+
270+
$expected = [
271+
0 => new Reference('foo'),
272+
1 => '123',
273+
];
274+
$this->assertEquals($expected, $definition->getArguments());
275+
}
252276
}

0 commit comments

Comments
 (0)
0