Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 45d614d

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

File tree

4 files changed

+55
-2
lines changed

4 files changed

+55
-2
lines changed

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

+5-1
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

+15-1
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) && (0 === $key || \array_key_exists($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/Tests/Compiler/AutowirePassTest.php

+15
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

+20
Original file line numberDiff line numberDiff line change
@@ -249,4 +249,24 @@ 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+
'$apiKey' => new BoundArgument('K'),
259+
];
260+
261+
$definition = $container->register(NamedArgumentsDummy::class, NamedArgumentsDummy::class);
262+
$definition->setArguments(['c' => 'C', 'hostName' => 'H']);
263+
$definition->setBindings($bindings);
264+
265+
$container->register('foo', CaseSensitiveClass::class);
266+
267+
$pass = new ResolveBindingsPass();
268+
$pass->process($container);
269+
270+
$this->assertEquals(['C', 'K', 'H'], $definition->getArguments());
271+
}
252272
}

0 commit comments

Comments
 (0)