Completed
Push — master ( 101310...011031 )
by Andrew
04:06
created

StringReader::read()   B

Complexity

Conditions 8
Paths 8

Size

Total Lines 42

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 21
CRAP Score 8.006

Importance

Changes 0
Metric Value
dl 0
loc 42
ccs 21
cts 22
cp 0.9545
rs 8.0035
c 0
b 0
f 0
cc 8
nc 8
nop 2
crap 8.006
1
<?php
2
3
namespace CsvParser\Reader;
4
5
class StringReader implements ReaderInterface
6
{
7 11
    public static function read(\CsvParser\Parser $parser, $string)
8
    {
9 11
        $data = array();
10
11
        // shorten some vars for use later
12 11
        $d = $parser->fieldDelimiter;
13 11
        $e = $parser->fieldEnclosure;
14 11
        $l = $parser->lineDelimiter;
15
16
        // get headings and body (if \n line feeds, also support reading on carriage returns)
17 11
        list($headings, $body) = $l=="\n" ? preg_split('/[\n\r]/', $string, 2) : explode($l, $string, 2);
18
19
        // format array of headings/keys
20 11
        $headings = str_getcsv($headings, $d, $e);
21
22
        // Split row lines
23
        // to do this we replace new lines with a key and then explode on them
24
        // regex to match new lines, but not inside quotes, based on: https://stackoverflow.com/questions/632475/regex-to-pick-commas-outside-of-quotes/25544437#25544437
25 11
        $rKey = '*%~LINE_BREAK~%*';
26 11
        $qE = preg_quote($e);
27 11
        $qL = $l=="\n" ? '\n|\r' : preg_quote($l);
28 11
        $body = preg_replace('/'.$qE.'[^'.$qE.']*'.$qE.'(*SKIP)(*F)|'.$qL.'/', $rKey, $body);
29 11
        $lines = explode($rKey, $body);
30
31
        // any lines found? loop them
32 11
        if ( ! empty($lines)) {
33 11
            foreach ($lines as $i => $line) {
34 11
                if ($line==='') {
35
                    continue; // blank line...
36
                }
37 11
                $fields = str_getcsv($line, $d, $e);
38 11
                $data[$i] = array();
39
                // loop the headings to map to columns
40 11
                foreach ($headings as $j => $heading) {
41 11
                    $field = isset($fields[$j]) ? $fields[$j] : '';
42 11
                    $data[$i][$heading] = $field;
43
                }
44
            }
45
        }
46
47 11
        return new \CsvParser\Csv($data);
48
    }
49
}
50