4 * This file is part of the Symfony package.
6 * (c) Fabien Potencier <fabien@symfony.com>
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
12 namespace Symfony\Component\DependencyInjection\Compiler;
14 use Symfony\Component\DependencyInjection\ContainerBuilder;
15 use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
16 use Symfony\Component\DependencyInjection\Reference;
19 * Replaces aliases with actual service definitions, effectively removing these
22 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
24 class ReplaceAliasByActualDefinitionPass extends AbstractRecursivePass
26 private $replacements;
29 * Process the Container to replace aliases with service definitions.
31 * @throws InvalidArgumentException if the service definition does not exist
33 public function process(ContainerBuilder $container)
35 // First collect all alias targets that need to be replaced
36 $seenAliasTargets = array();
37 $replacements = array();
38 foreach ($container->getAliases() as $definitionId => $target) {
39 $targetId = $container->normalizeId($target);
40 // Special case: leave this target alone
41 if ('service_container' === $targetId) {
44 // Check if target needs to be replaces
45 if (isset($replacements[$targetId])) {
46 $container->setAlias($definitionId, $replacements[$targetId])->setPublic($target->isPublic())->setPrivate($target->isPrivate());
48 // No need to process the same target twice
49 if (isset($seenAliasTargets[$targetId])) {
53 $seenAliasTargets[$targetId] = true;
55 $definition = $container->getDefinition($targetId);
56 } catch (InvalidArgumentException $e) {
57 throw new InvalidArgumentException(sprintf('Unable to replace alias "%s" with actual definition "%s".', $definitionId, $targetId), null, $e);
59 if ($definition->isPublic() || $definition->isPrivate()) {
62 // Remove private definition and schedule for replacement
63 $definition->setPublic(!$target->isPrivate());
64 $definition->setPrivate($target->isPrivate());
65 $container->setDefinition($definitionId, $definition);
66 $container->removeDefinition($targetId);
67 $replacements[$targetId] = $definitionId;
69 $this->replacements = $replacements;
71 parent::process($container);
72 $this->replacements = array();
78 protected function processValue($value, $isRoot = false)
80 if ($value instanceof Reference && isset($this->replacements[$referenceId = $this->container->normalizeId($value)])) {
81 // Perform the replacement
82 $newId = $this->replacements[$referenceId];
83 $value = new Reference($newId, $value->getInvalidBehavior());
84 $this->container->log($this, sprintf('Changed reference of service "%s" previously pointing to "%s" to "%s".', $this->currentId, $referenceId, $newId));
87 return parent::processValue($value, $isRoot);