Skip to content

Commit 40a6c45

Browse files
Merge branch '7.4' into 8.0
* 7.4: [DependencyInjection] Fix lazy proxy type resolution for decorated services [HttpClient] Fix dealing with truncated streams after headers arrived with CurlHttpClient [PropertyInfo] Fix DocBlock resolution for inherited promoted properties [HttpFoundation] Fix PdoSessionHandler charset-collation mismatch with the Doctrine DBAL on MySQL [HttpClient] Fix dealing with multiple levels of AsyncResponse decoration [Messenger] Only send UNLISTEN query if we are actively listening [RateLimiter] Persist state when consuming negative tokens
2 parents 59c3cf8 + 76a02cd commit 40a6c45

File tree

3 files changed

+73
-7
lines changed

3 files changed

+73
-7
lines changed

Compiler/AutowirePass.php

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -335,11 +335,6 @@ private function autowireMethod(\ReflectionFunctionAbstract $reflectionMethod, a
335335
$value = $this->doProcessValue($value);
336336
} elseif ($lazy = $attribute->lazy) {
337337
$value ??= $getValue();
338-
$type = $this->resolveProxyType($type, $value->getType());
339-
$definition = (new Definition($type))
340-
->setFactory('current')
341-
->setArguments([[$value]])
342-
->setLazy(true);
343338

344339
if (!\is_array($lazy)) {
345340
if (str_contains($type, '|')) {
@@ -348,8 +343,14 @@ private function autowireMethod(\ReflectionFunctionAbstract $reflectionMethod, a
348343
$lazy = str_contains($type, '&') ? explode('&', $type) : [];
349344
}
350345

346+
$proxyType = $lazy ? $type : $this->resolveProxyType($type, $value);
347+
$definition = (new Definition($proxyType))
348+
->setFactory('current')
349+
->setArguments([[$value]])
350+
->setLazy(true);
351+
351352
if ($lazy) {
352-
if (!class_exists($type) && !interface_exists($type, false)) {
353+
if (!$this->container->getReflectionClass($proxyType, false)) {
353354
$definition->setClass('object');
354355
}
355356
foreach ($lazy as $v) {
@@ -757,7 +758,7 @@ private function resolveProxyType(string $originalType, string $serviceId): stri
757758
$resolvedType = $this->container->findDefinition($serviceId)->getClass();
758759
$resolvedType = $this->container->getParameterBag()->resolveValue($resolvedType);
759760

760-
if (!$resolvedType || !class_exists($resolvedType, false) && !interface_exists($resolvedType, false)) {
761+
if (!$resolvedType || !$this->container->getReflectionClass($resolvedType, false)) {
761762
return $originalType;
762763
}
763764

Tests/Compiler/AutowirePassTest.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1487,4 +1487,30 @@ public function testLazyProxyWithClassInheritance()
14871487
$dep = $service->getDependency()->getSelf();
14881488
$this->assertInstanceOf(ExtendedLazyProxyClass::class, $dep);
14891489
}
1490+
1491+
public function testLazyProxyForDecoratedService()
1492+
{
1493+
$container = new ContainerBuilder();
1494+
1495+
$container->register('some_service', SomeServiceClass::class)
1496+
->setPublic(true);
1497+
1498+
$container->register('some_service.decorated', DecoratedSomeServiceClass::class)
1499+
->setDecoratedService('some_service')
1500+
->addArgument(new Reference('.inner'));
1501+
1502+
$container->register(LazyDecoratedServiceConsumer::class)
1503+
->setAutowired(true)
1504+
->setPublic(true);
1505+
1506+
$container->setAlias(SomeServiceInterface::class, 'some_service');
1507+
1508+
$container->compile();
1509+
1510+
$service = $container->get(LazyDecoratedServiceConsumer::class);
1511+
$this->assertInstanceOf(LazyDecoratedServiceConsumer::class, $service);
1512+
1513+
$result = $service->getValue();
1514+
$this->assertSame('decorated:original', $result);
1515+
}
14901516
}

Tests/Fixtures/includes/autowiring_classes.php

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -605,3 +605,42 @@ public function __construct(public ContainerInterface $container)
605605
{
606606
}
607607
}
608+
609+
interface SomeServiceInterface
610+
{
611+
public function getValue(): string;
612+
}
613+
614+
class SomeServiceClass implements SomeServiceInterface
615+
{
616+
public function getValue(): string
617+
{
618+
return 'original';
619+
}
620+
}
621+
622+
class DecoratedSomeServiceClass implements SomeServiceInterface
623+
{
624+
public function __construct(private SomeServiceInterface $inner)
625+
{
626+
}
627+
628+
public function getValue(): string
629+
{
630+
return 'decorated:'.$this->inner->getValue();
631+
}
632+
}
633+
634+
class LazyDecoratedServiceConsumer
635+
{
636+
public function __construct(
637+
#[Autowire(service: 'some_service', lazy: true)]
638+
private SomeServiceInterface $service,
639+
) {
640+
}
641+
642+
public function getValue(): string
643+
{
644+
return $this->service->getValue();
645+
}
646+
}

0 commit comments

Comments
 (0)