FIX #39113 CSV export: decode HTML entities in header labels (#39151)

Extrafield labels are stored HTML encoded in llx_extrafields.label
because they are saved through Translate::trans(), which runs the
string through htmlentities(). write_title() wrote the label as-is,
so the CSV header line showed raw entities (Données instead of
Données) while the data cells were fine. With a ; separator the
trailing ; of each entity also wrapped the label in double quotes.

Decode entities and remove HTML with dol_string_nohtmltag() before
csvClean(), consistent with the TSV and Excel export drivers. For the
derived _label column of Select extrafields, append the suffix before
csvClean() so the column stays valid CSV when the decoded label
contains the separator or a quote.

Signed-off-by: Gregory Aliot <greg.aliot@gmail.com>
Co-authored-by: Gregory Aliot <greg.aliot@gmail.com>
This commit is contained in:
Grégory Aliot 2026-07-15 00:44:37 +02:00 committed by GitHub
parent fe1386fa2d
commit 61899bb8cd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -210,6 +210,11 @@ class ExportCsv extends ModeleExports
$newvalue = $array_export_fields_label[$code];
// Label may be stored HTML encoded (for example extrafield labels saved through Translate::trans()),
// so decode entities and remove HTML to keep the header consistent with the data cells.
$newvalue = dol_string_nohtmltag($newvalue);
$decodedlabel = $newvalue;
// 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);
@ -218,7 +223,9 @@ class ExportCsv extends ModeleExports
$typefield = isset($array_types[$code]) ? $array_types[$code] : '';
if (preg_match('/^Select:/i', $typefield) && $typefield = substr($typefield, 7)) {
$selectlabel[$code."_label"] = $newvalue."_label";
// Append the "_label" suffix before cleaning so the derived column stays valid CSV
// even when the decoded label contains the separator or a quote.
$selectlabel[$code."_label"] = csvClean($decodedlabel."_label", $outputlangs->charset_output, $this->separator);
}
}