Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add DoctrinePaginatorAdapter to interface with Doctrine pagination #362

Merged
merged 2 commits into from
Mar 12, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -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.",
Expand Down
118 changes: 118 additions & 0 deletions src/Pagination/DoctrinePaginatorAdapter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
<?php
/*
* This file is part of the League\Fractal package.
*
* (c) Phil Sturgeon <[email protected]>
*
* 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 <[email protected]>
*/
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;
}
}
63 changes: 63 additions & 0 deletions test/Pagination/DoctrinePaginatorAdapterTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?php
namespace League\Fractal\Test\Pagination;

use Doctrine\ORM\Query;
use League\Fractal\Pagination\DoctrinePaginatorAdapter;
use Mockery;

class DoctrinePaginatorAdapterTest extends \PHPUnit_Framework_TestCase
{
public function testPaginationAdapter()
{
$total = 50;
$count = 5;
$perPage = 5;
$currentPage = 2;
$lastPage = 10;

//Mock the doctrine paginator
$paginator = Mockery::mock('Doctrine\ORM\Tools\Pagination\Paginator')->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();
}
}