diff --git a/htdocs/core/class/translate.class.php b/htdocs/core/class/translate.class.php
index e6c36e61e51..cef98ab273d 100644
--- a/htdocs/core/class/translate.class.php
+++ b/htdocs/core/class/translate.class.php
@@ -871,8 +871,6 @@ class Translate
public function get_available_languages($langdir = DOL_DOCUMENT_ROOT, $maxlength = 0, $usecode = 0, $mainlangonly = 0)
{
// phpcs:enable
- global $conf;
-
$this->load("languages");
// We scan directory langs to detect available languages
diff --git a/htdocs/core/lib/functions2.lib.php b/htdocs/core/lib/functions2.lib.php
index a21389385a7..aeb6086e29c 100644
--- a/htdocs/core/lib/functions2.lib.php
+++ b/htdocs/core/lib/functions2.lib.php
@@ -3075,3 +3075,53 @@ function removeEmoji($text, $allowedemoji = 1)
return $text;
}
+
+
+/**
+ * Clean a cell to respect rules of CSV file cells
+ *
+ * @param string $newvalue String to clean
+ * @param string $charset Input AND Output character set
+ * @param string $separator CSV char separator (often ',' or ';'). Default '' will use the value into EXPORT_CSV_SEPARATOR_TO_USE.
+ * @return string Value cleaned
+ */
+function csvClean($newvalue, $charset, $separator = '')
+{
+ $addquote = 0;
+
+ if (empty($separator)) {
+ $separator = getDolGlobalString('EXPORT_CSV_SEPARATOR_TO_USE');
+ }
+
+ // Rule Dolibarr: No HTML
+ //print $charset.' '.$newvalue."\n";
+ //$newvalue=dol_string_nohtmltag($newvalue,0,$charset);
+ $newvalue = dol_htmlcleanlastbr($newvalue);
+ //print $charset.' '.$newvalue."\n";
+
+ // Rule 1 CSV: No CR, LF in cells (except if USE_STRICT_CSV_RULES is 1, we can keep record as it is but we must add quotes)
+ $oldvalue = $newvalue;
+ $newvalue = str_replace("\r", '', $newvalue);
+ $newvalue = str_replace("\n", '\n', $newvalue);
+ if (getDolGlobalString('USE_STRICT_CSV_RULES') && $oldvalue != $newvalue) {
+ // If we must use enclusure on text with CR/LF)
+ if (getDolGlobalInt('USE_STRICT_CSV_RULES') == 1) {
+ // If we use strict CSV rules (original value must remain but we add quote)
+ $newvalue = $oldvalue;
+ }
+ $addquote = 1;
+ }
+
+ // Rule 2 CSV: If value contains ", we must escape with ", and add "
+ if (preg_match('/"/', $newvalue)) {
+ $addquote = 1;
+ $newvalue = str_replace('"', '""', $newvalue);
+ }
+
+ // Rule 3 CSV: If value contains separator, we must add "
+ if (preg_match('/'.$separator.'/', $newvalue)) {
+ $addquote = 1;
+ }
+
+ return ($addquote ? '"' : '').$newvalue.($addquote ? '"' : '');
+}
diff --git a/htdocs/core/modules/export/exportcsv.class.php b/htdocs/core/modules/export/exportcsv.class.php
index 4be654b38eb..91b7f63a161 100644
--- a/htdocs/core/modules/export/exportcsv.class.php
+++ b/htdocs/core/modules/export/exportcsv.class.php
@@ -209,7 +209,10 @@ class ExportCsv extends ModeleExports
}
$newvalue = $outputlangs->transnoentities($array_export_fields_label[$code]); // newvalue is now $outputlangs->charset_output encoded
- $newvalue = $this->csvClean($newvalue, $outputlangs->charset_output);
+
+ // Clean data and add encloser if required (depending on value of USE_STRICT_CSV_RULES)
+ include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
+ $newvalue = csvClean($newvalue, $outputlangs->charset_output, $this->separator);
fwrite($this->handle, $newvalue.$this->separator);
$typefield = isset($array_types[$code]) ? $array_types[$code] : '';
@@ -267,7 +270,8 @@ class ExportCsv extends ModeleExports
}
// Clean data and add encloser if required (depending on value of USE_STRICT_CSV_RULES)
- $newvalue = $this->csvClean($newvalue, $outputlangs->charset_output);
+ include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
+ $newvalue = csvClean($newvalue, $outputlangs->charset_output, $this->separator);
if (preg_match('/^Select:/i', $typefield) && $typefield = substr($typefield, 7)) {
$array = jsonOrUnserialize($typefield);
@@ -316,51 +320,4 @@ class ExportCsv extends ModeleExports
fclose($this->handle);
return 0;
}
-
-
- /**
- * Clean a cell to respect rules of CSV file cells
- * Note: It uses $this->separator
- * Note: We keep this function public to be able to test
- *
- * @param string $newvalue String to clean
- * @param string $charset Input AND Output character set
- * @return string Value cleaned
- */
- public function csvClean($newvalue, $charset)
- {
- $addquote = 0;
-
- // Rule Dolibarr: No HTML
- //print $charset.' '.$newvalue."\n";
- //$newvalue=dol_string_nohtmltag($newvalue,0,$charset);
- $newvalue = dol_htmlcleanlastbr($newvalue);
- //print $charset.' '.$newvalue."\n";
-
- // Rule 1 CSV: No CR, LF in cells (except if USE_STRICT_CSV_RULES is 1, we can keep record as it is but we must add quotes)
- $oldvalue = $newvalue;
- $newvalue = str_replace("\r", '', $newvalue);
- $newvalue = str_replace("\n", '\n', $newvalue);
- if (getDolGlobalString('USE_STRICT_CSV_RULES') && $oldvalue != $newvalue) {
- // If we must use enclusure on text with CR/LF)
- if (getDolGlobalInt('USE_STRICT_CSV_RULES') == 1) {
- // If we use strict CSV rules (original value must remain but we add quote)
- $newvalue = $oldvalue;
- }
- $addquote = 1;
- }
-
- // Rule 2 CSV: If value contains ", we must escape with ", and add "
- if (preg_match('/"/', $newvalue)) {
- $addquote = 1;
- $newvalue = str_replace('"', '""', $newvalue);
- }
-
- // Rule 3 CSV: If value contains separator, we must add "
- if (preg_match('/'.$this->separator.'/', $newvalue)) {
- $addquote = 1;
- }
-
- return ($addquote ? '"' : '').$newvalue.($addquote ? '"' : '');
- }
}
diff --git a/test/phpunit/ExportTest.php b/test/phpunit/ExportTest.php
index 4364eb8bb28..89d23a431ae 100644
--- a/test/phpunit/ExportTest.php
+++ b/test/phpunit/ExportTest.php
@@ -30,6 +30,7 @@ global $conf,$user,$langs,$db;
require_once dirname(__FILE__).'/../../htdocs/master.inc.php';
require_once dirname(__FILE__).'/../../htdocs/exports/class/export.class.php';
require_once dirname(__FILE__).'/../../htdocs/core/lib/files.lib.php';
+require_once dirname(__FILE__).'/../../htdocs/core/lib/functions2.lib.php';
require_once dirname(__FILE__).'/CommonClassTest.class.php';
if (! defined('NOREQUIREUSER')) {
@@ -99,31 +100,31 @@ class ExportTest extends CommonClassTest
$valtotest = 'A simple string';
print __METHOD__." valtotest=".$valtotest."\n";
- $result = $objmodel->csvClean($valtotest, $langs->charset_output);
+ $result = csvClean($valtotest, $langs->charset_output);
print __METHOD__." result=".$result."\n";
$this->assertEquals($result, 'A simple string');
$valtotest = 'A string with , and ; inside';
print __METHOD__." valtotest=".$valtotest."\n";
- $result = $objmodel->csvClean($valtotest, $langs->charset_output);
+ $result = csvClean($valtotest, $langs->charset_output);
print __METHOD__." result=".$result."\n";
$this->assertEquals($result, '"A string with , and ; inside"', 'Error in csvClean for '.$file);
$valtotest = 'A string with " inside';
print __METHOD__." valtotest=".$valtotest."\n";
- $result = $objmodel->csvClean($valtotest, $langs->charset_output);
+ $result = csvClean($valtotest, $langs->charset_output);
print __METHOD__." result=".$result."\n";
$this->assertEquals($result, '"A string with "" inside"');
$valtotest = 'A string with " inside and '."\r\n".' carriage returns';
print __METHOD__." valtotest=".$valtotest."\n";
- $result = $objmodel->csvClean($valtotest, $langs->charset_output);
+ $result = csvClean($valtotest, $langs->charset_output);
print __METHOD__." result=".$result."\n";
$this->assertEquals($result, '"A string with "" inside and \n carriage returns"');
$valtotest = 'A string with html
content inside
'."\n";
print __METHOD__." valtotest=".$valtotest."\n";
- $result = $objmodel->csvClean($valtotest, $langs->charset_output);
+ $result = csvClean($valtotest, $langs->charset_output);
print __METHOD__." result=".$result."\n";
$this->assertEquals($result, '"A string with html
content inside"');
@@ -132,31 +133,31 @@ class ExportTest extends CommonClassTest
$valtotest = 'A simple string';
print __METHOD__." valtotest=".$valtotest."\n";
- $result = $objmodel->csvClean($valtotest, $langs->charset_output);
+ $result = csvClean($valtotest, $langs->charset_output);
print __METHOD__." result=".$result."\n";
$this->assertEquals($result, 'A simple string');
$valtotest = 'A string with , and ; inside';
print __METHOD__." valtotest=".$valtotest."\n";
- $result = $objmodel->csvClean($valtotest, $langs->charset_output);
+ $result = csvClean($valtotest, $langs->charset_output);
print __METHOD__." result=".$result."\n";
$this->assertEquals($result, '"A string with , and ; inside"');
$valtotest = 'A string with " inside';
print __METHOD__." valtotest=".$valtotest."\n";
- $result = $objmodel->csvClean($valtotest, $langs->charset_output);
+ $result = csvClean($valtotest, $langs->charset_output);
print __METHOD__." result=".$result."\n";
$this->assertEquals($result, '"A string with "" inside"');
$valtotest = 'A string with " inside and '."\r\n".' carriage returns';
print __METHOD__." valtotest=".$valtotest."\n";
- $result = $objmodel->csvClean($valtotest, $langs->charset_output);
+ $result = csvClean($valtotest, $langs->charset_output);
print __METHOD__." result=".$result."\n";
$this->assertEquals($result, "\"A string with \"\" inside and \r\n carriage returns\"");
$valtotest = 'A string with html
content inside
'."\n";
print __METHOD__." valtotest=".$valtotest."\n";
- $result = $objmodel->csvClean($valtotest, $langs->charset_output);
+ $result = csvClean($valtotest, $langs->charset_output);
print __METHOD__." result=".$result."\n";
$this->assertEquals($result, '"A string with html
content inside"');
}
@@ -188,31 +189,31 @@ class ExportTest extends CommonClassTest
$valtotest = 'A simple string';
print __METHOD__." valtotest=".$valtotest."\n";
- $result = $objmodel->csvClean($valtotest, $langs->charset_output);
+ $result = csvClean($valtotest, $langs->charset_output);
print __METHOD__." result=".$result."\n";
$this->assertEquals($result, 'A simple string');
$valtotest = 'A string with , and ; inside';
print __METHOD__." valtotest=".$valtotest."\n";
- $result = $objmodel->csvClean($valtotest, $langs->charset_output);
+ $result = csvClean($valtotest, $langs->charset_output);
print __METHOD__." result=".$result."\n";
$this->assertEquals($result, '"A string with , and ; inside"', 'Error in csvClean for '.$file);
$valtotest = 'A string with " inside';
print __METHOD__." valtotest=".$valtotest."\n";
- $result = $objmodel->csvClean($valtotest, $langs->charset_output);
+ $result = csvClean($valtotest, $langs->charset_output);
print __METHOD__." result=".$result."\n";
$this->assertEquals($result, '"A string with "" inside"');
$valtotest = 'A string with " inside and '."\r\n".' carriage returns';
print __METHOD__." valtotest=".$valtotest."\n";
- $result = $objmodel->csvClean($valtotest, $langs->charset_output);
+ $result = csvClean($valtotest, $langs->charset_output);
print __METHOD__." result=".$result."\n";
$this->assertEquals($result, '"A string with "" inside and \n carriage returns"');
$valtotest = 'A string with html
content inside
'."\n";
print __METHOD__." valtotest=".$valtotest."\n";
- $result = $objmodel->csvClean($valtotest, $langs->charset_output);
+ $result = csvClean($valtotest, $langs->charset_output);
print __METHOD__." result=".$result."\n";
$this->assertEquals($result, '"A string with html
content inside"');
@@ -221,31 +222,31 @@ class ExportTest extends CommonClassTest
$valtotest = 'A simple string';
print __METHOD__." valtotest=".$valtotest."\n";
- $result = $objmodel->csvClean($valtotest, $langs->charset_output);
+ $result = csvClean($valtotest, $langs->charset_output);
print __METHOD__." result=".$result."\n";
$this->assertEquals($result, 'A simple string');
$valtotest = 'A string with , and ; inside';
print __METHOD__." valtotest=".$valtotest."\n";
- $result = $objmodel->csvClean($valtotest, $langs->charset_output);
+ $result = csvClean($valtotest, $langs->charset_output);
print __METHOD__." result=".$result."\n";
$this->assertEquals($result, '"A string with , and ; inside"');
$valtotest = 'A string with " inside';
print __METHOD__." valtotest=".$valtotest."\n";
- $result = $objmodel->csvClean($valtotest, $langs->charset_output);
+ $result = csvClean($valtotest, $langs->charset_output);
print __METHOD__." result=".$result."\n";
$this->assertEquals($result, '"A string with "" inside"');
$valtotest = 'A string with " inside and '."\r\n".' carriage returns';
print __METHOD__." valtotest=".$valtotest."\n";
- $result = $objmodel->csvClean($valtotest, $langs->charset_output);
+ $result = csvClean($valtotest, $langs->charset_output);
print __METHOD__." result=".$result."\n";
$this->assertEquals($result, "\"A string with \"\" inside and \r\n carriage returns\"");
$valtotest = 'A string with html
content inside
'."\n";
print __METHOD__." valtotest=".$valtotest."\n";
- $result = $objmodel->csvClean($valtotest, $langs->charset_output);
+ $result = csvClean($valtotest, $langs->charset_output);
print __METHOD__." result=".$result."\n";
$this->assertEquals($result, '"A string with html
content inside"');
}