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; } }