Completed
Push — task/csv-delimiters ( e13308 )
by Oliver
01:46
created

SimpleGenerator::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 5
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 2
1
<?php
2
declare(strict_types=1);
3
4
namespace MarcusJaschen\Collmex\Csv;
5
6
/**
7
 * CSV Generator Class.
8
 *
9
 * @author   Marcus Jaschen <[email protected]>
10
 */
11
class SimpleGenerator implements GeneratorInterface
12
{
13
    /**
14
     * @var string
15
     */
16
    private const DELIMITER = ';';
17
18
    /**
19
     * @var string
20
     */
21
    private const ENCLOSURE = '"';
22
23
    /**
24
     * Generates a CSV string from given array data.
25
     *
26
     * @param array $data
27
     *
28
     * @return string
29
     *
30
     * @throws \RuntimeException
31
     */
32
    public function generate(array $data): string
33
    {
34
        $fileHandle = fopen('php://temp', 'w');
35
36
        if (!$fileHandle) {
37
            throw new \RuntimeException('Cannot open temp file handle (php://temp)');
38
        }
39
40
        if (!is_array($data[0])) {
41
            $data = [$data];
42
        }
43
44
        $tmpPlaceholder = 'MJASCHEN_COLLMEX_WORKAROUND_PHP_BUG_43225_' . time();
45
        foreach ($data as $line) {
46
            // workaround for PHP bug 43225: temporarily insert a placeholder
47
            // between a backslash directly followed by a double-quote (for
48
            // string field values only)
49
            array_walk(
50
                $line,
51
                function (&$item) use ($tmpPlaceholder): void {
52
                    if (!is_string($item)) {
53
                        return;
54
                    }
55
                    $item = preg_replace('/(\\\\+)"/m', '$1' . $tmpPlaceholder . '"', $item);
56
                }
57
            );
58
59
            fputcsv($fileHandle, $line, self::DELIMITER, self::ENCLOSURE);
60
        }
61
62
        rewind($fileHandle);
63
        $csv = stream_get_contents($fileHandle);
64
        fclose($fileHandle);
65
66
        // remove the temporary placeholder from the final CSV string
67
        $csv = str_replace($tmpPlaceholder, '', $csv);
68
69
        return $csv;
70
    }
71
}
72