Passed
Pull Request — 2.2 (#20357)
by Wilmer
08:31
created

BaseDataProvider   A

Complexity

Total Complexity 32

Size/Duplication

Total Lines 247
Duplicated Lines 0 %

Test Coverage

Coverage 83.08%

Importance

Changes 0
Metric Value
eloc 61
dl 0
loc 247
ccs 54
cts 65
cp 0.8308
rs 9.84
c 0
b 0
f 0
wmc 32

14 Methods

Rating   Name   Duplication   Size   Complexity  
A prepare() 0 7 5
A init() 0 8 3
A getTotalCount() 0 9 3
A getKeys() 0 5 1
A setTotalCount() 0 3 1
A getCount() 0 3 1
A setKeys() 0 3 1
A getModels() 0 5 1
A setModels() 0 3 1
A getPagination() 0 6 2
A getSort() 0 7 2
A setSort() 0 12 5
A setPagination() 0 17 5
A refresh() 0 5 1
1
<?php
2
3
/**
4
 * @link https://www.yiiframework.com/
5
 * @copyright Copyright (c) 2008 Yii Software LLC
6
 * @license https://www.yiiframework.com/license/
7
 */
8
9
namespace yii\data;
10
11
use Yii;
12
use yii\base\Component;
13
use yii\base\InvalidArgumentException;
14
15
/**
16
 * BaseDataProvider provides a base class that implements the [[DataProviderInterface]].
17
 *
18
 * For more details and usage information on BaseDataProvider, see the [guide article on data providers](guide:output-data-providers).
19
 *
20
 * @property-read int $count The number of data models in the current page.
21
 * @property array $keys The list of key values corresponding to [[models]]. Each data model in [[models]] is
22
 * uniquely identified by the corresponding key value in this array.
23
 * @property array $models The list of data models in the current page.
24
 * @property Pagination|false $pagination The pagination object. If this is false, it means the pagination is
25
 * disabled. Note that the type of this property differs in getter and setter. See [[getPagination()]] and
26
 * [[setPagination()]] for details.
27
 * @property Sort|bool $sort The sorting object. If this is false, it means the sorting is disabled. Note that
28
 * the type of this property differs in getter and setter. See [[getSort()]] and [[setSort()]] for details.
29
 * @property int $totalCount Total number of possible data models.
30
 *
31
 * @author Qiang Xue <[email protected]>
32
 * @since 2.0
33
 * @phpcs:disable Squiz.NamingConventions.ValidVariableName.PrivateNoUnderscore
34
 */
35
abstract class BaseDataProvider extends Component implements DataProviderInterface
36
{
37
    /**
38
     * @var int Number of data providers on the current page. Used to generate unique IDs.
39
     */
40
    private static $counter = 0;
41
    /**
42
     * @var string|null an ID that uniquely identifies the data provider among all data providers.
43
     * Generated automatically the following way in case it is not set:
44
     *
45
     * - First data provider ID is empty.
46
     * - Second and all subsequent data provider IDs are: "dp-1", "dp-2", etc.
47
     */
48
    public $id;
49
50
    private $_sort;
51
    private $_pagination;
52
    private $_keys;
53
    private $_models;
54
    private $_totalCount;
55
56
57
    /**
58
     * {@inheritdoc}
59
     */
60 64
    public function init()
61
    {
62 64
        parent::init();
63 64
        if ($this->id === null) {
64 64
            if (self::$counter > 0) {
65 64
                $this->id = 'dp-' . self::$counter;
66
            }
67 64
            self::$counter++;
68
        }
69
    }
70
71
    /**
72
     * Prepares the data models that will be made available in the current page.
73
     * @return array the available data models
74
     */
75
    abstract protected function prepareModels();
76
77
    /**
78
     * Prepares the keys associated with the currently available data models.
79
     * @param array $models the available data models
80
     * @return array the keys
81
     */
82
    abstract protected function prepareKeys($models);
83
84
    /**
85
     * Returns a value indicating the total number of data models in this data provider.
86
     * @return int total number of data models in this data provider.
87
     */
88
    abstract protected function prepareTotalCount();
89
90
    /**
91
     * Prepares the data models and keys.
92
     *
93
     * This method will prepare the data models and keys that can be retrieved via
94
     * [[getModels()]] and [[getKeys()]].
95
     *
96
     * This method will be implicitly called by [[getModels()]] and [[getKeys()]] if it has not been called before.
97
     *
98
     * @param bool $forcePrepare whether to force data preparation even if it has been done before.
99
     */
100 55
    public function prepare($forcePrepare = false)
101
    {
102 55
        if ($forcePrepare || $this->_models === null) {
103 55
            $this->_models = $this->prepareModels();
104
        }
105 55
        if ($forcePrepare || $this->_keys === null) {
106 55
            $this->_keys = $this->prepareKeys($this->_models);
107
        }
108
    }
109
110
    /**
111
     * Returns the data models in the current page.
112
     * @return array the list of data models in the current page.
113
     */
114 54
    public function getModels()
115
    {
116 54
        $this->prepare();
117
118 54
        return $this->_models;
119
    }
120
121
    /**
122
     * Sets the data models in the current page.
123
     * @param array $models the models in the current page
124
     */
125
    public function setModels($models)
126
    {
127
        $this->_models = $models;
128
    }
129
130
    /**
131
     * Returns the key values associated with the data models.
132
     * @return array the list of key values corresponding to [[models]]. Each data model in [[models]]
133
     * is uniquely identified by the corresponding key value in this array.
134
     */
135 18
    public function getKeys()
136
    {
137 18
        $this->prepare();
138
139 18
        return $this->_keys;
140
    }
141
142
    /**
143
     * Sets the key values associated with the data models.
144
     * @param array $keys the list of key values corresponding to [[models]].
145
     */
146
    public function setKeys($keys)
147
    {
148
        $this->_keys = $keys;
149
    }
150
151
    /**
152
     * Returns the number of data models in the current page.
153
     * @return int the number of data models in the current page.
154
     */
155 23
    public function getCount()
156
    {
157 23
        return count($this->getModels());
158
    }
159
160
    /**
161
     * Returns the total number of data models.
162
     * When [[pagination]] is false, this returns the same value as [[count]].
163
     * Otherwise, it will call [[prepareTotalCount()]] to get the count.
164
     * @return int total number of possible data models.
165
     */
166 48
    public function getTotalCount()
167
    {
168 48
        if ($this->_pagination === false) {
169
            return $this->getCount();
170
        }
171 48
        if ($this->_totalCount === null) {
172 45
            $this->_totalCount = $this->prepareTotalCount();
173
        }
174 48
        return $this->_totalCount;
175
    }
176
177
    /**
178
     * Sets the total number of data models.
179
     * @param int $value the total number of data models.
180
     */
181 8
    public function setTotalCount($value)
182
    {
183 8
        $this->_totalCount = $value;
184
    }
185
186
    /**
187
     * Returns the pagination object used by this data provider.
188
     * Note that you should call [[prepare()]] or [[getModels()]] first to get correct values
189
     * of [[Pagination::totalCount]] and [[Pagination::pageCount]].
190
     * @return Pagination|false the pagination object. If this is false, it means the pagination is disabled.
191
     */
192 60
    public function getPagination()
193
    {
194 60
        if ($this->_pagination === null) {
195 39
            $this->setPagination([]);
196
        }
197 60
        return $this->_pagination;
198
    }
199
200
    /**
201
     * Sets the pagination for this data provider.
202
     * @param array|Pagination|bool $value the pagination to be used by this data provider.
203
     * This can be one of the following:
204
     *
205
     * - a configuration array for creating the pagination object. The "class" element defaults
206
     *   to 'yii\data\Pagination'
207
     * - an instance of [[Pagination]] or its subclass
208
     * - false, if pagination needs to be disabled.
209
     *
210
     * @throws InvalidArgumentException
211
     */
212 48
    public function setPagination($value)
213
    {
214 48
        if (is_array($value)) {
215 45
            $config = ['class' => Pagination::class];
216 45
            if ($this->id !== null) {
217 39
                $config['pageParam'] = $this->id . '-page';
218 39
                $config['pageSizeParam'] = $this->id . '-per-page';
219
            }
220 45
            $value = Yii::createObject(array_merge($config, $value));
221
        }
222 48
        if ($value instanceof Pagination) {
223 46
            $value->totalCount = $this->getTotalCount();
224 46
            $this->_pagination = $value;
225 2
        } elseif ($value === false) {
226 2
            $this->_pagination = false;
227
        } else {
228
            throw new InvalidArgumentException('Only Pagination instance, configuration array or false is allowed.');
229
        }
230
    }
231
232
    /**
233
     * Returns the sorting object used by this data provider.
234
     * @return Sort|bool the sorting object. If this is false, it means the sorting is disabled.
235
     */
236 61
    public function getSort()
237
    {
238 61
        if ($this->_sort === null) {
239 39
            $this->setSort([]);
240
        }
241
242 61
        return $this->_sort;
243
    }
244
245
    /**
246
     * Sets the sort definition for this data provider.
247
     * @param array|Sort|bool $value the sort definition to be used by this data provider.
248
     * This can be one of the following:
249
     *
250
     * - a configuration array for creating the sort definition object. The "class" element defaults
251
     *   to 'yii\data\Sort'
252
     * - an instance of [[Sort]] or its subclass
253
     * - false, if sorting needs to be disabled.
254
     *
255
     * @throws InvalidArgumentException
256
     */
257 60
    public function setSort($value)
258
    {
259 60
        if (is_array($value)) {
260 58
            $config = ['class' => Sort::class];
261 58
            if ($this->id !== null) {
262 39
                $config['sortParam'] = $this->id . '-sort';
263
            }
264 58
            $this->_sort = Yii::createObject(array_merge($config, $value));
265 2
        } elseif ($value instanceof Sort || $value === false) {
266 2
            $this->_sort = $value;
267
        } else {
268
            throw new InvalidArgumentException('Only Sort instance, configuration array or false is allowed.');
269
        }
270
    }
271
272
    /**
273
     * Refreshes the data provider.
274
     * After calling this method, if [[getModels()]], [[getKeys()]] or [[getTotalCount()]] is called again,
275
     * they will re-execute the query and return the latest data available.
276
     */
277
    public function refresh()
278
    {
279
        $this->_totalCount = null;
280
        $this->_models = null;
281
        $this->_keys = null;
282
    }
283
}
284