Completed
Push — master ( 01a024...a47183 )
by Marcus
02:07
created

SimpleGenerator::generate()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 36
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

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