-
Notifications
You must be signed in to change notification settings - Fork 0
/
Loader.php
83 lines (72 loc) · 2.81 KB
/
Loader.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
<?php
declare(strict_types=1);
namespace Kiboko\Component\Flow\Spreadsheet\Sheet\Safe;
use Box\Spout\Common\Entity\Cell;
use Box\Spout\Common\Entity\Row;
use Box\Spout\Common\Exception\IOException;
use Box\Spout\Writer\Exception\WriterNotOpenedException;
use Box\Spout\Writer\WriterInterface;
use Kiboko\Component\Bucket\AcceptanceResultBucket;
use Kiboko\Component\Bucket\EmptyResultBucket;
use Kiboko\Component\Bucket\RejectionResultBucket;
use Kiboko\Contract\Bucket\ResultBucketInterface;
use Kiboko\Contract\Pipeline\FlushableInterface;
use Kiboko\Contract\Pipeline\LoaderInterface;
use Psr\Log\LoggerInterface;
use Psr\Log\NullLogger;
final readonly class Loader implements LoaderInterface, FlushableInterface
{
public function __construct(
private WriterInterface $writer,
private string $sheetName,
private LoggerInterface $logger = new NullLogger()
) {
/* @phpstan-ignore-next-line */
$this->writer->getCurrentSheet()->setName($this->sheetName);
}
public function load(): \Generator
{
$line = yield new EmptyResultBucket();
$headers = array_keys($line);
try {
$this->writer->addRow(
new Row(array_map(fn ($value) => new Cell($value), array_keys($line)), null)
);
} catch (IOException|WriterNotOpenedException $exception) {
$this->logger->error('Impossible to load data to the given CSV file.', ['line' => $line, 'message' => $exception->getMessage(), 'previous' => $exception->getPrevious()]);
$line = yield new RejectionResultBucket(
'Impossible to load data to the given CSV file.',
$exception,
$line
);
}
/* @phpstan-ignore-next-line */
while (true) {
try {
$this->writer->addRow($this->orderColumns($headers, $line));
} catch (IOException|WriterNotOpenedException $exception) {
$this->logger->error('Impossible to load data to the given CSV file.', ['line' => $line, 'message' => $exception->getMessage(), 'previous' => $exception->getPrevious()]);
$line = yield new RejectionResultBucket(
'Impossible to load data to the given CSV file.',
$exception,
$line
);
continue;
}
$line = yield new AcceptanceResultBucket($line);
}
}
private function orderColumns(array $headers, array $line): Row
{
$result = [];
foreach ($headers as $cell) {
$result[$cell] = new Cell($line[$cell] ?? null);
}
return new Row($result, null);
}
public function flush(): ResultBucketInterface
{
$this->writer->close();
return new EmptyResultBucket();
}
}