Statement   A
last analyzed

Coupling/Cohesion

Components 1
Dependencies 3

Complexity

Total Complexity 14

Size/Duplication

Total Lines 164
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
dl 0
loc 164
ccs 45
cts 45
cp 1
rs 10
c 0
b 0
f 0
wmc 14
lcom 1
cbo 3

6 Methods

Rating   Name   Duplication   Size   Complexity  
A where() 0 7 1
A orderBy() 0 7 1
A offset() 0 15 3
A limit() 0 15 3
A process() 0 16 2
A buildOrderBy() 0 21 4
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 ArrayIterator;
18
use CallbackFilterIterator;
19
use Iterator;
20
use League\Csv\Exception\OutOfRangeException;
21
use LimitIterator;
22
23
/**
24
 * A trait to manage filtering a CSV
25
 *
26
 * @package League.csv
27
 * @since   9.0.0
28
 * @author  Ignace Nyamagana Butera <[email protected]>
29
 *
30
 */
31
class Statement
32
{
33
    /**
34
     * Callables to filter the iterator
35
     *
36
     * @var callable[]
37
     */
38
    protected $where = [];
39
40
    /**
41
     * Callables to sort the iterator
42
     *
43
     * @var callable[]
44
     */
45
    protected $order_by = [];
46
47
    /**
48
     * iterator Offset
49
     *
50
     * @var int
51
     */
52
    protected $offset = 0;
53
54
    /**
55
     * iterator maximum length
56
     *
57
     * @var int
58
     */
59
    protected $limit = -1;
60
61
    /**
62
     * Set the Iterator filter method
63
     *
64
     * @param callable $callable
65
     *
66
     * @return self
67
     */
68 10
    public function where(callable $callable): self
69
    {
70 10
        $clone = clone $this;
71 10
        $clone->where[] = $callable;
72
73 10
        return $clone;
74
    }
75
76
    /**
77
     * Set an Iterator sorting callable function
78
     *
79
     * @param callable $callable
80
     *
81
     * @return self
82
     */
83 4
    public function orderBy(callable $callable): self
84
    {
85 4
        $clone = clone $this;
86 4
        $clone->order_by[] = $callable;
87
88 4
        return $clone;
89
    }
90
91
    /**
92
     * Set LimitIterator Offset
93
     *
94
     * @param $offset
95
     *
96
     * @throws OutOfRangeException if the offset is lesser than 0
97
     *
98
     * @return self
99
     */
100 12
    public function offset(int $offset): self
101
    {
102 12
        if (0 > $offset) {
103 2
            throw new OutOfRangeException(sprintf('%s() expects the offset to be a positive integer or 0, %s given', __METHOD__, $offset));
104
        }
105
106 10
        if ($offset === $this->offset) {
107 2
            return $this;
108
        }
109
110 8
        $clone = clone $this;
111 8
        $clone->offset = $offset;
112
113 8
        return $clone;
114
    }
115
116
    /**
117
     * Set LimitIterator Count
118
     *
119
     * @param int $limit
120
     *
121
     * @throws OutOfRangeException if the limit is lesser than -1
122
     *
123
     * @return self
124
     */
125 22
    public function limit(int $limit): self
126
    {
127 22
        if (-1 > $limit) {
128 4
            throw new OutOfRangeException(sprintf('%s() expects the limit to be greater or equel to -1, %s given', __METHOD__, $limit));
129
        }
130
131 18
        if ($limit === $this->limit) {
132 2
            return $this;
133
        }
134
135 16
        $clone = clone $this;
136 16
        $clone->limit = $limit;
137
138 16
        return $clone;
139
    }
140
141
    /**
142
     * Returns the inner CSV Document Iterator object
143
     *
144
     * @param Reader   $csv
145
     * @param string[] $header an optional header to use instead of the CSV document header
146
     *
147
     * @return ResultSet
148
     */
149 16
    public function process(Reader $csv, array $header = []): ResultSet
150
    {
151 16
        if (empty($header)) {
152 16
            $header = $csv->getHeader();
153
        }
154
155
        $reducer = function (Iterator $iterator, callable $callable): Iterator {
156 10
            return new CallbackFilterIterator($iterator, $callable);
157 16
        };
158
159 16
        $iterator = array_reduce($this->where, $reducer, $csv->getRecords($header));
160 16
        $iterator = $this->buildOrderBy($iterator);
161 16
        $iterator = new LimitIterator($iterator, $this->offset, $this->limit);
162
163 16
        return new ResultSet($iterator, $header);
164
    }
165
166
    /**
167
    * Sort the Iterator
168
    *
169
    * @param Iterator $iterator
170
    *
171
    * @return Iterator
172
    */
173 12
    protected function buildOrderBy(Iterator $iterator): Iterator
174
    {
175 12
        if (empty($this->order_by)) {
176 8
            return $iterator;
177
        }
178
179 4
        $compare = function (array $record_a, array $record_b): int {
180 4
            foreach ($this->order_by as $callable) {
181 4
                if (0 !== ($cmp = $callable($record_a, $record_b))) {
182 4
                    return $cmp;
183
                }
184
            }
185
186 2
            return $cmp ?? 0;
187 4
        };
188
189 4
        $iterator = new ArrayIterator(iterator_to_array($iterator));
190 4
        $iterator->uasort($compare);
191
192 4
        return $iterator;
193
    }
194
}
195