12
12
namespace Symfony \Bundle \FrameworkBundle \Command ;
13
13
14
14
use Symfony \Component \Console \Command \Command ;
15
+ use Symfony \Component \Console \Completion \CompletionInput ;
16
+ use Symfony \Component \Console \Completion \CompletionSuggestions ;
15
17
use Symfony \Component \Console \Exception \InvalidArgumentException ;
16
18
use Symfony \Component \Console \Input \InputArgument ;
17
19
use Symfony \Component \Console \Input \InputInterface ;
@@ -40,6 +42,10 @@ class TranslationUpdateCommand extends Command
40
42
private const ASC = 'asc ' ;
41
43
private const DESC = 'desc ' ;
42
44
private const SORT_ORDERS = [self ::ASC , self ::DESC ];
45
+ private const FORMATS = [
46
+ 'xlf12 ' => ['xlf ' , '1.2 ' ],
47
+ 'xlf20 ' => ['xlf ' , '2.0 ' ],
48
+ ];
43
49
44
50
protected static $ defaultName = 'translation:update ' ;
45
51
protected static $ defaultDescription = 'Update the translation file ' ;
@@ -52,8 +58,9 @@ class TranslationUpdateCommand extends Command
52
58
private $ defaultViewsPath ;
53
59
private $ transPaths ;
54
60
private $ codePaths ;
61
+ private $ enabledLocales ;
55
62
56
- public function __construct (TranslationWriterInterface $ writer , TranslationReaderInterface $ reader , ExtractorInterface $ extractor , string $ defaultLocale , string $ defaultTransPath = null , string $ defaultViewsPath = null , array $ transPaths = [], array $ codePaths = [])
63
+ public function __construct (TranslationWriterInterface $ writer , TranslationReaderInterface $ reader , ExtractorInterface $ extractor , string $ defaultLocale , string $ defaultTransPath = null , string $ defaultViewsPath = null , array $ transPaths = [], array $ codePaths = [], array $ enabledLocales = [] )
57
64
{
58
65
parent ::__construct ();
59
66
@@ -65,6 +72,7 @@ public function __construct(TranslationWriterInterface $writer, TranslationReade
65
72
$ this ->defaultViewsPath = $ defaultViewsPath ;
66
73
$ this ->transPaths = $ transPaths ;
67
74
$ this ->codePaths = $ codePaths ;
75
+ $ this ->enabledLocales = $ enabledLocales ;
68
76
}
69
77
70
78
/**
@@ -147,10 +155,8 @@ protected function execute(InputInterface $input, OutputInterface $output): int
147
155
trigger_deprecation ('symfony/framework-bundle ' , '5.3 ' , 'The "--output-format" option is deprecated, use "--format=xlf%d" instead. ' , 10 * $ xliffVersion );
148
156
}
149
157
150
- switch ($ format ) {
151
- case 'xlf20 ' : $ xliffVersion = '2.0 ' ;
152
- // no break
153
- case 'xlf12 ' : $ format = 'xlf ' ;
158
+ if (\in_array ($ format , array_keys (self ::FORMATS ), true )) {
159
+ [$ format , $ xliffVersion ] = self ::FORMATS [$ format ];
154
160
}
155
161
156
162
// check format
@@ -165,15 +171,9 @@ protected function execute(InputInterface $input, OutputInterface $output): int
165
171
$ kernel = $ this ->getApplication ()->getKernel ();
166
172
167
173
// Define Root Paths
168
- $ transPaths = $ this ->transPaths ;
169
- if ($ this ->defaultTransPath ) {
170
- $ transPaths [] = $ this ->defaultTransPath ;
171
- }
172
- $ codePaths = $ this ->codePaths ;
173
- $ codePaths [] = $ kernel ->getProjectDir ().'/src ' ;
174
- if ($ this ->defaultViewsPath ) {
175
- $ codePaths [] = $ this ->defaultViewsPath ;
176
- }
174
+ $ transPaths = $ this ->getRootTransPaths ();
175
+ $ codePaths = $ this ->getRootCodePaths ($ kernel );
176
+
177
177
$ currentName = 'default directory ' ;
178
178
179
179
// Override with provided Bundle info
@@ -206,24 +206,11 @@ protected function execute(InputInterface $input, OutputInterface $output): int
206
206
$ io ->title ('Translation Messages Extractor and Dumper ' );
207
207
$ io ->comment (sprintf ('Generating "<info>%s</info>" translation files for "<info>%s</info>" ' , $ input ->getArgument ('locale ' ), $ currentName ));
208
208
209
- // load any messages from templates
210
- $ extractedCatalogue = new MessageCatalogue ($ input ->getArgument ('locale ' ));
211
209
$ io ->comment ('Parsing templates... ' );
212
- $ this ->extractor ->setPrefix ($ input ->getOption ('prefix ' ));
213
- foreach ($ codePaths as $ path ) {
214
- if (is_dir ($ path ) || is_file ($ path )) {
215
- $ this ->extractor ->extract ($ path , $ extractedCatalogue );
216
- }
217
- }
210
+ $ extractedCatalogue = $ this ->extractMessages ($ input ->getArgument ('locale ' ), $ codePaths , $ input ->getOption ('prefix ' ));
218
211
219
- // load any existing messages from the translation files
220
- $ currentCatalogue = new MessageCatalogue ($ input ->getArgument ('locale ' ));
221
212
$ io ->comment ('Loading translation files... ' );
222
- foreach ($ transPaths as $ path ) {
223
- if (is_dir ($ path )) {
224
- $ this ->reader ->read ($ path , $ currentCatalogue );
225
- }
226
- }
213
+ $ currentCatalogue = $ this ->loadCurrentMessages ($ input ->getArgument ('locale ' ), $ transPaths );
227
214
228
215
if (null !== $ domain = $ input ->getOption ('domain ' )) {
229
216
$ currentCatalogue = $ this ->filterCatalogue ($ currentCatalogue , $ domain );
@@ -321,6 +308,60 @@ protected function execute(InputInterface $input, OutputInterface $output): int
321
308
return 0 ;
322
309
}
323
310
311
+ public function complete (CompletionInput $ input , CompletionSuggestions $ suggestions ): void
312
+ {
313
+ if ($ input ->mustSuggestArgumentValuesFor ('locale ' )) {
314
+ $ suggestions ->suggestValues ($ this ->enabledLocales );
315
+
316
+ return ;
317
+ }
318
+
319
+ /** @var KernelInterface $kernel */
320
+ $ kernel = $ this ->getApplication ()->getKernel ();
321
+ if ($ input ->mustSuggestArgumentValuesFor ('bundle ' )) {
322
+ $ bundles = [];
323
+
324
+ foreach ($ kernel ->getBundles () as $ bundle ) {
325
+ $ bundles [] = $ bundle ->getName ();
326
+ if ($ bundle ->getContainerExtension ()) {
327
+ $ bundles [] = $ bundle ->getContainerExtension ()->getAlias ();
328
+ }
329
+ }
330
+
331
+ $ suggestions ->suggestValues ($ bundles );
332
+
333
+ return ;
334
+ }
335
+
336
+ if ($ input ->mustSuggestOptionValuesFor ('format ' )) {
337
+ $ suggestions ->suggestValues (array_merge (
338
+ $ this ->writer ->getFormats (),
339
+ array_keys (self ::FORMATS )
340
+ ));
341
+
342
+ return ;
343
+ }
344
+
345
+ if ($ input ->mustSuggestOptionValuesFor ('domain ' ) && $ locale = $ input ->getArgument ('locale ' )) {
346
+ $ extractedCatalogue = $ this ->extractMessages ($ locale , $ this ->getRootCodePaths ($ kernel ), $ input ->getOption ('prefix ' ));
347
+
348
+ $ currentCatalogue = $ this ->loadCurrentMessages ($ locale , $ this ->getRootTransPaths ());
349
+
350
+ // process catalogues
351
+ $ operation = $ input ->getOption ('clean ' )
352
+ ? new TargetOperation ($ currentCatalogue , $ extractedCatalogue )
353
+ : new MergeOperation ($ currentCatalogue , $ extractedCatalogue );
354
+
355
+ $ suggestions ->suggestValues ($ operation ->getDomains ());
356
+
357
+ return ;
358
+ }
359
+
360
+ if ($ input ->mustSuggestOptionValuesFor ('sort ' )) {
361
+ $ suggestions ->suggestValues (self ::SORT_ORDERS );
362
+ }
363
+ }
364
+
324
365
private function filterCatalogue (MessageCatalogue $ catalogue , string $ domain ): MessageCatalogue
325
366
{
326
367
$ filteredCatalogue = new MessageCatalogue ($ catalogue ->getLocale ());
@@ -353,4 +394,50 @@ private function filterCatalogue(MessageCatalogue $catalogue, string $domain): M
353
394
354
395
return $ filteredCatalogue ;
355
396
}
397
+
398
+ private function extractMessages (string $ locale , array $ transPaths , string $ prefix ): MessageCatalogue
399
+ {
400
+ $ extractedCatalogue = new MessageCatalogue ($ locale );
401
+ $ this ->extractor ->setPrefix ($ prefix );
402
+ foreach ($ transPaths as $ path ) {
403
+ if (is_dir ($ path ) || is_file ($ path )) {
404
+ $ this ->extractor ->extract ($ path , $ extractedCatalogue );
405
+ }
406
+ }
407
+
408
+ return $ extractedCatalogue ;
409
+ }
410
+
411
+ private function loadCurrentMessages (string $ locale , array $ transPaths ): MessageCatalogue
412
+ {
413
+ $ currentCatalogue = new MessageCatalogue ($ locale );
414
+ foreach ($ transPaths as $ path ) {
415
+ if (is_dir ($ path )) {
416
+ $ this ->reader ->read ($ path , $ currentCatalogue );
417
+ }
418
+ }
419
+
420
+ return $ currentCatalogue ;
421
+ }
422
+
423
+ private function getRootTransPaths (): array
424
+ {
425
+ $ transPaths = $ this ->transPaths ;
426
+ if ($ this ->defaultTransPath ) {
427
+ $ transPaths [] = $ this ->defaultTransPath ;
428
+ }
429
+
430
+ return $ transPaths ;
431
+ }
432
+
433
+ private function getRootCodePaths (KernelInterface $ kernel ): array
434
+ {
435
+ $ codePaths = $ this ->codePaths ;
436
+ $ codePaths [] = $ kernel ->getProjectDir ().'/src ' ;
437
+ if ($ this ->defaultViewsPath ) {
438
+ $ codePaths [] = $ this ->defaultViewsPath ;
439
+ }
440
+
441
+ return $ codePaths ;
442
+ }
356
443
}
0 commit comments