From 248a7d7ee24266c50d81e0776cbef2d192e01ba7 Mon Sep 17 00:00:00 2001
From: Laurent Destailleur <eldy@users.sourceforge.net>
Date: Thu, 9 Oct 2008 17:29:32 +0000
Subject: [PATCH] Change to support different page code in HTML output

---
 htdocs/conf/conf.class.php                 |   2 +-
 htdocs/conf/conf.php.example               |   6 +-
 htdocs/includes/boxes/box_external_rss.php |  32 +-----
 htdocs/install/inc.php                     |   4 +-
 htdocs/lib/databases/mssql.lib.php         |   4 +-
 htdocs/lib/databases/mysql.lib.php         |  96 +++++++++-------
 htdocs/lib/functions.lib.php               | 128 +++++++++++++--------
 htdocs/master.inc.php                      |   7 +-
 htdocs/translate.class.php                 |  29 +++--
 9 files changed, 170 insertions(+), 138 deletions(-)

diff --git a/htdocs/conf/conf.class.php b/htdocs/conf/conf.class.php
index 8ccb1bab6f0..f025a579514 100644
--- a/htdocs/conf/conf.class.php
+++ b/htdocs/conf/conf.class.php
@@ -40,7 +40,7 @@ class Conf
 	//! Objet des caracteristiques de connexions
 	var $db;            
 	//! Charset for HTML output
-	var $character_set_client;	
+	var $character_set_client;	// ISO-8859-1, UTF8
 
 	var $externalrss;
 	var $commande;
diff --git a/htdocs/conf/conf.php.example b/htdocs/conf/conf.php.example
index 4f07acdba1e..b24fe07535c 100644
--- a/htdocs/conf/conf.php.example
+++ b/htdocs/conf/conf.php.example
@@ -104,7 +104,7 @@ $dolibarr_main_db_type="";
 
 
 # dolibarr_main_db_character_set
-# Database character set used to store data.
+# Database character set used to store data (forced during database creation).
 # Default value: depends on database driver
 # Examples:
 # dolibarr_main_db_character_set="latin1";
@@ -113,7 +113,7 @@ $dolibarr_main_db_character_set="latin1";
 
 
 # dolibarr_main_db_collation
-# Database character set used to sort data.
+# Database character set used to sort data (forced during database creation).
 # Default value: depends on database driver
 # Examples:
 # dolibarr_main_db_collation="latin1_swedish_ci";
@@ -124,7 +124,7 @@ $dolibarr_main_db_collation="latin1_swedish_ci";
 # character_set_client
 # Page code for HTML outputs.
 # Default value: ISO-8859-1
-# Possible values: ISO-8859-1
+# Possible values: ISO-8859-1, UTF-8
 #
 $character_set_client="ISO-8859-1";
 
diff --git a/htdocs/includes/boxes/box_external_rss.php b/htdocs/includes/boxes/box_external_rss.php
index a2d569f814e..a473496d727 100644
--- a/htdocs/includes/boxes/box_external_rss.php
+++ b/htdocs/includes/boxes/box_external_rss.php
@@ -128,12 +128,12 @@ class box_external_rss extends ModeleBoxes {
 				//$item['atom_content']
 			}
 			if (is_numeric($date)) $date=dolibarr_print_date($date,"dayhour");
-			$result = $this->utf8_check($title);
-            if ($result)
-            {
-            	$title=utf8_decode($title);
-            }
-            $title=ereg_replace("([[:alnum:]])\?([[:alnum:]])","\\1'\\2",$title);   // G�re probl�me des apostrophes mal cod�e/d�cod�e par utf8
+			
+			$isutf8 = utf8_check($title);
+	        if (! $isutf8 && $conf->character_set_client == 'UTF-8') $title=utf8_encode($title); 
+	        elseif ($isutf8 && $conf->character_set_client == 'ISO-8859-1') $title=utf8_decode($title); 
+
+	        $title=ereg_replace("([[:alnum:]])\?([[:alnum:]])","\\1'\\2",$title);   // G�re probl�me des apostrophes mal cod�e/d�cod�e par utf8
             $title=ereg_replace("^\s+","",$title);                                  // Supprime espaces de d�but
             $this->info_box_contents["$href"]="$title";
             $this->info_box_contents[$i][0] = array('align' => 'left',
@@ -148,26 +148,6 @@ class box_external_rss extends ModeleBoxes {
         }
     }
     
-    /**
-     *      \brief      V�rifie si le flux est en UTF8
-     *      \param      $Str        chaine � v�rifier
-     */
-    function utf8_check($Str) {
-    	for ($i=0; $i<strlen($Str); $i++) {
-    		if (ord($Str[$i]) < 0x80) continue; # 0bbbbbbb
-    		elseif ((ord($Str[$i]) & 0xE0) == 0xC0) $n=1; # 110bbbbb
-    		elseif ((ord($Str[$i]) & 0xF0) == 0xE0) $n=2; # 1110bbbb
-    		elseif ((ord($Str[$i]) & 0xF8) == 0xF0) $n=3; # 11110bbb
-    		elseif ((ord($Str[$i]) & 0xFC) == 0xF8) $n=4; # 111110bb
-    		elseif ((ord($Str[$i]) & 0xFE) == 0xFC) $n=5; # 1111110b
-    		else return false; # Does not match any model
-    		for ($j=0; $j<$n; $j++) { # n bytes matching 10bbbbbb follow ?
-    			if ((++$i == strlen($Str)) || ((ord($Str[$i]) & 0xC0) != 0x80))
-    			return false;
-    		}
-    	}
-    	return true;
-    }
 
     function showBox()
     {
diff --git a/htdocs/install/inc.php b/htdocs/install/inc.php
index f67e8a7ef42..335e4c5c8df 100644
--- a/htdocs/install/inc.php
+++ b/htdocs/install/inc.php
@@ -61,7 +61,7 @@ else
 
 $includeconferror='';
 $conffile = "../conf/conf.php";
-$charset="ISO-8859-1";
+$charset="UTF-8";	// If not output format found in any conf file
 if (! defined('DONOTLOADCONF') && file_exists($conffile))
 {
 	$result=include_once($conffile);	// Load conf file
@@ -204,7 +204,7 @@ function conf($dolibarr_main_document_root)
 	$conf->db->pass = trim($dolibarr_main_db_pass);
 
 	if (empty($character_set_client)) $character_set_client=$charset;
-	$conf->character_set_client=$character_set_client;
+	$conf->character_set_client=strtoupper($character_set_client);
 	if (empty($dolibarr_main_db_charset)) $dolibarr_main_db_charset='latin1'; 
 	$conf->db->character_set=$dolibarr_main_db_charset;
 	if (empty($dolibarr_main_db_collation)) $dolibarr_main_db_collation='latin1_swedish_ci';
diff --git a/htdocs/lib/databases/mssql.lib.php b/htdocs/lib/databases/mssql.lib.php
index 912d3916104..075901604f8 100644
--- a/htdocs/lib/databases/mssql.lib.php
+++ b/htdocs/lib/databases/mssql.lib.php
@@ -40,9 +40,9 @@ class DoliDb
 	var $db;
 	//! Nom du gestionnaire
 	var $type='mssql';
-	//! Charset
+	//! Charset used to force charset when creating database
 	var $forcecharset='latin1';
-	//! Collate
+	//! Collate used to force collate when creating database
 	var $forcecollate='latin1_swedish_ci';
 	//! Version min database
 	var $versionmin=array(2000);
diff --git a/htdocs/lib/databases/mysql.lib.php b/htdocs/lib/databases/mysql.lib.php
index cb2e818f20a..67d6bb5ef8c 100644
--- a/htdocs/lib/databases/mysql.lib.php
+++ b/htdocs/lib/databases/mysql.lib.php
@@ -22,7 +22,7 @@
 
 /**
  *	\file       	htdocs/lib/databases/mysql.lib.php
- *	\brief      	Fichier de la classe permettant de g�rer une base mysql
+ *	\brief      	Class file to manage Dolibarr database access for a Mysql database
  *	\version		$Id$
  */
 // For compatibility during upgrade
@@ -32,23 +32,23 @@ if (! defined('ADODB_DATE_VERSION')) include_once(DOL_DOCUMENT_ROOT."/includes/a
 
 /**
  *	\class      DoliDb
- *	\brief      Classe de gestion de la database de dolibarr
+ *	\brief      Class to manage Dolibarr database access for a Mysql database
  */
 class DoliDb
 {
-	//! Handler de base
+	//! Database handler
 	var $db;
-	//! Nom du gestionnaire
+	//! Database type
 	var $type='mysql';
-	//! Charset
+	//! Charset used to force charset when creating database
 	var $forcecharset='latin1';
-	//! Collate
+	//! Collate used to force collate when creating database
 	var $forcecollate='latin1_swedish_ci';
 	//! Version min database
 	var $versionmin=array(3,1,0);
 	//! Resultset of last request
 	var $results;
-	//! 1 if connected, 0 else  
+	//! 1 if connected, 0 else
 	var $connected;
 	//! 1 if database selected, 0 else
 	var $database_selected;
@@ -80,7 +80,7 @@ class DoliDb
 	 \param	    name		Nom de la database
 	 \param	    port		Port of database server
 	 \return	int			1 en cas de succ�s, 0 sinon
-  	*/
+	 */
 	function DoliDb($type='mysql', $host, $user, $pass, $name='', $port=0)
 	{
 		global $conf,$langs;
@@ -129,7 +129,7 @@ class DoliDb
 			dolibarr_syslog("DoliDB::DoliDB : Erreur Connect mysql_error=".$this->error,LOG_ERR);
 		}
 
-		// Si connexion serveur ok et si connexion base demand�e, on essaie connexion base
+		// Si connexion serveur ok et si connexion base demandee, on essaie connexion base
 		if ($this->connected && $name)
 		{
 			if ($this->select_db($name))
@@ -138,13 +138,15 @@ class DoliDb
 				$this->database_name = $name;
 				$this->ok = 1;
 
-				// If client connected with different charset than Dolibarr database
-				// (La base Dolibarr was forced to this->forcecharset during install)
-				/*if (mysql_client_encoding ( $this->db ) != $this->getDefaultCharacterSetDatabase())
+				// If client connected with different charset than Dolibarr HTML output
+				$clientmustbe='';
+				if (eregi('UTF-8',$conf->character_set_client))      $clientmustbe='utf8';
+				if (eregi('ISO-8859-1',$conf->character_set_client)) $clientmustbe='latin1';
+				if (mysql_client_encoding($this->db) != $clientmustbe)
 				{
-				$this->query("SET NAMES '".$this->forcecharset."'", $this->db);
-				$this->query("SET CHARACTER SET ". $this->forcecharset);
-				}*/
+					$this->query("SET NAMES '".$clientmustbe."'", $this->db);
+					//$this->query("SET CHARACTER SET ". $this->forcecharset);
+				}
 			}
 			else
 			{
@@ -159,6 +161,19 @@ class DoliDb
 		{
 			// Pas de selection de base demandee, ok ou ko
 			$this->database_selected = 0;
+			
+			if ($this->connected)
+			{
+				// If client connected with different charset than Dolibarr HTML output
+				$clientmustbe='';
+				if (eregi('UTF-8',$conf->character_set_client))      $clientmustbe='utf8';
+				if (eregi('ISO-8859-1',$conf->character_set_client)) $clientmustbe='latin1';
+				if (mysql_client_encoding($this->db) != $clientmustbe)
+				{
+					$this->query("SET NAMES '".$clientmustbe."'", $this->db);
+					//$this->query("SET CHARACTER SET ". $this->forcecharset);
+				}
+			}
 		}
 
 		return $this->ok;
@@ -186,7 +201,7 @@ class DoliDb
 	}
 
 	/**
-	 *	\brief		Connection vers le serveur
+	 *	\brief		Connexion to server
 	 *	\param	    host		database server host
 	 *	\param	    login		login
 	 *	\param	    passwd		password
@@ -205,17 +220,7 @@ class DoliDb
 		if ($port) $newhost.=':'.$port;
 
 		$this->db  = @mysql_connect($newhost, $login, $passwd);
-		// Force recors to latin1 if database is in utf8 by default
-		// Removed becasue faile on my PHP-Mysql.
-		// De plus, la base est forcement en latin1 avec
-		// les nouvelles version de Dolibarr car force par l'install Dolibarr.
-		//$this->query('SET NAMES '.$this->forcecharset);
-		//print "Resultat fonction connect: ".$this->db;
-		if ($this->db)
-		{
-			$this->query("SET NAMES '".$this->forcecharset."'", $this->db);
-			$this->query("SET CHARACTER SET '".$this->forcecharset."'", $this->db);
-		}
+
 		//print "Resultat fonction connect: ".$this->db;
 		return $this->db;
 	}
@@ -250,7 +255,7 @@ class DoliDb
 	/**
 	 \brief          Renvoie la version du serveur dans un tableau
 	 \return	        array  		Tableau de chaque niveau de version
-  */
+	 */
 	function getVersionArray()
 	{
 		return split('\.',$this->getVersion());
@@ -261,7 +266,7 @@ class DoliDb
 	 \brief      Fermeture d'une connexion vers une database.
 	 \return	    resource
 	 \seealso	connect
-  */
+	 */
 	function close()
 	{
 		return mysql_close($this->db);
@@ -271,7 +276,7 @@ class DoliDb
 	/**
 	 \brief      Debut d'une transaction.
 	 \return	    int         1 si ouverture transaction ok ou deja ouverte, 0 en cas d'erreur
-  */
+	 */
 	function begin()
 	{
 		if (! $this->transaction_opened)
@@ -616,8 +621,8 @@ class DoliDb
 			1216 => 'DB_ERROR_NO_PARENT',
 			1217 => 'DB_ERROR_CHILD_EXISTS',
 			1451 => 'DB_ERROR_CHILD_EXISTS'
-		     );
-			
+			);
+				
 			if (isset($errorcode_map[mysql_errno($this->db)]))
 			{
 				return $errorcode_map[mysql_errno($this->db)];
@@ -672,21 +677,23 @@ class DoliDb
 
 
 	/**
-		\brief          Cr�ation d'une nouvelle base de donn�e
-		\param	        database		nom de la database � cr�er
-		\return	        resource		resource d�finie si ok, null si k
-		\remarks        Ne pas utiliser les fonctions xxx_create_db (xxx=mysql, ...) car elles sont deprecated
-		On force creation de la base avec le charset forcecharset
-		*/
+	 *	\brief          Create a new database
+	 *	\param	        database		Database name to create
+	 *	\return	        resource		resource defined if OK, null if KO
+	 *	\remarks        Do not use function xxx_create_db (xxx=mysql, ...) as they are deprecated
+	 *					We force to create database with charset this->forcecharset and collate this->forcecollate
+	 */
 	function DDLCreateDb($database)
 	{
 		// ALTER DATABASE dolibarr_db DEFAULT CHARACTER SET latin DEFAULT COLLATE latin1_swedish_ci
 		$sql = 'CREATE DATABASE '.$database;
 		$sql.= ' DEFAULT CHARACTER SET '.$this->forcecharset.' DEFAULT COLLATE '.$this->forcecollate;
+
+		dolibarr_syslog($sql,LOG_DEBUG);
 		$ret=$this->query($sql);
 		if (! $ret)
 		{
-			// On r�essaie pour compatibilit� avec Mysql < 4.1.1
+			// We try again for compatibility with Mysql < 4.1.1
 			$sql = 'CREATE DATABASE '.$database;
 			$ret=$this->query($sql);
 		}
@@ -900,6 +907,10 @@ class DoliDb
 		return $liste['Value'];
 	}
 
+	/**
+	 *	\brief		Return list of available charset that can be used to store data in database
+	 *	\return		array		List of Charset
+	 */
 	function getListOfCharacterSet()
 	{
 		$resql=$this->query('SHOW CHARSET');
@@ -937,7 +948,12 @@ class DoliDb
 		return $liste['Value'];
 	}
 
-	function getListOfCollation(){
+	/**
+	 *	\brief		Return list of available collation that can be used for database
+	 *	\return		array		Liste of Collation
+	 */
+	function getListOfCollation()
+	{
 		$resql=$this->query('SHOW COLLATION');
 		$liste = array();
 		if ($resql)
diff --git a/htdocs/lib/functions.lib.php b/htdocs/lib/functions.lib.php
index 5c6a2091d0d..90f0b1f02a2 100644
--- a/htdocs/lib/functions.lib.php
+++ b/htdocs/lib/functions.lib.php
@@ -112,7 +112,7 @@ function sanitize_string($str,$newstr='_')
 	$forbidden_chars_to_underscore=array(" ","'","/","\\",":","*","?","\"","<",">","|","[","]",",",";","=");
 	//$forbidden_chars_to_remove=array("(",")");
 	$forbidden_chars_to_remove=array();
-	
+
 	return str_replace($forbidden_chars_to_underscore,$newstr,str_replace($forbidden_chars_to_remove,"",$str));
 }
 
@@ -124,11 +124,11 @@ function sanitize_string($str,$newstr='_')
  */
 function dol_escape_js($stringtoescape)
 {
-    // escape quotes and backslashes, newlines, etc.
-    return strtr($stringtoescape, array('\\'=>'\\\\',"'"=>"\\'",'"'=>'\\"',"\r"=>'\\r',"\n"=>'\\n','</'=>'<\/'));			
+	// escape quotes and backslashes, newlines, etc.
+	return strtr($stringtoescape, array('\\'=>'\\\\',"'"=>"\\'",'"'=>'\\"',"\r"=>'\\r',"\n"=>'\\n','</'=>'<\/'));
 }
 
-    
+
 
 
 /**
@@ -410,7 +410,7 @@ function dolibarr_time_plus_duree($time,$duration_value,$duration_unit)
  *							"%d/%m/%Y %H:%M",
  *							"%d/%m/%Y %H:%M:%S",
  *							"day", "daytext", "dayhour", "dayhourldap", "dayhourtext"
- * 	\param		to_gmt		false=output string if for local server TZ users, true=output string is for GMT users 
+ * 	\param		to_gmt		false=output string if for local server TZ users, true=output string is for GMT users
  *	\return     string      Formated date or '' if time is null
  */
 function dolibarr_print_date($time,$format='',$to_gmt=false)
@@ -563,7 +563,7 @@ function dolibarr_mktime($hour,$minute,$second,$month,$day,$year,$gm=0,$check=1)
 	if ($hour   == -1) $hour=0;
 	if ($minute == -1) $minute=0;
 	if ($second == -1) $second=0;
-		
+
 	// Check parameters
 	if ($check)
 	{
@@ -1271,7 +1271,7 @@ function img_mime($file,$alt='')
 	if (eregi('\.(avi|mvw|divx|xvid)',$file))    $mime='video';
 	if (eregi('\.(zip|rar|gz|tgz|z|cab|bz2)',$file))       $mime='archive';
 	if (empty($alt)) $alt='Mime type: '.$mime;
-	
+
 	$mime.='.png';
 	return '<img src="'.DOL_URL_ROOT.'/theme/common/mime/'.$mime.'" border="0" alt="'.$alt.'" title="'.$alt.'">';
 }
@@ -1660,20 +1660,20 @@ function dol_move_uploaded_file($src_file, $dest_file, $allowoverwrite)
 		if (file_exists($file_name))
 		{
 			dolibarr_syslog("Functions.lib::dol_move_uploaded_file File ".$file_name." already exists", LOG_WARNING);
-			return -2;			
+			return -2;
 		}
 	}
-	
+
 	// Move file
 	$return=move_uploaded_file($src_file, $file_name);
 	if ($return)
 	{
 		dolibarr_syslog("Functions.lib::dol_move_uploaded_file Success to move ".$src_file." to ".$file_name, LOG_DEBUG);
-		return 1;			
+		return 1;
 	}
-	else 
+	else
 	{
-		dolibarr_syslog("Functions.lib::dol_move_uploaded_file Failed to move ".$src_file." to ".$file_name, LOG_ERR);			
+		dolibarr_syslog("Functions.lib::dol_move_uploaded_file Failed to move ".$src_file." to ".$file_name, LOG_ERR);
 		return -3;
 	}
 }
@@ -2021,7 +2021,7 @@ function price($amount, $html=0, $outlangs='', $trunc=1, $rounding=2)
 	global $langs,$conf;
 
 	$nbdecimal=$rounding;
-	
+
 	// Output separators by default (french)
 	$dec=','; $thousand=' ';
 
@@ -2620,7 +2620,7 @@ function dol_nl2br($stringtoencode,$nl2brmode=0)
  */
 function dol_htmlentitiesbr($stringtoencode,$nl2brmode=0)
 {
-	if (dol_textishtml($stringtoencode)) 
+	if (dol_textishtml($stringtoencode))
 	{
 		// Replace "<br type="_moz" />" by "<br>". It's same and avoid pb with FPDF.
 		$stringtoencode=eregi_replace('<br( [ a-zA-Z_="]*)?/?>','<br>',$stringtoencode);
@@ -2661,7 +2661,7 @@ function dol_entity_decode($stringhtml)
 
 /**
  \brief		Check if a string is a correct iso string
- 			If not, it will we considered not HTML encoded even if it is by FPDF.
+ If not, it will we considered not HTML encoded even if it is by FPDF.
  \remarks	Example, if string contains euro symbol that has ascii code 128.
  \param		s		String to check
  \return	int		0 if bad iso, 1 if good iso
@@ -2691,7 +2691,7 @@ function dol_nboflines($s,$maxchar=0)
 {
 	$arraystring=split("\n",$s);
 	$nb=sizeof($arraystring);
-	
+
 	return $nb;
 }
 
@@ -2709,23 +2709,23 @@ function num_lines($texte,$maxlinesize=0)
 	$pattern = '/(<[^>]+>)/Uu';
 	$a = preg_split($pattern, $texte, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
 	$nblines = ((count($a)+1)/2);
-    // count possible auto line breaks 	 
-         if($maxlinesize) 	 
-         { 	 
-                  foreach ($a as $line) 	 
-                  { 	 
-                         if (strlen($line)>$maxlinesize) 	 
-                         { 	 
-                                 //$line_dec = html_entity_decode(strip_tags($line)); 	 
-                                 $line_dec = html_entity_decode($line); 	 
-                                 if(strlen($line_dec)>$maxlinesize) 	 
-                                 { 	 
-                                 $line_dec=wordwrap($line_dec,$maxlinesize,'\n',true); 	 
-                                 $nblines+=substr_count($line_dec,'\n'); 	 
-                                 } 	 
-                         } 	 
-                  } 	 
-         }
+	// count possible auto line breaks
+	if($maxlinesize)
+	{
+		foreach ($a as $line)
+		{
+			if (strlen($line)>$maxlinesize)
+			{
+				//$line_dec = html_entity_decode(strip_tags($line));
+				$line_dec = html_entity_decode($line);
+				if(strlen($line_dec)>$maxlinesize)
+				{
+					$line_dec=wordwrap($line_dec,$maxlinesize,'\n',true);
+					$nblines+=substr_count($line_dec,'\n');
+				}
+			}
+		}
+	}
 	return $nblines;
 }
 
@@ -2976,24 +2976,24 @@ function dol_sort_array($array, $index, $order='asc', $natsort, $case_sensitive)
  * 	\return true is empty or non-existing, false if it contains files
  */
 function is_emtpy_folder($folder){
-   if(is_dir($folder) ){
-       $handle = opendir($folder);
-       while( (gettype( $name = readdir($handle)) != "boolean")){
-               $name_array[] = $name;
-       }
-       foreach($name_array as $temp)
-           $folder_content .= $temp;
-
-       if($folder_content == "...")
-           return true;
-       else
-           return false;
-       
-       closedir($handle);
-   }
-   else
-       return true; // Le r�pertoire n'existe pas
-} 
+	if(is_dir($folder) ){
+		$handle = opendir($folder);
+		while( (gettype( $name = readdir($handle)) != "boolean")){
+			$name_array[] = $name;
+		}
+		foreach($name_array as $temp)
+		$folder_content .= $temp;
+
+		if($folder_content == "...")
+		return true;
+		else
+		return false;
+		 
+		closedir($handle);
+	}
+	else
+	return true; // Le r�pertoire n'existe pas
+}
 
 /**
  * 	\brief	Return an html table from an array
@@ -3026,4 +3026,30 @@ function array2tr($data,$troptions='',$tdoptions=''){
 	$text.= '</tr>' ;
 	return $text ;
 }
+
+
+/**
+ *      \brief      Check if a string is in UTF8
+ *      \param      $Str        String to check
+ * 		\return		boolean		True if string is UTF8, false if not
+ */
+function utf8_check($Str)
+{
+	for ($i=0; $i<strlen($Str); $i++)
+	{
+		if (ord($Str[$i]) < 0x80) continue; # 0bbbbbbb
+		elseif ((ord($Str[$i]) & 0xE0) == 0xC0) $n=1; # 110bbbbb
+		elseif ((ord($Str[$i]) & 0xF0) == 0xE0) $n=2; # 1110bbbb
+		elseif ((ord($Str[$i]) & 0xF8) == 0xF0) $n=3; # 11110bbb
+		elseif ((ord($Str[$i]) & 0xFC) == 0xF8) $n=4; # 111110bb
+		elseif ((ord($Str[$i]) & 0xFE) == 0xFC) $n=5; # 1111110b
+		else return false; # Does not match any model
+		for ($j=0; $j<$n; $j++) { # n bytes matching 10bbbbbb follow ?
+			if ((++$i == strlen($Str)) || ((ord($Str[$i]) & 0xC0) != 0x80))
+			return false;
+		}
+	}
+	return true;
+}
+
 ?>
\ No newline at end of file
diff --git a/htdocs/master.inc.php b/htdocs/master.inc.php
index 8aac07c3ed6..c53508a4af2 100644
--- a/htdocs/master.inc.php
+++ b/htdocs/master.inc.php
@@ -139,9 +139,10 @@ $conf->db->dolibarr_main_db_collation=$dolibarr_main_db_collation;
 $conf->main_authentication = $dolibarr_main_authentication;
 // Force https
 $conf->main_force_https = $dolibarr_main_force_https;
-// Identifiant propre au client
-if (empty($character_set_client)) $character_set_client='ISO-8859-1';
-$conf->character_set_client=$character_set_client;
+// Define charset for HTML Output
+$charset='ISO-8859-1';	// If not output format found in any conf file
+if (empty($character_set_client)) $character_set_client=$charset;
+$conf->character_set_client=strtoupper($character_set_client);
 
 // Defini prefix
 if (isset($_SERVER["LLX_DBNAME"])) $dolibarr_main_db_prefix=$_SERVER["LLX_DBNAME"];
diff --git a/htdocs/translate.class.php b/htdocs/translate.class.php
index b27e400e3ad..2cba1587549 100644
--- a/htdocs/translate.class.php
+++ b/htdocs/translate.class.php
@@ -20,7 +20,7 @@
 
 /**
  *   	\file       htdocs/translate.class.php
- *		\brief      File for tanslation class
+ *		\brief      File for Tanslate class
  *		\author	    Eric Seigne
  *		\author	    Laurent Destailleur
  *		\version    $Id$
@@ -43,8 +43,8 @@ class Translate {
 	
     var $cache_labels=array();		// Cache for labels
 	
-    var $charset_inputfile='ISO-8859-1';	// Codage du contenu du fichier langue
-	var $charset_output='UTF-8';		// Codage par defaut de la sortie de la methode trans
+    var $charset_inputfile='ISO-8859-1';	// Codage used to encode lang files (used if CHARSET not found in file)
+	var $charset_output='UTF-8';			// Codage used by defaut for "trans" method output if $conf->character_set_client not defined (character_set_client in conf.php)
 	
 
     /**
@@ -54,13 +54,12 @@ class Translate {
      */
     function Translate($dir = "",$conf)
     {
-		// Si charset output defini
-		if (isset($conf->character_set_client) && $conf->character_set_client) 
+		// If charset output is forced
+		if (! empty($conf->character_set_client)) 
 		{
 			$this->charset_output=$conf->character_set_client;
 		}
 		$this->dir=(! $dir ? DOL_DOCUMENT_ROOT ."/langs" : $dir);
-		
 		// For developpement purpose
 		$this->dir_bis=(defined('DOL_DOCUMENT_ROOT_BIS') ? DOL_DOCUMENT_ROOT_BIS ."/langs" : "");
     }
@@ -484,17 +483,23 @@ class Translate {
 
    /**
      *  \brief      Renvoi le fichier $filename dans la version de la langue courante, sinon alternative
-     *  \param      filename        nom du fichier � rechercher
+     *  \param      filename        nom du fichier a rechercher
      *  \param      searchalt       cherche aussi dans langue alternative
 	 *	\return		boolean
      */
     function print_file($filename,$searchalt=0)
     {
+    	global $conf;
+    	
         // Test si fichier dans repertoire de la langue
         $htmlfile=$this->dir."/".$this->defaultlang."/".$filename;
         if (is_readable($htmlfile))
         {
-            include $htmlfile;
+            $content=file_get_contents($htmlfile);
+            $isutf8=utf8_check($content);
+	        if (! $isutf8 && $conf->character_set_client == 'UTF-8') print utf8_encode($content); 
+	        elseif ($isutf8 && $conf->character_set_client == 'ISO-8859-1') print utf8_decode($content); 
+	        else print $content;
             return true;
         }
 
@@ -504,8 +509,12 @@ class Translate {
             else $htmlfilealt = $this->dir."/fr_FR/".$filename;
             if (is_readable($htmlfilealt))
             {
-                include $htmlfilealt;
-                return true;
+	            $content=file_get_contents($htmlfile);
+            	$isutf8=utf8_check($content);
+	            if (! $isutf8 && $conf->character_set_client == 'UTF-8') print utf8_encode($content); 
+	            elseif ($isutf8 && $conf->character_set_client == 'ISO-8859-1') print utf8_decode($content); 
+	            else print $content;
+	            return true;
             }
         }
         
-- 
GitLab