Skip to content

Commit

Permalink
improvements for paginator helper
Browse files Browse the repository at this point in the history
  • Loading branch information
thinkingmedia committed Oct 19, 2016
1 parent 6c7a460 commit a55d555
Show file tree
Hide file tree
Showing 2 changed files with 147 additions and 109 deletions.
84 changes: 66 additions & 18 deletions src/View/Helper/PaginatorHelper.php
Expand Up @@ -194,6 +194,23 @@ public function current($model = null)
return 1;
}

/**
* Gets the total number of pages in the recordset for the given model.
*
* @param string|null $model Optional model name. Uses the default if none is specified.
* @return int The total pages for the recordset.
*/
public function total($model = null)
{
$params = $this->params($model);

if (isset($params['pageCount'])) {
return $params['pageCount'];
}

return 0;
}

/**
* Gets the current key by which the recordset is sorted
*
Expand Down Expand Up @@ -482,9 +499,6 @@ public function sort($key, $title = null, array $options = [])
*/
public function generateUrl(array $options = [], $model = null, $urlOptions = false)
{
$paging = $this->params($model);
$paging += ['page' => null, 'sort' => null, 'direction' => null, 'limit' => null];

if (!is_array($urlOptions)) {
$urlOptions = ['fullBase' => $urlOptions];
}
Expand All @@ -493,6 +507,21 @@ public function generateUrl(array $options = [], $model = null, $urlOptions = fa
'fullBase' => false
];

return $this->Url->build($this->generateUrlParams($options, $model), $urlOptions);
}

/**
* Merges passed URL options with current pagination state to generate a pagination URL.
*
* @param array $options Pagination/URL options array
* @param string|null $model Which model to paginate on
* @return array An array of URL parameters
*/
public function generateUrlParams(array $options = [], $model = null)
{
$paging = $this->params($model);
$paging += ['page' => null, 'sort' => null, 'direction' => null, 'limit' => null];

$url = [
'page' => $paging['page'],
'limit' => $paging['limit'],
Expand All @@ -519,6 +548,7 @@ public function generateUrl(array $options = [], $model = null, $urlOptions = fa
) {
$url['sort'] = $url['direction'] = null;
}

if (!empty($paging['scope'])) {
$scope = $paging['scope'];
$currentParams = $this->_config['options']['url'];
Expand All @@ -533,7 +563,7 @@ public function generateUrl(array $options = [], $model = null, $urlOptions = fa
}
}

return $this->Url->build($url, $urlOptions);
return $url;
}

/**
Expand Down Expand Up @@ -1076,40 +1106,58 @@ public function last($last = 'last >>', array $options = [])
*
* - `model` The model to use defaults to PaginatorHelper::defaultModel()
* - `block` The block name to append the output to, or false/absenst to return as a string
* - `prev` (default True) True to generate meta for previous page
* - `next` (default True) True to generate meta for next page
* - `first` (default False) True to generate meta for first page
* - `last` (default False) True to generate meta for last page
*
* @param array $options Array of options
* @return string|null Meta links
*/
public function meta(array $options = [])
{
$options = $options + [
'model' => null,
'block' => false,
'prev' => true,
'next' => true,
'first' => false,
'last' => false
];

$model = isset($options['model']) ? $options['model'] : null;
$params = $this->params($model);
$links = [];

if ($this->hasPrev()) {
$links[] = $this->Html->templater()->format('css', [
'rel' => 'prev',
'url' => $this->generateUrl(['page' => $params['page'] - 1], null, true)
]);
if ($options['prev'] && $this->hasPrev()) {
$links[] = $this->Html->meta('prev', $this->generateUrl(['page' => $params['page'] - 1], null, true));
}

if ($this->hasNext()) {
$links[] = $this->Html->templater()->format('css', [
'rel' => 'next',
'url' => $this->generateUrl(['page' => $params['page'] + 1], null, true)
]);
if ($options['next'] && $this->hasNext()) {
$links[] = $this->Html->meta('next', $this->generateUrl(['page' => $params['page'] + 1], null, true));
}

$out = implode($links);
if ($options['first']) {
$links[] = $this->Html->meta('first', $this->generateUrl(['page' => 1], null, true));
}

if (empty($options['block'])) {
return $out;
if ($options['last']) {
$links[] = $this->Html->meta('last', $this->generateUrl(['page' => $params['pageCount']], null, true));
}

$out = implode($links);

if ($options['block'] === true) {
$options['block'] = __FUNCTION__;
}
$this->_View->append($options['block'], $out);

if (!empty($options['block'])) {
$this->_View->append($options['block'], $out);

return null;
}

return $out;
}

/**
Expand Down
172 changes: 81 additions & 91 deletions tests/TestCase/View/Helper/PaginatorHelperTest.php
Expand Up @@ -33,6 +33,16 @@ class PaginatorHelperTest extends TestCase
*/
protected $locale;

/**
* @var \Cake\View\View
*/
protected $View;

/**
* @var \Cake\View\Helper\PaginatorHelper
*/
protected $Paginator;

/**
* setUp method
*
Expand All @@ -44,9 +54,6 @@ public function setUp()
Configure::write('Config.language', 'eng');
$this->View = new View();
$this->Paginator = new PaginatorHelper($this->View);
$this->Paginator->Js = $this->getMockBuilder('Cake\View\Helper\PaginatorHelper')
->setConstructorArgs([$this->View])
->getMock();
$this->Paginator->request = new Request();
$this->Paginator->request->addParams([
'paging' => [
Expand Down Expand Up @@ -2180,7 +2187,7 @@ public function testLastOptions()
'a' => [
'href' => '/index?page=15&sort=Client.name&direction=DESC',
],
'last >>', '/a',
'last >>', '/a',
'/li',
];
$this->assertHtml($expected, $result);
Expand Down Expand Up @@ -2385,6 +2392,20 @@ public function testCurrent()
$this->assertEquals(1, $result);
}

/**
* test the total() method
*
* @return void
*/
public function testTotal()
{
$result = $this->Paginator->total();
$this->assertSame($this->Paginator->request->params['paging']['Article']['pageCount'], $result);

$result = $this->Paginator->total('Incorrect');
$this->assertSame(0, $result);
}

/**
* test the defaultModel() method
*
Expand Down Expand Up @@ -2450,110 +2471,79 @@ public function testWithZeroPages()
}

/**
* Verifies that no next and prev links are created for single page results.
* Test data for meta()
*
* @return void
* @return array
*/
public function testMetaPage0()
public function dataMetaProvider()
{
$this->Paginator->request->params['paging'] = [
'Article' => [
'page' => 1,
'prevPage' => false,
'nextPage' => false,
'pageCount' => 1,
]
return [
// Verifies that no next and prev links are created for single page results.
[1, false, false, 1, [], ''],
// Verifies that first and last pages are created for single page results.
[1, false, false, 1, ['first' => true, 'last' => true], '<link href="http://localhost/index" rel="first"/>' .
'<link href="http://localhost/index" rel="last"/>'],
// Verifies that first page is created for single page results.
[1, false, false, 1, ['first' => true], '<link href="http://localhost/index" rel="first"/>'],
// Verifies that last page is created for single page results.
[1, false, false, 1, ['last' => true], '<link href="http://localhost/index" rel="last"/>'],
// Verifies that page 1 only has a next link.
[1, false, true, 2, [], '<link href="http://localhost/index?page=2" rel="next"/>'],
// Verifies that page 1 only has next, first and last link.
[1, false, true, 2, ['first' => true, 'last' => true], '<link href="http://localhost/index?page=2" rel="next"/>' .
'<link href="http://localhost/index" rel="first"/>' .
'<link href="http://localhost/index?page=2" rel="last"/>'],
// Verifies that page 1 only has next and first link.
[1, false, true, 2, ['first' => true], '<link href="http://localhost/index?page=2" rel="next"/>' .
'<link href="http://localhost/index" rel="first"/>'],
// Verifies that page 1 only has next and last link.
[1, false, true, 2, ['last' => true], '<link href="http://localhost/index?page=2" rel="next"/>' .
'<link href="http://localhost/index?page=2" rel="last"/>'],
// Verifies that the last page only has a prev link.
[2, true, false, 2, [], '<link href="http://localhost/index" rel="prev"/>'],
// Verifies that the last page only has a prev, first and last link.
[2, true, false, 2, ['first' => true, 'last' => true], '<link href="http://localhost/index" rel="prev"/>' .
'<link href="http://localhost/index" rel="first"/>' .
'<link href="http://localhost/index?page=2" rel="last"/>'],
// Verifies that a page in the middle has both links.
[5, true, true, 10, [], '<link href="http://localhost/index?page=4" rel="prev"/>' .
'<link href="http://localhost/index?page=6" rel="next"/>'],
// Verifies that a page in the middle has both links.
[5, true, true, 10, ['first' => true, 'last' => true], '<link href="http://localhost/index?page=4" rel="prev"/>' .
'<link href="http://localhost/index?page=6" rel="next"/>' .
'<link href="http://localhost/index" rel="first"/>' .
'<link href="http://localhost/index?page=10" rel="last"/>']
];

$expected = '';
$result = $this->Paginator->meta();
$this->assertSame($expected, $result);
}

/**
* Verifies that page 1 only has a next link.
*
* @return void
* @param int $page
* @param int $prevPage
* @param int $nextPage
* @param int $pageCount
* @param array $options
* @param string $expected
* @dataProvider dataMetaProvider
*/
public function testMetaPage1()
public function testMeta($page, $prevPage, $nextPage, $pageCount, $options, $expected)
{
$this->Paginator->request->params['paging'] = [
'Article' => [
'page' => 1,
'prevPage' => false,
'nextPage' => true,
'pageCount' => 2,
'page' => $page,
'prevPage' => $prevPage,
'nextPage' => $nextPage,
'pageCount' => $pageCount,
]
];

$expected = '<link rel="next" href="http://localhost/index?page=2"/>';
$result = $this->Paginator->meta();
$result = $this->Paginator->meta($options);
$this->assertSame($expected, $result);
}

/**
* Verifies that the method will append to a block.
*
* @return void
*/
public function testMetaPage1InlineFalse()
{
$this->Paginator->request->params['paging'] = [
'Article' => [
'page' => 1,
'prevPage' => false,
'nextPage' => true,
'pageCount' => 2,
]
];

$expected = '<link rel="next" href="http://localhost/index?page=2"/>';
$this->Paginator->meta(['block' => true]);
$result = $this->View->fetch('meta');
$this->assertSame($expected, $result);
}

/**
* Verifies that the last page only has a prev link.
*
* @return void
*/
public function testMetaPage1Last()
{
$this->Paginator->request->params['paging'] = [
'Article' => [
'page' => 2,
'prevPage' => true,
'nextPage' => false,
'pageCount' => 2,
]
];

$expected = '<link rel="prev" href="http://localhost/index"/>';
$result = $this->Paginator->meta();

$this->assertSame($expected, $result);
}
$this->assertEquals('', $this->View->fetch('meta'));

/**
* Verifies that a page in the middle has both links.
*
* @return void
*/
public function testMetaPage10Last()
{
$this->Paginator->request->params['paging'] = [
'Article' => [
'page' => 5,
'prevPage' => true,
'nextPage' => true,
'pageCount' => 10,
]
];
$result = $this->Paginator->meta($options + ['block' => true]);
$this->assertNull($result);

$expected = '<link rel="prev" href="http://localhost/index?page=4"/>';
$expected .= '<link rel="next" href="http://localhost/index?page=6"/>';
$result = $this->Paginator->meta();
$this->assertSame($expected, $result);
$this->assertSame($expected, $this->View->fetch('meta'));
}
}

0 comments on commit a55d555

Please sign in to comment.