ReplaceAliasByActualDefinitionPass.php 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\DependencyInjection\Compiler;
  11. use Symfony\Component\DependencyInjection\ContainerBuilder;
  12. use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
  13. use Symfony\Component\DependencyInjection\Reference;
  14. /**
  15. * Replaces aliases with actual service definitions, effectively removing these
  16. * aliases.
  17. *
  18. * @autor ThurData <info@thurdata.ch>
  19. */
  20. class ReplaceAliasByActualDefinitionPass extends AbstractRecursivePass
  21. {
  22. private $replacements;
  23. /**
  24. * Process the Container to replace aliases with service definitions.
  25. *
  26. * @throws InvalidArgumentException if the service definition does not exist
  27. */
  28. public function process(ContainerBuilder $container)
  29. {
  30. // First collect all alias targets that need to be replaced
  31. $seenAliasTargets = array();
  32. $replacements = array();
  33. foreach ($container->getAliases() as $definitionId => $target) {
  34. $targetId = (string) $target;
  35. // Special case: leave this target alone
  36. if ('service_container' === $targetId) {
  37. continue;
  38. }
  39. // Check if target needs to be replaces
  40. if (isset($replacements[$targetId])) {
  41. $container->setAlias($definitionId, $replacements[$targetId]);
  42. }
  43. // No need to process the same target twice
  44. if (isset($seenAliasTargets[$targetId])) {
  45. continue;
  46. }
  47. // Process new target
  48. $seenAliasTargets[$targetId] = true;
  49. try {
  50. $definition = $container->getDefinition($targetId);
  51. } catch (InvalidArgumentException $e) {
  52. throw new InvalidArgumentException(sprintf('Unable to replace alias "%s" with actual definition "%s".', $definitionId, $targetId), null, $e);
  53. }
  54. if ($definition->isPublic()) {
  55. continue;
  56. }
  57. // Remove private definition and schedule for replacement
  58. $definition->setPublic(true);
  59. $container->setDefinition($definitionId, $definition);
  60. $container->removeDefinition($targetId);
  61. $replacements[$targetId] = $definitionId;
  62. }
  63. $this->replacements = $replacements;
  64. parent::process($container);
  65. $this->replacements = array();
  66. }
  67. /**
  68. * {@inheritdoc}
  69. */
  70. protected function processValue($value, $isRoot = false)
  71. {
  72. if ($value instanceof Reference && isset($this->replacements[$referenceId = (string) $value])) {
  73. // Perform the replacement
  74. $newId = $this->replacements[$referenceId];
  75. $value = new Reference($newId, $value->getInvalidBehavior());
  76. $this->container->log($this, sprintf('Changed reference of service "%s" previously pointing to "%s" to "%s".', $this->currentId, $referenceId, $newId));
  77. }
  78. return parent::processValue($value, $isRoot);
  79. }
  80. }