Passed
Push — master ( a0f654...53c07a )
by Fabrice
02:26
created

CsvExtractor::getTraversable()   B

Complexity

Conditions 5
Paths 6

Size

Total Lines 21
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 9
nc 6
nop 1
dl 0
loc 21
rs 8.7624
c 0
b 0
f 0
1
<?php
2
3
/*
4
 * This file is part of YaEtl.
5
 *     (c) Fabrice de Stefanis / https://github.com/fab2s/YaEtl
6
 * This source file is licensed under the MIT license which you will
7
 * find in the LICENSE file or at https://opensource.org/licenses/MIT
8
 */
9
10
namespace fab2s\YaEtl\Loaders\File;
11
12
use fab2s\NodalFlow\NodalFlowException;
13
use fab2s\NodalFlow\YaEtlException;
14
use fab2s\YaEtl\Extractors\File\FileExtractorAbstract;
15
use fab2s\YaEtl\Traits\CsvHandlerTrait;
16
17
/**
18
 * Class CsvExtractor
19
 */
20
class CsvExtractor extends FileExtractorAbstract
21
{
22
    use CsvHandlerTrait;
23
24
    /**
25
     * CsvExtractor constructor
26
     *
27
     * @param resource|string $input
28
     * @param string|null     $delimiter
29
     * @param string|null     $enclosure
30
     * @param string|null     $escape
31
     *
32
     * @throws NodalFlowException
33
     * @throws YaEtlException
34
     */
35
    public function __construct($input, $delimiter = null, $enclosure = null, $escape = null)
36
    {
37
        parent::__construct($input);
38
        $this->initCsvOptions($delimiter, $enclosure, $escape);
39
    }
40
41
    /**
42
     * @param mixed $param
43
     *
44
     * @return \Generator
45
     */
46
    public function getTraversable($param = null)
47
    {
48
        if (!$this->extract($param)) {
49
            return;
50
        }
51
52
        if (false == ($firstLine = $this->getNextNonEmptyLine(true))) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
53
            return;
54
        }
55
56
        if (false !== ($firstRecord = $this->handleHeader($firstLine))) {
0 ignored issues
show
Bug introduced by
$firstLine of type true is incompatible with the type string expected by parameter $line of fab2s\YaEtl\Loaders\File...tractor::handleHeader(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

56
        if (false !== ($firstRecord = $this->handleHeader(/** @scrutinizer ignore-type */ $firstLine))) {
Loading history...
57
            /* @var array $firstRecord */
58
            yield $this->bakeRecord($firstRecord);
59
        }
60
61
        while (false !== ($record = fgetcsv($this->handle, 0, $this->delimiter, $this->enclosure, $this->escape))) {
62
            /* @var array $record */
63
            yield $this->bakeRecord($record);
64
        }
65
66
        $this->releaseHandle();
67
    }
68
69
    /**
70
     * @param array $record
71
     *
72
     * @return array
73
     */
74
    protected function bakeRecord(array $record)
75
    {
76
        return isset($this->header) ? array_combine($this->header, $record) : $record;
77
    }
78
79
    /**
80
     * @param string $line
81
     *
82
     * @return array|bool
83
     */
84
    protected function handleHeader($line)
85
    {
86
        // obey excel sep
87
        if (strpos($line, 'sep=') === 0) {
88
            $this->useSep    = true;
89
            $this->delimiter = $line[4];
90
            if (false === ($line = $this->getNextNonEmptyLine(false))) {
91
                return false;
92
            }
93
        }
94
95
        $record = str_getcsv($line, $this->delimiter, $this->enclosure, $this->escape);
0 ignored issues
show
Bug introduced by
$line of type true is incompatible with the type string expected by parameter $input of str_getcsv(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

95
        $record = str_getcsv(/** @scrutinizer ignore-type */ $line, $this->delimiter, $this->enclosure, $this->escape);
Loading history...
96
        if ($this->useHeader && !isset($this->header)) {
97
            $this->header = array_map('trim', $record);
98
99
            return false;
100
        }
101
102
        return $record;
103
    }
104
105
    /**
106
     * @param array $record
107
     *
108
     * @return bool|int
109
     */
110
    protected function writeCsvLine(array $record)
111
    {
112
        return fputcsv($this->handle, $record, $this->delimiter, $this->enclosure, $this->escape);
113
    }
114
}
115