DataProviderIterator   A
last analyzed

Complexity

Total Complexity 18

Size/Duplication

Total Lines 178
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 18
lcom 1
cbo 3
dl 0
loc 178
ccs 0
cts 77
cp 0
rs 10
c 0
b 0
f 0

13 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 12 3
A getDataProvider() 0 4 1
A getTotalItemCount() 0 4 1
A current() 0 4 1
A getCurrentIndex() 0 4 1
A key() 0 6 1
A getCurrentPage() 0 4 1
A next() 0 10 2
A rewind() 0 6 1
A valid() 0 4 1
A count() 0 4 1
A loadPage() 0 7 1
A getItem() 0 11 3
1
<?php
2
3
/*
4
 * This file is part of the 2amigos/yii2-exportable-widget project.
5
 * (c) 2amigOS! <http://2amigos.us/>
6
 * For the full copyright and license information, please view
7
 * the LICENSE file that was distributed with this source code.
8
 */
9
10
namespace dosamigos\exportable\iterators;
11
12
use Countable;
13
use dosamigos\exportable\mappers\ColumnValueMapper;
14
use Iterator;
15
use OutOfBoundsException;
16
use yii\data\BaseDataProvider;
17
use yii\data\Pagination;
18
19
class DataProviderIterator implements Iterator, Countable
20
{
21
    /**
22
     * @var ColumnValueMapper|null
23
     */
24
    protected $itemMapper;
25
    /**
26
     * @var \yii\data\BaseDataProvider
27
     */
28
    private $dataProvider;
29
    /**
30
     * @var int
31
     */
32
    private $currentIndex = -1;
33
    /**
34
     * @var int
35
     */
36
    private $currentPage = 0;
37
    /**
38
     * @var int
39
     */
40
    private $totalItemCount = -1;
41
    /**
42
     * @var
43
     */
44
    private $items;
45
46
    /**
47
     * Constructor.
48
     *
49
     * @param BaseDataProvider $dataProvider the data provider to iterate over
50
     * @param ColumnValueMapper|null $itemMapper apply column transformations to Models
51
     * @param integer $pageSize pageSize to use for iteration. This is the number of objects loaded into memory at the same time.
52
     */
53
    public function __construct(BaseDataProvider $dataProvider, ColumnValueMapper $itemMapper = null, $pageSize = null)
54
    {
55
        $this->dataProvider = $dataProvider;
56
        $this->totalItemCount = $dataProvider->getTotalCount();
57
        $this->itemMapper = $itemMapper;
58
        if (($pagination = $this->dataProvider->getPagination()) === false) {
59
            $this->dataProvider->setPagination($pagination = new Pagination());
60
        }
61
        if ($pageSize !== null) {
62
            $pagination->pageSize = $pageSize;
63
        }
64
    }
65
66
    /**
67
     * Returns the data provider to iterate over
68
     * @return BaseDataProvider the data provider to iterate over
69
     */
70
    public function getDataProvider()
71
    {
72
        return $this->dataProvider;
73
    }
74
75
    /**
76
     * Gets the total number of items to iterate over
77
     * @return integer the total number of items to iterate over
78
     */
79
    public function getTotalItemCount()
80
    {
81
        return $this->totalItemCount;
82
    }
83
84
    /**
85
     * Gets the current item in the list.
86
     * This method is required by the Iterator interface.
87
     * @return mixed the current item in the list
88
     */
89
    public function current()
90
    {
91
        return $this->getItem($this->getCurrentIndex());
92
    }
93
94
    /**
95
     * @return int
96
     */
97
    public function getCurrentIndex()
98
    {
99
        return $this->currentIndex;
100
    }
101
102
    /**
103
     * Gets the key of the current item.
104
     * This method is required by the Iterator interface.
105
     * @return integer the key of the current item
106
     */
107
    public function key()
108
    {
109
        $pageSize = $this->getDataProvider()->getPagination()->pageSize;
110
111
        return $this->getCurrentPage() * $pageSize + $this->getCurrentIndex();
112
    }
113
114
    /**
115
     * @return int
116
     */
117
    public function getCurrentPage()
118
    {
119
        return $this->currentPage;
120
    }
121
122
    /**
123
     * Moves the pointer to the next item in the list.
124
     * This method is required by the Iterator interface.
125
     */
126
    public function next()
127
    {
128
        $pageSize = $this->getDataProvider()->getPagination()->pageSize;
129
        $this->currentIndex++;
130
        if ($this->currentIndex >= $pageSize) {
131
            $this->currentPage++;
132
            $this->currentIndex = 0;
133
            $this->loadPage();
134
        }
135
    }
136
137
    /**
138
     * Rewinds the iterator to the start of the list.
139
     * This method is required by the Iterator interface.
140
     */
141
    public function rewind()
142
    {
143
        $this->currentIndex = 0;
144
        $this->currentPage = 0;
145
        $this->loadPage();
146
    }
147
148
    /**
149
     * Checks if the current position is valid or not.
150
     * This method is required by the Iterator interface.
151
     * @return boolean true if this index is valid
152
     */
153
    public function valid()
154
    {
155
        return $this->key() < $this->getTotalItemCount();
156
    }
157
158
    /**
159
     * Gets the total number of items in the dataProvider.
160
     * This method is required by the Countable interface.
161
     * @return integer the total number of items
162
     */
163
    public function count()
164
    {
165
        return $this->getTotalItemCount();
166
    }
167
168
    /**
169
     * Loads a page of items
170
     * @return array the items from the next page of results
171
     */
172
    protected function loadPage()
173
    {
174
        $this->getDataProvider()->getPagination()->setPage($this->getCurrentPage());
175
        $this->getDataProvider()->prepare(true);
176
177
        return $this->items = $this->getDataProvider()->getModels();
178
    }
179
180
    /**
181
     * @param $index
182
     *
183
     * @return array
184
     */
185
    protected function getItem($index)
186
    {
187
        if (!isset($this->items[$index])) {
188
            throw new OutOfBoundsException('Index is not allowed be limits of current page');
189
        }
190
        if (!empty($this->itemMapper)) {
191
            return $this->itemMapper->map($this->items[$index], $index);
192
        }
193
194
        return $this->items[$index];
195
    }
196
}
197