Wrong DataProvider->totalCount
$query = MyModel::find();
$dataProvider = new ActiveDataProvider(['query' => $query);
$dataProvider->pagination->pageSize = 30;
// Now $dataProvider->totalCount is set because of BaseDataProvider::getPagination()
$query->andFilterWhere(['number' => $this->number]);
// From now on totalCount is NOT updated to consider this condition and any other conditions added before feeding it to a GridView and rendering.
totalCount should be set only when DataProvider gets to be used to fetch and render data.
Up to version 12.0.15 DataProvider pagination could be invoked and set before setting all its query conditions and afterwards totalCount was calculated correctly as expected.
DataProvider totalCount is wrong - total number of rows in the table!! - doesn't care about query conditions added after invoking $dataProvider->pagination.
Related issue: https://github.com/yiisoft/yii2/issues/16891
| Q | A
| ---------------- | ---
| Yii version | 2.0.16
| PHP version | 7.*
| Operating system |Windows/Linux
What is the AR storage you are using?
Is here any reason you don't use config to set pageSize value?
I think we should block any changes in query or pagination after ActiveDataProvider was initialized. Otherwise we have to recalculate it parameters every time. Or introduce an events system, which to be able to catch such changes and adjust only needed parameters.
What is the AR storage you are using?
MySQL
Is here any reason you don't use config to set
pageSizevalue?
Supposing you refer to app config, the reason is pageSize is not fixed but different for different DataProviders.
I think we should block any changes in
queryorpaginationafterActiveDataProviderwas initialized. Otherwise we have to recalculate it parameters every time. Or introduce an events system, which to be able to catch such changes and adjust only needed parameters.
...or delay calculating and setting totalCount until it is really needed. Why not?
Supposing you refer to app config, the reason is
pageSizeis not fixed but different for differentDataProviders.
No proplem:
$dataProvider = new ActiveDataProvider([
'query' => $query,
'pagination' => [
'pageSize' => $YOUR_DYNAMIC_VALUE_HERE,
],
);
...or delay calculating and setting
totalCountuntil it is really needed. Why not?
Just let the framework take care about this. It makes sense but in current case you can get exactly what you want by making up right config before ActiveDataProvider initialization.
Discussed the case in private messages with @GHopperMSK. He has a good solution for it.
@GHopperMSK 's solution works, of course :-), and I'm refactoring this way.
It's refreshing to find myself still learning basing stuff after 3 yers of using Yii2. Thanks!
But if you find a (easy) way to have totalCount reflect query at final stage (get data and render) it would be great.
Unfortunately, my solution isn't good at all. Here are a few cases:
totalCount by usual way:$provider = new ActiveDataProvider([
'query' => Order::find()->orderBy('id'),
'totalCount' => 10, // it makes no sense anymore
'pagination' => [
'pageSize' => 1,
// now 'totalCount' must be declared here
],
]);
$provider = new ActiveDataProvider([
'db' => $this->getConnection(),
'query' => $query->from('order')->orderBy('id'),
]);
$perPage = $provider->getPagination()->getPageCount(); // null
// Pagination: getPageCount() => getPageSize() => setPageSize() => totalCount = null;
Next code works fine:
$provider = new ActiveDataProvider([
'query' => Order::find()->orderBy('id'),
'pagination' => [
'pageSize' => 1,
'totalCount' => 100,
],
]);
But if we just swap two lines, it will break:
$provider = new ActiveDataProvider([
'query' => Order::find()->orderBy('id'),
'pagination' => [
'totalCount' => 100,
'pageSize' => 1,
],
]);
// the same reason as in 2
Looks like we need to revert https://github.com/yiisoft/yii2/commit/e1623868f9e95769074312f8582c1709cfcb52a8#diff-3a9563dfdfd2448d1b7edfad3ec14522
I tryed to fix in https://github.com/yiisoft/yii2/pull/17132
This is limiting us to move to 2.0.16 :( How can I help to fix this one?
Most helpful comment
Looks like we need to revert https://github.com/yiisoft/yii2/commit/e1623868f9e95769074312f8582c1709cfcb52a8#diff-3a9563dfdfd2448d1b7edfad3ec14522