Skip to content

Commit 4a0dc36

Browse files
Handle non conventional controller names
1 parent 9df343a commit 4a0dc36

File tree

6 files changed

+139
-4
lines changed

6 files changed

+139
-4
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ build
22
composer.lock
33
vendor
44
.phpunit.result.cache
5+
.idea

README.md

+7-2
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ and will look something like this:
7373

7474
### Configuring the Pagination Output
7575

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

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

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

86+
* `model` allows you to set the name of the model the pagination is applied on
87+
if the controller does not follow CakePHP conventions, e.g. `ArticlesIndexController`.
88+
Per default the model is the name of the controller, e.g. `Articles` for `ArticlesController`.
89+
8690
An example using all these configuration keys:
8791

8892
``` php
@@ -97,7 +101,8 @@ $this->loadComponent('BryanCrowe/ApiPagination.ApiPagination', [
97101
'resultCount',
98102
'prevPage',
99103
'nextPage'
100-
]
104+
],
105+
'model' => 'Articles',
101106
]);
102107
```
103108

src/Controller/Component/ApiPaginationComponent.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ public function beforeRender(Event $event)
4545
}
4646

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

5152
if (!empty($config['aliases'])) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace BryanCrowe\ApiPagination\Test;
5+
6+
use BryanCrowe\ApiPagination\Controller\Component\ApiPaginationComponent;
7+
use BryanCrowe\ApiPagination\TestApp\Controller\ArticlesIndexController;
8+
use Cake\Event\Event;
9+
use Cake\Http\ServerRequest as Request;
10+
use Cake\ORM\TableRegistry;
11+
use Cake\TestSuite\TestCase;
12+
13+
/**
14+
* ApiPaginationComponentTest class
15+
*
16+
* @property ArticlesIndexController $controller
17+
*/
18+
class ApiPaginationComponentOnNonConventionalControllerNameTest extends TestCase
19+
{
20+
public $fixtures = ['plugin.BryanCrowe/ApiPagination.Articles'];
21+
22+
/**
23+
* setUp method
24+
*
25+
* @return void
26+
*/
27+
public function setUp(): void
28+
{
29+
$this->request = new Request(['url' => '/articles']);
30+
$this->response = $this->createMock('Cake\Http\Response');
31+
$this->controller = new ArticlesIndexController($this->request, $this->response);
32+
$this->Articles = TableRegistry::getTableLocator()->get('BryanCrowe/ApiPagination.Articles', ['table' => 'bryancrowe_articles']);
33+
parent::setUp();
34+
}
35+
36+
/**
37+
* tearDown method
38+
*
39+
* @return void
40+
*/
41+
public function tearDown(): void
42+
{
43+
parent::tearDown();
44+
}
45+
46+
/**
47+
* Test that a non conventional controller name is supported using the 'model' config.
48+
*
49+
* @dataProvider dataForTestVariousModelValueOnNonConventionalController
50+
* @param array $config
51+
* @param $expected
52+
* @return void
53+
*/
54+
public function testVariousModelValueOnNonConventionalController(array $config, $expected)
55+
{
56+
$this->controller->setRequest(
57+
$this->controller->getRequest()->withEnv('HTTP_ACCEPT', 'application/json')
58+
);
59+
$this->controller->set('data', $this->controller->paginate($this->Articles));
60+
$apiPaginationComponent = new ApiPaginationComponent($this->controller->components(), $config);
61+
$event = new Event('Controller.beforeRender', $this->controller);
62+
$apiPaginationComponent->beforeRender($event);
63+
64+
$result = $apiPaginationComponent->getController()->viewBuilder()->getVar('pagination');
65+
$this->assertSame($expected, $result);
66+
}
67+
68+
/**
69+
* If the name of the paginated model is not specified, the result of the pagination
70+
* on a controller not having the same name as the model fails.
71+
*
72+
* @return array[]
73+
*/
74+
public function dataForTestVariousModelValueOnNonConventionalController(): array
75+
{
76+
return [
77+
78+
[[], null],
79+
[['model' => 'Articles'], $this->getDefaultPagination()],
80+
[['model' => 'articles'], $this->getDefaultPagination()],
81+
[['model' => 'NonExistingModel'], null],
82+
];
83+
}
84+
85+
/**
86+
* Returns the standard pagination result.
87+
*
88+
* @return array
89+
*/
90+
private function getDefaultPagination(): array
91+
{
92+
return [
93+
'count' => 23,
94+
'current' => 20,
95+
'perPage' => 20,
96+
'page' => 1,
97+
'requestedPage' => 1,
98+
'pageCount' => 2,
99+
'start' => 1,
100+
'end' => 20,
101+
'prevPage' => false,
102+
'nextPage' => true,
103+
'sort' => null,
104+
'direction' => null,
105+
'sortDefault' => false,
106+
'directionDefault' => false,
107+
'completeSort' => [],
108+
'limit' => null,
109+
'scope' => null,
110+
'finder' => 'all',
111+
];
112+
}
113+
}

tests/TestCase/Controller/Component/ApiPaginationComponentTest.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public function setUp(): void
2929
$this->request = new Request(['url' => '/articles']);
3030
$this->response = $this->createMock('Cake\Http\Response');
3131
$this->controller = new ArticlesController($this->request, $this->response);
32-
$this->Articles = TableRegistry::get('BryanCrowe/ApiPagination.Articles', ['table' => 'bryancrowe_articles']);
32+
$this->Articles = TableRegistry::getTableLocator()->get('BryanCrowe/ApiPagination.Articles', ['table' => 'bryancrowe_articles']);
3333
parent::setUp();
3434
}
3535

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace BryanCrowe\ApiPagination\TestApp\Controller;
5+
6+
use Cake\Controller\Controller;
7+
8+
class ArticlesIndexController extends Controller
9+
{
10+
public function initialize(): void
11+
{
12+
parent::initialize();
13+
$this->loadComponent('Paginator');
14+
}
15+
}

0 commit comments

Comments
 (0)