Skip to content

Commit 84bc4b7

Browse files
committed
Merge branch '5.4' into 6.0
* 5.4: [FrameworkBundle] Add completion feature on translation:update command [Security] Backport 6.0 compat fixes Add completion feature on translation pull and push commands [Console] Add completion to debug:translation command [Console] Add autocompletion for security commands choose the proper array element to decode the message [RateLimiter] Add support for long intervals (months and years)
2 parents f7a351f + 93340c8 commit 84bc4b7

File tree

5 files changed

+407
-52
lines changed

5 files changed

+407
-52
lines changed

Command/TranslationDebugCommand.php

Lines changed: 66 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313

1414
use Symfony\Component\Console\Attribute\AsCommand;
1515
use Symfony\Component\Console\Command\Command;
16+
use Symfony\Component\Console\Completion\CompletionInput;
17+
use Symfony\Component\Console\Completion\CompletionSuggestions;
1618
use Symfony\Component\Console\Exception\InvalidArgumentException;
1719
use Symfony\Component\Console\Input\InputArgument;
1820
use Symfony\Component\Console\Input\InputInterface;
@@ -55,8 +57,9 @@ class TranslationDebugCommand extends Command
5557
private $defaultViewsPath;
5658
private $transPaths;
5759
private $codePaths;
60+
private $enabledLocales;
5861

59-
public function __construct(TranslatorInterface $translator, TranslationReaderInterface $reader, ExtractorInterface $extractor, string $defaultTransPath = null, string $defaultViewsPath = null, array $transPaths = [], array $codePaths = [])
62+
public function __construct(TranslatorInterface $translator, TranslationReaderInterface $reader, ExtractorInterface $extractor, string $defaultTransPath = null, string $defaultViewsPath = null, array $transPaths = [], array $codePaths = [], array $enabledLocales = [])
6063
{
6164
parent::__construct();
6265

@@ -67,6 +70,7 @@ public function __construct(TranslatorInterface $translator, TranslationReaderIn
6770
$this->defaultViewsPath = $defaultViewsPath;
6871
$this->transPaths = $transPaths;
6972
$this->codePaths = $codePaths;
73+
$this->enabledLocales = $enabledLocales;
7074
}
7175

7276
/**
@@ -133,15 +137,8 @@ protected function execute(InputInterface $input, OutputInterface $output): int
133137
$kernel = $this->getApplication()->getKernel();
134138

135139
// Define Root Paths
136-
$transPaths = $this->transPaths;
137-
if ($this->defaultTransPath) {
138-
$transPaths[] = $this->defaultTransPath;
139-
}
140-
$codePaths = $this->codePaths;
141-
$codePaths[] = $kernel->getProjectDir().'/src';
142-
if ($this->defaultViewsPath) {
143-
$codePaths[] = $this->defaultViewsPath;
144-
}
140+
$transPaths = $this->getRootTransPaths();
141+
$codePaths = $this->getRootCodePaths($kernel);
145142

146143
// Override with provided Bundle info
147144
if (null !== $input->getArgument('bundle')) {
@@ -257,6 +254,44 @@ protected function execute(InputInterface $input, OutputInterface $output): int
257254
return $exitCode;
258255
}
259256

257+
public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void
258+
{
259+
if ($input->mustSuggestArgumentValuesFor('locale')) {
260+
$suggestions->suggestValues($this->enabledLocales);
261+
262+
return;
263+
}
264+
265+
/** @var KernelInterface $kernel */
266+
$kernel = $this->getApplication()->getKernel();
267+
268+
if ($input->mustSuggestArgumentValuesFor('bundle')) {
269+
$availableBundles = [];
270+
foreach ($kernel->getBundles() as $bundle) {
271+
$availableBundles[] = $bundle->getName();
272+
273+
if ($extension = $bundle->getContainerExtension()) {
274+
$availableBundles[] = $extension->getAlias();
275+
}
276+
}
277+
278+
$suggestions->suggestValues($availableBundles);
279+
280+
return;
281+
}
282+
283+
if ($input->mustSuggestOptionValuesFor('domain')) {
284+
$locale = $input->getArgument('locale');
285+
286+
$mergeOperation = new MergeOperation(
287+
$this->extractMessages($locale, $this->getRootCodePaths($kernel)),
288+
$this->loadCurrentMessages($locale, $this->getRootTransPaths())
289+
);
290+
291+
$suggestions->suggestValues($mergeOperation->getDomains());
292+
}
293+
}
294+
260295
private function formatState(int $state): string
261296
{
262297
if (self::MESSAGE_MISSING === $state) {
@@ -352,4 +387,25 @@ private function loadFallbackCatalogues(string $locale, array $transPaths): arra
352387

353388
return $fallbackCatalogues;
354389
}
390+
391+
private function getRootTransPaths(): array
392+
{
393+
$transPaths = $this->transPaths;
394+
if ($this->defaultTransPath) {
395+
$transPaths[] = $this->defaultTransPath;
396+
}
397+
398+
return $transPaths;
399+
}
400+
401+
private function getRootCodePaths(KernelInterface $kernel): array
402+
{
403+
$codePaths = $this->codePaths;
404+
$codePaths[] = $kernel->getProjectDir().'/src';
405+
if ($this->defaultViewsPath) {
406+
$codePaths[] = $this->defaultViewsPath;
407+
}
408+
409+
return $codePaths;
410+
}
355411
}

Command/TranslationUpdateCommand.php

Lines changed: 116 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313

1414
use Symfony\Component\Console\Attribute\AsCommand;
1515
use Symfony\Component\Console\Command\Command;
16+
use Symfony\Component\Console\Completion\CompletionInput;
17+
use Symfony\Component\Console\Completion\CompletionSuggestions;
1618
use Symfony\Component\Console\Exception\InvalidArgumentException;
1719
use Symfony\Component\Console\Input\InputArgument;
1820
use Symfony\Component\Console\Input\InputInterface;
@@ -43,6 +45,10 @@ class TranslationUpdateCommand extends Command
4345
private const ASC = 'asc';
4446
private const DESC = 'desc';
4547
private const SORT_ORDERS = [self::ASC, self::DESC];
48+
private const FORMATS = [
49+
'xlf12' => ['xlf', '1.2'],
50+
'xlf20' => ['xlf', '2.0'],
51+
];
4652

4753
private $writer;
4854
private $reader;
@@ -52,8 +58,9 @@ class TranslationUpdateCommand extends Command
5258
private $defaultViewsPath;
5359
private $transPaths;
5460
private $codePaths;
61+
private $enabledLocales;
5562

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 = [])
5764
{
5865
parent::__construct();
5966

@@ -65,6 +72,7 @@ public function __construct(TranslationWriterInterface $writer, TranslationReade
6572
$this->defaultViewsPath = $defaultViewsPath;
6673
$this->transPaths = $transPaths;
6774
$this->codePaths = $codePaths;
75+
$this->enabledLocales = $enabledLocales;
6876
}
6977

7078
/**
@@ -143,10 +151,8 @@ protected function execute(InputInterface $input, OutputInterface $output): int
143151
$format = $input->getOption('format');
144152
$xliffVersion = '1.2';
145153

146-
switch ($format) {
147-
case 'xlf20': $xliffVersion = '2.0';
148-
// no break
149-
case 'xlf12': $format = 'xlf';
154+
if (\in_array($format, array_keys(self::FORMATS), true)) {
155+
[$format, $xliffVersion] = self::FORMATS[$format];
150156
}
151157

152158
// check format
@@ -161,15 +167,9 @@ protected function execute(InputInterface $input, OutputInterface $output): int
161167
$kernel = $this->getApplication()->getKernel();
162168

163169
// Define Root Paths
164-
$transPaths = $this->transPaths;
165-
if ($this->defaultTransPath) {
166-
$transPaths[] = $this->defaultTransPath;
167-
}
168-
$codePaths = $this->codePaths;
169-
$codePaths[] = $kernel->getProjectDir().'/src';
170-
if ($this->defaultViewsPath) {
171-
$codePaths[] = $this->defaultViewsPath;
172-
}
170+
$transPaths = $this->getRootTransPaths();
171+
$codePaths = $this->getRootCodePaths($kernel);
172+
173173
$currentName = 'default directory';
174174

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

205-
// load any messages from templates
206-
$extractedCatalogue = new MessageCatalogue($input->getArgument('locale'));
207205
$io->comment('Parsing templates...');
208-
$this->extractor->setPrefix($input->getOption('prefix'));
209-
foreach ($codePaths as $path) {
210-
if (is_dir($path) || is_file($path)) {
211-
$this->extractor->extract($path, $extractedCatalogue);
212-
}
213-
}
206+
$extractedCatalogue = $this->extractMessages($input->getArgument('locale'), $codePaths, $input->getOption('prefix'));
214207

215-
// load any existing messages from the translation files
216-
$currentCatalogue = new MessageCatalogue($input->getArgument('locale'));
217208
$io->comment('Loading translation files...');
218-
foreach ($transPaths as $path) {
219-
if (is_dir($path)) {
220-
$this->reader->read($path, $currentCatalogue);
221-
}
222-
}
209+
$currentCatalogue = $this->loadCurrentMessages($input->getArgument('locale'), $transPaths);
223210

224211
if (null !== $domain = $input->getOption('domain')) {
225212
$currentCatalogue = $this->filterCatalogue($currentCatalogue, $domain);
@@ -317,6 +304,60 @@ protected function execute(InputInterface $input, OutputInterface $output): int
317304
return 0;
318305
}
319306

307+
public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void
308+
{
309+
if ($input->mustSuggestArgumentValuesFor('locale')) {
310+
$suggestions->suggestValues($this->enabledLocales);
311+
312+
return;
313+
}
314+
315+
/** @var KernelInterface $kernel */
316+
$kernel = $this->getApplication()->getKernel();
317+
if ($input->mustSuggestArgumentValuesFor('bundle')) {
318+
$bundles = [];
319+
320+
foreach ($kernel->getBundles() as $bundle) {
321+
$bundles[] = $bundle->getName();
322+
if ($bundle->getContainerExtension()) {
323+
$bundles[] = $bundle->getContainerExtension()->getAlias();
324+
}
325+
}
326+
327+
$suggestions->suggestValues($bundles);
328+
329+
return;
330+
}
331+
332+
if ($input->mustSuggestOptionValuesFor('format')) {
333+
$suggestions->suggestValues(array_merge(
334+
$this->writer->getFormats(),
335+
array_keys(self::FORMATS)
336+
));
337+
338+
return;
339+
}
340+
341+
if ($input->mustSuggestOptionValuesFor('domain') && $locale = $input->getArgument('locale')) {
342+
$extractedCatalogue = $this->extractMessages($locale, $this->getRootCodePaths($kernel), $input->getOption('prefix'));
343+
344+
$currentCatalogue = $this->loadCurrentMessages($locale, $this->getRootTransPaths());
345+
346+
// process catalogues
347+
$operation = $input->getOption('clean')
348+
? new TargetOperation($currentCatalogue, $extractedCatalogue)
349+
: new MergeOperation($currentCatalogue, $extractedCatalogue);
350+
351+
$suggestions->suggestValues($operation->getDomains());
352+
353+
return;
354+
}
355+
356+
if ($input->mustSuggestOptionValuesFor('sort')) {
357+
$suggestions->suggestValues(self::SORT_ORDERS);
358+
}
359+
}
360+
320361
private function filterCatalogue(MessageCatalogue $catalogue, string $domain): MessageCatalogue
321362
{
322363
$filteredCatalogue = new MessageCatalogue($catalogue->getLocale());
@@ -349,4 +390,50 @@ private function filterCatalogue(MessageCatalogue $catalogue, string $domain): M
349390

350391
return $filteredCatalogue;
351392
}
393+
394+
private function extractMessages(string $locale, array $transPaths, string $prefix): MessageCatalogue
395+
{
396+
$extractedCatalogue = new MessageCatalogue($locale);
397+
$this->extractor->setPrefix($prefix);
398+
foreach ($transPaths as $path) {
399+
if (is_dir($path) || is_file($path)) {
400+
$this->extractor->extract($path, $extractedCatalogue);
401+
}
402+
}
403+
404+
return $extractedCatalogue;
405+
}
406+
407+
private function loadCurrentMessages(string $locale, array $transPaths): MessageCatalogue
408+
{
409+
$currentCatalogue = new MessageCatalogue($locale);
410+
foreach ($transPaths as $path) {
411+
if (is_dir($path)) {
412+
$this->reader->read($path, $currentCatalogue);
413+
}
414+
}
415+
416+
return $currentCatalogue;
417+
}
418+
419+
private function getRootTransPaths(): array
420+
{
421+
$transPaths = $this->transPaths;
422+
if ($this->defaultTransPath) {
423+
$transPaths[] = $this->defaultTransPath;
424+
}
425+
426+
return $transPaths;
427+
}
428+
429+
private function getRootCodePaths(KernelInterface $kernel): array
430+
{
431+
$codePaths = $this->codePaths;
432+
$codePaths[] = $kernel->getProjectDir().'/src';
433+
if ($this->defaultViewsPath) {
434+
$codePaths[] = $this->defaultViewsPath;
435+
}
436+
437+
return $codePaths;
438+
}
352439
}

Resources/config/console.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,7 @@
221221
null, // twig.default_path
222222
[], // Translator paths
223223
[], // Twig paths
224+
param('kernel.enabled_locales'),
224225
])
225226
->tag('console.command')
226227

@@ -234,6 +235,7 @@
234235
null, // twig.default_path
235236
[], // Translator paths
236237
[], // Twig paths
238+
param('kernel.enabled_locales'),
237239
])
238240
->tag('console.command')
239241

0 commit comments

Comments
 (0)