Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit375a89a

Browse files
committed
feature#43676 [FrameworkBundle] Add completion feature on translation:update command (stephenkhoo)
This PR was squashed before being merged into the 5.4 branch.Discussion----------[FrameworkBundle] Add completion feature on translation:update command| Q | A| ------------- | ---| Branch? | 5.4| Bug fix? | no| New feature? | yes| Deprecations? | no| Tickets | Part of#43594| License | MIT| Doc PR | -Adding completion for translation:update.- [x] locale- [X] bundle- [X] --format- [X] --domain- [X] --sortTest for- [x] locale- [x] bundle- [X] --format- [X] --domain- [X] --sortLocale completion still under discussion in#43644 (review)Locale and bundle test still not completeCommits-------2f301ae [FrameworkBundle] Add completion feature on translation:update command
2 parents3f0f0ce +2f301ae commit375a89a

File tree

3 files changed

+267
-29
lines changed

3 files changed

+267
-29
lines changed

‎src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php‎

Lines changed: 116 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
namespaceSymfony\Bundle\FrameworkBundle\Command;
1313

1414
useSymfony\Component\Console\Command\Command;
15+
useSymfony\Component\Console\Completion\CompletionInput;
16+
useSymfony\Component\Console\Completion\CompletionSuggestions;
1517
useSymfony\Component\Console\Exception\InvalidArgumentException;
1618
useSymfony\Component\Console\Input\InputArgument;
1719
useSymfony\Component\Console\Input\InputInterface;
@@ -41,6 +43,10 @@ class TranslationUpdateCommand extends Command
4143
privateconstASC ='asc';
4244
privateconstDESC ='desc';
4345
privateconstSORT_ORDERS = [self::ASC,self::DESC];
46+
privateconstFORMATS = [
47+
'xlf12' => ['xlf','1.2'],
48+
'xlf20' => ['xlf','2.0'],
49+
];
4450

4551
protectedstatic$defaultName ='translation:extract|translation:update';
4652
protectedstatic$defaultDescription ='Extract missing translations keys from code to translation files.';
@@ -53,8 +59,9 @@ class TranslationUpdateCommand extends Command
5359
private$defaultViewsPath;
5460
private$transPaths;
5561
private$codePaths;
62+
private$enabledLocales;
5663

57-
publicfunction__construct(TranslationWriterInterface$writer,TranslationReaderInterface$reader,ExtractorInterface$extractor,string$defaultLocale,string$defaultTransPath =null,string$defaultViewsPath =null,array$transPaths = [],array$codePaths = [])
64+
publicfunction__construct(TranslationWriterInterface$writer,TranslationReaderInterface$reader,ExtractorInterface$extractor,string$defaultLocale,string$defaultTransPath =null,string$defaultViewsPath =null,array$transPaths = [],array$codePaths = [],array$enabledLocales = [])
5865
{
5966
parent::__construct();
6067

@@ -66,6 +73,7 @@ public function __construct(TranslationWriterInterface $writer, TranslationReade
6673
$this->defaultViewsPath =$defaultViewsPath;
6774
$this->transPaths =$transPaths;
6875
$this->codePaths =$codePaths;
76+
$this->enabledLocales =$enabledLocales;
6977
}
7078

7179
/**
@@ -155,10 +163,8 @@ protected function execute(InputInterface $input, OutputInterface $output): int
155163
trigger_deprecation('symfony/framework-bundle','5.3','The "--output-format" option is deprecated, use "--format=xlf%d" instead.',10 *$xliffVersion);
156164
}
157165

158-
switch ($format) {
159-
case'xlf20':$xliffVersion ='2.0';
160-
// no break
161-
case'xlf12':$format ='xlf';
166+
if (\in_array($format,array_keys(self::FORMATS),true)) {
167+
[$format,$xliffVersion] =self::FORMATS[$format];
162168
}
163169

164170
// check format
@@ -173,15 +179,9 @@ protected function execute(InputInterface $input, OutputInterface $output): int
173179
$kernel =$this->getApplication()->getKernel();
174180

175181
// Define Root Paths
176-
$transPaths =$this->transPaths;
177-
if ($this->defaultTransPath) {
178-
$transPaths[] =$this->defaultTransPath;
179-
}
180-
$codePaths =$this->codePaths;
181-
$codePaths[] =$kernel->getProjectDir().'/src';
182-
if ($this->defaultViewsPath) {
183-
$codePaths[] =$this->defaultViewsPath;
184-
}
182+
$transPaths =$this->getRootTransPaths();
183+
$codePaths =$this->getRootCodePaths($kernel);
184+
185185
$currentName ='default directory';
186186

187187
// Override with provided Bundle info
@@ -214,24 +214,11 @@ protected function execute(InputInterface $input, OutputInterface $output): int
214214
$io->title('Translation Messages Extractor and Dumper');
215215
$io->comment(sprintf('Generating "<info>%s</info>" translation files for "<info>%s</info>"',$input->getArgument('locale'),$currentName));
216216

217-
// load any messages from templates
218-
$extractedCatalogue =newMessageCatalogue($input->getArgument('locale'));
219217
$io->comment('Parsing templates...');
220-
$this->extractor->setPrefix($input->getOption('prefix'));
221-
foreach ($codePathsas$path) {
222-
if (is_dir($path) ||is_file($path)) {
223-
$this->extractor->extract($path,$extractedCatalogue);
224-
}
225-
}
218+
$extractedCatalogue =$this->extractMessages($input->getArgument('locale'),$codePaths,$input->getOption('prefix'));
226219

227-
// load any existing messages from the translation files
228-
$currentCatalogue =newMessageCatalogue($input->getArgument('locale'));
229220
$io->comment('Loading translation files...');
230-
foreach ($transPathsas$path) {
231-
if (is_dir($path)) {
232-
$this->reader->read($path,$currentCatalogue);
233-
}
234-
}
221+
$currentCatalogue =$this->loadCurrentMessages($input->getArgument('locale'),$transPaths);
235222

236223
if (null !==$domain =$input->getOption('domain')) {
237224
$currentCatalogue =$this->filterCatalogue($currentCatalogue,$domain);
@@ -329,6 +316,60 @@ protected function execute(InputInterface $input, OutputInterface $output): int
329316
return0;
330317
}
331318

319+
publicfunctioncomplete(CompletionInput$input,CompletionSuggestions$suggestions):void
320+
{
321+
if ($input->mustSuggestArgumentValuesFor('locale')) {
322+
$suggestions->suggestValues($this->enabledLocales);
323+
324+
return;
325+
}
326+
327+
/** @var KernelInterface $kernel */
328+
$kernel =$this->getApplication()->getKernel();
329+
if ($input->mustSuggestArgumentValuesFor('bundle')) {
330+
$bundles = [];
331+
332+
foreach ($kernel->getBundles()as$bundle) {
333+
$bundles[] =$bundle->getName();
334+
if ($bundle->getContainerExtension()) {
335+
$bundles[] =$bundle->getContainerExtension()->getAlias();
336+
}
337+
}
338+
339+
$suggestions->suggestValues($bundles);
340+
341+
return;
342+
}
343+
344+
if ($input->mustSuggestOptionValuesFor('format')) {
345+
$suggestions->suggestValues(array_merge(
346+
$this->writer->getFormats(),
347+
array_keys(self::FORMATS)
348+
));
349+
350+
return;
351+
}
352+
353+
if ($input->mustSuggestOptionValuesFor('domain') &&$locale =$input->getArgument('locale')) {
354+
$extractedCatalogue =$this->extractMessages($locale,$this->getRootCodePaths($kernel),$input->getOption('prefix'));
355+
356+
$currentCatalogue =$this->loadCurrentMessages($locale,$this->getRootTransPaths());
357+
358+
// process catalogues
359+
$operation =$input->getOption('clean')
360+
?newTargetOperation($currentCatalogue,$extractedCatalogue)
361+
:newMergeOperation($currentCatalogue,$extractedCatalogue);
362+
363+
$suggestions->suggestValues($operation->getDomains());
364+
365+
return;
366+
}
367+
368+
if ($input->mustSuggestOptionValuesFor('sort')) {
369+
$suggestions->suggestValues(self::SORT_ORDERS);
370+
}
371+
}
372+
332373
privatefunctionfilterCatalogue(MessageCatalogue$catalogue,string$domain):MessageCatalogue
333374
{
334375
$filteredCatalogue =newMessageCatalogue($catalogue->getLocale());
@@ -361,4 +402,50 @@ private function filterCatalogue(MessageCatalogue $catalogue, string $domain): M
361402

362403
return$filteredCatalogue;
363404
}
405+
406+
privatefunctionextractMessages(string$locale,array$transPaths,string$prefix):MessageCatalogue
407+
{
408+
$extractedCatalogue =newMessageCatalogue($locale);
409+
$this->extractor->setPrefix($prefix);
410+
foreach ($transPathsas$path) {
411+
if (is_dir($path) ||is_file($path)) {
412+
$this->extractor->extract($path,$extractedCatalogue);
413+
}
414+
}
415+
416+
return$extractedCatalogue;
417+
}
418+
419+
privatefunctionloadCurrentMessages(string$locale,array$transPaths):MessageCatalogue
420+
{
421+
$currentCatalogue =newMessageCatalogue($locale);
422+
foreach ($transPathsas$path) {
423+
if (is_dir($path)) {
424+
$this->reader->read($path,$currentCatalogue);
425+
}
426+
}
427+
428+
return$currentCatalogue;
429+
}
430+
431+
privatefunctiongetRootTransPaths():array
432+
{
433+
$transPaths =$this->transPaths;
434+
if ($this->defaultTransPath) {
435+
$transPaths[] =$this->defaultTransPath;
436+
}
437+
438+
return$transPaths;
439+
}
440+
441+
privatefunctiongetRootCodePaths(KernelInterface$kernel):array
442+
{
443+
$codePaths =$this->codePaths;
444+
$codePaths[] =$kernel->getProjectDir().'/src';
445+
if ($this->defaultViewsPath) {
446+
$codePaths[] =$this->defaultViewsPath;
447+
}
448+
449+
return$codePaths;
450+
}
364451
}

‎src/Symfony/Bundle/FrameworkBundle/Resources/config/console.php‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@
234234
null,// twig.default_path
235235
[],// Translator paths
236236
[],// Twig paths
237+
param('kernel.enabled_locales'),
237238
])
238239
->tag('console.command')
239240

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
<?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+
12+
namespaceSymfony\Bundle\FrameworkBundle\Tests\Command;
13+
14+
usePHPUnit\Framework\TestCase;
15+
useSymfony\Bundle\FrameworkBundle\Command\TranslationUpdateCommand;
16+
useSymfony\Bundle\FrameworkBundle\Console\Application;
17+
useSymfony\Component\Console\Tester\CommandCompletionTester;
18+
useSymfony\Component\DependencyInjection\Container;
19+
useSymfony\Component\Filesystem\Filesystem;
20+
useSymfony\Component\HttpKernel\Bundle\BundleInterface;
21+
useSymfony\Component\HttpKernel\KernelInterface;
22+
useSymfony\Component\HttpKernel\Tests\Fixtures\ExtensionPresentBundle\ExtensionPresentBundle;
23+
useSymfony\Component\Translation\Extractor\ExtractorInterface;
24+
useSymfony\Component\Translation\Reader\TranslationReader;
25+
useSymfony\Component\Translation\Translator;
26+
useSymfony\Component\Translation\Writer\TranslationWriter;
27+
28+
class TranslationUpdateCommandCompletionTestextends TestCase
29+
{
30+
private$fs;
31+
private$translationDir;
32+
33+
/**
34+
* @dataProvider provideCompletionSuggestions
35+
*/
36+
publicfunctiontestComplete(array$input,array$expectedSuggestions)
37+
{
38+
$tester =$this->createCommandCompletionTester(['messages' => ['foo' =>'foo']]);
39+
40+
$suggestions =$tester->complete($input);
41+
42+
$this->assertSame($expectedSuggestions,$suggestions);
43+
}
44+
45+
publicfunctionprovideCompletionSuggestions()
46+
{
47+
$bundle =newExtensionPresentBundle();
48+
49+
yield'locale' => [[''], ['en','fr']];
50+
yield'bundle' => [['en',''], [$bundle->getName(),$bundle->getContainerExtension()->getAlias()]];
51+
yield'domain with locale' => [['en','--domain=m'], ['messages']];
52+
yield'domain without locale' => [['--domain=m'], []];
53+
yield'format' => [['en','--format='], ['php','xlf','po','mo','yml','yaml','ts','csv','ini','json','res','xlf12','xlf20']];
54+
yield'sort' => [['en','--sort='], ['asc','desc']];
55+
}
56+
57+
protectedfunctionsetUp():void
58+
{
59+
$this->fs =newFilesystem();
60+
$this->translationDir =sys_get_temp_dir().'/'.uniqid('sf_translation',true);
61+
$this->fs->mkdir($this->translationDir.'/translations');
62+
$this->fs->mkdir($this->translationDir.'/templates');
63+
}
64+
65+
protectedfunctiontearDown():void
66+
{
67+
$this->fs->remove($this->translationDir);
68+
}
69+
70+
privatefunctioncreateCommandCompletionTester($extractedMessages = [],$loadedMessages = [],KernelInterface$kernel =null,array$transPaths = [],array$codePaths = []):CommandCompletionTester
71+
{
72+
$translator =$this->createMock(Translator::class);
73+
$translator
74+
->expects($this->any())
75+
->method('getFallbackLocales')
76+
->willReturn(['en']);
77+
78+
$extractor =$this->createMock(ExtractorInterface::class);
79+
$extractor
80+
->expects($this->any())
81+
->method('extract')
82+
->willReturnCallback(
83+
function ($path,$catalogue)use ($extractedMessages) {
84+
foreach ($extractedMessagesas$domain =>$messages) {
85+
$catalogue->add($messages,$domain);
86+
}
87+
}
88+
);
89+
90+
$loader =$this->createMock(TranslationReader::class);
91+
$loader
92+
->expects($this->any())
93+
->method('read')
94+
->willReturnCallback(
95+
function ($path,$catalogue)use ($loadedMessages) {
96+
$catalogue->add($loadedMessages);
97+
}
98+
);
99+
100+
$writer =$this->createMock(TranslationWriter::class);
101+
$writer
102+
->expects($this->any())
103+
->method('getFormats')
104+
->willReturn(
105+
['php','xlf','po','mo','yml','yaml','ts','csv','ini','json','res']
106+
);
107+
108+
if (null ===$kernel) {
109+
$returnValues = [
110+
['foo',$this->getBundle($this->translationDir)],
111+
['test',$this->getBundle('test')],
112+
];
113+
$kernel =$this->createMock(KernelInterface::class);
114+
$kernel
115+
->expects($this->any())
116+
->method('getBundle')
117+
->willReturnMap($returnValues);
118+
}
119+
120+
$kernel
121+
->expects($this->any())
122+
->method('getBundles')
123+
->willReturn([newExtensionPresentBundle()]);
124+
125+
$container =newContainer();
126+
$kernel
127+
->expects($this->any())
128+
->method('getContainer')
129+
->willReturn($container);
130+
131+
$command =newTranslationUpdateCommand($writer,$loader,$extractor,'en',$this->translationDir.'/translations',$this->translationDir.'/templates',$transPaths,$codePaths, ['en','fr']);
132+
133+
$application =newApplication($kernel);
134+
$application->add($command);
135+
136+
returnnewCommandCompletionTester($application->find('translation:update'));
137+
}
138+
139+
privatefunctiongetBundle($path)
140+
{
141+
$bundle =$this->createMock(BundleInterface::class);
142+
$bundle
143+
->expects($this->any())
144+
->method('getPath')
145+
->willReturn($path)
146+
;
147+
148+
return$bundle;
149+
}
150+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp