diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php index 32ff6cce551de..65b8013450e2d 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php @@ -23,6 +23,7 @@ use Symfony\Component\Translation\Catalogue\TargetOperation; use Symfony\Component\Translation\Extractor\ExtractorInterface; use Symfony\Component\Translation\MessageCatalogue; +use Symfony\Component\Translation\MessageCatalogueInterface; use Symfony\Component\Translation\Reader\TranslationReaderInterface; use Symfony\Component\Translation\Writer\TranslationWriterInterface; @@ -254,6 +255,24 @@ protected function execute(InputInterface $input, OutputInterface $output): int $resultMessage = 'Translation files were successfully updated'; + // move new messages to intl domain when possible + if (class_exists(\MessageFormatter::class)) { + foreach ($operation->getDomains() as $domain) { + $intlDomain = $domain.MessageCatalogueInterface::INTL_DOMAIN_SUFFIX; + $newMessages = $operation->getNewMessages($domain); + + if ([] === $newMessages || ([] === $currentCatalogue->all($intlDomain) && [] !== $currentCatalogue->all($domain))) { + continue; + } + + $result = $operation->getResult(); + $allIntlMessages = $result->all($intlDomain); + $currentMessages = array_diff_key($newMessages, $result->all($domain)); + $result->replace($currentMessages, $domain); + $result->replace($allIntlMessages + $newMessages, $intlDomain); + } + } + // show compiled list of messages if (true === $input->getOption('dump-messages')) { $extractedMessagesCount = 0; diff --git a/src/Symfony/Component/Translation/Dumper/FileDumper.php b/src/Symfony/Component/Translation/Dumper/FileDumper.php index 477fcfa19ee33..2009c53403f25 100644 --- a/src/Symfony/Component/Translation/Dumper/FileDumper.php +++ b/src/Symfony/Component/Translation/Dumper/FileDumper.php @@ -67,37 +67,36 @@ public function dump(MessageCatalogue $messages, $options = []) throw new InvalidArgumentException('The file dumper needs a path option.'); } - $hasMessageFormatter = class_exists(\MessageFormatter::class); - // save a file for each domain foreach ($messages->getDomains() as $domain) { - if ($hasMessageFormatter) { - $defaultDomain = $domain.MessageCatalogue::INTL_DOMAIN_SUFFIX; - $altDomain = $domain; - } else { - $defaultDomain = $domain; - $altDomain = $domain.MessageCatalogue::INTL_DOMAIN_SUFFIX; - } - $defaultPath = $options['path'].'/'.$this->getRelativePath($defaultDomain, $messages->getLocale()); - $altPath = $options['path'].'/'.$this->getRelativePath($altDomain, $messages->getLocale()); - - if (!file_exists($defaultPath) && file_exists($altPath)) { - [$defaultPath, $altPath] = [$altPath, $defaultPath]; - } - - if (!file_exists($defaultPath)) { - $directory = \dirname($defaultPath); + $fullpath = $options['path'].'/'.$this->getRelativePath($domain, $messages->getLocale()); + if (!file_exists($fullpath)) { + $directory = \dirname($fullpath); if (!file_exists($directory) && !@mkdir($directory, 0777, true)) { throw new RuntimeException(sprintf('Unable to create directory "%s".', $directory)); } } - if (file_exists($altPath)) { - // clear alternative translation file - file_put_contents($altPath, $this->formatCatalogue(new MessageCatalogue($messages->getLocale()), $altDomain, $options)); + $intlDomain = $domain.MessageCatalogue::INTL_DOMAIN_SUFFIX; + $intlMessages = $messages->all($intlDomain); + + if ($intlMessages) { + $intlPath = $options['path'].'/'.$this->getRelativePath($intlDomain, $messages->getLocale()); + file_put_contents($intlPath, $this->formatCatalogue($messages, $intlDomain, $options)); + + $messages->replace([], $intlDomain); + + try { + if ($messages->all($domain)) { + file_put_contents($fullpath, $this->formatCatalogue($messages, $domain, $options)); + } + continue; + } finally { + $messages->replace($intlMessages, $intlDomain); + } } - file_put_contents($defaultPath, $this->formatCatalogue($messages, $domain, $options)); + file_put_contents($fullpath, $this->formatCatalogue($messages, $domain, $options)); } } diff --git a/src/Symfony/Component/Translation/Tests/Dumper/FileDumperTest.php b/src/Symfony/Component/Translation/Tests/Dumper/FileDumperTest.php index 9dd1377e49729..6e42b1e5683e5 100644 --- a/src/Symfony/Component/Translation/Tests/Dumper/FileDumperTest.php +++ b/src/Symfony/Component/Translation/Tests/Dumper/FileDumperTest.php @@ -27,15 +27,11 @@ public function testDump() $dumper = new ConcreteFileDumper(); $dumper->dump($catalogue, ['path' => $tempDir]); - $suffix = class_exists(\MessageFormatter::class) ? '+intl-icu' : ''; - $this->assertFileExists($tempDir."/messages$suffix.en.concrete"); + $this->assertFileExists($tempDir.'/messages.en.concrete'); - @unlink($tempDir."/messages$suffix.en.concrete"); + @unlink($tempDir.'/messages.en.concrete'); } - /** - * @requires extension intl - */ public function testDumpIntl() { $tempDir = sys_get_temp_dir(); @@ -46,11 +42,13 @@ public function testDumpIntl() $catalogue->add(['bar' => 'foo'], 'd2+intl-icu'); $dumper = new ConcreteFileDumper(); + @unlink($tempDir.'/d2.en.concrete'); $dumper->dump($catalogue, ['path' => $tempDir]); - $this->assertFileNotExists($tempDir.'/d1.en.concrete'); + $this->assertStringEqualsFile($tempDir.'/d1.en.concrete', 'foo=bar'); + @unlink($tempDir.'/d1.en.concrete'); - $this->assertStringEqualsFile($tempDir.'/d1+intl-icu.en.concrete', 'bar=foo&foo=bar'); + $this->assertStringEqualsFile($tempDir.'/d1+intl-icu.en.concrete', 'bar=foo'); @unlink($tempDir.'/d1+intl-icu.en.concrete'); $this->assertFileNotExists($tempDir.'/d2.en.concrete'); @@ -62,8 +60,7 @@ public function testDumpCreatesNestedDirectoriesAndFile() { $tempDir = sys_get_temp_dir(); $translationsDir = $tempDir.'/test/translations'; - $suffix = class_exists(\MessageFormatter::class) ? '+intl-icu' : ''; - $file = $translationsDir."/messages$suffix.en.concrete"; + $file = $translationsDir.'/messages.en.concrete'; $catalogue = new MessageCatalogue('en'); $catalogue->add(['foo' => 'bar']);
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: