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

Skip to content

Commit 2f8af44

Browse files
bug #51219 [DependencyInjection][HttpKernel] Fix using #[AutowireCallable] with controller arguments (HypeMC)
This PR was merged into the 6.3 branch. Discussion ---------- [DependencyInjection][HttpKernel] Fix using `#[AutowireCallable]` with controller arguments | Q | A | ------------- | --- | Branch? | 6.3 | Bug fix? | yes | New feature? | no | Deprecations? | no | Tickets | Fix #51200 | License | MIT | Doc PR | - Fixes using the `#[AutowireCallable]` attribute with controller arguments. Commits ------- 64f788d [DependencyInjection][HttpKernel] Fix using `#[AutowireCallable]` with controller arguments
2 parents 951530d + 64f788d commit 2f8af44

File tree

5 files changed

+32
-8
lines changed

5 files changed

+32
-8
lines changed

src/Symfony/Component/DependencyInjection/Attribute/AutowireCallable.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Component\DependencyInjection\Attribute;
1313

14+
use Symfony\Component\DependencyInjection\Definition;
1415
use Symfony\Component\DependencyInjection\Exception\LogicException;
1516
use Symfony\Component\DependencyInjection\Reference;
1617

@@ -38,4 +39,12 @@ public function __construct(
3839

3940
parent::__construct($callable ?? [new Reference($service), $method ?? '__invoke'], lazy: $lazy);
4041
}
42+
43+
public function buildDefinition(mixed $value, ?string $type, \ReflectionParameter $parameter): Definition
44+
{
45+
return (new Definition($type = \is_string($this->lazy) ? $this->lazy : ($type ?: 'Closure')))
46+
->setFactory(['Closure', 'fromCallable'])
47+
->setArguments([\is_array($value) ? $value + [1 => '__invoke'] : $value])
48+
->setLazy($this->lazy || 'Closure' !== $type && 'callable' !== (string) $parameter->getType());
49+
}
4150
}

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

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -314,10 +314,7 @@ private function autowireMethod(\ReflectionFunctionAbstract $reflectionMethod, a
314314
}
315315

316316
if ($attribute instanceof AutowireCallable) {
317-
$value = (new Definition($type = \is_string($attribute->lazy) ? $attribute->lazy : ($type ?: 'Closure')))
318-
->setFactory(['Closure', 'fromCallable'])
319-
->setArguments([\is_array($value) ? $value + [1 => '__invoke'] : $value])
320-
->setLazy($attribute->lazy || 'Closure' !== $type && 'callable' !== (string) $parameter->getType());
317+
$value = $attribute->buildDefinition($value, $type, $parameter);
321318
} elseif ($lazy = $attribute->lazy) {
322319
$definition = (new Definition($type))
323320
->setFactory('current')

src/Symfony/Component/HttpKernel/DependencyInjection/RegisterControllerArgumentLocatorsPass.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Component\HttpKernel\DependencyInjection;
1313

1414
use Symfony\Component\DependencyInjection\Attribute\Autowire;
15+
use Symfony\Component\DependencyInjection\Attribute\AutowireCallable;
1516
use Symfony\Component\DependencyInjection\Attribute\Target;
1617
use Symfony\Component\DependencyInjection\ChildDefinition;
1718
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
@@ -160,7 +161,12 @@ public function process(ContainerBuilder $container)
160161
}
161162

162163
if ($autowireAttributes) {
163-
$value = $autowireAttributes[0]->newInstance()->value;
164+
$attribute = $autowireAttributes[0]->newInstance();
165+
$value = $parameterBag->resolveValue($attribute->value);
166+
167+
if ($attribute instanceof AutowireCallable) {
168+
$value = $attribute->buildDefinition($value, $type, $p);
169+
}
164170

165171
if ($value instanceof Reference) {
166172
$args[$p->name] = $type ? new TypedReference($value, $type, $invalidBehavior, $p->name) : new Reference($value, $invalidBehavior);

src/Symfony/Component/HttpKernel/Tests/DependencyInjection/RegisterControllerArgumentLocatorsPassTest.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@
1212
namespace Symfony\Component\HttpKernel\Tests\DependencyInjection;
1313

1414
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\DependencyInjection\Argument\LazyClosure;
1516
use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
1617
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
1718
use Symfony\Component\DependencyInjection\Attribute\Autowire;
19+
use Symfony\Component\DependencyInjection\Attribute\AutowireCallable;
1820
use Symfony\Component\DependencyInjection\Attribute\TaggedIterator;
1921
use Symfony\Component\DependencyInjection\Attribute\TaggedLocator;
2022
use Symfony\Component\DependencyInjection\Attribute\Target;
@@ -481,7 +483,7 @@ public function testAutowireAttribute()
481483

482484
$locator = $container->get($locatorId)->get('foo::fooAction');
483485

484-
$this->assertCount(8, $locator->getProvidedServices());
486+
$this->assertCount(9, $locator->getProvidedServices());
485487
$this->assertInstanceOf(\stdClass::class, $locator->get('service1'));
486488
$this->assertSame('foo/bar', $locator->get('value'));
487489
$this->assertSame('foo', $locator->get('expression'));
@@ -490,6 +492,9 @@ public function testAutowireAttribute()
490492
$this->assertSame('bar', $locator->get('rawValue'));
491493
$this->assertSame('@bar', $locator->get('escapedRawValue'));
492494
$this->assertSame('foo', $locator->get('customAutowire'));
495+
$this->assertInstanceOf(FooInterface::class, $autowireCallable = $locator->get('autowireCallable'));
496+
$this->assertInstanceOf(LazyClosure::class, $autowireCallable);
497+
$this->assertInstanceOf(\stdClass::class, $autowireCallable->service);
493498
$this->assertFalse($locator->has('service2'));
494499
}
495500

@@ -625,6 +630,11 @@ public function __construct(string $parameter)
625630
}
626631
}
627632

633+
interface FooInterface
634+
{
635+
public function foo();
636+
}
637+
628638
class WithAutowireAttribute
629639
{
630640
public function fooAction(
@@ -644,6 +654,8 @@ public function fooAction(
644654
string $escapedRawValue,
645655
#[CustomAutowire('some.parameter')]
646656
string $customAutowire,
657+
#[AutowireCallable(service: 'some.id', method: 'bar')]
658+
FooInterface $autowireCallable,
647659
#[Autowire(service: 'invalid.id')]
648660
\stdClass $service2 = null,
649661
) {

src/Symfony/Component/HttpKernel/composer.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
"symfony/config": "^6.1",
3131
"symfony/console": "^5.4|^6.0",
3232
"symfony/css-selector": "^5.4|^6.0",
33-
"symfony/dependency-injection": "^6.3",
33+
"symfony/dependency-injection": "^6.3.4",
3434
"symfony/dom-crawler": "^5.4|^6.0",
3535
"symfony/expression-language": "^5.4|^6.0",
3636
"symfony/finder": "^5.4|^6.0",
@@ -57,7 +57,7 @@
5757
"symfony/config": "<6.1",
5858
"symfony/console": "<5.4",
5959
"symfony/form": "<5.4",
60-
"symfony/dependency-injection": "<6.3",
60+
"symfony/dependency-injection": "<6.3.4",
6161
"symfony/doctrine-bridge": "<5.4",
6262
"symfony/http-client": "<5.4",
6363
"symfony/http-client-contracts": "<2.5",

0 commit comments

Comments
 (0)