TestServiceContainerWeakRefPass.php 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  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\Bundle\FrameworkBundle\DependencyInjection\Compiler;
  11. use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
  12. use Symfony\Component\DependencyInjection\Compiler\ServiceLocatorTagPass;
  13. use Symfony\Component\DependencyInjection\ContainerBuilder;
  14. use Symfony\Component\DependencyInjection\Definition;
  15. use Symfony\Component\DependencyInjection\Reference;
  16. /**
  17. * @author Nicolas Grekas <p@tchwork.com>
  18. */
  19. class TestServiceContainerWeakRefPass implements CompilerPassInterface
  20. {
  21. private $privateTagName;
  22. public function __construct(string $privateTagName = 'container.private')
  23. {
  24. $this->privateTagName = $privateTagName;
  25. }
  26. public function process(ContainerBuilder $container)
  27. {
  28. if (!$container->hasDefinition('test.private_services_locator')) {
  29. return;
  30. }
  31. $privateServices = [];
  32. $definitions = $container->getDefinitions();
  33. $hasErrors = method_exists(Definition::class, 'hasErrors') ? 'hasErrors' : 'getErrors';
  34. foreach ($definitions as $id => $definition) {
  35. if ($id && '.' !== $id[0] && (!$definition->isPublic() || $definition->isPrivate() || $definition->hasTag($this->privateTagName)) && !$definition->$hasErrors() && !$definition->isAbstract()) {
  36. $privateServices[$id] = new Reference($id, ContainerBuilder::IGNORE_ON_UNINITIALIZED_REFERENCE);
  37. }
  38. }
  39. $aliases = $container->getAliases();
  40. foreach ($aliases as $id => $alias) {
  41. if ($id && '.' !== $id[0] && (!$alias->isPublic() || $alias->isPrivate())) {
  42. while (isset($aliases[$target = (string) $alias])) {
  43. $alias = $aliases[$target];
  44. }
  45. if (isset($definitions[$target]) && !$definitions[$target]->$hasErrors() && !$definitions[$target]->isAbstract()) {
  46. $privateServices[$id] = new Reference($target, ContainerBuilder::IGNORE_ON_UNINITIALIZED_REFERENCE);
  47. }
  48. }
  49. }
  50. if ($privateServices) {
  51. $id = (string) ServiceLocatorTagPass::register($container, $privateServices);
  52. $container->setDefinition('test.private_services_locator', $container->getDefinition($id))->setPublic(true);
  53. $container->removeDefinition($id);
  54. }
  55. }
  56. }