QUAL Move function csvClean into functions2.lib.php

This commit is contained in:
Laurent Destailleur 2024-10-03 21:36:39 +02:00
parent 5203d99c2f
commit e09d9df3ee
4 changed files with 77 additions and 71 deletions

View File

@ -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

View File

@ -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 ? '"' : '');
}

View File

@ -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 ? '"' : '');
}
}

View File

@ -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 <a href="aaa"><strong>html<br>content</strong></a> inside<br>'."\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 <a href=""aaa""><strong>html<br>content</strong></a> 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 <a href="aaa"><strong>html<br>content</strong></a> inside<br>'."\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 <a href=""aaa""><strong>html<br>content</strong></a> 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 <a href="aaa"><strong>html<br>content</strong></a> inside<br>'."\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 <a href=""aaa""><strong>html<br>content</strong></a> 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 <a href="aaa"><strong>html<br>content</strong></a> inside<br>'."\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 <a href=""aaa""><strong>html<br>content</strong></a> inside"');
}