protected function execute(InputInterface $input, OutputInterface $output) { $container = $this->getContainer(); $filesystem = new Filesystem(); $locator = $container->get("agit.common.filecollector"); $bundles = $container->getParameter("kernel.bundles"); $catalogPath = $container->getParameter("kernel.root_dir") . "/{$this->catalogSubdir}"; $this->getContainer()->get("event_dispatcher")->dispatch("agit.intl.global.translations", new TranslationsEvent($this)); foreach ($container->getParameter("agit.intl.locales") as $locale) { $catalog = new Translations(); $messagesPath = "{$catalogPath}/{$locale}/LC_MESSAGES"; $catalogFile = "{$messagesPath}/agit.po"; $oldCatalog = $filesystem->exists($catalogFile) ? Translations::fromPoFile($catalogFile) : new Translations(); foreach ($oldCatalog as $translation) { $translation->deleteReferences(); } $catalog->mergeWith($oldCatalog, 0); foreach ($bundles as $alias => $namespace) { $bundlePath = $locator->resolve($alias); $bundleCatalogFile = "{$bundlePath}/{$this->catalogSubdir}/bundle.{$locale}.po"; $bundleCatalog = $filesystem->exists($bundleCatalogFile) ? Translations::fromPoFile($bundleCatalogFile) : new Translations(); $catalog->mergeWith($bundleCatalog, Merge::ADD); } if (isset($this->extraTranslations[$locale])) { foreach ($this->extraTranslations[$locale] as $translation) { $catalog[] = $translation; } } // NOTE: we delete all headers and only set language in order to avoid garbage commits $catalog->deleteHeaders(); $catalog->setLanguage($locale); $catalog->setHeader("Content-Type", "text/plain; charset=UTF-8"); $filesystem->dumpFile($catalogFile, $catalog->toPoString()); $filesystem->dumpFile("{$messagesPath}/agit.mo", $catalog->toMoString()); } }
protected function execute(InputInterface $input, OutputInterface $output) { $container = $this->getContainer(); $filesystem = new Filesystem(); $bundleAlias = $input->getArgument("bundle"); $bundlePath = $container->get("agit.common.filecollector")->resolve($bundleAlias); $defaultLocale = $container->get("agit.intl.locale")->getDefaultLocale(); $locales = $input->getArgument("locales") ? array_map("trim", explode(",", $input->getArgument("locales"))) : $container->getParameter("agit.intl.locales"); $globalCatalogPath = $container->getParameter("kernel.root_dir") . "/{$this->catalogSubdir}"; $this->cacheBasePath = sprintf("%s/agit.intl.temp/%s", sys_get_temp_dir(), $bundleAlias); $filesystem->mkdir($this->cacheBasePath); $finder = (new Finder())->in("{$bundlePath}")->name("*\\.php")->name("*\\.js")->notPath("/test.*/i")->notPath("public/js/ext"); $files = []; foreach ($finder as $file) { $filePath = $file->getRealpath(); $alias = str_replace($bundlePath, "@{$bundleAlias}/", $filePath); $files[$filePath] = $alias; } $this->getContainer()->get("event_dispatcher")->dispatch("agit.intl.bundle.files", new BundleTranslationFilesEvent($this, $bundleAlias, $this->cacheBasePath)); $this->extraTranslations = new Translations(); $this->getContainer()->get("event_dispatcher")->dispatch("agit.intl.bundle.translations", new BundleTranslationsEvent($this, $bundleAlias)); $files += $this->extraSourceFiles; $frontendFiles = array_filter(array_keys($files), function ($file) { return preg_match("|\\.js\$|", $file); }); $backendFiles = array_filter(array_keys($files), function ($file) { return !preg_match("|\\.js\$|", $file); }); $frontendCatalogs = ""; foreach ($locales as $locale) { if (!preg_match("|^[a-z]{2}_[A-Z]{2}|", $locale)) { throw new Exception("Invalid locale: {$locale}"); } // we use the global catalog as source for already translated strings $globalCatalogFile = "{$globalCatalogPath}/{$locale}/LC_MESSAGES/agit.po"; $globalCatalog = $filesystem->exists($globalCatalogFile) ? $this->deleteReferences(Translations::fromPoFile($globalCatalogFile)) : new Translations(); $bundleCatalogFile = "{$bundlePath}/{$this->catalogSubdir}/bundle.{$locale}.po"; $oldBundleCatalog = $filesystem->exists($bundleCatalogFile) ? $this->deleteReferences(Translations::fromPoFile($bundleCatalogFile)) : new Translations(); // NOTE: we delete all headers and only set language, in order to avoid garbage commits $bundleCatalog = new Translations(); $bundleCatalog->deleteHeaders(); $bundleCatalog->setLanguage($locale); // first: only JS messages foreach ($frontendFiles as $file) { $bundleCatalog->addFromJsCodeFile($file, $this->extractorOptions); } $bundleCatalog->mergeWith($oldBundleCatalog, 0); $bundleCatalog->mergeWith($globalCatalog, 0); if ($bundleCatalog->count() && $locale !== $defaultLocale) { $transMap = []; foreach ($bundleCatalog as $entry) { $msgid = ltrim($entry->getId(), ""); $msgstr = $entry->getTranslation(); $transMap[$msgid] = $entry->hasPlural() ? array_merge([$msgstr], $entry->getPluralTranslations()) : $msgstr; } $frontendCatalogs .= sprintf("ag.intl.register(\"%s\", %s);\n\n", $locale, json_encode($transMap, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)); } // now the same with all messages foreach ($backendFiles as $file) { $bundleCatalog->addFromPhpCodeFile($file, $this->extractorOptions); } $bundleCatalog->mergeWith($this->extraTranslations, Merge::ADD); $bundleCatalog->mergeWith($oldBundleCatalog, 0); $bundleCatalog->mergeWith($globalCatalog, 0); $catalog = $bundleCatalog->toPoString(); $catalog = str_replace(array_keys($files), array_values($files), $catalog); if ($bundleCatalog->count()) { $filesystem->dumpFile("{$bundlePath}/{$this->catalogSubdir}/bundle.{$locale}.po", $catalog); } } if ($frontendCatalogs) { $filesystem->dumpFile("{$bundlePath}/{$this->frontendSubdir}/translations.js", $frontendCatalogs); } $filesystem->remove($this->cacheBasePath); }