From 4637dc692c5a568747b56142c8a525ba8625571a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Mon, 29 Sep 2025 13:05:32 +0200 Subject: [PATCH] Add `OverrideTranslationCommand` for generating customized translation catalogues - Introduced a Symfony console command `chill:main:override_translation` to apply YAML-defined translation overrides. - Added an example configuration file in `resources/translation_override/` to illustrate usage. - Updated service definitions to register the new command. --- resources/translation_override/README.md | 6 + resources/translation_override/overrides.yaml | 8 ++ .../Command/OverrideTranslationCommand.php | 115 ++++++++++++++++++ .../config/services/command.yaml | 18 +-- 4 files changed, 132 insertions(+), 15 deletions(-) create mode 100644 resources/translation_override/README.md create mode 100644 resources/translation_override/overrides.yaml create mode 100644 src/Bundle/ChillMainBundle/Command/OverrideTranslationCommand.php diff --git a/resources/translation_override/README.md b/resources/translation_override/README.md new file mode 100644 index 000000000..837f071fd --- /dev/null +++ b/resources/translation_override/README.md @@ -0,0 +1,6 @@ +In this directory, you find an example of file for the command `chill:main:override_translation`. + +This file contains a list of translations to override in the translation catalogue. Each entry is a dictionary with two keys: `from` and `to`. The `from` key contains the original translation string, and the `to` key contains the replacement string. + +The command `chill:main:override_translation` uses this file to generate a new translation catalogue with the specified overrides applied. + diff --git a/resources/translation_override/overrides.yaml b/resources/translation_override/overrides.yaml new file mode 100644 index 000000000..c9f896df0 --- /dev/null +++ b/resources/translation_override/overrides.yaml @@ -0,0 +1,8 @@ +- {from: "de l'usager", to: "du patient"} +- {from: "l'usager", to: "le patient"} +- {from: "L'usager", to: "Le patient"} +- {from: "d'usagers", to: "de patients"} +- {from: "usagers", to: "patients"} +- {from: "Usagers", to: "Patients"} +- {from: "usager", to: "patient"} +- {from: "Usager", to: "Patient"} diff --git a/src/Bundle/ChillMainBundle/Command/OverrideTranslationCommand.php b/src/Bundle/ChillMainBundle/Command/OverrideTranslationCommand.php new file mode 100644 index 000000000..0f8070456 --- /dev/null +++ b/src/Bundle/ChillMainBundle/Command/OverrideTranslationCommand.php @@ -0,0 +1,115 @@ +setName('chill:main:override_translation'); + parent::__construct(); + } + + protected function configure(): void + { + $this + ->setDescription('Generate a translation catalogue with translation remplacements based on replacements provided in a YAML file.') + ->addArgument('locale', InputArgument::REQUIRED, 'The locale to process (e.g. fr, en).') + ->addArgument('overrides', InputArgument::REQUIRED, 'Path to the overrides YAML file (list of {from, to}).'); + } + + protected function execute(InputInterface $input, OutputInterface $output): int + { + $locale = (string) $input->getArgument('locale'); + $overridesPath = (string) $input->getArgument('overrides'); + + $catalogue = $this->loadCatalogue($locale); + $overrides = $this->loadOverrides($overridesPath); + + + $toOverrideCatalogue = new MessageCatalogue($locale); + foreach ($catalogue->getDomains() as $domain) { + // hack: we have to replace the suffix ".intl-icu" by "+intl-ic" + $domain = str_replace('.intl-icu', '+intl-icu', $domain); + foreach ($catalogue->all($domain) as $key => $translation) { + foreach ($overrides as $changes) { + $from = $changes['from']; + $to = $changes['to']; + + if (is_string($translation) && str_contains($translation, $from)) { + $newTranslation = strtr($translation, [$from => $to]); + $toOverrideCatalogue->set($key, $newTranslation, $domain); + $translation = $newTranslation; + } + } + } + } + + /** @var KernelInterface $kernel */ + /* @phpstan-ignore-next-line */ + $kernel = $this->getApplication()->getKernel(); + $outputDir = rtrim($kernel->getProjectDir(), '/').'/translations'; + if (!is_dir($outputDir)) { + @mkdir($outputDir, 0775, true); + } + + // Writer expects the 'path' option to be a directory; it will create the proper file name + $this->writer->write($toOverrideCatalogue, 'yaml', ['path' => $outputDir]); + + $output->writeln(sprintf('Override catalogue written to %s (domain: messages, locale: %s).', $outputDir, $locale)); + + return Command::SUCCESS; + } + + /** + * @return list + */ + private function loadOverrides(string $path): array + { + return Yaml::parseFile($path); + } + + private function loadCatalogue(string $locale): MessageCatalogue + { + /** @var KernelInterface $kernel */ + /* @phpstan-ignore-next-line */ + $kernel = $this->getApplication()->getKernel(); + + // collect path for translations + $transPaths = []; + foreach ($kernel->getBundles() as $bundle) { + $bundleDir = $bundle->getPath(); + $transPaths[] = is_dir($bundleDir.'/Resources/translations') ? $bundleDir.'/Resources/translations' : $bundle->getPath().'/translations'; + } + + $currentCatalogue = new MessageCatalogue($locale); + foreach ($transPaths as $path) { + if (is_dir($path)) { + $this->reader->read($path, $currentCatalogue); + } + } + + return $currentCatalogue; + } +} diff --git a/src/Bundle/ChillMainBundle/config/services/command.yaml b/src/Bundle/ChillMainBundle/config/services/command.yaml index 313ca28c5..2b765a1c1 100644 --- a/src/Bundle/ChillMainBundle/config/services/command.yaml +++ b/src/Bundle/ChillMainBundle/config/services/command.yaml @@ -42,38 +42,26 @@ services: - { name: console.command } Chill\MainBundle\Command\LoadAddressesFRFromBANOCommand: - autoconfigure: true - autowire: true tags: - { name: console.command } Chill\MainBundle\Command\LoadAddressesFRFromBANCommand: - autoconfigure: true - autowire: true tags: - { name: console.command } Chill\MainBundle\Command\LoadAddressesBEFromBestAddressCommand: - autoconfigure: true - autowire: true tags: - { name: console.command } Chill\MainBundle\Command\LoadPostalCodeFR: - autoconfigure: true - autowire: true tags: - { name: console.command } Chill\MainBundle\Command\LoadAddressesLUFromBDAddressCommand: - autoconfigure: true - autowire: true tags: - { name: console.command } Chill\MainBundle\Command\ExecuteCronJobCommand: - autoconfigure: true - autowire: true tags: - {name: console.command } @@ -81,6 +69,6 @@ services: tags: - {name: console.command} - Chill\MainBundle\Command\DumpListPermissionsCommand: - autoconfigure: true - autowire: true + Chill\MainBundle\Command\DumpListPermissionsCommand: ~ + + Chill\MainBundle\Command\OverrideTranslationCommand: ~