26 require
'../main.inc.php';
27 require_once DOL_DOCUMENT_ROOT.
'/core/lib/admin.lib.php';
28 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
29 require_once DOL_DOCUMENT_ROOT.
'/core/class/html.formadmin.class.php';
32 $langs->loadLangs(array(
"companies",
"products",
"admin",
"sms",
"other",
"errors"));
39 $action =
GETPOST(
'action',
'aZ09');
40 $optioncss =
GETPOST(
'optionscss',
'aZ09');
41 $contextpage =
GETPOST(
'contextpage',
'aZ09');
43 $langcode =
GETPOST(
'langcode',
'alphanohtml');
44 $transkey =
GETPOST(
'transkey',
'alphanohtml');
45 $transvalue =
GETPOST(
'transvalue',
'restricthtml');
48 $mode =
GETPOST(
'mode',
'aZ09') ?
GETPOST(
'mode',
'aZ09') :
'searchkey';
50 $limit =
GETPOST(
'limit',
'int') ?
GETPOST(
'limit',
'int') : $conf->liste_limit;
51 $sortfield =
GETPOST(
'sortfield',
'aZ09comma');
52 $sortorder =
GETPOST(
'sortorder',
'aZ09comma');
54 if (empty($page) || $page == -1) {
57 $offset = $limit * $page;
58 $pageprev = $page - 1;
59 $pagenext = $page + 1;
61 $sortfield =
'lang,transkey';
68 $hookmanager->initHooks(array(
'admintranslation',
'globaladmin'));
75 if (
GETPOST(
'cancel',
'alpha')) {
76 $action =
'list'; $massaction =
'';
78 if (!
GETPOST(
'confirmmassaction',
'alpha') && !empty($massaction) && $massaction !=
'presend' && $massaction !=
'confirm_presend') {
82 $parameters = array();
83 $reshook = $hookmanager->executeHooks(
'doActions', $parameters, $object, $action);
88 include DOL_DOCUMENT_ROOT.
'/core/actions_changeselectedfields.inc.php';
91 if (
GETPOST(
'button_removefilter_x',
'alpha') ||
GETPOST(
'button_removefilter.x',
'alpha') ||
GETPOST(
'button_removefilter',
'alpha')) {
95 $search_array_options = array();
98 if ($action ==
'setMAIN_ENABLE_OVERWRITE_TRANSLATION') {
100 dolibarr_set_const($db,
'MAIN_ENABLE_OVERWRITE_TRANSLATION', 1,
'chaine', 0,
'', $conf->entity);
102 dolibarr_set_const($db,
'MAIN_ENABLE_OVERWRITE_TRANSLATION', 0,
'chaine', 0,
'', $conf->entity);
106 if ($action ==
'update') {
107 if ($transkey ==
'') {
108 setEventMessages($langs->trans(
"ErrorFieldRequired", $langs->transnoentitiesnoconv(
"Key")),
null,
'errors');
111 if ($transvalue ==
'') {
112 setEventMessages($langs->trans(
"ErrorFieldRequired", $langs->transnoentitiesnoconv(
"NewTranslationStringToShow")),
null,
'errors');
118 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"overwrite_trans set transkey = '".$db->escape($transkey).
"', transvalue = '".$db->escape($transvalue).
"' WHERE rowid = ".((int)
GETPOST(
'rowid',
'int'));
119 $result = $db->query(
$sql);
128 if ($db->lasterrno() ==
'DB_ERROR_RECORD_ALREADY_EXISTS') {
129 setEventMessages($langs->trans(
"WarningAnEntryAlreadyExistForTransKey"),
null,
'warnings');
138 if ($action ==
'add') {
141 if (empty($langcode)) {
142 setEventMessages($langs->trans(
"ErrorFieldRequired", $langs->transnoentitiesnoconv(
"Language")),
null,
'errors');
145 if ($transkey ==
'') {
146 setEventMessages($langs->trans(
"ErrorFieldRequired", $langs->transnoentitiesnoconv(
"Key")),
null,
'errors');
149 if ($transvalue ==
'') {
150 setEventMessages($langs->trans(
"ErrorFieldRequired", $langs->transnoentitiesnoconv(
"NewTranslationStringToShow")),
null,
'errors');
156 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.
"overwrite_trans(lang, transkey, transvalue, entity) VALUES ('".$db->escape($langcode).
"','".$db->escape($transkey).
"','".$db->escape($transvalue).
"', ".((int) $conf->entity).
")";
157 $result = $db->query(
$sql);
166 if ($db->lasterrno() ==
'DB_ERROR_RECORD_ALREADY_EXISTS') {
167 setEventMessages($langs->trans(
"WarningAnEntryAlreadyExistForTransKey"),
null,
'warnings');
177 if ($action ==
'delete') {
178 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"overwrite_trans WHERE rowid = ".((int) $id);
179 $result = $db->query(
$sql);
198 $wikihelp =
'EN:Setup_Translation|FR:Paramétrage_Traduction|ES:Configuración_Traducción';
201 $param =
'&mode='.urlencode($mode);
203 $enabledisablehtml =
'';
204 $enabledisablehtml .= $langs->trans(
"EnableOverwriteTranslation").
' ';
205 if (empty($conf->global->MAIN_ENABLE_OVERWRITE_TRANSLATION)) {
207 $enabledisablehtml .=
'<a class="reposition valignmiddle" href="'.$_SERVER[
"PHP_SELF"].
'?action=setMAIN_ENABLE_OVERWRITE_TRANSLATION&token='.
newToken().
'&value=1'.$param.
'">';
208 $enabledisablehtml .=
img_picto($langs->trans(
"Disabled"),
'switch_off');
209 $enabledisablehtml .=
'</a>';
212 $enabledisablehtml .=
'<a class="reposition valignmiddle" href="'.$_SERVER[
"PHP_SELF"].
'?action=setMAIN_ENABLE_OVERWRITE_TRANSLATION&token='.
newToken().
'&value=0'.$param.
'">';
213 $enabledisablehtml .=
img_picto($langs->trans(
"Activated"),
'switch_on');
214 $enabledisablehtml .=
'</a>';
217 print
load_fiche_titre($langs->trans(
"Translation"), $enabledisablehtml,
'title_setup');
219 $current_language_code = $langs->defaultlang;
221 print
$form->textwithpicto(
'<span class="opacitymedium">'.$langs->trans(
"CurrentUserLanguage").
':</span> <strong>'.$s.
' '.$current_language_code.
'</strong>', $langs->trans(
"TranslationDesc")).
'</span><br>';
225 if (!empty($contextpage) && $contextpage != $_SERVER[
"PHP_SELF"]) {
226 $param .=
'&contextpage='.urlencode($contextpage);
228 if ($limit > 0 && $limit != $conf->liste_limit) {
229 $param .=
'&limit='.((int) $limit);
231 if (isset($optioncss) && $optioncss !=
'') {
232 $param .=
'&optioncss='.urlencode($optioncss);
235 $param .=
'&langcode='.urlencode($langcode);
238 $param .=
'&transkey='.urlencode($transkey);
241 $param .=
'&transvalue='.urlencode($transvalue);
245 print
'<form action="'.$_SERVER[
"PHP_SELF"].((empty($user->entity) && !empty($debug)) ?
'?debug=1' :
'').
'" method="POST">';
246 if (isset($optioncss) && $optioncss !=
'') {
247 print
'<input type="hidden" name="optioncss" value="'.$optioncss.
'">';
249 print
'<input type="hidden" name="token" value="'.newToken().
'">';
250 print
'<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
251 print
'<input type="hidden" name="sortfield" value="'.$sortfield.
'">';
252 print
'<input type="hidden" name="sortorder" value="'.$sortorder.
'">';
262 $newlang->setDefaultLang($langcode);
264 $langsenfileonly =
new Translate(
'', $conf);
265 $langsenfileonly->setDefaultLang(
'en_US');
267 $newlangfileonly =
new Translate(
'', $conf);
268 $newlangfileonly->setDefaultLang($langcode);
270 $recordtoshow = array();
275 $listoffiles = array();
276 $listoffilesexternalmodules = array();
280 foreach ($modulesdir as $keydir => $tmpsearchdir) {
281 $searchdir = $tmpsearchdir;
284 $dir_lang = dirname(dirname($searchdir)).
"/langs/".$langcode;
287 $filearray =
dol_dir_list($dir_lang_osencoded,
'files', 0,
'',
'', $sortfield, (strtolower($sortorder) ==
'asc' ?SORT_ASC:SORT_DESC), 1);
288 foreach ($filearray as $file) {
289 $tmpfile = preg_replace(
'/.lang/i',
'', basename($file[
'name']));
290 $moduledirname = (basename(dirname(dirname($dir_lang))));
294 $langkey .=
'@'.$moduledirname;
298 $result = $newlang->load($langkey, 0, 0,
'', 0);
299 $result = $newlangfileonly->load($langkey, 0, 0,
'', 1);
301 print
'Failed to load language file '.$tmpfile.
'<br>'.
"\n";
303 $listoffiles[$langkey] = $tmpfile;
304 if (strpos($langkey,
'@') !==
false) {
305 $listoffilesexternalmodules[$langkey] = $tmpfile;
310 $result = $langsenfileonly->load($langkey, 0, 0,
'', 1);
315 $nbtotaloffiles = count($listoffiles);
316 $nbtotaloffilesexternal = count($listoffilesexternalmodules);
318 if ($mode ==
'overwrite') {
319 print
'<input type="hidden" name="page" value="'.$page.
'">';
322 if ($action ==
'edit' || empty($conf->global->MAIN_ENABLE_OVERWRITE_TRANSLATION)) {
323 $disabled =
' disabled="disabled"';
326 if ($action ==
'edit' || empty($conf->global->MAIN_ENABLE_OVERWRITE_TRANSLATION)) {
327 $disablededit =
' disabled';
330 print
'<div class="justify"><span class="opacitymedium">';
331 print
img_info().
' '.$langs->trans(
"SomeTranslationAreUncomplete");
332 $urlwikitranslatordoc =
'https://wiki.dolibarr.org/index.php/Translator_documentation';
333 print
' ('.str_replace(
'{s1}',
'<a href="'.$urlwikitranslatordoc.
'" target="_blank" rel="noopener noreferrer external">'.$langs->trans(
"Here").
'</a>', $langs->trans(
"SeeAlso",
'{s1}')).
')<br>';
334 print $langs->trans(
"TranslationOverwriteDesc", $langs->transnoentitiesnoconv(
"Language"), $langs->transnoentitiesnoconv(
"Key"), $langs->transnoentitiesnoconv(
"NewTranslationStringToShow")).
"\n";
335 print
' ('.$langs->trans(
"TranslationOverwriteDesc2").
').'.
"<br>\n";
336 print
'</span></div>';
341 print
'<input type="hidden" name="action" value="'.($action ==
'edit' ?
'update' :
'add').
'">';
342 print
'<input type="hidden" id="mode" name="mode" value="'.$mode.
'">';
344 print
'<div class="div-table-responsive-no-min">';
345 print
'<table class="noborder centpercent">';
346 print
'<tr class="liste_titre">';
347 print_liste_field_titre(
"Language_en_US_es_MX_etc", $_SERVER[
"PHP_SELF"],
'lang,transkey',
'', $param,
'', $sortfield, $sortorder);
349 print_liste_field_titre(
"NewTranslationStringToShow", $_SERVER[
"PHP_SELF"],
'transvalue',
'', $param,
'', $sortfield, $sortorder);
351 print
'<td align="center"></td>';
358 print
'<tr class="oddeven"><td>';
359 print $formadmin->select_language(
GETPOST(
'langcode'),
'langcode', 0,
null, 1, 0, $disablededit ? 1 : 0,
'maxwidth250', 1);
362 print
'<input type="text" class="flat maxwidthonsmartphone"'.$disablededit.
' name="transkey" id="transkey" value="'.(!empty($transkey) ? $transkey :
"").
'">';
364 print
'<input type="text" class="quatrevingtpercent"'.$disablededit.
' name="transvalue" id="transvalue" value="'.(!empty($transvalue) ? $transvalue :
"").
'">';
366 print
'<td class="center">';
367 print
'<input type="hidden" name="entity" value="'.$conf->entity.
'">';
368 print
'<input type="submit" class="button"'.$disabled.
' value="'.$langs->trans(
"Add").
'" name="add" title="'.
dol_escape_htmltag($langs->trans(
"YouMustEnableTranslationOverwriteBefore")).
'">';
374 $sql =
"SELECT rowid, entity, lang, transkey, transvalue";
375 $sql .=
" FROM ".MAIN_DB_PREFIX.
"overwrite_trans";
376 $sql .=
" WHERE 1 = 1";
377 $sql .=
" AND entity IN (".getEntity(
'overwrite_trans').
")";
378 $sql .= $db->order($sortfield, $sortorder);
380 dol_syslog(
"translation::select from table", LOG_DEBUG);
381 $result = $db->query(
$sql);
383 $num = $db->num_rows($result);
387 $obj = $db->fetch_object($result);
391 print
'<tr class="oddeven">';
393 print
'<td>'.$obj->lang.
'</td>'.
"\n";
395 if ($action ==
'edit' && $obj->rowid ==
GETPOST(
'rowid',
'int')) {
396 print
'<input type="text" class="quatrevingtpercent" name="transkey" value="'.dol_escape_htmltag($obj->transkey).
'">';
398 print $obj->transkey;
403 print
'<td class="small">';
409 if ($action ==
'edit' && $obj->rowid ==
GETPOST(
'rowid',
'int')) {
410 print
'<input type="text" class="quatrevingtpercent" name="transvalue" value="'.dol_escape_htmltag($obj->transvalue).
'">';
413 $titleforvalue = $langs->trans(
"Translation").
' en_US for key '.$obj->transkey.
':<br>'.($langsenfileonly->tab_translate[$obj->transkey] ? $langsenfileonly->trans($obj->transkey) :
'<span class="opacitymedium">'.$langs->trans(
"None").
'</span>');
417 print
'<span title="'.dol_escape_htmltag($titleforvalue).
'" class="classfortooltip">';
423 print
'<td class="center">';
424 if ($action ==
'edit' && $obj->rowid ==
GETPOST(
'rowid',
'int')) {
425 print
'<input type="hidden" class="button" name="rowid" value="'.$obj->rowid.
'">';
426 print
'<input type="submit" class="button buttongen button-save" name="save" value="'.dol_escape_htmltag($langs->trans(
"Save")).
'">';
428 print
'<input type="submit" class="button buttongen button-cancel" name="cancel" value="'.dol_escape_htmltag($langs->trans(
"Cancel")).
'">';
430 print
'<a class="reposition editfielda paddingrightonly" href="'.$_SERVER[
'PHP_SELF'].
'?rowid='.$obj->rowid.
'&entity='.$obj->entity.
'&mode='.urlencode($mode).
'&action=edit&token='.
newToken().((empty($user->entity) && $debug) ?
'&debug=1' :
'').
'">'.
img_edit().
'</a>';
432 print
'<a class="reposition" href="'.$_SERVER[
'PHP_SELF'].
'?rowid='.$obj->rowid.
'&entity='.$obj->entity.
'&mode='.urlencode($mode).
'&action=delete&token='.
newToken().((empty($user->entity) && $debug) ?
'&debug=1' :
'').
'">'.
img_delete().
'</a>';
446 if ($mode ==
'searchkey') {
451 if (empty($langcode) || $langcode ==
'-1') {
454 if (empty($transkey)) {
457 if (empty($transvalue)) {
461 if ($action ==
'search' && ($nbempty > 999)) {
462 setEventMessages($langs->trans(
"WarningAtLeastKeyOrTranslationRequired"),
null,
'warnings');
465 foreach ($newlang->tab_translate as $key => $val) {
466 $newtranskey = preg_replace(
'/\$$/',
'', preg_replace(
'/^\^/',
'', $transkey));
467 $newtranskeystart = preg_match(
'/^\^/', $transkey);
468 $newtranskeyend = preg_match(
'/\$$/', $transkey);
469 $regexstring = ($newtranskeystart ?
'^' :
'').preg_quote($newtranskey,
'/').($newtranskeyend ?
'$' :
'');
470 if ($transkey && !preg_match(
'/'.$regexstring.
'/i', $key)) {
473 if ($transvalue && !preg_match(
'/'.preg_quote($transvalue,
'/').
'/i', $val)) {
476 $recordtoshow[$key] = $val;
481 $nbtotalofrecordswithoutfilters = count($newlang->tab_translate);
482 $nbtotalofrecords = count($recordtoshow);
484 if (($offset + $num) > $nbtotalofrecords) {
489 $title = $langs->trans(
"Translation");
490 if ($nbtotalofrecords > 0) {
491 $title .=
' <span class="opacitymedium colorblack paddingleft">('.$nbtotalofrecords.
' / '.$nbtotalofrecordswithoutfilters.
' - <span title="'.
dol_escape_htmltag(($nbtotaloffiles - $nbtotaloffilesexternal).
' core - '.($nbtotaloffilesexternal).
' external').
'">'.$nbtotaloffiles.
' '.$langs->trans(
"Files").
'</span>)</span>';
493 print_barre_liste($title, $page, $_SERVER[
"PHP_SELF"], $param, $sortfield, $sortorder,
'', $num, -1 * $nbtotalofrecords,
'', 0,
'',
'', $limit, 0, 0, 1);
495 $massactionbutton =
'';
497 print
'<input type="hidden" id="action" name="action" value="search">';
498 print
'<input type="hidden" id="mode" name="mode" value="'.$mode.
'">';
500 print
'<div class="div-table-responsive-no-min">';
501 print
'<table class="noborder centpercent">';
503 print
'<tr class="liste_titre_filter"><td>';
505 print $formadmin->select_language($langcode,
'langcode', 0,
null, 0, 0, 0,
'maxwidth250', 1);
508 print
'<input type="text" class="flat maxwidthonsmartphone" name="transkey" value="'.dol_escape_htmltag($transkey).
'">';
510 print
'<input type="text" class="quatrevingtpercent" name="transvalue" value="'.dol_escape_htmltag($transvalue).
'">';
519 print
'<input type="hidden" name="entitysearch" value="'.$conf->entity.
'">';
523 print
'<td class="right nowraponall">';
524 $searchpicto =
$form->showFilterAndCheckAddButtons(!empty($massactionbutton) ? 1 : 0,
'checkforselect', 1);
529 print
'<tr class="liste_titre">';
530 print_liste_field_titre(
"Language_en_US_es_MX_etc", $_SERVER[
"PHP_SELF"],
'lang,transkey',
'', $param,
'', $sortfield, $sortorder);
532 print_liste_field_titre(
"CurrentTranslationString", $_SERVER[
"PHP_SELF"],
'transvalue',
'', $param,
'', $sortfield, $sortorder);
534 print
'<td align="center"></td>';
538 if ($sortfield ==
'transkey' && strtolower($sortorder) ==
'asc') {
539 ksort($recordtoshow);
541 if ($sortfield ==
'transkey' && strtolower($sortorder) ==
'desc') {
542 krsort($recordtoshow);
544 if ($sortfield ==
'transvalue' && strtolower($sortorder) ==
'asc') {
545 asort($recordtoshow);
547 if ($sortfield ==
'transvalue' && strtolower($sortorder) ==
'desc') {
548 arsort($recordtoshow);
553 foreach ($recordtoshow as $key => $val) {
558 if ($i > ($offset + $limit)) {
561 print
'<tr class="oddeven"><td>'.$langcode.
'</td><td>'.$key.
'</td><td class="small">';
562 $titleforvalue = $langs->trans(
"Translation").
' en_US for key '.$key.
':<br>'.(!empty($langsenfileonly->tab_translate[$key]) ? $langsenfileonly->trans($key) :
'<span class="opacitymedium">'.$langs->trans(
"None").
'</span>');
563 print
'<span title="'.dol_escape_htmltag($titleforvalue).
'" class="classfortooltip">';
567 print
'<td class="right nowraponall">';
568 if (!empty($newlangfileonly->tab_translate[$key])) {
569 if ($val != $newlangfileonly->tab_translate[$key]) {
571 $sql =
"SELECT rowid";
572 $sql .=
" FROM ".MAIN_DB_PREFIX.
"overwrite_trans";
573 $sql .=
" WHERE entity IN (".getEntity(
'overwrite_trans').
")";
574 $sql .=
" AND transkey = '".$db->escape($key).
"'";
575 dol_syslog(
"translation::select from table", LOG_DEBUG);
576 $result = $db->query(
$sql);
578 $obj = $db->fetch_object($result);
580 print
'<a class="editfielda reposition marginrightonly" href="'.$_SERVER[
'PHP_SELF'].
'?rowid='.$obj->rowid.
'&entity='.$conf->entity.
'&mode=overwrite&action=edit&token='.
newToken().
'">'.
img_edit().
'</a>';
582 print
'<a class="marginleftonly marginrightonly" href="'.$_SERVER[
'PHP_SELF'].
'?rowid='.$obj->rowid.
'&entity='.$conf->entity.
'&mode='.urlencode($mode).
'&action=delete&token='.
newToken().
'&mode='.urlencode($mode).
'">'.
img_delete().
'</a>';
583 print
' ';
584 $htmltext = $langs->trans(
"OriginalValueWas",
'<i>'.$newlangfileonly->tab_translate[$key].
'</i>');
585 print
$form->textwithpicto(
'', $htmltext, 1,
'info');
586 } elseif (!empty($conf->global->MAIN_ENABLE_OVERWRITE_TRANSLATION)) {
588 print
'<a class="reposition paddingrightonly" href="'.$_SERVER[
'PHP_SELF'].
'?mode=overwrite&langcode='.urlencode($langcode).
'&transkey='.urlencode($key).
'">'.
img_edit_add($langs->trans(
"TranslationOverwriteKey")).
'</a>';
592 $transifexlangfile =
'$';
594 $transifexurl =
'https://www.transifex.com/dolibarr-association/dolibarr/translate/#'.$langcode.
'/'.$transifexlangfile.
'?q=key%3A'.$key;
596 print
' <a href="'.$transifexurl.
'" target="transifex">'.
img_picto($langs->trans(
'FixOnTransifex'),
'globe').
'</a>';
600 $sql =
"SELECT rowid";
601 $sql .=
" FROM ".MAIN_DB_PREFIX.
"overwrite_trans";
602 $sql .=
" WHERE entity IN (".getEntity(
'overwrite_trans').
")";
603 $sql .=
" AND transkey = '".$db->escape($key).
"'";
604 dol_syslog(
"translation::select from table", LOG_DEBUG);
605 $result = $db->query(
$sql);
607 $obj = $db->fetch_object($result);
609 print
'<a class="editfielda reposition marginrightonly" href="'.$_SERVER[
'PHP_SELF'].
'?rowid='.$obj->rowid.
'&entity='.$conf->entity.
'&mode=overwrite&action=edit&token='.
newToken().
'">'.
img_edit().
'</a>';
611 print
'<a class="marginleftonly marginrightonly" href="'.$_SERVER[
'PHP_SELF'].
'?rowid='.$obj->rowid.
'&entity='.$conf->entity.
'&mode='.urlencode($mode).
'&action=delete&token='.
newToken().
'&mode='.urlencode($mode).
'">'.
img_delete().
'</a>';
612 print
' ';
614 $htmltext = $langs->trans(
"TransKeyWithoutOriginalValue", $key);
615 print
$form->textwithpicto(
'', $htmltext, 1,
'warning');
621 print
'</td></tr>'.
"\n";
632 if (!empty($langcode)) {