Completed
Push — master ( 648cdf...2a5d2e )
by Andy
05:43
created

Reader::setOffset()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
namespace Palmtree\Csv;
4
5
use Palmtree\Csv\Normalizer\NormalizerInterface;
6
use Palmtree\Csv\Normalizer\NullNormalizer;
7
use Palmtree\Csv\Row\Row;
8
use Palmtree\Csv\Util\StringUtil;
9
10
/**
11
 * Reads a CSV file by loading each line into memory
12
 * one at a time.
13
 */
14
class Reader extends AbstractCsv implements \Iterator
15
{
16
    /** @var string */
17
    protected $defaultNormalizer = NullNormalizer::class;
18
    /** @var string */
19
    protected $openMode = 'r';
20
    /** @var NormalizerInterface[] */
21
    protected $normalizers = [];
22
    /** @var Row */
23
    protected $headers;
24
    /** @var Row */
25
    protected $row;
26
    /** @var bool */
27
    protected $bom = false;
28
    /** @var int */
29
    protected $offset = 0;
30
31
    /**
32
     * @param string $file
33
     *
34
     * @return Reader
35
     */
36
    public static function read($file)
37
    {
38
        $csv = new static($file);
39
40
        return $csv;
41
    }
42
43
    /**
44
     * @return Row
45
     */
46 2
    public function getHeaders()
47
    {
48 2
        if (is_null($this->headers) && $this->hasHeaders()) {
49 2
            $this->rewind();
50
        }
51
52 2
        return $this->headers;
53
    }
54
55
    /**
56
     * @param $key
57
     *
58
     * @return mixed
59
     */
60 7
    public function getHeader($key)
61
    {
62 7
        if (!isset($this->headers[$key])) {
63 7
            return $key;
64
        }
65
66 2
        return $this->headers[$key];
67
    }
68
69
    /**
70
     * @param mixed               $key
71
     * @param NormalizerInterface $normalizer Normalizer instance.
72
     *
73
     * @return $this
74
     */
75
    public function addNormalizer($key, NormalizerInterface $normalizer)
76
    {
77
        $this->normalizers[$key] = $normalizer;
78
79
        return $this;
80
    }
81
82
    /**
83
     * @param array|\Traversable $normalizers
84
     *
85
     * @return $this
86
     */
87
    public function addNormalizers($normalizers)
88
    {
89
        foreach ($normalizers as $key => $normalizer) {
90
            $this->addNormalizer($key, $normalizer);
91
        }
92
93
        return $this;
94
    }
95
96
    /**
97
     * @param mixed $key
98
     *
99
     * @return NormalizerInterface
100
     */
101 7
    public function getNormalizer($key)
102
    {
103 7
        if (!isset($this->normalizers[$key])) {
104 7
            $class = $this->getDefaultNormalizer();
105
106 7
            $this->normalizers[$key] = new $class();
107
        }
108
109 7
        return $this->normalizers[$key];
110
    }
111
112
    /**
113
     * Reads the next line in the CSV file
114
     * and returns a Row object from it.
115
     *
116
     * @return Row|null
117
     */
118 4
    protected function getCurrentRow()
119
    {
120 4
        $cells = $this->getDocument()->current();
121
122 4
        if (!is_array($cells)) {
123 2
            return null;
124
        }
125
126 4
        if ($this->key() === 0 && $this->hasBom()) {
127 1
            $stripped = StringUtil::stripBom($cells[0], StringUtil::BOM_UTF8);
128
129 1
            if ($stripped !== $cells[0]) {
130 1
                $cells[0] = trim($stripped, $this->getEnclosure());
131
            }
132
        }
133
134 4
        $row = new Row($cells, $this);
135
136 4
        return $row;
137
    }
138
139
    /**
140
     * @inheritDoc
141
     */
142 2
    public function current()
143
    {
144 2
        return $this->row;
145
    }
146
147
    /**
148
     * @inheritDoc
149
     */
150 4
    public function next()
151
    {
152 4
        $this->getDocument()->next();
153 4
    }
154
155
    /**
156
     * @inheritDoc
157
     */
158 4
    public function key()
159
    {
160 4
        return $this->getDocument()->key();
161
    }
162
163
    /**
164
     * @inheritDoc
165
     */
166 2
    public function valid()
167
    {
168 2
        $this->row = $this->getCurrentRow();
169
170 2
        return $this->row instanceof Row;
171
    }
172
173
    /**
174
     * @inheritDoc
175
     */
176 4
    public function rewind()
177
    {
178 4
        $this->getDocument()->rewind();
179 4
        $this->getDocument()->seek($this->offset);
180
181 4
        if ($this->hasHeaders()) {
182
            // Set headers to null first so the header row is a zero-based array and can be used
183
            // to set the array keys of all other rows.
184 4
            $this->headers = null;
185 4
            $this->headers = $this->getCurrentRow();
186 4
            $this->next();
187
        }
188 4
    }
189
190
    /**
191
     * @param string $defaultNormalizer
192
     *
193
     * @return Reader
194
     */
195
    public function setDefaultNormalizer($defaultNormalizer)
196
    {
197
        $this->defaultNormalizer = $defaultNormalizer;
198
199
        return $this;
200
    }
201
202
    /**
203
     * @return string
204
     */
205 7
    public function getDefaultNormalizer()
206
    {
207 7
        return $this->defaultNormalizer;
208
    }
209
210
    /**
211
     * @param bool $bom
212
     *
213
     * @return Reader
214
     */
215 2
    public function setBom($bom)
216
    {
217 2
        $this->bom = $bom;
218
219 2
        return $this;
220
    }
221
222
    /**
223
     * @return bool
224
     */
225 3
    public function hasBom()
226
    {
227 3
        return $this->bom;
228
    }
229
230
    /**
231
     * @param int $offset
232
     */
233 1
    public function setOffset($offset)
234
    {
235 1
        $this->offset = $offset;
236 1
    }
237
238
    /**
239
     * @return int
240
     */
241
    public function getOffset()
242
    {
243
        return $this->offset;
244
    }
245
246
    /**
247
     * @return array
248
     */
249
    public function toArray()
250
    {
251
        $result = [];
252
        foreach ($this as $rowKey => $row) {
253
            $result[$rowKey] = $row->toArray();
254
        }
255
256
        return $result;
257
    }
258
}
259