Completed
Push — master ( 32377d...16aae2 )
by ignace nyamagana
04:12
created

Statement   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 151
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
dl 0
loc 151
ccs 40
cts 40
cp 1
rs 10
c 0
b 0
f 0
wmc 11
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 12 1
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 2
    public function where(callable $callable): self
70
    {
71 2
        $clone = clone $this;
72 2
        $clone->where[] = $callable;
73
74 2
        return $clone;
75
    }
76
77
    /**
78
     * Set an Iterator sorting callable function
79
     *
80
     * @param callable $callable
81
     *
82
     * @return self
83
     */
84 2
    public function orderBy(callable $callable): self
85
    {
86 2
        $clone = clone $this;
87 2
        $clone->order_by[] = $callable;
88
89 2
        return $clone;
90
    }
91
92
    /**
93
     * Set LimitIterator Offset
94
     *
95
     * @param $offset
96
     *
97
     * @return self
98
     */
99 18
    public function offset(int $offset): self
100
    {
101 18
        $offset = $this->filterMinRange($offset, 0, 'The Statement offset must be a positive integer or 0');
102 18
        if ($offset === $this->offset) {
103 2
            return $this;
104
        }
105
106 16
        $clone = clone $this;
107 16
        $clone->offset = $offset;
108
109 16
        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, 'The Statement limit must an integer greater or equals to -1');
122 20
        if ($limit === $this->limit) {
123 2
            return $this;
124
        }
125
126 18
        $clone = clone $this;
127 18
        $clone->limit = $limit;
128
129 18
        return $clone;
130
    }
131
132
    /**
133
     * Returns the inner CSV Document Iterator object
134
     *
135
     * @param Reader $reader
136
     *
137
     * @return RecordSet
138
     */
139 100
    public function process(Reader $reader): RecordSet
140
    {
141
        $reducer = function (Iterator $iterator, callable $callable): Iterator {
142 2
            return new CallbackFilterIterator($iterator, $callable);
143 50
        };
144
145 100
        $iterator = array_reduce($this->where, $reducer, $reader->getIterator());
146 98
        $iterator = $this->buildOrderBy($iterator);
147 98
        $iterator = new LimitIterator($iterator, $this->offset, $this->limit);
148
149 98
        return new RecordSet($iterator, $reader->getHeader());
150
    }
151
152
    /**
153
    * Sort the Iterator
154
    *
155
    * @param Iterator $iterator
156
    *
157
    * @return Iterator
158
    */
159 98
    protected function buildOrderBy(Iterator $iterator): Iterator
160
    {
161 98
        if (empty($this->order_by)) {
162 96
            return $iterator;
163
        }
164
165 2
        $compare = function (array $record_a, array $record_b): int {
166 2
            foreach ($this->order_by as $callable) {
167 2
                if (0 !== ($cmp = $callable($record_a, $record_b))) {
168 2
                    return $cmp;
169
                }
170
            }
171
172
            return $cmp ?? 0;
173 1
        };
174
175 2
        $iterator = new ArrayIterator(iterator_to_array($iterator));
176 2
        $iterator->uasort($compare);
177
178 2
        return $iterator;
179
    }
180
}
181