Chris@0: Chris@0: * Chris@0: * For the full copyright and license information, please view the LICENSE Chris@0: * file that was distributed with this source code. Chris@0: */ Chris@0: Chris@0: namespace Symfony\Component\DependencyInjection\Compiler; Chris@0: Chris@17: use Symfony\Component\DependencyInjection\Alias; Chris@0: use Symfony\Component\DependencyInjection\ContainerBuilder; Chris@0: Chris@0: /** Chris@0: * Overwrites a service but keeps the overridden one. Chris@0: * Chris@0: * @author Christophe Coevoet Chris@0: * @author Fabien Potencier Chris@0: * @author Diego Saint Esteben Chris@0: */ Chris@0: class DecoratorServicePass implements CompilerPassInterface Chris@0: { Chris@0: public function process(ContainerBuilder $container) Chris@0: { Chris@0: $definitions = new \SplPriorityQueue(); Chris@0: $order = PHP_INT_MAX; Chris@0: Chris@0: foreach ($container->getDefinitions() as $id => $definition) { Chris@0: if (!$decorated = $definition->getDecoratedService()) { Chris@0: continue; Chris@0: } Chris@17: $definitions->insert([$id, $definition], [$decorated[2], --$order]); Chris@0: } Chris@17: $decoratingDefinitions = []; Chris@0: Chris@0: foreach ($definitions as list($id, $definition)) { Chris@0: list($inner, $renamedId) = $definition->getDecoratedService(); Chris@0: Chris@0: $definition->setDecoratedService(null); Chris@0: Chris@0: if (!$renamedId) { Chris@0: $renamedId = $id.'.inner'; Chris@0: } Chris@0: Chris@0: // we create a new alias/service for the service we are replacing Chris@0: // to be able to reference it in the new one Chris@0: if ($container->hasAlias($inner)) { Chris@0: $alias = $container->getAlias($inner); Chris@0: $public = $alias->isPublic(); Chris@14: $private = $alias->isPrivate(); Chris@14: $container->setAlias($renamedId, new Alias($container->normalizeId($alias), false)); Chris@0: } else { Chris@0: $decoratedDefinition = $container->getDefinition($inner); Chris@0: $public = $decoratedDefinition->isPublic(); Chris@14: $private = $decoratedDefinition->isPrivate(); Chris@0: $decoratedDefinition->setPublic(false); Chris@17: $container->setDefinition($renamedId, $decoratedDefinition); Chris@17: $decoratingDefinitions[$inner] = $decoratedDefinition; Chris@17: } Chris@17: Chris@17: if (isset($decoratingDefinitions[$inner])) { Chris@17: $decoratingDefinition = $decoratingDefinitions[$inner]; Chris@17: $definition->setTags(array_merge($decoratingDefinition->getTags(), $definition->getTags())); Chris@17: $autowiringTypes = $decoratingDefinition->getAutowiringTypes(false); Chris@17: if ($types = array_merge($autowiringTypes, $definition->getAutowiringTypes(false))) { Chris@17: $definition->setAutowiringTypes($types); Chris@14: } Chris@17: $decoratingDefinition->setTags([]); Chris@17: if ($autowiringTypes) { Chris@17: $decoratingDefinition->setAutowiringTypes([]); Chris@17: } Chris@17: $decoratingDefinitions[$inner] = $definition; Chris@0: } Chris@0: Chris@14: $container->setAlias($inner, $id)->setPublic($public)->setPrivate($private); Chris@0: } Chris@0: } Chris@0: }