Completed
Pull Request — master (#210)
by ignace nyamagana
02:16
created

Reader::getFieldIndex()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 17
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 4

Importance

Changes 0
Metric Value
dl 0
loc 17
rs 9.2
c 0
b 0
f 0
ccs 8
cts 8
cp 1
cc 4
eloc 9
nc 4
nop 2
crap 4

1 Method

Rating   Name   Duplication   Size   Complexity  
A Reader::fetchColumn() 0 4 1
1
<?php
2
/**
3
* This file is part of the League.csv library
4
*
5
* @license http://opensource.org/licenses/MIT
6
* @link https://github.com/thephpleague/csv/
7
* @version 9.0.0
8
* @package League.csv
9
*
10
* For the full copyright and license information, please view the LICENSE
11
* file that was distributed with this source code.
12
*/
13
declare(strict_types=1);
14
15
namespace League\Csv;
16
17
use CallbackFilterIterator;
18
use Countable;
19
use DomDocument;
20
use Generator;
21
use Iterator;
22
use IteratorAggregate;
23
use JsonSerializable;
24
use LimitIterator;
25
use SplFileObject;
26
27
/**
28
 *  A class to manage extracting and filtering a CSV
29
 *
30
 * @package League.csv
31
 * @since  3.0.0
32
 *
33
 */
34
class Reader extends AbstractCsv implements JsonSerializable, Countable, IteratorAggregate
35
{
36
    /**
37
     * @inheritdoc
38
     */
39
    protected $stream_filter_mode = STREAM_FILTER_READ;
40
41
    /**
42
     * CSV Document header offset
43 159
     *
44
     * @var int|null
45 159
     */
46
    protected $header_offset;
47
48
    /**
49
     * Returns the record offset used as header
50
     *
51
     * If no CSV record is used this method MUST return null
52
     *
53
     * @return int|null
54
     */
55
    public function getHeaderOffset()
56 159
    {
57
        return $this->header_offset;
58 159
    }
59 75
60
    /**
61
     * Selects the record to be used as the CSV header
62 144
     *
63
     * Because of the header is represented as an array, to be valid
64
     * a header MUST contain only unique string value.
65
     *
66
     * @param int|null $offset the header row offset
67
     *
68
     * @return $this
69
     */
70
    public function setHeaderOffset($offset): self
71
    {
72
        $this->header_offset = null;
73
        if (null !== $offset) {
74 63
            $this->header_offset = $this->filterInteger(
75
                $offset,
76 63
                0,
77
                'the header offset index must be a positive integer or 0'
78
            );
79
        }
80
81
        return $this;
82
    }
83
84
    /**
85
     * Detect Delimiters occurences in the CSV
86
     *
87
     * Returns a associative array where each key represents
88
     * a valid delimiter and each value the number of occurences
89 9
     *
90
     * @param string[] $delimiters the delimiters to consider
91 9
     * @param int      $nb_rows    Detection is made using $nb_rows of the CSV
92 9
     *
93 9
     * @return array
94 9
     */
95 6
    public function fetchDelimitersOccurrence(array $delimiters, int $nb_rows = 1): array
96 9
    {
97 9
        $nb_rows = $this->filterInteger($nb_rows, 1, 'The number of rows to consider must be a valid positive integer');
98
        $filter_row = function ($row) {
99 6
            return is_array($row) && count($row) > 1;
100 9
        };
101 9
        $delimiters = array_unique(array_filter($delimiters, function ($value) {
102 6
            return 1 == strlen($value);
103
        }));
104 9
        $csv = $this->getDocument();
105
        $csv->setFlags(SplFileObject::READ_CSV);
106
        $res = [];
107
        foreach ($delimiters as $delim) {
108
            $csv->setCsvControl($delim, $this->enclosure, $this->escape);
109
            $iterator = new CallbackFilterIterator(new LimitIterator($csv, 0, $nb_rows), $filter_row);
110
            $res[$delim] = count(iterator_to_array($iterator, false), COUNT_RECURSIVE);
111
        }
112
        arsort($res, SORT_NUMERIC);
113
114
        return $res;
115
    }
116 12
117
    /**
118 12
     * Returns a collection of selected records
119 12
     *
120 12
     * @param Statement|null $stmt
121 12
     *
122
     * @return RecordSet
123 12
     */
124
    public function select(Statement $stmt = null): RecordSet
125
    {
126
        $stmt = $stmt ?: new Statement();
127
128
        return $stmt->process($this);
129
    }
130
131
    /**
132
     * @inheritdoc
133
     */
134
    public function count(): int
135
    {
136
        return count($this->select());
137
    }
138 21
139
    /**
140 21
     * @inheritdoc
141
     */
142
    public function getIterator(): Iterator
143 18
    {
144 18
        return $this->select()->getIterator();
145
    }
146
147 15
    /**
148 18
     * @inheritdoc
149
     */
150 18
    public function jsonSerialize()
151 18
    {
152 18
        return $this->select()->jsonSerialize();
153 18
    }
154
155 18
    /**
156
     * Returns the column header associate with the RecordSet
157
     *
158
     * @return string[]
159
     */
160
    public function getHeader()
161
    {
162
        return $this->select()->getHeader();
163
    }
164
165
    /**
166
     * Returns a HTML table representation of the CSV Table
167
     *
168
     * @param string $class_attr optional classname
169
     *
170
     * @return string
171
     */
172
    public function toHTML(string $class_attr = 'table-csv-data'): string
173
    {
174 27
        return $this->select()->toHTML($class_attr);
175
    }
176 27
177 27
    /**
178
     * Transforms a CSV into a XML
179 27
     *
180 27
     * @param string $root_name XML root node name
181
     * @param string $row_name  XML row node name
182
     * @param string $cell_name XML cell node name
183 24
     *
184 24
     * @return DomDocument
185 16
     */
186 27
    public function toXML(string $root_name = 'csv', string $row_name = 'row', string $cell_name = 'cell'): DomDocument
187
    {
188 27
        return $this->select()->toXML($root_name, $row_name, $cell_name);
189 27
    }
190 27
191 27
    /**
192
     * Returns a sequential array of all CSV lines
193 27
     *
194
     * @return array
195
     */
196
    public function fetchAll(): array
197
    {
198
        return $this->select()->fetchAll();
199
    }
200
201
    /**
202
     * Returns a single row from the CSV
203 27
     *
204
     * By default if no offset is provided the first row of the CSV is selected
205 27
     *
206 24
     * @param int $offset the CSV row offset
207 18
     *
208 27
     * @return array
209
     */
210
    public function fetchOne(int $offset = 0): array
211
    {
212
        return $this->select()->fetchOne($offset);
213
    }
214
215
    /**
216
     * Returns the next value from a single CSV column
217
     *
218
     * By default if no column index is provided the first column of the CSV is selected
219
     *
220
     * @param string|int $column_index CSV column index
221
     *
222
     * @return Iterator
223
     */
224
    public function fetchColumn($column_index = 0): Iterator
225 39
    {
226
        return $this->select()->fetchColumn($column_index);
227 39
    }
228 27
229
    /**
230 27
     * Fetches the next key-value pairs from a result set (first
231 6
     * column is the key, second column is the value).
232 4
     *
233
     * By default if no column index is provided:
234 27
     * - the first CSV column is used to provide the keys
235 27
     * - the second CSV column is used to provide the value
236
     *
237 27
     * @param string|int $offset_index The column index to serve as offset
238 27
     * @param string|int $value_index  The column index to serve as value
239 27
     *
240
     * @return Generator
241 27
     */
242
    public function fetchPairs($offset_index = 0, $value_index = 1)
243
    {
244
        return $this->select()->fetchPairs($offset_index, $value_index);
245
    }
246
}
247