1<?php 2 3/* 4 * This file is part of the Symfony package. 5 * 6 * (c) Fabien Potencier <fabien@symfony.com> 7 * 8 * For the full copyright and license information, please view the LICENSE 9 * file that was distributed with this source code. 10 */ 11 12namespace Symfony\Component\DependencyInjection\Compiler; 13 14use Psr\Container\ContainerInterface; 15use Symfony\Component\DependencyInjection\Definition; 16use Symfony\Component\DependencyInjection\Reference; 17 18/** 19 * Compiler pass to inject their service locator to service subscribers. 20 * 21 * @author Nicolas Grekas <p@tchwork.com> 22 */ 23class ResolveServiceSubscribersPass extends AbstractRecursivePass 24{ 25 private $serviceLocator; 26 27 protected function processValue($value, $isRoot = false) 28 { 29 if ($value instanceof Reference && $this->serviceLocator && ContainerInterface::class === $this->container->normalizeId($value)) { 30 return new Reference($this->serviceLocator); 31 } 32 33 if (!$value instanceof Definition) { 34 return parent::processValue($value, $isRoot); 35 } 36 37 $serviceLocator = $this->serviceLocator; 38 $this->serviceLocator = null; 39 40 if ($value->hasTag('container.service_subscriber.locator')) { 41 $this->serviceLocator = $value->getTag('container.service_subscriber.locator')[0]['id']; 42 $value->clearTag('container.service_subscriber.locator'); 43 } 44 45 try { 46 return parent::processValue($value); 47 } finally { 48 $this->serviceLocator = $serviceLocator; 49 } 50 } 51} 52