From 4b8cd5205eb40eb063c781cb8ffd7abbd28514d0 Mon Sep 17 00:00:00 2001 From: Kevin Bond Date: Tue, 8 Mar 2022 13:07:55 -0500 Subject: [PATCH] [DI] fix `ServiceSubscriberTrait` bug where parent has `__call()` --- .../Service/ServiceSubscriberTrait.php | 4 +- .../Service/ServiceSubscriberTraitTest.php | 39 +++++++++++++++++++ 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Contracts/Service/ServiceSubscriberTrait.php b/src/Symfony/Contracts/Service/ServiceSubscriberTrait.php index 0c085303748d9..020887b3f5736 100644 --- a/src/Symfony/Contracts/Service/ServiceSubscriberTrait.php +++ b/src/Symfony/Contracts/Service/ServiceSubscriberTrait.php @@ -35,7 +35,7 @@ public static function getSubscribedServices(): array return $services; } - $services = \is_callable(['parent', __FUNCTION__]) ? parent::getSubscribedServices() : []; + $services = method_exists(get_parent_class(self::class) ?: '', __FUNCTION__) ? parent::getSubscribedServices() : []; foreach ((new \ReflectionClass(self::class))->getMethods() as $method) { if ($method->isStatic() || $method->isAbstract() || $method->isGenerator() || $method->isInternal() || $method->getNumberOfRequiredParameters()) { @@ -69,7 +69,7 @@ public function setContainer(ContainerInterface $container) { $this->container = $container; - if (\is_callable(['parent', __FUNCTION__])) { + if (method_exists(get_parent_class(self::class) ?: '', __FUNCTION__)) { return parent::setContainer($container); } diff --git a/src/Symfony/Contracts/Tests/Service/ServiceSubscriberTraitTest.php b/src/Symfony/Contracts/Tests/Service/ServiceSubscriberTraitTest.php index 17fd108dbd08c..1d95824baf1e1 100644 --- a/src/Symfony/Contracts/Tests/Service/ServiceSubscriberTraitTest.php +++ b/src/Symfony/Contracts/Tests/Service/ServiceSubscriberTraitTest.php @@ -36,6 +36,32 @@ public function testSetContainerIsCalledOnParent() $this->assertSame($container, (new TestService())->setContainer($container)); } + public function testParentNotCalledIfHasMagicCall() + { + $container = new class([]) implements ContainerInterface { + use ServiceLocatorTrait; + }; + $service = new class() extends ParentWithMagicCall { + use ServiceSubscriberTrait; + }; + + $this->assertNull($service->setContainer($container)); + $this->assertSame([], $service::getSubscribedServices()); + } + + public function testParentNotCalledIfNoParent() + { + $container = new class([]) implements ContainerInterface { + use ServiceLocatorTrait; + }; + $service = new class() { + use ServiceSubscriberTrait; + }; + + $this->assertNull($service->setContainer($container)); + $this->assertSame([], $service::getSubscribedServices()); + } + /** * @requires PHP 8 */ @@ -77,3 +103,16 @@ public function aChildService(): Service3 { } } + +class ParentWithMagicCall +{ + public function __call($method, $args) + { + throw new \BadMethodCallException('Should not be called.'); + } + + public static function __callStatic($method, $args) + { + throw new \BadMethodCallException('Should not be called.'); + } +}