blob: b85c0662181d6b9dc87bc0ae0e08be0f37fc3076 [file] [log] [blame]
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +02001<?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\Translation\DependencyInjection;
13
14use Symfony\Component\DependencyInjection\Compiler\AbstractRecursivePass;
15use Symfony\Component\DependencyInjection\ContainerBuilder;
16use Symfony\Component\DependencyInjection\Definition;
17use Symfony\Component\DependencyInjection\Reference;
18use Symfony\Component\DependencyInjection\ServiceLocator;
19
20/**
21 * @author Yonel Ceruto <yonelceruto@gmail.com>
22 */
23class TranslatorPathsPass extends AbstractRecursivePass
24{
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +010025 private int $level = 0;
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +020026
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +010027 /**
28 * @var array<string, bool>
29 */
30 private array $paths = [];
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +020031
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +010032 /**
33 * @var array<int, Definition>
34 */
35 private array $definitions = [];
36
37 /**
38 * @var array<string, array<string, bool>>
39 */
40 private array $controllers = [];
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +020041
42 public function process(ContainerBuilder $container)
43 {
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +010044 if (!$container->hasDefinition('translator')) {
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +020045 return;
46 }
47
48 foreach ($this->findControllerArguments($container) as $controller => $argument) {
49 $id = substr($controller, 0, strpos($controller, ':') ?: \strlen($controller));
50 if ($container->hasDefinition($id)) {
51 [$locatorRef] = $argument->getValues();
52 $this->controllers[(string) $locatorRef][$container->getDefinition($id)->getClass()] = true;
53 }
54 }
55
56 try {
57 parent::process($container);
58
59 $paths = [];
60 foreach ($this->paths as $class => $_) {
61 if (($r = $container->getReflectionClass($class)) && !$r->isInterface()) {
62 $paths[] = $r->getFileName();
63 foreach ($r->getTraits() as $trait) {
64 $paths[] = $trait->getFileName();
65 }
66 }
67 }
68 if ($paths) {
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +010069 if ($container->hasDefinition('console.command.translation_debug')) {
70 $definition = $container->getDefinition('console.command.translation_debug');
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +020071 $definition->replaceArgument(6, array_merge($definition->getArgument(6), $paths));
72 }
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +010073 if ($container->hasDefinition('console.command.translation_extract')) {
74 $definition = $container->getDefinition('console.command.translation_extract');
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +020075 $definition->replaceArgument(7, array_merge($definition->getArgument(7), $paths));
76 }
77 }
78 } finally {
79 $this->level = 0;
80 $this->paths = [];
81 $this->definitions = [];
82 }
83 }
84
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +010085 protected function processValue(mixed $value, bool $isRoot = false): mixed
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +020086 {
87 if ($value instanceof Reference) {
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +010088 if ('translator' === (string) $value) {
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +020089 for ($i = $this->level - 1; $i >= 0; --$i) {
90 $class = $this->definitions[$i]->getClass();
91
92 if (ServiceLocator::class === $class) {
93 if (!isset($this->controllers[$this->currentId])) {
94 continue;
95 }
96 foreach ($this->controllers[$this->currentId] as $class => $_) {
97 $this->paths[$class] = true;
98 }
99 } else {
100 $this->paths[$class] = true;
101 }
102
103 break;
104 }
105 }
106
107 return $value;
108 }
109
110 if ($value instanceof Definition) {
111 $this->definitions[$this->level++] = $value;
112 $value = parent::processValue($value, $isRoot);
113 unset($this->definitions[--$this->level]);
114
115 return $value;
116 }
117
118 return parent::processValue($value, $isRoot);
119 }
120
121 private function findControllerArguments(ContainerBuilder $container): array
122 {
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +0100123 if ($container->hasDefinition('argument_resolver.service')) {
124 $argument = $container->getDefinition('argument_resolver.service')->getArgument(0);
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +0200125 if ($argument instanceof Reference) {
126 $argument = $container->getDefinition($argument);
127 }
128
129 return $argument->getArgument(0);
130 }
131
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +0100132 if ($container->hasDefinition('debug.'.'argument_resolver.service')) {
133 $argument = $container->getDefinition('debug.'.'argument_resolver.service')->getArgument(0);
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +0200134 if ($argument instanceof Reference) {
135 $argument = $container->getDefinition($argument);
136 }
137 $argument = $argument->getArgument(0);
138 if ($argument instanceof Reference) {
139 $argument = $container->getDefinition($argument);
140 }
141
142 return $argument->getArgument(0);
143 }
144
145 return [];
146 }
147}