Completed
Push — develop ( 901acc...d30c0f )
by Baptiste
02:13
created

CsvWriter::fill()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 13
ccs 7
cts 7
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 7
nc 1
nop 2
crap 1
1
<?php
2
declare(strict_types = 1);
3
4
namespace Spreadsheet\Writer;
5
6
use Spreadsheet\{
7
    SpreadsheetInterface,
8
    Exception\InvalidArgumentException,
9
    SheetInterface,
10
    RowInterface,
11
    CellInterface,
12
    File\Csv
13
};
14
use Innmind\Filesystem\{
15
    FileInterface,
16
    Directory,
17
    Stream\Stream
18
};
19
use Innmind\Immutable\MapInterface;
20
21
final class CsvWriter implements WriterInterface
22
{
23
    private $delimiter;
24
    private $withHeader;
25
26 5
    public function __construct(string $delimiter, bool $withHeader)
27
    {
28 5
        if (empty($delimiter)) {
29
            throw new InvalidArgumentException;
30
        }
31
32 5
        $this->delimiter = $delimiter;
33 5
        $this->withHeader = $withHeader;
34 5
    }
35
36 4
    public function write(SpreadsheetInterface $spreadsheet): FileInterface
37
    {
38
        $directory = $spreadsheet
39 4
            ->sheets()
40 4
            ->reduce(
41 4
                new Directory($spreadsheet->name()),
42
                function(Directory $carry, string $name, SheetInterface $sheet): Directory {
43 4
                    return $carry->add($this->buildFile($sheet));
44 4
                }
45
            );
46
47 4
        if ($directory->count() === 1) {
48 3
            return $directory->get(
49 3
                $spreadsheet->sheets()->values()->first()->name().'.csv'
50
            );
51
        }
52
53 1
        return $directory;
54
    }
55
56 4
    private function buildFile(SheetInterface $sheet): FileInterface
57
    {
58 4
        $csv = tmpfile();
59
        $columns = $sheet
60 4
            ->columns()
61 4
            ->keys()
62
            ->sort(function($a, $b): bool {
63 4
                return $a > $b;
64 4
            })
65 4
            ->toPrimitive();
66 4
        $default = array_fill_keys(array_values($columns), '');
67
68 4
        if ($this->withHeader) {
69 2
            fputcsv($csv, $columns, $this->delimiter);
70
        }
71
72
        $sheet
73 4
            ->rows()
74 4
            ->values()
75
            ->sort(function(RowInterface $a, RowInterface $b): bool {
76 4
                return $a->identifier() > $b->identifier();
77 4
            })
78 4
            ->reduce(
79
                $csv,
80
                function($carry, RowInterface $row) use ($default) {
81 4
                    fputcsv(
82
                        $carry,
83 4
                        $this->fill($default, $row->cells()),
84 4
                        $this->delimiter
85
                    );
86
87 4
                    return $carry;
88 4
                }
89
            );
90
91 4
        return new Csv($sheet->name(), new Stream($csv));
92
    }
93
94 4
    private function fill(array $default, MapInterface $cells): array
95
    {
96 4
        $line = $cells->reduce(
97
            $default,
98 4
            function(array $carry, $column, CellInterface $cell): array {
99 4
                $carry[$column] = (string) $cell;
100
101 4
                return $carry;
102 4
            }
103
        );
104
105 4
        return array_values($line);
106
    }
107
}
108