From a2cecfbdd8ef075b313a254001dbcb8303e6102b Mon Sep 17 00:00:00 2001 From: Dan Richards Date: Mon, 11 Sep 2017 16:30:09 +0100 Subject: [PATCH] Removed setter for the offset and lastPage values from Paginator. The offset and lastPage are now automatically updated if any of the other values change. Added tests. --- src/Pagination/Paginator.php | 78 ++++++++++++++++++++++------------ tests/MicroServiceCoreTest.php | 65 ++++++++++++++++++++++++++++ 2 files changed, 116 insertions(+), 27 deletions(-) diff --git a/src/Pagination/Paginator.php b/src/Pagination/Paginator.php index 1d84f7b..b0fab03 100644 --- a/src/Pagination/Paginator.php +++ b/src/Pagination/Paginator.php @@ -60,14 +60,26 @@ class Paginator */ public function __construct($total, $perPage, $page) { + if (!is_int($total)) { + throw new \RuntimeException('Total value must be an integer.'); + } + + if (!is_int($perPage)) { + throw new \RuntimeException('Per page value must be an integer.'); + } + + if (!is_int($page)) { + throw new \RuntimeException('Page value must be an integer.'); + } + // Set up the basic pagination values. - $this->setTotal($total); - $this->setPerPage($perPage); - $this->setPage($page); + $this->total = $total; + $this->perPage = $perPage; + $this->page = $page; // Calculate the offset and last possible page based on these values. - $this->setOffset(($this->page - 1) * $this->perPage); - $this->setLastPage(ceil($total / $this->perPage)); + $this->calculateOffset(); + $this->calculateLastPage(); } /** @@ -88,6 +100,10 @@ public function setPerPage($perPage) } $this->perPage = $perPage; + + // Calculate the offset and last possible page based on this change. + $this->calculateOffset(); + $this->calculateLastPage(); } /** @@ -108,6 +124,10 @@ public function setPage($page) } $this->page = $page; + + // Calculate the offset and last possible page based on this change. + $this->calculateOffset(); + $this->calculateLastPage(); } /** @@ -118,18 +138,6 @@ public function getOffset() return $this->offset; } - /** - * @param int $offset - */ - public function setOffset($offset) - { - if (!is_int($offset)) { - throw new \RuntimeException('Offset value must be an integer.'); - } - - $this->offset = $offset; - } - /** * @return int */ @@ -148,6 +156,10 @@ public function setTotal($total) } $this->total = $total; + + // Calculate the offset and last possible page based on this change. + $this->calculateOffset(); + $this->calculateLastPage(); } /** @@ -159,24 +171,36 @@ public function getLastPage() } /** - * @param int $lastPage + * Prepare the pagination response. + * + * @return Response */ - public function setLastPage($lastPage) + public function preparePaginationResponse() { - if (!is_int($lastPage)) { - throw new \RuntimeException('Last page value must be an integer.'); + return new Response($this->total, $this->perPage, $this->page, $this->lastPage); + } + + /** + * Calculate the offset based on the current values. + */ + protected function calculateOffset() + { + if (empty($this->page) || empty($this->perPage)) { + throw new \RuntimeException('Cannot calculate offset. Insufficient data'); } - $this->lastPage = $lastPage; + $this->offset = ($this->page - 1) * $this->perPage; } /** - * Prepare the pagination response. - * - * @return Response + * Calculate the last page based on the current values. */ - public function preparePaginationResponse() + protected function calculateLastPage() { - return new Response($this->total, $this->perPage, $this->page, $this->lastPage); + if (empty($this->total) || empty($this->perPage)) { + throw new \RuntimeException('Cannot calculate last page. Insufficient data'); + } + + $this->lastPage = (int) ceil($this->total / $this->perPage); } } \ No newline at end of file diff --git a/tests/MicroServiceCoreTest.php b/tests/MicroServiceCoreTest.php index da7eaa5..f0a1859 100644 --- a/tests/MicroServiceCoreTest.php +++ b/tests/MicroServiceCoreTest.php @@ -8,6 +8,7 @@ use Illuminate\Validation\ValidationException; use LushDigital\MicroServiceCore\Enum\BaseEnum; use LushDigital\MicroServiceCore\Helpers\MicroServiceHelper; +use LushDigital\MicroServiceCore\Pagination\Paginator; use Symfony\Component\HttpKernel\Exception\HttpException; /** @@ -254,6 +255,70 @@ public function testStringTrait() $this->assertEquals('Test000', $stringExample->examplePadTrim('Test', '0', 7, STR_PAD_RIGHT)); $this->assertEquals('0Test00', $stringExample->examplePadTrim('Test', '0', 7, STR_PAD_BOTH)); } + + public function testPagination() + { + // Test the basics of pagination. + $paginator = new Paginator(100, 10, 1); + $this->assertEquals($paginator->getOffset(), 0); + $this->assertEquals($paginator->getLastPage(), 10); + + $paginatorTwo = new Paginator(100, 10, 2); + $this->assertEquals($paginatorTwo->getOffset(), 10); + $this->assertEquals($paginatorTwo->getLastPage(), 10); + + $paginatorThree = new Paginator(100, 7, 1); + $this->assertEquals($paginatorThree->getOffset(), 0); + $this->assertEquals($paginatorThree->getLastPage(), 15); + + $paginatorFour = new Paginator(100, 7, 2); + $this->assertEquals($paginatorFour->getOffset(), 7); + $this->assertEquals($paginatorFour->getLastPage(), 15); + + // Test changing values after creation. + $changedPaginator = new Paginator(100, 10, 1); + $changedPaginator->setPage(2); + $this->assertEquals($changedPaginator->getOffset(), 10); + $this->assertEquals($changedPaginator->getLastPage(), 10); + + $changedPaginatorTwo = new Paginator(100, 10, 1); + $changedPaginatorTwo->setPerPage(50); + $this->assertEquals($changedPaginatorTwo->getOffset(), 0); + $this->assertEquals($changedPaginatorTwo->getLastPage(), 2); + + $changedPaginatorThree = new Paginator(100, 10, 1); + $changedPaginatorThree->setTotal(19); + $this->assertEquals($changedPaginatorThree->getOffset(), 0); + $this->assertEquals($changedPaginatorThree->getLastPage(), 2); + + $changedPaginatorFour = new Paginator(100, 10, 1); + $changedPaginator->setPage(2); + $changedPaginatorTwo->setPerPage(50); + $changedPaginatorFour->setTotal(19); + $this->assertEquals($changedPaginatorFour->getOffset(), 0); + $this->assertEquals($changedPaginatorFour->getLastPage(), 2); + + // Test the pagination response. + $responsePaginator = new Paginator(100, 10, 1); + $this->assertEquals((array) [ + 'total' => 100, + 'per_page' => 10, + 'current_page' => 1, + 'last_page' => 10, + 'next_page' => 2, + 'prev_page' => null + ], (array) $responsePaginator->preparePaginationResponse()->snakeFormat()); + + $responsePaginatorTwo = new Paginator(100, 10, 2); + $this->assertEquals((array) [ + 'total' => 100, + 'per_page' => 10, + 'current_page' => 2, + 'last_page' => 10, + 'next_page' => 3, + 'prev_page' => 1 + ], (array) $responsePaginatorTwo->preparePaginationResponse()->snakeFormat()); + } } /**