Browse Source

Fix #19171: Added `$pagination` and `$sort` to `\yii\rest\IndexAction` for easy configuration

tags/2.0.45
rhertogh 3 years ago committed by GitHub
parent
commit
e691713ed7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 36
      docs/guide/rest-quick-start.md
  2. 1
      framework/CHANGELOG.md
  3. 57
      framework/rest/IndexAction.php
  4. 120
      tests/framework/rest/IndexActionTest.php

36
docs/guide/rest-quick-start.md

@ -195,6 +195,42 @@ Additionally, you can sort collections like `http://localhost/users?sort=email`
`http://localhost/users?filter[email][like]=gmail.com` could be implemented using
data filters. See [Resources](rest-resources.md#filtering-collections) section for details.
## Customizing Pagination and Sorting in the list<span id="customizing-pagination-and-sorting"></span>
In order to change the default [pagination](output-pagination.md) and [sorting](output-sorting.md) of the model list
you can configure the [[yii\rest\IndexAction]] in your controller. For example:
```php
<?php
namespace app\controllers;
use yii\rest\ActiveController;
use yii\helpers\ArrayHelper;
class UserController extends ActiveController
{
public $modelClass = 'app\models\User';
public function actions()
{
return ArrayHelper::merge(parent::actions(), [
'index' => [
'pagination' => [
'pageSize' => 10,
],
'sort' => [
'defaultOrder' => [
'created_at' => SORT_DESC,
],
],
],
]);
}
}
```
Please see [Extending ActiveController](rest-controllers#extending-active-controller) for more information on how to
configure actions of the ActiveController.
## Summary <span id="summary"></span>

1
framework/CHANGELOG.md

@ -8,6 +8,7 @@ Yii Framework 2 Change Log
- Bug #19138: Allow digits in language code (ntesic)
- Bug #19148: Fix undefined array key errors in `yii\db\ActiveRelationTrait` (stevekr)
- Bug #19041: Fix PHP 8.1 issues (longthanhtran, samdark, pamparam83, sartor, githubjeka)
- Enh #19171: Added `$pagination` and `$sort` to `\yii\rest\IndexAction` for easy configuration (rhertogh)
2.0.44 December 30, 2021

57
framework/rest/IndexAction.php

@ -10,6 +10,9 @@ namespace yii\rest;
use Yii;
use yii\data\ActiveDataProvider;
use yii\data\DataFilter;
use yii\data\Pagination;
use yii\data\Sort;
use yii\helpers\ArrayHelper;
/**
* IndexAction implements the API endpoint for listing multiple models.
@ -87,6 +90,24 @@ class IndexAction extends Action
/**
* @var array|Pagination|false The pagination to be used by [[prepareDataProvider()]].
* If this is `false`, it means pagination is disabled.
* Note: if a Pagination object is passed, it's `params` will be set to the request parameters.
* @see Pagination
* @since 2.0.45
*/
public $pagination = [];
/**
* @var array|Sort|false The sorting to be used by [[prepareDataProvider()]].
* If this is `false`, it means sorting is disabled.
* Note: if a Sort object is passed, it's `params` will be set to the request parameters.
* @see Sort
* @since 2.0.45
*/
public $sort = [];
/**
* @return ActiveDataProvider
*/
public function run()
@ -135,15 +156,39 @@ class IndexAction extends Action
$query = call_user_func($this->prepareSearchQuery, $query, $requestParams);
}
if (is_array($this->pagination)) {
$pagination = ArrayHelper::merge(
[
'params' => $requestParams,
],
$this->pagination
);
} else {
$pagination = $this->pagination;
if ($this->pagination instanceof Pagination) {
$pagination->params = $requestParams;
}
}
if (is_array($this->sort)) {
$sort = ArrayHelper::merge(
[
'params' => $requestParams,
],
$this->sort
);
} else {
$sort = $this->sort;
if ($this->sort instanceof Sort) {
$sort->params = $requestParams;
}
}
return Yii::createObject([
'class' => ActiveDataProvider::className(),
'query' => $query,
'pagination' => [
'params' => $requestParams,
],
'sort' => [
'params' => $requestParams,
],
'pagination' => $pagination,
'sort' => $sort,
]);
}
}

120
tests/framework/rest/IndexActionTest.php

@ -3,6 +3,9 @@
namespace yiiunit\framework\rest;
use Yii;
use yii\data\ActiveDataProvider;
use yii\data\Pagination;
use yii\data\Sort;
use yii\db\ActiveRecord;
use yii\db\Query;
use yii\rest\ActiveController;
@ -63,6 +66,123 @@ class IndexActionTest extends TestCase
$sql
);
}
/**
* @dataProvider dataProviderTestPrepareDataProviderWithPaginationAndSorting
*
* @param string $sql
* @param array $params
* @param string $expectedRawSql
*/
public function testPrepareDataProviderWithPaginationAndSorting(
$pagination,
$sort,
$expectedPaginationPageSize = null,
$expectedPaginationDefaultPageSize = null,
$expectedSortOrders = [],
$expectedSortDefaultOrder = null
) {
Yii::$app->getRequest()->setBodyParams([
'per-page' => 11,
'sort' => '-test-sort'
]);
$controller = new RestController(
'rest',
new Module('rest'), [
'modelClass' => IndexActionModel::className(),
'actions' => [
'index' => [
'class' => IndexAction::className(),
'modelClass' => IndexActionModel::className(),
'pagination' => $pagination,
'sort' => $sort,
],
],
]);
/** @var ActiveDataProvider $dataProvider */
$dataProvider = $controller->createAction('index')->runWithParams([]);
$actualPagination = $dataProvider->getPagination();
$actualSort = $dataProvider->getSort();
if ($pagination === false) {
$this->assertFalse($actualPagination);
} else {
$this->assertEquals($expectedPaginationPageSize, $actualPagination->pageSize);
$this->assertEquals($expectedPaginationDefaultPageSize, $actualPagination->defaultPageSize);
}
if ($sort === false) {
$this->assertFalse($actualSort);
} else {
$this->assertEquals($expectedSortOrders, $actualSort->getOrders());
$this->assertEquals($expectedSortDefaultOrder, $actualSort->defaultOrder);
}
}
/**
* Data provider for [[testPrepareDataProviderWithPaginationAndSorting()]].
* @return array test data
*/
public function dataProviderTestPrepareDataProviderWithPaginationAndSorting()
{
return [
[ // Default config
[],
[],
11, // page size set as param in test
(new Pagination())->defaultPageSize,
[],
null
],
[ // Default config
[],
[
'attributes' => ['test-sort'],
],
11, // page size set as param in test
(new Pagination())->defaultPageSize,
['test-sort' => SORT_DESC], // test sort set as param in test
null
],
[ // Config via array
[
'pageSize' => 12, // Testing a fixed page size
'defaultPageSize' => 991,
],
[
'attributes' => ['test-sort'],
'defaultOrder' => [
'created_at_1' => SORT_DESC,
],
],
12,
991,
['test-sort' => SORT_DESC], // test sort set as param in test
['created_at_1' => SORT_DESC]
],
[ // Config via objects
new Pagination([
'defaultPageSize' => 992,
]),
new Sort([
'attributes' => ['created_at_2'],
'defaultOrder' => [
'created_at_2' => SORT_DESC,
],
]),
11, // page size set as param in test
992,
['created_at_2' => SORT_DESC], // test sort set as param in test is ignored
['created_at_2' => SORT_DESC]
],
[ // Disable pagination and sort
false,
false,
]
];
}
}
class RestController extends ActiveController

Loading…
Cancel
Save