diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_issues49591.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_issues49591.php new file mode 100644 index 0000000000000..9142d3df3375e --- /dev/null +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_issues49591.php @@ -0,0 +1,95 @@ +services = $this->privates = []; + $this->methodMap = [ + 'connection' => 'getConnectionService', + 'session' => 'getSessionService', + 'subscriber' => 'getSubscriberService', + ]; + + $this->aliases = []; + } + + public function compile(): void + { + throw new LogicException('You cannot compile a dumped container that was already compiled.'); + } + + public function isCompiled(): bool + { + return true; + } + + public function getRemovedIds(): array + { + return [ + '.service_locator.SoPO3vR' => true, + 'repository' => true, + ]; + } + + /** + * Gets the public 'connection' shared service. + * + * @return \Symfony\Component\DependencyInjection\Tests\Connection + */ + protected static function getConnectionService($container) + { + return $container->services['connection'] = new \Symfony\Component\DependencyInjection\Tests\Connection(new \Symfony\Component\DependencyInjection\Argument\ServiceLocator($container->getService ??= $container->getService(...), [ + 'subscriber' => ['services', 'subscriber', 'getSubscriberService', false], + ], [ + 'subscriber' => 'Symfony\\Component\\DependencyInjection\\Tests\\Subscriber', + ])); + } + + /** + * Gets the public 'session' shared service. + * + * @return \Symfony\Component\DependencyInjection\Tests\Session + */ + protected static function getSessionService($container) + { + $a = ($container->services['connection'] ?? self::getConnectionService($container)); + + if (isset($container->services['session'])) { + return $container->services['session']; + } + + return $container->services['session'] = (new \Symfony\Component\DependencyInjection\Tests\Repository())->login($a); + } + + /** + * Gets the public 'subscriber' shared service. + * + * @return \Symfony\Component\DependencyInjection\Tests\Subscriber + */ + protected static function getSubscriberService($container) + { + $a = ($container->services['session'] ?? self::getSessionService($container)); + + if (isset($container->services['subscriber'])) { + return $container->services['subscriber']; + } + + return $container->services['subscriber'] = new \Symfony\Component\DependencyInjection\Tests\Subscriber($a); + } +} diff --git a/src/Symfony/Component/DependencyInjection/Tests/Issues49591Test.php b/src/Symfony/Component/DependencyInjection/Tests/Issues49591Test.php new file mode 100644 index 0000000000000..ccece67c34536 --- /dev/null +++ b/src/Symfony/Component/DependencyInjection/Tests/Issues49591Test.php @@ -0,0 +1,93 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests; + +use PHPUnit\Framework\TestCase; +use Psr\Container\ContainerInterface; +use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument; +use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Dumper\PhpDumper; +use Symfony\Component\DependencyInjection\Reference; + +class Issues49591Test extends TestCase +{ + public function testServices() + { + $containerBuilder = new ContainerBuilder(); + + $containerBuilder->register('connection', Connection::class) + ->addArgument(new ServiceLocatorArgument(new TaggedIteratorArgument('subscriber', needsIndexes: true))) + ->setPublic(true); + + $containerBuilder->register('repository', Repository::class); + + $containerBuilder->register('session', Session::class) + ->setFactory([new Reference('repository'), 'login']) + ->addArgument(new Reference('connection')) + ->setPublic(true); + + $containerBuilder->register('subscriber', Subscriber::class) + ->addArgument(new Reference('session')) + ->addTag('subscriber') + ->setPublic(true); + + $containerBuilder->compile(); + + $dumper = new PhpDumper($containerBuilder); + $dump = $dumper->dump(['class' => 'Symfony_DI_PhpDumper_Issues49591']); + + eval('?>'.$dump); + + $container = new \Symfony_DI_PhpDumper_Issues49591(); + + self::assertSame($container->get('session'), $container->get('subscriber')->session); + } +} + +class Connection +{ + public bool $connection = false; + + public function __construct(public ContainerInterface $container) + { + } + + public function connect() + { + if (!$this->connection) { + $this->connection = true; + $this->container->get('subscriber'); + } + } +} + +class Subscriber +{ + public function __construct(public Session $session) + { + } +} + +class Repository +{ + public function login(Connection $connection) + { + $connection->connect(); + + return new Session(); + } +} + +class Session +{ +}