11
11
12
12
namespace Symfony \Bundle \FrameworkBundle \Command ;
13
13
14
- use Symfony \Component \ Translation \Catalogue \ MergeOperation ;
14
+ use Symfony \Bundle \ FrameworkBundle \ Translation \TranslationLoader ;
15
15
use Symfony \Component \Console \Helper \Table ;
16
+ use Symfony \Component \HttpKernel \Kernel ;
17
+ use Symfony \Component \Translation \Catalogue \MergeOperation ;
16
18
use Symfony \Component \Console \Input \InputInterface ;
17
19
use Symfony \Component \Console \Output \OutputInterface ;
18
20
use Symfony \Component \Console \Input \InputArgument ;
@@ -48,6 +50,7 @@ protected function configure()
48
50
new InputOption ('domain ' , null , InputOption::VALUE_OPTIONAL , 'The messages domain ' ),
49
51
new InputOption ('only-missing ' , null , InputOption::VALUE_NONE , 'Displays only missing messages ' ),
50
52
new InputOption ('only-unused ' , null , InputOption::VALUE_NONE , 'Displays only unused messages ' ),
53
+ new InputOption ('all ' , null , InputOption::VALUE_NONE , 'Load messages from all registered bundles ' ),
51
54
))
52
55
->setDescription ('Displays translation messages information ' )
53
56
->setHelp (<<<EOF
@@ -75,9 +78,12 @@ protected function configure()
75
78
76
79
<info>php %command.full_name% en</info>
77
80
81
+ You can display information about translations in all registered bundles in a specific locale:
82
+
83
+ <info>php %command.full_name% --all en</info>
84
+
78
85
EOF
79
- )
80
- ;
86
+ );
81
87
}
82
88
83
89
/**
@@ -86,134 +92,139 @@ protected function configure()
86
92
protected function execute (InputInterface $ input , OutputInterface $ output )
87
93
{
88
94
if (false !== strpos ($ input ->getFirstArgument (), ':d ' )) {
89
- $ output ->writeln ('<comment>The use of "translation:debug" command is deprecated since version 2.7 and will be removed in 3.0. Use the "debug:translation" instead.</comment> ' );
95
+ $ output ->writeln (
96
+ '<comment>The use of "translation:debug" command is deprecated since version 2.7 and will be removed in 3.0. Use the "debug:translation" instead.</comment> '
97
+ );
90
98
}
91
99
92
100
$ locale = $ input ->getArgument ('locale ' );
93
101
$ domain = $ input ->getOption ('domain ' );
102
+ /** @var TranslationLoader $loader */
94
103
$ loader = $ this ->getContainer ()->get ('translation.loader ' );
104
+ /** @var Kernel $kernel */
95
105
$ kernel = $ this ->getContainer ()->get ('kernel ' );
96
106
97
107
// Define Root Path to App folder
98
- $ rootPath = $ kernel ->getRootDir ();
108
+ $ rootPaths = array ( $ kernel ->getRootDir () );
99
109
100
110
// Override with provided Bundle info
101
111
if (null !== $ input ->getArgument ('bundle ' )) {
102
112
try {
103
- $ rootPath = $ kernel ->getBundle ($ input ->getArgument ('bundle ' ))->getPath ();
113
+ $ rootPaths = array ( $ kernel ->getBundle ($ input ->getArgument ('bundle ' ))->getPath () );
104
114
} catch (\InvalidArgumentException $ e ) {
105
115
// such a bundle does not exist, so treat the argument as path
106
- $ rootPath = $ input ->getArgument ('bundle ' );
116
+ $ rootPaths = array ( $ input ->getArgument ('bundle ' ) );
107
117
108
- if (!is_dir ($ rootPath )) {
109
- throw new \InvalidArgumentException (sprintf ('<error>"%s" is neither an enabled bundle nor a directory.</error> ' , $ rootPath ));
118
+ if (!is_dir ($ rootPaths [0 ])) {
119
+ throw new \InvalidArgumentException (
120
+ sprintf ('<error>"%s" is neither an enabled bundle nor a directory.</error> ' , $ rootPaths [0 ])
121
+ );
110
122
}
111
123
}
124
+ } elseif ($ input ->getOption ('all ' )) {
125
+ foreach ($ kernel ->getBundles () as $ bundle ) {
126
+ $ rootPaths [] = $ bundle ->getPath ();
127
+ }
112
128
}
113
129
114
- // get bundle directory
115
- $ translationsPath = $ rootPath .'/Resources/translations ' ;
116
-
117
- // Extract used messages
118
- $ extractedCatalogue = new MessageCatalogue ($ locale );
119
- if (is_dir ($ rootPath .'/Resources/views ' )) {
120
- $ this ->getContainer ()->get ('translation.extractor ' )->extract ($ rootPath .'/Resources/views ' , $ extractedCatalogue );
121
- }
130
+ foreach ($ rootPaths as $ rootPath ) {
131
+ // get bundle directory
132
+ $ translationsPath = $ rootPath .'/Resources/translations ' ;
122
133
123
- // Load defined messages
124
- $ currentCatalogue = new MessageCatalogue ($ locale );
125
- if (is_dir ($ translationsPath )) {
126
- $ loader ->loadMessages ($ translationsPath , $ currentCatalogue );
127
- }
134
+ $ output ->writeln (sprintf ('Translations in <info>%s</info> ' , $ translationsPath ));
128
135
129
- // Merge defined and extracted messages to get all message ids
130
- $ mergeOperation = new MergeOperation ($ extractedCatalogue , $ currentCatalogue );
131
- $ allMessages = $ mergeOperation ->getResult ()->all ($ domain );
132
- if (null !== $ domain ) {
133
- $ allMessages = array ($ domain => $ allMessages );
134
- }
136
+ // Extract used messages
137
+ $ extractedCatalogue = $ this ->extractMessages ($ locale , $ rootPath );
135
138
136
- // No defined or extracted messages
137
- if (empty ($ allMessages ) || null !== $ domain && empty ($ allMessages [$ domain ])) {
138
- $ outputMessage = sprintf ('<info>No defined or extracted messages for locale "%s"</info> ' , $ locale );
139
+ // Load defined messages
140
+ $ currentCatalogue = $ this ->loadCurrentMessages ($ locale , $ translationsPath , $ loader );
139
141
142
+ // Merge defined and extracted messages to get all message ids
143
+ $ mergeOperation = new MergeOperation ($ extractedCatalogue , $ currentCatalogue );
144
+ $ allMessages = $ mergeOperation ->getResult ()->all ($ domain );
140
145
if (null !== $ domain ) {
141
- $ outputMessage .= sprintf ( ' <info>and domain "%s"</info> ' , $ domain );
146
+ $ allMessages = array ( $ domain => $ allMessages );
142
147
}
143
148
144
- $ output ->writeln ($ outputMessage );
149
+ // No defined or extracted messages
150
+ if (empty ($ allMessages ) || null !== $ domain && empty ($ allMessages [$ domain ])) {
151
+ $ outputMessage = sprintf ('<info>No defined or extracted messages for locale "%s"</info> ' , $ locale );
145
152
146
- return ;
147
- }
148
-
149
- // Load the fallback catalogues
150
- $ fallbackCatalogues = array ();
151
- $ translator = $ this ->getContainer ()->get ('translator ' );
152
- if ($ translator instanceof Translator) {
153
- foreach ($ translator ->getFallbackLocales () as $ fallbackLocale ) {
154
- if ($ fallbackLocale === $ locale ) {
155
- continue ;
153
+ if (null !== $ domain ) {
154
+ $ outputMessage .= sprintf (' <info>and domain "%s"</info> ' , $ domain );
156
155
}
157
156
158
- $ fallbackCatalogue = new MessageCatalogue ( $ fallbackLocale );
159
- $ loader -> loadMessages ( $ translationsPath , $ fallbackCatalogue );
160
- $ fallbackCatalogues [] = $ fallbackCatalogue ;
157
+ $ output -> writeln ( $ outputMessage );
158
+
159
+ continue ;
161
160
}
162
- }
163
161
164
- /** @var \Symfony\Component\Console\Helper\Table $table */
165
- $ table = new Table ( $ output );
162
+ // Load the fallback catalogues
163
+ $ fallbackCatalogues = $ this -> loadFallbackCatalogues ( $ locale , $ translationsPath , $ loader );
166
164
167
- // Display header line
168
- $ headers = array ('State(s) ' , 'Domain ' , 'Id ' , sprintf ('Message Preview (%s) ' , $ locale ));
169
- foreach ($ fallbackCatalogues as $ fallbackCatalogue ) {
170
- $ headers [] = sprintf ('Fallback Message Preview (%s) ' , $ fallbackCatalogue ->getLocale ());
171
- }
172
- $ table ->setHeaders ($ headers );
165
+ $ table = new Table ($ output );
173
166
174
- // Iterate all message ids and determine their state
175
- foreach ($ allMessages as $ domain => $ messages ) {
176
- foreach (array_keys ($ messages ) as $ messageId ) {
177
- $ value = $ currentCatalogue ->get ($ messageId , $ domain );
178
- $ states = array ();
167
+ // Display header line
168
+ $ headers = array ('State(s) ' , 'Domain ' , 'Id ' , sprintf ('Message Preview (%s) ' , $ locale ));
169
+ foreach ($ fallbackCatalogues as $ fallbackCatalogue ) {
170
+ $ headers [] = sprintf ('Fallback Message Preview (%s) ' , $ fallbackCatalogue ->getLocale ());
171
+ }
172
+ $ table ->setHeaders ($ headers );
173
+
174
+ // Iterate all message ids and determine their state
175
+ foreach ($ allMessages as $ domain => $ messages ) {
176
+ foreach (array_keys ($ messages ) as $ messageId ) {
177
+ $ value = $ currentCatalogue ->get ($ messageId , $ domain );
178
+ $ states = array ();
179
+
180
+ if ($ extractedCatalogue ->defines ($ messageId , $ domain )) {
181
+ if (!$ currentCatalogue ->defines ($ messageId , $ domain )) {
182
+ $ states [] = self ::MESSAGE_MISSING ;
183
+ }
184
+ } elseif ($ currentCatalogue ->defines ($ messageId , $ domain )) {
185
+ $ states [] = self ::MESSAGE_UNUSED ;
186
+ }
179
187
180
- if ($ extractedCatalogue ->defines ($ messageId , $ domain )) {
181
- if (!$ currentCatalogue ->defines ($ messageId , $ domain )) {
182
- $ states [] = self ::MESSAGE_MISSING ;
188
+ if (!in_array (self ::MESSAGE_UNUSED , $ states ) && true === $ input ->getOption ('only-unused ' )
189
+ || !in_array (self ::MESSAGE_MISSING , $ states ) && true === $ input ->getOption ('only-missing ' )
190
+ ) {
191
+ continue ;
183
192
}
184
- } elseif ($ currentCatalogue ->defines ($ messageId , $ domain )) {
185
- $ states [] = self ::MESSAGE_UNUSED ;
186
- }
187
193
188
- if (!in_array (self ::MESSAGE_UNUSED , $ states ) && true === $ input ->getOption ('only-unused ' )
189
- || !in_array (self ::MESSAGE_MISSING , $ states ) && true === $ input ->getOption ('only-missing ' )) {
190
- continue ;
191
- }
194
+ foreach ($ fallbackCatalogues as $ fallbackCatalogue ) {
195
+ if ($ fallbackCatalogue ->defines ($ messageId , $ domain )
196
+ && $ value === $ fallbackCatalogue ->get ($ messageId , $ domain )
197
+ ) {
198
+ $ states [] = self ::MESSAGE_EQUALS_FALLBACK ;
192
199
193
- foreach ( $ fallbackCatalogues as $ fallbackCatalogue ) {
194
- if ( $ fallbackCatalogue -> defines ( $ messageId , $ domain ) && $ value === $ fallbackCatalogue -> get ( $ messageId , $ domain )) {
195
- $ states [] = self :: MESSAGE_EQUALS_FALLBACK ;
200
+ break ;
201
+ }
202
+ }
196
203
197
- break ;
204
+ $ row = array (
205
+ $ this ->formatStates ($ states ),
206
+ $ domain ,
207
+ $ this ->formatId ($ messageId ),
208
+ $ this ->sanitizeString ($ value ),
209
+ );
210
+ foreach ($ fallbackCatalogues as $ fallbackCatalogue ) {
211
+ $ row [] = $ this ->sanitizeString ($ fallbackCatalogue ->get ($ messageId , $ domain ));
198
212
}
199
- }
200
213
201
- $ row = array ($ this ->formatStates ($ states ), $ domain , $ this ->formatId ($ messageId ), $ this ->sanitizeString ($ value ));
202
- foreach ($ fallbackCatalogues as $ fallbackCatalogue ) {
203
- $ row [] = $ this ->sanitizeString ($ fallbackCatalogue ->get ($ messageId , $ domain ));
214
+ $ table ->addRow ($ row );
204
215
}
205
-
206
- $ table ->addRow ($ row );
207
216
}
208
- }
209
217
210
- $ table ->render ();
218
+ $ table ->render ();
219
+ $ output ->writeln ('' );
220
+ }
211
221
212
- $ output ->writeln ('' );
213
222
$ output ->writeln ('<info>Legend:</info> ' );
214
223
$ output ->writeln (sprintf (' %s Missing message ' , $ this ->formatState (self ::MESSAGE_MISSING )));
215
224
$ output ->writeln (sprintf (' %s Unused message ' , $ this ->formatState (self ::MESSAGE_UNUSED )));
216
- $ output ->writeln (sprintf (' %s Same as the fallback message ' , $ this ->formatState (self ::MESSAGE_EQUALS_FALLBACK )));
225
+ $ output ->writeln (
226
+ sprintf (' %s Same as the fallback message ' , $ this ->formatState (self ::MESSAGE_EQUALS_FALLBACK ))
227
+ );
217
228
}
218
229
219
230
private function formatState ($ state )
@@ -262,4 +273,63 @@ private function sanitizeString($string, $length = 40)
262
273
263
274
return $ string ;
264
275
}
276
+
277
+ /**
278
+ * @param string $locale
279
+ * @param string $rootPath
280
+ *
281
+ * @return MessageCatalogue
282
+ */
283
+ private function extractMessages ($ locale , $ rootPath )
284
+ {
285
+ $ extractedCatalogue = new MessageCatalogue ($ locale );
286
+ if (is_dir ($ rootPath .'/Resources/views ' )) {
287
+ $ this ->getContainer ()->get ('translation.extractor ' )->extract ($ rootPath .'/Resources/views ' , $ extractedCatalogue );
288
+ }
289
+
290
+ return $ extractedCatalogue ;
291
+ }
292
+
293
+ /**
294
+ * @param string $locale
295
+ * @param string $translationsPath
296
+ * @param TranslationLoader $loader
297
+ *
298
+ * @return MessageCatalogue
299
+ */
300
+ private function loadCurrentMessages ($ locale , $ translationsPath , TranslationLoader $ loader )
301
+ {
302
+ $ currentCatalogue = new MessageCatalogue ($ locale );
303
+ if (is_dir ($ translationsPath )) {
304
+ $ loader ->loadMessages ($ translationsPath , $ currentCatalogue );
305
+ }
306
+
307
+ return $ currentCatalogue ;
308
+ }
309
+
310
+ /**
311
+ * @param string $locale
312
+ * @param string $translationsPath
313
+ * @param TranslationLoader $loader
314
+ *
315
+ * @return MessageCatalogue[]
316
+ */
317
+ private function loadFallbackCatalogues ($ locale , $ translationsPath , TranslationLoader $ loader )
318
+ {
319
+ $ fallbackCatalogues = array ();
320
+ $ translator = $ this ->getContainer ()->get ('translator ' );
321
+ if ($ translator instanceof Translator) {
322
+ foreach ($ translator ->getFallbackLocales () as $ fallbackLocale ) {
323
+ if ($ fallbackLocale === $ locale ) {
324
+ continue ;
325
+ }
326
+
327
+ $ fallbackCatalogue = new MessageCatalogue ($ fallbackLocale );
328
+ $ loader ->loadMessages ($ translationsPath , $ fallbackCatalogue );
329
+ $ fallbackCatalogues [] = $ fallbackCatalogue ;
330
+ }
331
+ }
332
+
333
+ return $ fallbackCatalogues ;
334
+ }
265
335
}
0 commit comments