Skip to content

Commit

Permalink
Merge pull request #622 from natanfelles/response-setHeaderLink
Browse files Browse the repository at this point in the history
Add Header Link Pagination
  • Loading branch information
jim-parry authored Nov 29, 2018
2 parents 540e94b + b412d16 commit a4b9526
Show file tree
Hide file tree
Showing 11 changed files with 271 additions and 23 deletions.
1 change: 1 addition & 0 deletions application/Config/Pager.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class Pager extends BaseConfig
public $templates = [
'default_full' => 'CodeIgniter\Pager\Views\default_full',
'default_simple' => 'CodeIgniter\Pager\Views\default_simple',
'default_head' => 'CodeIgniter\Pager\Views\default_head',
];

/*
Expand Down
38 changes: 38 additions & 0 deletions system/HTTP/Response.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
use Config\App;
use Config\Format;
use CodeIgniter\HTTP\Exceptions\HTTPException;
use CodeIgniter\Pager\PagerInterface;

/**
* Representation of an outgoing, getServer-side response.
Expand Down Expand Up @@ -375,6 +376,43 @@ public function setDate(\DateTime $date)

//--------------------------------------------------------------------

/**
* Set the Link Header
*
* @param \CodeIgniter\Pager\PagerInterface $pager
*
* @see http://tools.ietf.org/html/rfc5988
*
* @return Response
*/
public function setLink(PagerInterface $pager)
{
$links = '';

if ($previous = $pager->getPreviousPageURI())
{
$links .= '<' . $pager->getPageURI($pager->getFirstPage()) . '>; rel="first",';
$links .= '<' . $previous . '>; rel="prev"';
}

if (($next = $pager->getNextPageURI()) && $previous)
{
$links .= ',';
}

if ($next)
{
$links .= '<' . $next . '>; rel="next",';
$links .= '<' . $pager->getPageURI($pager->getLastPage()) . '>; rel="last"';
}

$this->setHeader('Link', $links);

return $this;
}

//--------------------------------------------------------------------

/**
* Sets the Content Type header for this response with the mime type
* and, optionally, the charset.
Expand Down
29 changes: 13 additions & 16 deletions system/Pager/Pager.php
Original file line number Diff line number Diff line change
Expand Up @@ -325,36 +325,33 @@ public function getPageURI(int $page = null, string $group = 'default', $returnO
{
$this->ensureGroup($group);

/**
* @var \CodeIgniter\HTTP\URI $uri
*/
$uri = $this->groups[$group]['uri'];

$segment = $this->segment[$group] ?? 0;

if ($segment)
{
$uri->setSegment($segment, $page);
}
else
{
$uri->addQuery('page', $page);
}

if ($this->only)
{
$query = array_intersect_key($_GET, array_flip($this->only));

if ($segment > 0)
{
$uri->setSegment($segment, $page);
}
else
if (! $segment)
{
$query['page'] = $page;
}

$uri->setQueryArray($query);
}
else
{
if ($segment > 0)
{
$uri->setSegment($segment, $page);
}
else
{
$uri->addQuery('page', $page);
}
}

return $returnObject === true ? $uri : (string) $uri;
}
Expand Down
24 changes: 24 additions & 0 deletions system/Pager/PagerInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,19 @@ public function getCurrentPage(string $group = 'default'): int;

//--------------------------------------------------------------------

/**
* Returns the URI for a specific page for the specified group.
*
* @param integer|null $page
* @param string $group
* @param boolean $returnObject
*
* @return string|\CodeIgniter\HTTP\URI
*/
public function getPageURI(int $page = null, string $group = 'default', $returnObject = false);

//--------------------------------------------------------------------

/**
* Tells whether this group of results has any more pages of results.
*
Expand All @@ -138,6 +151,17 @@ public function hasMore(string $group = 'default'): bool;

//--------------------------------------------------------------------

/**
* Returns the first page.
*
* @param string $group
*
* @return integer
*/
public function getFirstPage(string $group = 'default');

//--------------------------------------------------------------------

/**
* Returns the last page, if we have a total that we can calculate with.
*
Expand Down
23 changes: 23 additions & 0 deletions system/Pager/PagerRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,29 @@ public function getLast(): string

//--------------------------------------------------------------------

/**
* Returns the URI of the current page.
*
* @return string
*/
public function getCurrent(): string
{
$uri = clone $this->uri;

if ($this->segment === 0)
{
$uri->addQuery('page', $this->current);
}
else
{
$uri->setSegment($this->segment, $this->current);
}

return (string) $uri;
}

//--------------------------------------------------------------------

/**
* Returns an array of links that should be displayed. Each link
* is represented by another array containing of the URI the link
Expand Down
8 changes: 7 additions & 1 deletion system/Pager/Views/default_full.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
<?php $pager->setSurroundCount(2) ?>
<?php
/**
* @var \CodeIgniter\Pager\PagerRenderer $pager
*/

$pager->setSurroundCount(2);
?>

<nav aria-label="<?= lang('Pager.pageNavigation') ?>">
<ul class="pagination">
Expand Down
18 changes: 18 additions & 0 deletions system/Pager/Views/default_head.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php
/**
* @var \CodeIgniter\Pager\PagerRenderer $pager
*/

$pager->setSurroundCount(0);

if ($pager->hasPrevious())
{
echo '<link rel="prev" href="' . $pager->getPrevious() . '">' . PHP_EOL;
}

echo '<link rel="canonical" href="' . $pager->getCurrent() . '">' . PHP_EOL;

if ($pager->hasNext())
{
echo '<link rel="next" href="' . $pager->getNext() . '">' . PHP_EOL;
}
8 changes: 7 additions & 1 deletion system/Pager/Views/default_simple.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
<?php $pager->setSurroundCount(0) ?>
<?php
/**
* @var \CodeIgniter\Pager\PagerRenderer $pager
*/

$pager->setSurroundCount(0);
?>
<nav>
<ul class="pager">
<li <?= $pager->hasPrevious() ? '' : 'class="disabled"' ?>>
Expand Down
32 changes: 32 additions & 0 deletions tests/system/HTTP/ResponseTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,38 @@ public function testSetDateRemembersDateInUTC()

//--------------------------------------------------------------------

public function testSetLink()
{
$response = new Response(new App());
$pager = \Config\Services::pager();

$pager->store('default', 3, 10, 200);
$response->setLink($pager);

$this->assertEquals(
'<http://example.com?page=1>; rel="first",<http://example.com?page=2>; rel="prev",<http://example.com?page=4>; rel="next",<http://example.com?page=20>; rel="last"',
$response->getHeader('Link')->getValue()
);

$pager->store('default', 1, 10, 200);
$response->setLink($pager);

$this->assertEquals(
'<http://example.com?page=2>; rel="next",<http://example.com?page=20>; rel="last"',
$response->getHeader('Link')->getValue()
);

$pager->store('default', 20, 10, 200);
$response->setLink($pager);

$this->assertEquals(
'<http://example.com?page=1>; rel="first",<http://example.com?page=19>; rel="prev"',
$response->getHeader('Link')->getValue()
);
}

//--------------------------------------------------------------------

public function testSetContentType()
{
$response = new Response(new App());
Expand Down
43 changes: 42 additions & 1 deletion tests/system/Pager/PagerRendererTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@

class PagerRendererTest extends \CIUnitTestCase
{

/**
* @var URI
*/
protected $uri;

//--------------------------------------------------------------------
Expand Down Expand Up @@ -194,6 +196,45 @@ public function testGetFirstAndGetLast()

//--------------------------------------------------------------------

public function testGetCurrent()
{
$uri = $this->uri;
$uri->addQuery('foo', 'bar');

$details = [
'uri' => $uri,
'pageCount' => 50,
'currentPage' => 10,
'total' => 100,
];

$pager = new PagerRenderer($details);

$this->assertEquals('http://example.com/foo?foo=bar&page=10', $pager->getCurrent());
}

//--------------------------------------------------------------------

public function testGetCurrentWithSegment()
{
$uri = $this->uri;
$uri->addQuery('foo', 'bar');

$details = [
'uri' => $uri,
'pageCount' => 50,
'currentPage' => 10,
'total' => 100,
'segment' => 2,
];

$pager = new PagerRenderer($details);

$this->assertEquals('http://example.com/foo/10?foo=bar', $pager->getCurrent());
}

//--------------------------------------------------------------------

public function testSurroundCount()
{
$uri = $this->uri;
Expand Down
Loading

0 comments on commit a4b9526

Please sign in to comment.