diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md index ec38cf0cccd..302698ff536 100644 --- a/framework/CHANGELOG.md +++ b/framework/CHANGELOG.md @@ -9,6 +9,7 @@ Yii Framework 2 Change Log - Bug #18469: Fixed `Link::serialize(array $links)` method in `yii\web\Link` (ggh2e3) - Bug #19691: Allow using custom class to style error summary (skepticspriggan) - Bug #20040: Fix type `boolean` in `MSSQL` (terabytesoftw) +- Bug #20055: Fix Response header X-Pagination-Total-Count is always 0 (lav45, xicond) - Bug #20005: Fix `yii\console\controllers\ServeController` to specify the router script (terabytesoftw) - Bug #19060: Fix `yii\widgets\Menu` bug when using Closure for active item and adding additional tests in `tests\framework\widgets\MenuTest` (atrandafir) - Bug #13920: Fixed erroneous validation for specific cases (tim-fischer-maschinensucher) diff --git a/framework/data/ActiveDataProvider.php b/framework/data/ActiveDataProvider.php index b0aab615305..9280c1c0d1c 100644 --- a/framework/data/ActiveDataProvider.php +++ b/framework/data/ActiveDataProvider.php @@ -103,7 +103,6 @@ protected function prepareModels() } $query = clone $this->query; if (($pagination = $this->getPagination()) !== false) { - $pagination->totalCount = $this->getTotalCount(); if ($pagination->totalCount === 0) { return []; } diff --git a/framework/data/ArrayDataProvider.php b/framework/data/ArrayDataProvider.php index 1655b18b5bb..14511c54556 100644 --- a/framework/data/ArrayDataProvider.php +++ b/framework/data/ArrayDataProvider.php @@ -87,14 +87,10 @@ protected function prepareModels() $models = $this->sortModels($models, $sort); } - if (($pagination = $this->getPagination()) !== false) { - $pagination->totalCount = $this->getTotalCount(); - - if ($pagination->getPageSize() > 0) { - $models = array_slice($models, $pagination->getOffset(), $pagination->getLimit(), true); - } + $pagination = $this->getPagination(); + if ($pagination !== false && $pagination->getPageSize() > 0) { + $models = array_slice($models, $pagination->getOffset(), $pagination->getLimit(), true); } - return $models; } diff --git a/framework/data/BaseDataProvider.php b/framework/data/BaseDataProvider.php index 623ead89306..409b9f28bca 100644 --- a/framework/data/BaseDataProvider.php +++ b/framework/data/BaseDataProvider.php @@ -165,12 +165,12 @@ public function getCount() */ public function getTotalCount() { - if ($this->getPagination() === false) { + if ($this->_pagination === false) { return $this->getCount(); - } elseif ($this->_totalCount === null) { + } + if ($this->_totalCount === null) { $this->_totalCount = $this->prepareTotalCount(); } - return $this->_totalCount; } @@ -194,7 +194,6 @@ public function getPagination() if ($this->_pagination === null) { $this->setPagination([]); } - return $this->_pagination; } @@ -218,9 +217,13 @@ public function setPagination($value) $config['pageParam'] = $this->id . '-page'; $config['pageSizeParam'] = $this->id . '-per-page'; } - $this->_pagination = Yii::createObject(array_merge($config, $value)); - } elseif ($value instanceof Pagination || $value === false) { + $value = Yii::createObject(array_merge($config, $value)); + } + if ($value instanceof Pagination) { + $value->totalCount = $this->getTotalCount(); $this->_pagination = $value; + } elseif ($value === false) { + $this->_pagination = false; } else { throw new InvalidArgumentException('Only Pagination instance, configuration array or false is allowed.'); } diff --git a/framework/data/SqlDataProvider.php b/framework/data/SqlDataProvider.php index 97c6000c053..3ecf0595c9a 100644 --- a/framework/data/SqlDataProvider.php +++ b/framework/data/SqlDataProvider.php @@ -128,7 +128,6 @@ protected function prepareModels() } if ($pagination !== false) { - $pagination->totalCount = $this->getTotalCount(); $limit = $pagination->getLimit(); $offset = $pagination->getOffset(); } diff --git a/tests/framework/data/ActiveDataProviderTest.php b/tests/framework/data/ActiveDataProviderTest.php index af96dfef267..789a0337260 100644 --- a/tests/framework/data/ActiveDataProviderTest.php +++ b/tests/framework/data/ActiveDataProviderTest.php @@ -170,9 +170,8 @@ public function testPaginationBeforeModels() 'query' => $query->from('order')->orderBy('id'), ]); $pagination = $provider->getPagination(); - $this->assertEquals(0, $pagination->getPageCount()); - $this->assertCount(3, $provider->getModels()); $this->assertEquals(1, $pagination->getPageCount()); + $this->assertCount(3, $provider->getModels()); $provider->getPagination()->pageSize = 2; $this->assertCount(3, $provider->getModels()); diff --git a/tests/framework/rest/SerializerTest.php b/tests/framework/rest/SerializerTest.php index 91b627b8f8e..f2e0ed72e5e 100644 --- a/tests/framework/rest/SerializerTest.php +++ b/tests/framework/rest/SerializerTest.php @@ -439,6 +439,30 @@ public function testHeadSerializeDataProvider($dataProvider, $expectedResult, $s ]); $serializer->preserveKeys = $saveKeys; $this->assertEmpty($serializer->serialize($dataProvider)); + $this->assertNotEmpty($serializer->response->getHeaders()->get($serializer->totalCountHeader)); + + $arrayDataProviderMock = $this->getMockBuilder(ArrayDataProvider::className()) + ->disableOriginalConstructor() + ->getMock(); + + // stub getModels to prevent empty + $arrayDataProviderMock + ->method('getModels') + ->willReturn($expectedResult); + + // stub getPagination for header + $arrayDataProviderMock + ->method('getPagination') + ->willReturn($dataProvider->getPagination()); + + // assert normal HEAD is empty response + $this->assertEmpty($serializer->serialize($arrayDataProviderMock)); + + // Test #20002: Set up the expectation for the getModels method + $arrayDataProviderMock->expects($this->never()) + ->method('getModels'); + + // reset Method unset($_POST[$request->methodParam], $_SERVER['REQUEST_METHOD']); }