Skip to content

Commit 03defa6

Browse files
Merge pull request #82 from lkssmnt/csv-linebreaks-fix
fix: correct textarea linebreaks in csv files
2 parents d17d764 + ea12bb6 commit 03defa6

File tree

1 file changed

+47
-6
lines changed

1 file changed

+47
-6
lines changed

classes/Request.php

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -370,28 +370,69 @@ private function downloadLink($form_id, $title) {
370370
], '/') . '.csv';
371371
}
372372

373+
/**
374+
* Create a CSV line with proper escaping for delimiters and newlines
375+
*/
376+
private function csvLine(array $columns): string
377+
{
378+
$normalized = array_map(static function ($value) {
379+
if ($value === null) {
380+
$value = '';
381+
} elseif (is_bool($value)) {
382+
$value = $value ? '1' : '0';
383+
} elseif (is_array($value)) {
384+
$value = json_encode($value, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
385+
} elseif (is_object($value)) {
386+
if (method_exists($value, 'value')) {
387+
$value = $value->value();
388+
} elseif (method_exists($value, '__toString')) {
389+
$value = (string) $value;
390+
} else {
391+
$value = json_encode($value, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
392+
}
393+
}
394+
395+
$string = (string) $value;
396+
397+
return str_replace(["\r\n", "\r"], "\n", $string);
398+
}, $columns);
399+
400+
$stream = fopen('php://temp', 'r+');
401+
fputcsv($stream, $normalized, ';');
402+
rewind($stream);
403+
$line = rtrim(stream_get_contents($stream), "\r\n");
404+
fclose($stream);
405+
406+
return $line;
407+
}
408+
373409
public function download()
374410
{
375411

376412
$output = null;
377413

378-
function parseField($field) {
414+
$parseField = static function ($field) {
379415
$array = json_decode($field->value(), true);
380416
unset($array['summary']);
381417
return array_values($array);
382-
}
418+
};
383419

384420
foreach ($this->container->drafts()->sortBy('received', 'desc') as $b) {
385421

386422
$content = $b->content();
387423
$received = $content->received()->toValue();
388424
$id = $content->slug();
389425

390-
$output ??= A::join(['ID', ...parseField($content->formfields()), 'Received'], ';') . "\n";
391-
$output .= A::join([$id, ...parseField($content->formdata()), $received], ';') . "\n";
392-
426+
if ($output === null) {
427+
$header = array_merge(['ID'], $parseField($content->formfields()), ['Received']);
428+
$output = $this->csvLine($header) . "\n";
429+
}
430+
431+
$row = array_merge([$id], $parseField($content->formdata()), [$received]);
432+
$output .= $this->csvLine($row) . "\n";
433+
393434
}
394-
435+
395436
return $output;
396437
}
397438

0 commit comments

Comments
 (0)