Passed
Push — master ( 8d04f1...688970 )
by Lito
03:43
created

Csv::open()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 0
dl 0
loc 8
ccs 0
cts 4
cp 0
crap 2
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace Anavel\Crud\Services\Export;
4
5
class Csv
6
{
7
    private $fp;
8
    private $headers = [];
9
    private $csv = '';
10
11
    public function fromArray(array $data)
12
    {
13
        if (empty($data)) {
14
            return '';
15
        }
16
17
        $this->open();
18
19
        foreach ($data as $line) {
20
            $this->headers($line);
21
        }
22
23
        $this->write($this->headers);
24
25
        $fill = array_fill_keys($this->headers, '');
26
27
        foreach ($data as $line) {
28
            $this->write(array_merge($fill, $this->line($line)));
29
        }
30
31
        $this->close();
32
33
        return $this;
34
    }
35
36
    public function __toString()
37
    {
38
        return $this->csv;
39
    }
40
41
    private function open()
42
    {
43
        // Use memory as file
44
        $this->fp = fopen('php://memory', 'w');
45
46
        // Add BOM to fix UTF-8 in Excel
47
        fwrite($this->fp, chr(0xEF).chr(0xBB).chr(0xBF));
48
    }
49
50
    private function write(array $data)
51
    {
52
        fputcsv($this->fp, $data);
53
    }
54
55
    private function close()
56
    {
57
        rewind($this->fp);
58
59
        $this->csv = stream_get_contents($this->fp);
60
61
        fclose($this->fp);
62
    }
63
64
    private function headers(array $data, $prefix = null)
65
    {
66
        $prefix = $prefix ? ($prefix.'.') : '';
67
68
        foreach ($data as $key => $value) {
69
            $key = $prefix.$key;
70
71
            if ($this->existsHeader($key)) {
72
                continue;
73
            }
74
75
            $isArray = is_array($value);
76
77
            if ($isArray && array_key_exists(0, $value)) {
78
                continue;
79
            }
80
81
            if ($isArray) {
82
                $this->headers($value, $key);
83
            } elseif ($this->isValidHeader($key)) {
84
                $this->headers[] = $key;
85
            }
86
        }
87
    }
88
89
    private function line(array $line, $prefix = null)
90
    {
91
        $data = [];
92
        $prefix = $prefix ? ($prefix.'.') : '';
93
94
        foreach ($line as $key => $value) {
95
            $key = $prefix.$key;
96
            $isArray = is_array($value);
97
98
            if ($isArray && array_key_exists(0, $value)) {
99
                continue;
100
            }
101
102
            if ($isArray) {
103
                $data = array_merge($data, $this->line($value, $key));
104
            } elseif ($this->existsHeader($key)) {
105
                $data[$key] = trim(str_replace(["\n", "\r"], '', $value));
106
            }
107
        }
108
109
        return $data;
110
    }
111
112
    private function isValidHeader($key)
113
    {
114
        return preg_match('/_id$/', $key) === 0;
115
    }
116
117
    private function existsHeader($key)
118
    {
119
        return in_array($key, $this->headers, true);
120
    }
121
}
122