diff --git a/composer.json b/composer.json index 3e249f4f..8275c092 100644 --- a/composer.json +++ b/composer.json @@ -26,7 +26,8 @@ "illuminate/contracts": "~5.0", "squizlabs/php_codesniffer": "~1.5", "pagerfanta/pagerfanta": "~1.0.0", - "zendframework/zend-paginator":"~2.3" + "zendframework/zend-paginator":"~2.3", + "doctrine/orm": "^2.5" }, "suggest": { "illuminate/pagination": "The Illuminate Pagination component.", diff --git a/src/Pagination/DoctrinePaginatorAdapter.php b/src/Pagination/DoctrinePaginatorAdapter.php new file mode 100644 index 00000000..07d4ef35 --- /dev/null +++ b/src/Pagination/DoctrinePaginatorAdapter.php @@ -0,0 +1,118 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace League\Fractal\Pagination; + +use Doctrine\ORM\Tools\Pagination\Paginator; + +/** + * A paginator adapter for doctrine pagination. + * + * @author Fraser Stockley + */ +class DoctrinePaginatorAdapter implements PaginatorInterface +{ + /** + * The paginator instance. + * @var Paginator + */ + private $paginator; + + /** + * The route generator. + * + * @var callable + */ + private $routeGenerator; + + /** + * Create a new DoctrinePaginatorAdapter. + * @param Paginator $paginator + * @param callable $routeGenerator + * + */ + public function __construct(Paginator $paginator, callable $routeGenerator) + { + $this->paginator = $paginator; + $this->routeGenerator = $routeGenerator; + } + + /** + * Get the current page. + * + * @return int + */ + public function getCurrentPage() + { + return ($this->paginator->getQuery()->getFirstResult() / $this->paginator->getQuery()->getMaxResults()) + 1; + } + + /** + * Get the last page. + * + * @return int + */ + public function getLastPage() + { + return (int) ceil($this->getTotal() / $this->paginator->getQuery()->getMaxResults()); + } + + /** + * Get the total. + * + * @return int + */ + public function getTotal() + { + return count($this->paginator); + } + + /** + * Get the count. + * + * @return int + */ + public function getCount() + { + return $this->paginator->getIterator()->count(); + } + + /** + * Get the number per page. + * + * @return int + */ + public function getPerPage() + { + return $this->paginator->getQuery()->getMaxResults(); + } + + /** + * Get the url for the given page. + * + * @param int $page + * + * @return string + */ + public function getUrl($page) + { + return call_user_func($this->getRouteGenerator(), $page); + } + + /** + * Get the the route generator. + * + * @return callable + */ + private function getRouteGenerator() + { + return $this->routeGenerator; + } +} diff --git a/test/Pagination/DoctrinePaginatorAdapterTest.php b/test/Pagination/DoctrinePaginatorAdapterTest.php new file mode 100644 index 00000000..afd30015 --- /dev/null +++ b/test/Pagination/DoctrinePaginatorAdapterTest.php @@ -0,0 +1,63 @@ +makePartial(); + $paginator->shouldReceive('count')->andReturn($total); + + + //Mock the query that the paginator is acting on + $query = Mockery::mock('Doctrine\ORM\AbstractQuery'); + $query->shouldReceive('getFirstResult')->andReturn(($currentPage - 1) * $perPage); + $query->shouldReceive('getMaxResults')->andReturn($perPage); + $paginator->shouldReceive('getQuery')->andReturn($query); + + //Mock the iterator of the paginator + $iterator = Mockery::mock('IteratorAggregate'); + $iterator->shouldReceive('count')->andReturn($count); + $paginator->shouldReceive('getIterator')->andReturn($iterator); + + + $adapter = new DoctrinePaginatorAdapter($paginator, function ($page) { + return 'http://example.com/foo?page='.$page; + }); + + $this->assertInstanceOf( + 'League\Fractal\Pagination\PaginatorInterface', + $adapter + ); + + $this->assertSame($currentPage, $adapter->getCurrentPage()); + $this->assertSame($lastPage, $adapter->getLastPage()); + $this->assertSame($count, $adapter->getCount()); + $this->assertSame($total, $adapter->getTotal()); + $this->assertSame($perPage, $adapter->getPerPage()); + $this->assertSame( + 'http://example.com/foo?page=1', + $adapter->getUrl(1) + ); + $this->assertSame( + 'http://example.com/foo?page=3', + $adapter->getUrl(3) + ); + } + + public function tearDown() + { + Mockery::close(); + } +}