Statement   A
last analyzed

Coupling/Cohesion

Components 1
Dependencies 3

Complexity

Total Complexity 12

Size/Duplication

Total Lines 156
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
dl 0
loc 156
ccs 43
cts 43
cp 1
rs 10
c 0
b 0
f 0
wmc 12
lcom 1
cbo 3

6 Methods

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