Kunsthelden Posted February 10, 2018 Share Posted February 10, 2018 (edited) Dear community, We detected an odd behavior on Prestashop 1.7.2.4 that maybe somebody knows already. Pls let us know. Issues as following: - We cannot see the subject translations, although we translated it. Fields remain empty (pls see illustration below) for 3rd party and Prestashop modules. - We use a child_theme: Therefore some of the translations are stored by Prestashop to /themes/classic_childtheme/mails/de/lang.php (3rd party module reading form here), /mails/de/lang.php (Prestashop seems not to use this anymore for own and 3rd party mail translation) and /app/Resources/translations/de-DE/EmailsSubject.de-DE.xlf. 3rd party modules cannot saved to EmailsSubject.de-DE.xlf indeed. If we send the mail, the data is working but we cannot amend it via BO or if we do, we delete the current translations. - Also Umlaute seem not to work properly if used in old translation way through .txt file. Email is not being sent in this case. Without Umlaute it works fine. Solution: We have found a workaround for us but we believe that it could be a Prestashop 1.7.2.4 issue. Our workaround includes a programming change (override) of AdminTranslationsController.php to actually use the lang.php file (seems missing). To us, new translation file EmailsSubject.de-DE.xlf seems not to work for Prestashop modules and 3rd party modules either. It's just not in the code. We now changed to use lang file from /mails/yourLang/lang.php only and this works as a workaround to change the subject in the mail translation as well as to send the mail subject title in correct language. Edited February 12, 2018 by Kunsthelden (see edit history) Link to comment Share on other sites More sharing options...
Adam Pro Posted November 14, 2019 Share Posted November 14, 2019 Hello, I have the exact same issue... Could you please share your AdminTranslationsController.php override ? Thanks, Adam Link to comment Share on other sites More sharing options...
Kunsthelden Posted November 14, 2019 Author Share Posted November 14, 2019 <?php /* * * date: 2018-09-17 23:15:00 * version: 1.0.1 */ //use PrestaShop\PrestaShop\Core\Cldr\Update; //use PrestaShop\PrestaShop\Core\Addon\Theme\ThemeManagerBuilder; //use PrestaShop\PrestaShop\Core\Addon\Theme\Theme; class AdminTranslationsController extends AdminTranslationsControllerCore { /** * Display mails in html format. * This was create for factorize the html displaying * @since 1.4.0.14 * * @param array $mails * @param array $all_subject_mail * @param Language $obj_lang * @param string $id_html Use for set html id attribute for the block * @param string $title Set the title for the block * @param string|bool $name_for_module Is not false define add a name for distinguish mails module * * @return string */ protected function displayMailContent($mails, $all_subject_mail, $obj_lang, $id_html, $title, $name_for_module = false) { $str_return = ''; $group_name = 'mail'; if (array_key_exists('group_name', $mails)) { $group_name = $mails['group_name']; } if ($mails['empty_values'] == 0) { $translation_missing_badge_type = 'badge-success'; } else { $translation_missing_badge_type = 'badge-danger'; } $str_return .= '<div class="mails_field"> <h4> <span class="badge">'.((int)$mails['empty_values'] + (int)$mails['total_filled']).' <i class="icon-envelope-o"></i></span> <a href="javascript:void(0);" onclick="$(\'#'.$id_html.'\').slideToggle();">'.$title.'</a> <span class="pull-right badge '.$translation_missing_badge_type.'">'.$mails['empty_values'].' '.$this->trans('missing translation(s)', array(), 'Admin.International.Notification').'</span> </h4> <div name="mails_div" id="'.$id_html.'" class="panel-group">'; if (!empty($mails['files'])) { $topic_already_displayed = array(); foreach ($mails['files'] as $mail_name => $mail_files) { $str_return .= '<div class="panel translations-email-panel">'; $str_return .= '<a href="#'.$id_html.'-'.$mail_name.'" class="panel-title" data-toggle="collapse" data-parent="#'.$id_html.'" >'.$mail_name.' <i class="icon-caret-down"></i> </a>'; $str_return .= '<div id="'.$id_html.'-'.$mail_name.'" class="email-collapse panel-collapse collapse">'; if (array_key_exists('html', $mail_files) || array_key_exists('txt', $mail_files)) { if (array_key_exists($mail_name, $all_subject_mail)) { foreach ($all_subject_mail[$mail_name] as $subject_mail) { $subject_key = 'subject['.Tools::htmlentitiesUTF8($group_name).']['.Tools::htmlentitiesUTF8($subject_mail).']'; $mails['subject']['trad'] = $this->getSubjectMailTrans($subject_mail, $name_of_module); // Added 16.02.2018 if (in_array($subject_key, $topic_already_displayed)) { continue; } $topic_already_displayed[] = $subject_key; $value_subject_mail = isset($mails['subject']) ? $mails['subject'] : ''; // Added 16.02.2018 //$value_subject_mail = isset($mails['subject'][$subject_mail]) ? $mails['subject'][$subject_mail] : ''; // Deleted 16.02.2018 $str_return .= ' <div class="label-subject row"> <label class="control-label col-lg-3">'.$this->trans('Email subject', array(), 'Admin.International.Feature'); if (isset($value_subject_mail['use_sprintf']) && $value_subject_mail['use_sprintf']) { $str_return .= '<span class="useSpecialSyntax" title="'.$this->trans('This expression uses a special syntax:', array(), 'Admin.International.Notification').' '.$value_subject_mail['use_sprintf'].'"> <i class="icon-exclamation-triangle"></i> </span>'; } $str_return .= '</label><div class="col-lg-9">'; if (isset($value_subject_mail['trad']) && $value_subject_mail['trad']) { $str_return .= '<input class="form-control" type="text" name="subject['.Tools::htmlentitiesUTF8($group_name).']['.Tools::htmlentitiesUTF8($subject_mail).']" value="'.$value_subject_mail['trad'].'" />'; } else { $str_return .= '<input class="form-control" type="text" name="subject['.Tools::htmlentitiesUTF8($group_name).']['.Tools::htmlentitiesUTF8($subject_mail).']" value="" />'; } $str_return .= '<p class="help-block">'.stripcslashes($subject_mail).'</p>'; $str_return .= '</div></div>'; } } else { $str_return .= ' <hr><div class="alert alert-info">' .$this->trans('No Subject was found for %mail_name% in the database.', array('%mail_name%' => $mail_name), 'Admin.International.Notification') .'</div>'; } // tab menu $str_return .= '<hr><ul class="nav nav-pills"> <li class="active"><a href="#'.$mail_name.'-html" data-toggle="tab">'.$this->trans('View HTML version', array(), 'Admin.International.Feature').'</a></li> <li><a href="#'.$mail_name.'-editor" data-toggle="tab">'.$this->trans('Edit HTML version', array(), 'Admin.International.Feature').'</a></li> <li><a href="#'.$mail_name.'-text" data-toggle="tab">'.$this->trans('View/Edit TXT version', array(), 'Admin.International.Feature').'</a></li> </ul>'; // tab-content $str_return .= '<div class="tab-content">'; $base_uri = str_replace(_PS_ROOT_DIR_, __PS_BASE_URI__, $mails['directory']); $base_uri = str_replace('//', '/', $base_uri); $url_mail = $base_uri.$mail_name.'.html'; $mail_files_html = empty($mail_files['html']) ? false : $mail_files['html']; $str_return .= '<div class="tab-pane active" id="'.$mail_name.'-html">'; $str_return .= $this->displayMailBlockHtml($mail_files_html, $obj_lang->iso_code, $url_mail, $mail_name, $group_name, $name_for_module); $str_return .= '</div>'; $mail_files_txt = empty($mail_files['txt']) ? false : $mail_files['txt']; $str_return .= '<div class="tab-pane" id="'.$mail_name.'-text">'; $str_return .= $this->displayMailBlockTxt($mail_files_txt, $obj_lang->iso_code, $mail_name, $group_name, $name_for_module); $str_return .= '</div>'; $str_return .= '<div class="tab-pane" id="'.$mail_name.'-editor">'; $str_return .= $this->displayMailEditor($mail_files_html, $obj_lang->iso_code, $mail_name, $group_name, $name_for_module); $str_return .= '</div>'; $str_return .= '</div>'; $str_return .= '</div><!--end .panel-collapse -->'; $str_return .= '</div><!--end .panel -->'; } } } else { $str_return .= '<p class="error"> '.$this->trans('There was a problem getting the mail files.', array(), 'Admin.International.Notification').'<br> '.$this->trans('English language files must exist in %folder% folder', array( '%folder%' => '<em>'.preg_replace('@/[a-z]{2}(/?)$@', '/en$1', $mails['directory']).'</em>' ), 'Admin.International.Notification').' </p>'; } $str_return .= '</div><!-- #'.$id_html.' --></div><!-- end .mails_field -->'; return $str_return; } /** * This method generate the form for mails translations * * @param bool $no_display * * @return array|string */ public function initFormMails($no_display = false) { $module_mails = array(); // get all mail subjects, this method parse each files in Prestashop !! $subject_mail = array(); $modules_has_mails = $this->getModulesHasMails(true); $files_by_directiories = $this->getFileToParseByTypeTranslation(); if (!$this->theme_selected || !@filemtime($this->translations_informations[$this->type_selected]['override']['dir'])) { $this->copyMailFilesForAllLanguages(); } foreach ($files_by_directiories['php'] as $dir => $files) { if (!empty($files)) { foreach ($files as $file) { // If file exist and is not in ignore_folder, in the next step we check if a folder or mail if (Tools::file_exists_cache($dir . $file) && !in_array($file, self::$ignore_folder)) { $subject_mail = $this->getSubjectMail($dir, $file, $subject_mail); } } } } // Get path of directory for find a good path of translation file if ($this->theme_selected && @filemtime($this->translations_informations[$this->type_selected]['override']['dir'])) { $i18n_dir = $this->translations_informations[$this->type_selected]['override']['dir']; } else { $i18n_dir = $this->translations_informations[$this->type_selected]['dir']; } $core_mails = $this->getMailFiles($i18n_dir, 'core_mail'); foreach ($modules_has_mails as $module_name => $module_path) { $module_path = rtrim($module_path, '/'); $module_mails[$module_name] = $this->getMailFiles($module_path.'/mails/'.$this->lang_selected->iso_code.'/', 'module_mail'); $module_mails[$module_name]['subject']['trad'] = $this->getSubjectMailTrans($module_path.'/mails/'.$this->lang_selected->iso_code.'/', 'lang.php', $subject_mail, $module_name); // Added $module_mails[$module_name]['display'] = $this->displayMailContent($module_mails[$module_name], $subject_mail, $this->lang_selected, Tools::strtolower($module_name), $module_name, $module_name); $module_mails[$module_name]['subject'] = $subject_mail; // Added } if ($no_display) { $empty = 0; $total = 0; $total += (int)$core_mails['total_filled']; $empty += (int)$core_mails['empty_values']; foreach ($module_mails as $mod_infos) { $total += (int)$mod_infos['total_filled']; $empty += (int)$mod_infos['empty_values']; } return array('total' => $total, 'empty' => $empty); } $this->tpl_view_vars = array_merge($this->tpl_view_vars, array( 'limit_warning' => $this->displayLimitPostWarning($this->total_expression), 'mod_security_warning' => Tools::apacheModExists('mod_security'), 'tinyMCE' => $this->getTinyMCEForMails($this->lang_selected->iso_code), 'mail_content' => $this->displayMailContent($core_mails, $subject_mail, $this->lang_selected, 'core', $this->trans('Core emails', array(), 'Admin.International.Feature')), 'cancel_url' => $this->context->link->getAdminLink('AdminTranslations'), 'module_mails' => $module_mails, 'theme_name' => $this->theme_selected )); $this->initToolbar(); $this->base_tpl_view = 'translation_mails.tpl'; return parent::renderView(); } // Added /** * This method is used to write translation for mails. * This writes subject translation files * (in root/mails/lang_choosen/lang.php or root/_PS_THEMES_DIR_/mails/lang_choosen/lang.php) * and mails files. */ protected function submitTranslationsMails() { $arr_mail_content = array(); $arr_mail_path = array(); if (Tools::getValue('core_mail')) { $arr_mail_content['core_mail'] = Tools::getValue('core_mail'); // Get path of directory for find a good path of translation file if (!$this->theme_selected) { $arr_mail_path['core_mail'] = $this->translations_informations[$this->type_selected]['dir']; } else { $arr_mail_path['core_mail'] = $this->translations_informations[$this->type_selected]['override']['dir']; } } if (Tools::getValue('module_mail')) { $arr_mail_content['module_mail'] = Tools::getValue('module_mail'); // Get path of directory for find a good path of translation file if (!$this->theme_selected) { $arr_mail_path['module_mail'] = $this->translations_informations['modules']['dir'].'{module}/mails/'.$this->lang_selected->iso_code.'/'; } else { $arr_mail_path['module_mail'] = $this->translations_informations['modules']['override']['dir'].'{module}/mails/'.$this->lang_selected->iso_code.'/'; } } // Save each mail content foreach ($arr_mail_content as $group_name => $all_content) { foreach ($all_content as $type_content => $mails) { if (!in_array($type_content, self::$content_type_accepted)) { throw new PrestaShopException($this->trans('This %type_content% file extension is not accepted.', array('%type_content%' => $type_content), 'Admin.International.Notification')); } foreach ($mails as $mail_name => $content) { $module_name = false; $module_name_pipe_pos = stripos($mail_name, '|'); if ($module_name_pipe_pos) { $module_name = substr($mail_name, 0, $module_name_pipe_pos); if (!Validate::isModuleName($module_name)) { throw new PrestaShopException($this->trans('Invalid module name "%module%"', array('%module%' => Tools::safeOutput($module_name)), 'Admin.International.Notification')); } $mail_name = substr($mail_name, $module_name_pipe_pos + 1); if (!Validate::isTplName($mail_name)) { throw new PrestaShopException($this->trans('Invalid mail name "%mail%"', array('%mail%' => Tools::safeOutput($mail_name)), 'Admin.International.Notification')); } } if ($type_content == 'html') { $content = Tools::htmlentitiesUTF8($content); $content = htmlspecialchars_decode($content); // replace correct end of line $content = str_replace("\r\n", PHP_EOL, $content); // Magic Quotes shall... not.. PASS! if (_PS_MAGIC_QUOTES_GPC_) { $content = stripslashes($content); } } if (Validate::isCleanHTML($content)) { $path = $arr_mail_path[$group_name]; if ($module_name) { $path = str_replace('{module}', $module_name, $path); } if (!file_exists($path) && !mkdir($path, 0777, true)) { throw new PrestaShopException($this->trans('Directory "%folder%" cannot be created', array('%folder%' => dirname($path)), 'Admin.International.Notification')); } if ($type_content == 'tpl') { preg_match('/{\s*[^$]+/s', $content, $matches); if (!empty($matches)) { throw new PrestaShopException($this->trans('Your email translations contain some invalid HTML and cannot be saved. Please check your content.', array(), 'Admin.International.Notification')); } } file_put_contents($path.$mail_name.'.'.$type_content, $content); } else { throw new PrestaShopException($this->trans('Your HTML email templates cannot contain JavaScript code.', array(), 'Admin.International.Notification')); } } } } // Update subjects $array_subjects = array(); if (($subjects = Tools::getValue('subject')) && is_array($subjects)) { $array_subjects['core_and_modules'] = array('translations' => array(), 'path' => $arr_mail_path['core_mail'].'lang.php'); foreach ($subjects as $subject_translation) { $array_subjects['core_and_modules']['translations'] = array_merge($array_subjects['core_and_modules']['translations'], $subject_translation); } } if (!empty($array_subjects)) { foreach ($array_subjects as $infos) { $this->writeSubjectTranslationFile($infos['translations'], $infos['path']); $this->writeSubjectTranslationFile($infos['translations'], _PS_THEME_DIR_.'mails/'.$this->lang_selected->iso_code.'/lang.php'); // Added 17.09.2018 } } if (Tools::isSubmit('submitTranslationsMailsAndStay')) { $this->redirect(true); } else { $this->redirect(); } } /** * Get list of subjects of mails * * Added * @param Language $subject_mail * @param string $moduel_name * * @return array with translations */ protected function getSubjectMailTrans($subject_mail, $module_name) { $dirMail = 'mails/'.$this->lang_selected->iso_code.'/'; $file = 'lang.php'; // If is file if (is_file(_PS_THEME_DIR_.$dirMail.$file) && preg_match('/lang.php/', $file)) { $lines = file(_PS_THEME_DIR_.$dirMail.$file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); foreach ($lines as $line_num => $line) { $line_array = explode("'", $line); if ($subject_mail == $line_array[1]) { $subject_mail_trans = $line_array[3]; } } } else { if (is_file(_PS_ROOT_DIR_.'/'.$dirMail.$file) && preg_match('/lang.php/', $file)) { $lines = file(_PS_ROOT_DIR_.'/'.$dirMail.$file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); foreach ($lines as $line_num => $line) { $line_array = explode("'", $line); if ($subject_mail == $line_array[1]) { $subject_mail_trans = $line_array[3]; } } } } return $subject_mail_trans; } } This is a work-around only. We just copy the data to further areas in Prestashop (default, classic, child_themes). So we have the translation variable anywhere. As you can see this is an override. Kind regards Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now