Skip to content

Commit 708ab39

Browse files
committed
Add --update-source option in translation:extract
1 parent 745da80 commit 708ab39

File tree

7 files changed

+69
-5
lines changed

7 files changed

+69
-5
lines changed

src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ CHANGELOG
44
7.1
55
---
66

7+
* Add `--update-source` option to `translation:extract` command to use de default locale target in the `source` tag of XLIFF files
78
* Add `private_ranges` as a shortcut for private IP address ranges to the `trusted_proxies` option
89
* Mark classes `ConfigBuilderCacheWarmer`, `Router`, `SerializerCacheWarmer`, `TranslationsCacheWarmer`, `Translator` and `ValidatorCacheWarmer` as `final`
910
* Move the Router `cache_dir` to `kernel.build_dir`

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

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ protected function configure(): void
8686
new InputOption('dump-messages', null, InputOption::VALUE_NONE, 'Should the messages be dumped in the console'),
8787
new InputOption('force', null, InputOption::VALUE_NONE, 'Should the extract be done'),
8888
new InputOption('clean', null, InputOption::VALUE_NONE, 'Should clean not found messages'),
89+
new InputOption('update-source', null, InputOption::VALUE_NONE, 'Should update source tag in XLIFF'),
8990
new InputOption('domain', null, InputOption::VALUE_OPTIONAL, 'Specify the domain to extract'),
9091
new InputOption('sort', null, InputOption::VALUE_OPTIONAL, 'Return list of messages sorted alphabetically (only works with --dump-messages)', 'asc'),
9192
new InputOption('as-tree', null, InputOption::VALUE_OPTIONAL, 'Dump the messages as a tree-like structure: The given value defines the level where to switch to inline YAML'),
@@ -277,7 +278,31 @@ protected function execute(InputInterface $input, OutputInterface $output): int
277278
$bundleTransPath = end($transPaths);
278279
}
279280

280-
$this->writer->write($operation->getResult(), $format, ['path' => $bundleTransPath, 'default_locale' => $this->defaultLocale, 'xliff_version' => $xliffVersion, 'as_tree' => $input->getOption('as-tree'), 'inline' => $input->getOption('as-tree') ?? 0]);
281+
$resultCatalogue = $operation->getResult();
282+
$writerOptions = ['path' => $bundleTransPath, 'default_locale' => $this->defaultLocale, 'xliff_version' => $xliffVersion, 'as_tree' => $input->getOption('as-tree'), 'inline' => $input->getOption('as-tree') ?? 0];
283+
284+
if (true === $input->getOption('update-source')) {
285+
$defaultLocaleCatalogue = $this->loadCurrentMessages($this->defaultLocale, $transPaths);
286+
287+
$domains = (null !== $domain) ? [$domain] : $resultCatalogue->getDomains();
288+
289+
// Update source metadata with default locale target for each message in result catalogue
290+
foreach ($domains as $domain) {
291+
foreach ($resultCatalogue->all($domain) as $key => $value) {
292+
if (!$defaultLocaleCatalogue->has($key, $domain)) {
293+
continue;
294+
}
295+
296+
$resultMetadata = $resultCatalogue->getMetadata($key, $domain);
297+
if (!isset($resultMetadata['source']) || $resultMetadata['source'] === $key) {
298+
$resultMetadata['source'] = $defaultLocaleCatalogue->get($key, $domain);
299+
$resultCatalogue->setMetadata($key, $resultMetadata, $domain);
300+
}
301+
}
302+
}
303+
}
304+
305+
$this->writer->write($resultCatalogue, $format, $writerOptions);
281306

282307
if (true === $input->getOption('dump-messages')) {
283308
$resultMessage .= ' and translation files were updated';

src/Symfony/Bundle/FrameworkBundle/Tests/Command/TranslationUpdateCommandTest.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,13 @@ public function testFilterDuplicateTransPaths()
171171
$this->assertEquals($expectedPaths, $filteredTransPaths);
172172
}
173173

174+
public function testWriteMessagesWithUpdateSourceOption()
175+
{
176+
$tester = $this->createCommandTester(['messages' => ['foo' => 'foo']]);
177+
$tester->execute(['command' => 'translation:extract', 'locale' => 'en', '--force' => true, '--update-source' => true]);
178+
$this->assertMatchesRegularExpression('/Translation files were successfully updated\./', $tester->getDisplay());
179+
}
180+
174181
protected function setUp(): void
175182
{
176183
$this->fs = new Filesystem();

src/Symfony/Component/Translation/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ CHANGELOG
44
7.1
55
---
66

7+
* `XliffFileDumper` now uses the `source` metadata to create the `source` tag if available
78
* Mark class `DataCollectorTranslator` as `final`
89

910
7.0

src/Symfony/Component/Translation/Dumper/XliffFileDumper.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,14 +96,15 @@ private function dumpXliff1(string $defaultLocale, MessageCatalogue $messages, ?
9696
$translation->setAttribute('id', strtr(substr(base64_encode(hash('xxh128', $source, true)), 0, 7), '/+', '._'));
9797
$translation->setAttribute('resname', $source);
9898

99+
$metadata = $messages->getMetadata($source, $domain);
100+
99101
$s = $translation->appendChild($dom->createElement('source'));
100-
$s->appendChild($dom->createTextNode($source));
102+
$s->appendChild($dom->createTextNode($metadata['source'] ?? $source));
101103

102104
// Does the target contain characters requiring a CDATA section?
103105
$text = 1 === preg_match('/[&<>]/', $target) ? $dom->createCDATASection($target) : $dom->createTextNode($target);
104106

105107
$targetElement = $dom->createElement('target');
106-
$metadata = $messages->getMetadata($source, $domain);
107108
if ($this->hasMetadataArrayInfo('target-attributes', $metadata)) {
108109
foreach ($metadata['target-attributes'] as $name => $value) {
109110
$targetElement->setAttribute($name, $value);
@@ -141,7 +142,6 @@ private function dumpXliff2(string $defaultLocale, MessageCatalogue $messages, ?
141142
{
142143
$dom = new \DOMDocument('1.0', 'utf-8');
143144
$dom->formatOutput = true;
144-
145145
$xliff = $dom->appendChild($dom->createElement('xliff'));
146146
$xliff->setAttribute('xmlns', 'urn:oasis:names:tc:xliff:document:2.0');
147147
$xliff->setAttribute('version', '2.0');
@@ -194,7 +194,7 @@ private function dumpXliff2(string $defaultLocale, MessageCatalogue $messages, ?
194194
$segment = $translation->appendChild($dom->createElement('segment'));
195195

196196
$s = $segment->appendChild($dom->createElement('source'));
197-
$s->appendChild($dom->createTextNode($source));
197+
$s->appendChild($dom->createTextNode($metadata['source'] ?? $source));
198198

199199
// Does the target contain characters requiring a CDATA section?
200200
$text = 1 === preg_match('/[&<>]/', $target) ? $dom->createCDATASection($target) : $dom->createTextNode($target);

src/Symfony/Component/Translation/Tests/Dumper/XliffFileDumperTest.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,4 +147,20 @@ public function testDumpCatalogueWithXliffExtension()
147147
$dumper->formatCatalogue($catalogue, 'messages', ['default_locale' => 'fr_FR'])
148148
);
149149
}
150+
151+
public function testFormatCatalogueWithSourceMetadata()
152+
{
153+
$catalogue = new MessageCatalogue('en_US');
154+
$catalogue->add([
155+
'foo' => 'bar',
156+
]);
157+
$catalogue->setMetadata('foo', ['source' => 'foo_source']);
158+
159+
$dumper = new XliffFileDumper('xliff');
160+
161+
$this->assertStringEqualsFile(
162+
__DIR__.'/../Fixtures/resources-source-meta.xliff',
163+
$dumper->formatCatalogue($catalogue, 'messages', ['default_locale' => 'fr_FR'])
164+
);
165+
}
150166
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
3+
<file source-language="fr-FR" target-language="en-US" datatype="plaintext" original="file.ext">
4+
<header>
5+
<tool tool-id="symfony" tool-name="Symfony"/>
6+
</header>
7+
<body>
8+
<trans-unit id="ea75LoN" resname="foo">
9+
<source>foo_source</source>
10+
<target>bar</target>
11+
</trans-unit>
12+
</body>
13+
</file>
14+
</xliff>

0 commit comments

Comments
 (0)