NEW Introduce table llx_overwrite_trans to be able to overwrite

translations by simple database edition.
This commit is contained in:
Laurent Destailleur 2015-09-17 17:52:34 +02:00
parent 8ff41a8ded
commit b1168d223a
3 changed files with 208 additions and 14 deletions

View File

@ -29,17 +29,17 @@
*/
class Translate
{
var $dir; // Directories that contains /langs subdirectory
var $dir; // Directories that contains /langs subdirectory
var $defaultlang; // Current language for current user
var $direction = 'ltr'; // Left to right or Right to left
var $charset_output='UTF-8'; // Codage used by "trans" method outputs
var $defaultlang; // Current language for current user
var $direction = 'ltr'; // Left to right or Right to left
var $charset_output='UTF-8'; // Codage used by "trans" method outputs
var $tab_translate=array(); // Array of all translations key=>value
private $_tab_loaded=array(); // Array to store result after loading each language file
var $tab_translate=array(); // Array of all translations key=>value
private $_tab_loaded=array(); // Array to store result after loading each language file
var $cache_labels=array(); // Cache for labels return by getLabelFromKey method
var $cache_currencies=array(); // Cache to store currency symbols
var $cache_labels=array(); // Cache for labels return by getLabelFromKey method
var $cache_currencies=array(); // Cache to store currency symbols
@ -157,9 +157,11 @@ class Translate
* @param int $forcelangdir To force a different lang directory
* @return int <0 if KO, 0 if already loaded or loading not required, >0 if OK
*/
function Load($domain,$alt=0,$stopafterdirection=0,$forcelangdir='')
function load($domain,$alt=0,$stopafterdirection=0,$forcelangdir='')
{
global $conf;
global $conf,$db;
if (count($this->tab_translate) == 0) $this->loadFromDatabase($db); // Nothing was loaded yet, so we load database.
// Check parameters
if (empty($domain))
@ -239,7 +241,7 @@ class Translate
$tmparray=dol_getcache($usecachekey);
if (is_array($tmparray) && count($tmparray))
{
$this->tab_translate=array_merge($tmparray,$this->tab_translate); // Already found values tab_translate overwrites duplicates
$this->tab_translate+=$tmparray; // Faster than array_merge($tmparray,$this->tab_translate). Note: If a valuer already exists into tab_translate, value into tmparaay is not added.
//print $newdomain."\n";
//var_dump($this->tab_translate);
if ($alt == 2) $fileread=1;
@ -329,11 +331,12 @@ class Translate
if (empty($this->_tab_loaded[$newdomain])) $this->_tab_loaded[$newdomain]=2; // Marque ce fichier comme non trouve
}
// Overwrite translation
// This part is deprecated and replaced with table llx_overwrite_trans
// Kept for backward compatibility.
$overwritekey='MAIN_OVERWRITE_TRANS_'.$this->defaultlang;
if (! empty($conf->global->$overwritekey)) // Overwrite translation with key1:newstring1,key2:newstring2
{
// Overwrite translation with param MAIN_OVERWRITE_TRANS_xx_XX
$tmparray=explode(',', $conf->global->$overwritekey);
foreach($tmparray as $tmp)
{
@ -342,13 +345,167 @@ class Translate
}
}
// Check to be sure that SeparatorDecimal differs from SeparatorThousand
// Check to be sure that SeparatorDecimal differs from SeparatorThousand
if (! empty($this->tab_translate["SeparatorDecimal"]) && ! empty($this->tab_translate["SeparatorThousand"])
&& $this->tab_translate["SeparatorDecimal"] == $this->tab_translate["SeparatorThousand"]) $this->tab_translate["SeparatorThousand"]='';
return 1;
}
/**
* Load translation key-value from database into a memory array.
* If data already loaded, do nothing.
* All data in translation array are stored in UTF-8 format.
* tab_loaded is completed with $domain key.
* rule "we keep first entry found with we keep last entry found" so it is probably not what you want to do.
*
* Value for hash are: 1:Loaded from disk, 2:Not found, 3:Loaded from cache
*
* @param Database $db Database handler
* @return int <0 if KO, 0 if already loaded or loading not required, >0 if OK
*/
function loadFromDatabase($db)
{
global $conf;
$domain='database';
if ($this->defaultlang == 'none_NONE') return 0; // Special language code to not translate keys
// Check parameters
if (empty($db)) return 0; // Database handler can't be used
//dol_syslog("Translate::Load Start domain=".$domain." alt=".$alt." forcelangdir=".$forcelangdir." this->defaultlang=".$this->defaultlang);
$newdomain = $domain;
$modulename = '';
// Check cache
if (! empty($this->_tab_loaded[$newdomain])) // File already loaded for this domain
{
//dol_syslog("Translate::Load already loaded for newdomain=".$newdomain);
return 0;
}
$this->_tab_loaded[$newdomain] = 1; // We want to be sure this function is called once only.
$fileread=0;
$langofdir=(empty($forcelangdir)?$this->defaultlang:$forcelangdir);
// Redefine alt
$alt=2;
if (empty($langofdir)) // This may occurs when load is called without setting the language and without providing a value for forcelangdir
{
dol_syslog("Error: ".get_class($this)."::Load was called but language was not set yet with langs->setDefaultLang(). Nothing will be loaded.", LOG_WARNING);
return -1;
}
// TODO Move cache read out of loop on dirs or at least filelangexists
$found=false;
// Enable caching of lang file in memory (not by default)
$usecachekey='';
// Using a memcached server
if (! empty($conf->memcached->enabled) && ! empty($conf->global->MEMCACHED_SERVER))
{
$usecachekey=$newdomain.'_'.$langofdir.'_'.md5($file_lang); // Should not contains special chars
}
// Using cache with shmop. Speed gain: 40ms - Memory overusage: 200ko (Size of session cache file)
else if (isset($conf->global->MAIN_OPTIMIZE_SPEED) && ($conf->global->MAIN_OPTIMIZE_SPEED & 0x02))
{
$usecachekey=$newdomain;
}
if ($usecachekey)
{
//dol_syslog('Translate::Load we will cache result into usecachekey '.$usecachekey);
//global $aaa; $aaa+=1;
//print $aaa." ".$usecachekey."\n";
require_once DOL_DOCUMENT_ROOT .'/core/lib/memory.lib.php';
$tmparray=dol_getcache($usecachekey);
if (is_array($tmparray) && count($tmparray))
{
$this->tab_translate+=$tmparray; // Faster than array_merge($tmparray,$this->tab_translate). Note: If a valuer already exists into tab_translate, value into tmparaay is not added.
//print $newdomain."\n";
//var_dump($this->tab_translate);
if ($alt == 2) $fileread=1;
$found=true; // Found in dolibarr PHP cache
}
}
if (! $found)
{
// Overwrite translation with database read
$sql="SELECT transkey, transvalue FROM ".MAIN_DB_PREFIX."overwrite_trans where lang='".$this->defaultlang."'";
$resql=$db->query($sql);
if ($resql)
{
$num = $db->num_rows($resql);
if ($num)
{
if ($usecachekey) $tabtranslatedomain=array(); // To save lang content in cache
$i = 0;
while ($i < $num) // Ex: Need 225ms for all fgets on all lang file for Third party page. Same speed than file_get_contents
{
$obj=$db->fetch_object($resql);
$key=$obj->transkey;
$value=$obj->transvalue;
//print "Domain=$domain, found a string for $tab[0] with value $tab[1]<br>";
if (empty($this->tab_translate[$key])) // If translation was already found, we must not continue, even if MAIN_FORCELANGDIR is set (MAIN_FORCELANGDIR is to replace lang dir, not to overwrite entries)
{
$value=trim(preg_replace('/\\n/',"\n",$value));
$this->tab_translate[$key]=$value;
if ($usecachekey) $tabtranslatedomain[$key]=$value; // To save lang content in cache
}
$i++;
}
$fileread=1;
// TODO Move cache write out of loop on dirs
// To save lang content for usecachekey into cache
if ($usecachekey && count($tabtranslatedomain))
{
$ressetcache=dol_setcache($usecachekey,$tabtranslatedomain);
if ($ressetcache < 0)
{
$error='Failed to set cache for usecachekey='.$usecachekey.' result='.$ressetcache;
dol_syslog($error, LOG_ERR);
}
}
}
}
else
{
dol_print_error($db);
}
}
if ($alt == 2)
{
if ($fileread) $this->_tab_loaded[$newdomain]=1; // Set domain file as loaded
if (empty($this->_tab_loaded[$newdomain])) $this->_tab_loaded[$newdomain]=2; // Marque ce cas comme non trouve (no lines found for language)
}
// Check to be sure that SeparatorDecimal differs from SeparatorThousand
if (! empty($this->tab_translate["SeparatorDecimal"]) && ! empty($this->tab_translate["SeparatorThousand"])
&& $this->tab_translate["SeparatorDecimal"] == $this->tab_translate["SeparatorThousand"]) $this->tab_translate["SeparatorThousand"]='';
return 1;
}
/**
* Return translated value of key for special keys ("Currency...", "Civility...", ...).
* Search in lang file, then into database. Key must be any complete entry into lang file: CurrencyEUR, ...

View File

@ -31,3 +31,13 @@ ALTER TABLE llx_accountingaccount RENAME TO llx_accounting_account;
ALTER TABLE llx_societe ADD COLUMN model_pdf varchar(255);
ALTER TABLE llx_societe_commerciaux ADD COLUMN import_key varchar(14) AFTER fk_user;
create table llx_overwrite_trans
(
rowid integer AUTO_INCREMENT PRIMARY KEY,
lang varchar(5), -- en_US, fr_FR ...
transkey varchar(128),
transvalue text
)ENGINE=innodb;

View File

@ -0,0 +1,27 @@
-- ============================================================================
-- Copyright (C) 2013 Laurent Destailleur <eldy@users.sourceforge.net>
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation; either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
-- ============================================================================
create table llx_overwrite_trans
(
rowid integer AUTO_INCREMENT PRIMARY KEY,
lang varchar(5), -- en_US, fr_FR ...
transkey varchar(128),
transvalue text
)ENGINE=innodb;