Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ build
composer.lock
vendor
.phpunit.result.cache
.idea
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ and will look something like this:

### Configuring the Pagination Output

ApiPagination has three keys for configuration: `key`, `aliases`, and `visible`.
ApiPagination has four keys for configuration: `key`, `aliases`, `visible` and `model`.

* `key` allows you to change the name of the pagination key.

Expand All @@ -83,6 +83,10 @@ ApiPagination has three keys for configuration: `key`, `aliases`, and `visible`.
response. **Note:** Whenever setting a key's visibility, make sure to use the
aliased name if you've given it one.

* `model` allows you to set the name of the model the pagination is applied on
if the controller does not follow CakePHP conventions, e.g. `ArticlesIndexController`.
Per default the model is the name of the controller, e.g. `Articles` for `ArticlesController`.

An example using all these configuration keys:

``` php
Expand All @@ -97,7 +101,8 @@ $this->loadComponent('BryanCrowe/ApiPagination.ApiPagination', [
'resultCount',
'prevPage',
'nextPage'
]
],
'model' => 'Articles',
]);
```

Expand Down
3 changes: 2 additions & 1 deletion src/Controller/Component/ApiPaginationComponent.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ public function beforeRender(Event $event)
}

$subject = $event->getSubject();
$this->pagingInfo = $this->getController()->getRequest()->getAttribute('paging')[$subject->getName()];
$modelName = ucfirst($this->getConfig('model', $subject->getName()));
$this->pagingInfo = $this->getController()->getRequest()->getAttribute('paging')[$modelName];
$config = $this->getConfig();

if (!empty($config['aliases'])) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
<?php
declare(strict_types=1);

namespace BryanCrowe\ApiPagination\Test;

use BryanCrowe\ApiPagination\Controller\Component\ApiPaginationComponent;
use BryanCrowe\ApiPagination\TestApp\Controller\ArticlesIndexController;
use Cake\Event\Event;
use Cake\Http\ServerRequest as Request;
use Cake\ORM\TableRegistry;
use Cake\TestSuite\TestCase;

/**
* ApiPaginationComponentTest class
*
* @property ArticlesIndexController $controller
*/
class ApiPaginationComponentOnNonConventionalControllerNameTest extends TestCase
{
public $fixtures = ['plugin.BryanCrowe/ApiPagination.Articles'];

/**
* setUp method
*
* @return void
*/
public function setUp(): void
{
$this->request = new Request(['url' => '/articles']);
$this->response = $this->createMock('Cake\Http\Response');
$this->controller = new ArticlesIndexController($this->request, $this->response);
$this->Articles = TableRegistry::getTableLocator()->get('BryanCrowe/ApiPagination.Articles', ['table' => 'bryancrowe_articles']);
parent::setUp();
}

/**
* tearDown method
*
* @return void
*/
public function tearDown(): void
{
parent::tearDown();
}

/**
* Test that a non conventional controller name is supported using the 'model' config.
*
* @dataProvider dataForTestVariousModelValueOnNonConventionalController
* @param array $config
* @param $expected
* @return void
*/
public function testVariousModelValueOnNonConventionalController(array $config, $expected)
{
$this->controller->setRequest(
$this->controller->getRequest()->withEnv('HTTP_ACCEPT', 'application/json')
);
$this->controller->set('data', $this->controller->paginate($this->Articles));
$apiPaginationComponent = new ApiPaginationComponent($this->controller->components(), $config);
$event = new Event('Controller.beforeRender', $this->controller);
$apiPaginationComponent->beforeRender($event);

$result = $apiPaginationComponent->getController()->viewBuilder()->getVar('pagination');
$this->assertSame($expected, $result);
}

/**
* If the name of the paginated model is not specified, the result of the pagination
* on a controller not having the same name as the model fails.
*
* @return array[]
*/
public function dataForTestVariousModelValueOnNonConventionalController(): array
{
return [

[[], null],
[['model' => 'Articles'], $this->getDefaultPagination()],
[['model' => 'articles'], $this->getDefaultPagination()],
[['model' => 'NonExistingModel'], null],
];
}

/**
* Returns the standard pagination result.
*
* @return array
*/
private function getDefaultPagination(): array
{
return [
'count' => 23,
'current' => 20,
'perPage' => 20,
'page' => 1,
'requestedPage' => 1,
'pageCount' => 2,
'start' => 1,
'end' => 20,
'prevPage' => false,
'nextPage' => true,
'sort' => null,
'direction' => null,
'sortDefault' => false,
'directionDefault' => false,
'completeSort' => [],
'limit' => null,
'scope' => null,
'finder' => 'all',
];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public function setUp(): void
$this->request = new Request(['url' => '/articles']);
$this->response = $this->createMock('Cake\Http\Response');
$this->controller = new ArticlesController($this->request, $this->response);
$this->Articles = TableRegistry::get('BryanCrowe/ApiPagination.Articles', ['table' => 'bryancrowe_articles']);
$this->Articles = TableRegistry::getTableLocator()->get('BryanCrowe/ApiPagination.Articles', ['table' => 'bryancrowe_articles']);
parent::setUp();
}

Expand Down
15 changes: 15 additions & 0 deletions tests/test_app/TestApp/Controller/ArticlesIndexController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php
declare(strict_types=1);

namespace BryanCrowe\ApiPagination\TestApp\Controller;

use Cake\Controller\Controller;

class ArticlesIndexController extends Controller
{
public function initialize(): void
{
parent::initialize();
$this->loadComponent('Paginator');
}
}