Completed
Push — 2.1 ( 68dd3d...1f97e0 )
by Alexander
11:18
created

BaseDataProvider::prepareTotalCount()

Size

Total Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

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