Passed
Pull Request — master (#20176)
by Loban
07:53
created

BaseDataProvider::setPagination()   A

Complexity

Conditions 5
Paths 9

Size

Total Lines 19
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 5.0073

Importance

Changes 0
Metric Value
cc 5
eloc 14
nc 9
nop 1
dl 0
loc 19
ccs 14
cts 15
cp 0.9333
crap 5.0073
rs 9.4888
c 0
b 0
f 0
1
<?php
2
/**
3
 * @link https://www.yiiframework.com/
4
 * @copyright Copyright (c) 2008 Yii Software LLC
5
 * @license https://www.yiiframework.com/license/
6
 */
7
8
namespace yii\data;
9
10
use Yii;
11
use yii\base\Component;
12
use yii\base\InvalidArgumentException;
13
14
/**
15
 * BaseDataProvider provides a base class that implements the [[DataProviderInterface]].
16
 *
17
 * For more details and usage information on BaseDataProvider, see the [guide article on data providers](guide:output-data-providers).
18
 *
19
 * @property-read int $count The number of data models in the current page.
20
 * @property array $keys The list of key values corresponding to [[models]]. Each data model in [[models]] is
21
 * uniquely identified by the corresponding key value in this array.
22
 * @property array $models The list of data models in the current page.
23
 * @property Pagination|false $pagination The pagination object. If this is false, it means the pagination is
24
 * disabled. Note that the type of this property differs in getter and setter. See [[getPagination()]] and
25
 * [[setPagination()]] for details.
26
 * @property Sort|bool $sort The sorting object. If this is false, it means the sorting is disabled. Note that
27
 * the type of this property differs in getter and setter. See [[getSort()]] and [[setSort()]] for details.
28
 * @property int $totalCount Total number of possible data models.
29
 *
30
 * @author Qiang Xue <[email protected]>
31
 * @since 2.0
32
 * @phpcs:disable Squiz.NamingConventions.ValidVariableName.PrivateNoUnderscore
33
 */
34
abstract class BaseDataProvider extends Component implements DataProviderInterface
35
{
36
    /**
37
     * @var int Number of data providers on the current page. Used to generate unique IDs.
38
     */
39
    private static $counter = 0;
40
    /**
41
     * @var string|null an ID that uniquely identifies the data provider among all data providers.
42
     * Generated automatically the following way in case it is not set:
43
     *
44
     * - First data provider ID is empty.
45
     * - Second and all subsequent data provider IDs are: "dp-1", "dp-2", etc.
46
     */
47
    public $id;
48
49
    private $_sort;
50
    private $_pagination;
51
    private $_keys;
52
    private $_models;
53
    private $_totalCount;
54
55
56
    /**
57
     * {@inheritdoc}
58
     */
59 93
    public function init()
60
    {
61 93
        parent::init();
62 93
        if ($this->id === null) {
63 93
            if (self::$counter > 0) {
64 93
                $this->id = 'dp-' . self::$counter;
65
            }
66 93
            self::$counter++;
67
        }
68
    }
69
70
    /**
71
     * Prepares the data models that will be made available in the current page.
72
     * @return array the available data models
73
     */
74
    abstract protected function prepareModels();
75
76
    /**
77
     * Prepares the keys associated with the currently available data models.
78
     * @param array $models the available data models
79
     * @return array the keys
80
     */
81
    abstract protected function prepareKeys($models);
82
83
    /**
84
     * Returns a value indicating the total number of data models in this data provider.
85
     * @return int total number of data models in this data provider.
86
     */
87
    abstract protected function prepareTotalCount();
88
89
    /**
90
     * Prepares the data models and keys.
91
     *
92
     * This method will prepare the data models and keys that can be retrieved via
93
     * [[getModels()]] and [[getKeys()]].
94
     *
95
     * This method will be implicitly called by [[getModels()]] and [[getKeys()]] if it has not been called before.
96
     *
97
     * @param bool $forcePrepare whether to force data preparation even if it has been done before.
98
     */
99 81
    public function prepare($forcePrepare = false)
100
    {
101 81
        if ($forcePrepare || $this->_models === null) {
102 79
            $this->_models = $this->prepareModels();
103
        }
104 81
        if ($forcePrepare || $this->_keys === null) {
105 81
            $this->_keys = $this->prepareKeys($this->_models);
106
        }
107
    }
108
109
    /**
110
     * Returns the data models in the current page.
111
     * @return array the list of data models in the current page.
112
     */
113 80
    public function getModels()
114
    {
115 80
        $this->prepare();
116
117 80
        return $this->_models;
118
    }
119
120
    /**
121
     * Sets the data models in the current page.
122
     * @param array $models the models in the current page
123
     */
124 2
    public function setModels($models)
125
    {
126 2
        $this->_models = $models;
127
    }
128
129
    /**
130
     * Returns the key values associated with the data models.
131
     * @return array the list of key values corresponding to [[models]]. Each data model in [[models]]
132
     * is uniquely identified by the corresponding key value in this array.
133
     */
134 30
    public function getKeys()
135
    {
136 30
        $this->prepare();
137
138 30
        return $this->_keys;
139
    }
140
141
    /**
142
     * Sets the key values associated with the data models.
143
     * @param array $keys the list of key values corresponding to [[models]].
144
     */
145
    public function setKeys($keys)
146
    {
147
        $this->_keys = $keys;
148
    }
149
150
    /**
151
     * Returns the number of data models in the current page.
152
     * @return int the number of data models in the current page.
153
     */
154 25
    public function getCount()
155
    {
156 25
        return count($this->getModels());
157
    }
158
159
    /**
160
     * Returns the total number of data models.
161
     * When [[pagination]] is false, this returns the same value as [[count]].
162
     * Otherwise, it will call [[prepareTotalCount()]] to get the count.
163
     * @return int total number of possible data models.
164
     */
165 83
    public function getTotalCount()
166
    {
167 83
        if ($this->_pagination === false) {
168
            return $this->getCount();
169
        }
170 83
        if ($this->_totalCount !== null) {
171 3
            return (int)$this->_totalCount;
172
        }
173 80
        return $this->prepareTotalCount();
174
    }
175
176
    /**
177
     * Sets the total number of data models.
178
     * @param int $value the total number of data models.
179
     */
180 10
    public function setTotalCount($value)
181
    {
182 10
        $this->_totalCount = $value;
183
    }
184
185
    /**
186
     * Returns the pagination object used by this data provider.
187
     * Note that you should call [[prepare()]] or [[getModels()]] first to get correct values
188
     * of [[Pagination::totalCount]] and [[Pagination::pageCount]].
189
     * @return Pagination|false the pagination object. If this is false, it means the pagination is disabled.
190
     */
191 87
    public function getPagination()
192
    {
193 87
        if ($this->_pagination === null) {
194 63
            $this->setPagination([]);
195
        }
196 87
        return $this->_pagination;
197
    }
198
199
    /**
200
     * Sets the pagination for this data provider.
201
     * @param array|Pagination|bool $value the pagination to be used by this data provider.
202
     * This can be one of the following:
203
     *
204
     * - a configuration array for creating the pagination object. The "class" element defaults
205
     *   to 'yii\data\Pagination'
206
     * - an instance of [[Pagination]] or its subclass
207
     * - false, if pagination needs to be disabled.
208
     *
209
     * @throws InvalidArgumentException
210
     */
211 81
    public function setPagination($value)
212
    {
213 75
        if (is_array($value)) {
214 72
            $config = ['class' => Pagination::className()];
0 ignored issues
show
Deprecated Code introduced by
The function yii\base\BaseObject::className() has been deprecated: since 2.0.14. On PHP >=5.5, use `::class` instead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

214
            $config = ['class' => /** @scrutinizer ignore-deprecated */ Pagination::className()];

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
215 72
            if ($this->id !== null) {
216 63
                $config['pageParam'] = $this->id . '-page';
217 63
                $config['pageSizeParam'] = $this->id . '-per-page';
218
            }
219 72
            $value = Yii::createObject(array_merge($config, $value));
220
        }
221 75
        if ($value instanceof Pagination) {
222 73
            $value->setTotalCount(function () {
223 81
                return $this->getTotalCount();
224 73
            });
225 73
            $this->_pagination = $value;
226 2
        } elseif ($value === false) {
227 2
            $this->_pagination = false;
228
        } else {
229
            throw new InvalidArgumentException('Only Pagination instance, configuration array or false is allowed.');
230
        }
231
    }
232
233
    /**
234
     * Returns the sorting object used by this data provider.
235
     * @return Sort|bool the sorting object. If this is false, it means the sorting is disabled.
236
     */
237 84
    public function getSort()
238
    {
239 84
        if ($this->_sort === null) {
240 60
            $this->setSort([]);
241
        }
242
243 84
        return $this->_sort;
244
    }
245
246
    /**
247
     * Sets the sort definition for this data provider.
248
     * @param array|Sort|bool $value the sort definition to be used by this data provider.
249
     * This can be one of the following:
250
     *
251
     * - a configuration array for creating the sort definition object. The "class" element defaults
252
     *   to 'yii\data\Sort'
253
     * - an instance of [[Sort]] or its subclass
254
     * - false, if sorting needs to be disabled.
255
     *
256
     * @throws InvalidArgumentException
257
     */
258 83
    public function setSort($value)
259
    {
260 83
        if (is_array($value)) {
261 81
            $config = ['class' => Sort::className()];
0 ignored issues
show
Deprecated Code introduced by
The function yii\base\BaseObject::className() has been deprecated: since 2.0.14. On PHP >=5.5, use `::class` instead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

261
            $config = ['class' => /** @scrutinizer ignore-deprecated */ Sort::className()];

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
262 81
            if ($this->id !== null) {
263 60
                $config['sortParam'] = $this->id . '-sort';
264
            }
265 81
            $this->_sort = Yii::createObject(array_merge($config, $value));
266 2
        } elseif ($value instanceof Sort || $value === false) {
267 2
            $this->_sort = $value;
268
        } else {
269
            throw new InvalidArgumentException('Only Sort instance, configuration array or false is allowed.');
270
        }
271
    }
272
273
    /**
274
     * Refreshes the data provider.
275
     * After calling this method, if [[getModels()]], [[getKeys()]] or [[getTotalCount()]] is called again,
276
     * they will re-execute the query and return the latest data available.
277
     */
278 6
    public function refresh()
279
    {
280 6
        $this->_totalCount = null;
281 6
        $this->_models = null;
282 6
        $this->_keys = null;
283
    }
284
}
285