public static function createWriteFileEvent($translationFilePath, $translatableStrings, $translatedStrings, $createFileIfNotExists) { $event = new TranslationEvent(); $event->setTranslatableStrings($translatableStrings); $event->setTranslatedStrings($translatedStrings); $event->setCreateFileIfNotExists($createFileIfNotExists); $event->setTranslationFilePath($translationFilePath); return $event; }
public function writeFallbackFile(TranslationEvent $event) { $file = THELIA_LOCAL_DIR . 'I18n' . DS . $event->getLocale() . '.php'; $fs = new Filesystem(); $translations = []; if (!$fs->exists($file)) { if (true === $event->isCreateFileIfNotExists()) { $dir = dirname($file); $fs->mkdir($dir); $this->cacheClear($event->getDispatcher()); } else { throw new \RuntimeException(Translator::getInstance()->trans('Failed to open translation file %file. Please be sure that this file is writable by your Web server', array('%file' => $file))); } } else { /*$loader = new PhpFileLoader(); $catalogue = $loade r->load($file); $translations = $catalogue->all(); */ $translations = (require $file); if (!is_array($translations)) { $translations = []; } } if ($fp = @fopen($file, 'w')) { $texts = $event->getTranslatableStrings(); $customs = $event->getCustomFallbackStrings(); $globals = $event->getGlobalFallbackStrings(); // just reset current translations for this domain to remove strings that do not exist anymore $translations[$event->getDomain()] = []; foreach ($texts as $key => $text) { if (!empty($customs[$key])) { $translations[$event->getDomain()][$text] = $customs[$key]; } if (!empty($globals[$key])) { $translations[$text] = $globals[$key]; } else { unset($translations[$text]); } } fwrite($fp, '<' . "?php\n\n"); fwrite($fp, "return [\n"); // Sort keys alphabetically while keeping index ksort($translations); foreach ($translations as $key => $text) { // Write only defined (not empty) translations if (!empty($translations[$key])) { if (is_array($translations[$key])) { $key = str_replace("'", "\\'", $key); fwrite($fp, sprintf(" '%s' => [\n", $key)); ksort($translations[$key]); foreach ($translations[$key] as $subKey => $subText) { $subKey = str_replace("'", "\\'", $subKey); $translation = str_replace("'", "\\'", $subText); fwrite($fp, sprintf(" '%s' => '%s',\n", $subKey, $translation)); } fwrite($fp, " ],\n"); } else { $key = str_replace("'", "\\'", $key); $translation = str_replace("'", "\\'", $text); fwrite($fp, sprintf(" '%s' => '%s',\n", $key, $translation)); } } } fwrite($fp, "];\n"); @fclose($fp); } }
protected function renderTemplate() { // Get related strings, if all input data are here $itemToTranslate = $this->getRequest()->get('item_to_translate'); $itemName = $this->getRequest()->get('item_name', ''); if ($itemToTranslate == 'mo' && !empty($itemName)) { $modulePart = $this->getRequest()->get('module_part', ''); } else { $modulePart = false; } $template = $directory = $i18nDirectory = false; $walkMode = TranslationEvent::WALK_MODE_TEMPLATE; $templateArguments = array('item_to_translate' => $itemToTranslate, 'item_name' => $itemName, 'module_part' => $modulePart, 'view_missing_traductions_only' => $this->getRequest()->get('view_missing_traductions_only'), 'max_input_vars_warning' => false); // Find the i18n directory, and the directory to examine. if (!empty($itemName) || $itemToTranslate == 'co' || $itemToTranslate == 'in') { switch ($itemToTranslate) { // Module core case 'mo': $module = $this->getModule($itemName); if ($modulePart == 'core') { $directory = $module->getAbsoluteBaseDir(); $domain = $module->getTranslationDomain(); $i18nDirectory = $module->getAbsoluteI18nPath(); $walkMode = TranslationEvent::WALK_MODE_PHP; } elseif ($modulePart == 'admin-includes') { $directory = $module->getAbsoluteAdminIncludesPath(); $domain = $module->getAdminIncludesTranslationDomain(); $i18nDirectory = $module->getAbsoluteAdminIncludesI18nPath(); $walkMode = TranslationEvent::WALK_MODE_TEMPLATE; } elseif (!empty($modulePart)) { // Front, back, pdf or email office template, // form of $module_part is [bo|fo|pdf|email].subdir-name list($type, $subdir) = explode('.', $modulePart); switch ($type) { case 'bo': $directory = $module->getAbsoluteBackOfficeTemplatePath($subdir); $domain = $module->getBackOfficeTemplateTranslationDomain($subdir); $i18nDirectory = $module->getAbsoluteBackOfficeI18nTemplatePath($subdir); break; case 'fo': $directory = $module->getAbsoluteFrontOfficeTemplatePath($subdir); $domain = $module->getFrontOfficeTemplateTranslationDomain($subdir); $i18nDirectory = $module->getAbsoluteFrontOfficeI18nTemplatePath($subdir); break; case 'email': $directory = $module->getAbsoluteEmailTemplatePath($subdir); $domain = $module->getEmailTemplateTranslationDomain($subdir); $i18nDirectory = $module->getAbsoluteEmailI18nTemplatePath($subdir); break; case 'pdf': $directory = $module->getAbsolutePdfTemplatePath($subdir); $domain = $module->getPdfTemplateTranslationDomain($subdir); $i18nDirectory = $module->getAbsolutePdfI18nTemplatePath($subdir); break; default: throw new \InvalidArgumentException("Undefined module template type: '{$type}'."); } $walkMode = TranslationEvent::WALK_MODE_TEMPLATE; } // Modules translations files are in the cache, and are not always // updated. Force a reload of the files to get last changes. if (!empty($domain)) { $this->loadTranslation($i18nDirectory, $domain); } // List front and back office templates defined by this module $templateArguments['back_office_templates'] = implode(',', $this->getModuleTemplateNames($module, TemplateDefinition::BACK_OFFICE)); $templateArguments['front_office_templates'] = implode(',', $this->getModuleTemplateNames($module, TemplateDefinition::FRONT_OFFICE)); $templateArguments['email_templates'] = implode(',', $this->getModuleTemplateNames($module, TemplateDefinition::EMAIL)); $templateArguments['pdf_templates'] = implode(',', $this->getModuleTemplateNames($module, TemplateDefinition::PDF)); // Check if we have admin-include files try { $finder = Finder::create()->files()->depth(0)->in($module->getAbsoluteAdminIncludesPath())->name('/\\.html$/i'); $hasAdminIncludes = $finder->count() > 0; } catch (\InvalidArgumentException $ex) { $hasAdminIncludes = false; } $templateArguments['has_admin_includes'] = $hasAdminIncludes; break; // Thelia Core // Thelia Core case 'co': $directory = THELIA_LIB; $domain = 'core'; $i18nDirectory = THELIA_LIB . 'Config' . DS . 'I18n'; $walkMode = TranslationEvent::WALK_MODE_PHP; break; // Thelia Install // Thelia Install case 'in': $directory = THELIA_SETUP_DIRECTORY; $domain = 'install'; $i18nDirectory = THELIA_SETUP_DIRECTORY . 'I18n'; $walkMode = TranslationEvent::WALK_MODE_TEMPLATE; // resources not loaded by default $this->loadTranslation($i18nDirectory, $domain); break; // Front-office template // Front-office template case 'fo': $template = new TemplateDefinition($itemName, TemplateDefinition::FRONT_OFFICE); break; // Back-office template // Back-office template case 'bo': $template = new TemplateDefinition($itemName, TemplateDefinition::BACK_OFFICE); break; // PDF templates // PDF templates case 'pf': $template = new TemplateDefinition($itemName, TemplateDefinition::PDF); break; // Email templates // Email templates case 'ma': $template = new TemplateDefinition($itemName, TemplateDefinition::EMAIL); break; } if ($template) { $directory = $template->getAbsolutePath(); $i18nDirectory = $template->getAbsoluteI18nPath(); $domain = $template->getTranslationDomain(); // Load translations files is this template is not the current template // as it is not loaded in Thelia.php if (!$this->getTemplateHelper()->isActive($template)) { $this->loadTranslation($i18nDirectory, $domain); } } // Load strings to translate if ($directory && !empty($domain)) { // Save the string set, if the form was submitted if ($i18nDirectory) { $save_mode = $this->getRequest()->get('save_mode', false); if ($save_mode !== false) { $texts = $this->getRequest()->get('text', array()); if (!empty($texts)) { $event = TranslationEvent::createWriteFileEvent(sprintf("%s" . DS . "%s.php", $i18nDirectory, $this->getCurrentEditionLocale()), $texts, $this->getRequest()->get('translation', []), true); $event->setDomain($domain)->setLocale($this->getCurrentEditionLocale())->setCustomFallbackStrings($this->getRequest()->get('translation_custom', []))->setGlobalFallbackStrings($this->getRequest()->get('translation_global', [])); $this->getDispatcher()->dispatch(TheliaEvents::TRANSLATION_WRITE_FILE, $event); if ($save_mode == 'stay') { return $this->generateRedirectFromRoute("admin.configuration.translations", $templateArguments); } else { return $this->generateRedirect(URL::getInstance()->adminViewUrl('configuration')); } } } } // Load strings $event = TranslationEvent::createGetStringsEvent($directory, $walkMode, $this->getCurrentEditionLocale(), $domain); $this->getDispatcher()->dispatch(TheliaEvents::TRANSLATION_GET_STRINGS, $event); // Estimate number of fields, and compare to php ini max_input_vars $stringsCount = $event->getTranslatableStringCount() * 4 + 6; if ($stringsCount > ini_get('max_input_vars')) { $templateArguments['max_input_vars_warning'] = true; $templateArguments['required_max_input_vars'] = $stringsCount; $templateArguments['current_max_input_vars'] = ini_get('max_input_vars'); } else { $templateArguments['all_strings'] = $event->getTranslatableStrings(); } $templateArguments['is_writable'] = $this->checkWritableI18nDirectory(THELIA_LOCAL_DIR . 'I18n'); } } return $this->render('translations', $templateArguments); }