Passed
Push — master ( 5d8af1...e44bd6 )
by Petr
09:24
created

Csv::pack()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 7
c 0
b 0
f 0
nc 2
nop 1
dl 0
loc 10
ccs 8
cts 8
cp 1
crap 2
rs 10
1
<?php
2
3
namespace kalanis\kw_mapper\Storage\Shared\FormatFiles;
4
5
6
use kalanis\kw_mapper\Interfaces\IFileFormat;
7
8
9
/**
10
 * Class Csv
11
 * @package kalanis\kw_mapper\Storage\Shared\FormatFiles
12
 * Store it in CSV table
13
 */
14
class Csv implements IFileFormat
15
{
16
    use TNl;
17
18
    protected string $delimitLines = PHP_EOL;
19
20 1
    public function setDelimiters(string $lines = PHP_EOL): self
21
    {
22 1
        $this->delimitLines = $lines;
23 1
        return $this;
24
    }
25
26 1
    public function unpack(string $content): array
27
    {
28 1
        $lines = str_getcsv($content, $this->delimitLines); //parse the rows
29 1
        $records = [];
30 1
        foreach ($lines as &$line) {
31 1
            if (empty($line)) {
32 1
                continue;
33
            }
34
35 1
            $records[] = array_map([$this, 'unescapeNl'], str_getcsv($line));
36
        }
37 1
        return $records;
38
    }
39
40 1
    public function pack(array $records): string
41
    {
42 1
        $lines = [];
43 1
        foreach ($records as &$record) {
44 1
            $record = (array) $record;
45 1
            ksort($record);
46 1
            $record[] = ''; // separator on end
47 1
            $lines[] = $this->str_putcsv(array_map([$this, 'escapeNl'], $record));
48
        }
49 1
        return implode($this->delimitLines, $lines);
50
    }
51
52
    /**
53
     * @param array<string|int, string|int|float|array<string|int, string|int>> $array
54
     * @param string $delimiter
55
     * @param string $enclosure
56
     * @param string $terminator
57
     * @return string
58
     * @link https://www.php.net/manual/en/function.str-getcsv.php#88353
59
     * @codeCoverageIgnore better try it live
60
     */
61
    protected function str_putcsv($array, $delimiter = ',', $enclosure = '"', $terminator = "\n") {
62
        # First convert associative array to numeric indexed array
63
        $workArray = [];
64
        foreach ($array as $key => $value) {
65
            $workArray[] = $value;
66
        }
67
68
        $returnString = '';                 # Initialize return string
69
        $arraySize = count($workArray);     # Get size of array
70
71
        for ($i=0; $i<$arraySize; $i++) {
72
            # Nested array, process nest item
73
            if (is_array($workArray[$i])) {
74
                $returnString .= $this->str_putcsv($workArray[$i], $delimiter, $enclosure, $terminator);
75
            } else {
76
                switch (gettype($workArray[$i])) {
77
                    # Manually set some strings
78
                    case "NULL":     $_spFormat = ''; break;
79
                    case "boolean":  $_spFormat = (true == $workArray[$i]) ? 'true': 'false'; break;
80
                    # Make sure sprintf has a good datatype to work with
81
                    case "integer":  $_spFormat = '%i'; break;
82
                    case "double":   $_spFormat = '%0.2f'; break;
83
                    case "string":   $_spFormat = '%s'; break;
84
                    # Unknown or invalid items for a csv - note: the datatype of array is already handled above, assuming the data is nested
85
                    case "object":
86
                    case "resource":
87
                    default:         $_spFormat = ''; break;
88
                }
89
                $returnString .= sprintf('%2$s'.$_spFormat.'%2$s', $workArray[$i], $enclosure);
90
                $returnString .= ($i < ($arraySize-1)) ? $delimiter : $terminator;
91
            }
92
        }
93
        # Done the workload, return the output information
94
        return $returnString;
95
    }
96
97
}
98