Last active
December 5, 2016 10:29
-
-
Save cifren/7938081 to your computer and use it in GitHub Desktop.
Paginator class for symfony2 Give the possibility to create pagination on symfon2 and with bootstrap3, including Doctrine management
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/*Controller/InvoiceController.php*/ | |
namespace Ruby\CheckbookBundle\Controller; | |
use Symfony\Bundle\FrameworkBundle\Controller\Controller; | |
class InvoiceController extends Controller | |
{ | |
public function listAction($page) | |
{ | |
$maxPerPage = 20; | |
$itemQueryBuilder = $this->getEm()->getRepository('Concept:Invoice') | |
->createQueryBuilder('s') | |
->setParameter('fgsId', 10902); | |
//build object paginator | |
$paginator = $this->get('model.helper.paginator'); | |
//instantiate all information for paginator | |
$paginator->applyOnQueryBuilder($maxPerPage, $itemQueryBuilder, 'ruby_checkbook_invoice_manager'); | |
//items to display | |
$items = $itemQueryBuilder->getQuery()->getResult(); | |
return $this->render('RubyCheckbookBundle:Invoice:list.html.twig', array( | |
'items' => $items, | |
'paginator' => $paginator | |
)); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{#views/Invoice/list.html.twig#} | |
{% block body %} | |
<h1>Checkbook manager</h1> | |
<div class="container"> | |
<table class="table table-bordered"> | |
<thead> | |
<tr> | |
<th>id</th> | |
<th>Business date</th> | |
<th>Invoice date</th> | |
<th>Invoice</th> | |
<th>Supplier</th> | |
<th>Total account</th> | |
<th>Status</th> | |
<th>Action</th> | |
</tr> | |
</thead> | |
<tbody> | |
{% for item in items %} | |
<tr> | |
<td>{{item.id}}</td> | |
<td>{{item.businessDate.format('Y-m-d')}}</td> | |
<td>{{item.invoiceDate.format('Y-m-d')}}</td> | |
<td>{{item.supplierInvoiceId}}</td> | |
<td>{{item.supplierId}}</td> | |
<td>{{item.invoiceAmount}}</td> | |
<td>new</td> | |
<td><a class="btn btn-primary" href='#'>Edit</a></td> | |
</tr> | |
{% endfor %} | |
</tbody> | |
</table> | |
<div class="center-block"> | |
{% include "RubyCheckbookBundle:Invoice:pagination.html.twig" with { 'paginator' : paginator}%} | |
</div> | |
</div> | |
{% endblock %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{#views/Invoice/pagination.html.twig#} | |
{% if paginator.maxPage > 1 %} | |
<ul class="pagination"> | |
{% if paginator.currentPage > 1 %} | |
<li><a href="{{ path(paginator.paginationPath, paginator.currentFilters|merge({page: paginator.currentPage-1})) }}">« Previous</a></li> | |
{% else %} | |
<li class="disabled"><a>« Previous</a></li> | |
{% endif %} | |
{% for i in range(1, paginator.extremePagesLimit) if ( i < paginator.currentPage - paginator.nearbyPagesLimit ) %} | |
<li><a href="{{ path(paginator.paginationPath, paginator.currentFilters|merge({page: i})) }}">{{ i }}</a></li> | |
{% endfor %} | |
{% if paginator.extremePagesLimit + 1 < paginator.currentPage - paginator.nearbyPagesLimit %} | |
<li><a>...</a></li> | |
{% endif %} | |
{% for i in range(paginator.currentPage-paginator.nearbyPagesLimit, paginator.currentPage-1) if ( i > 0 ) %} | |
<li><a href="{{ path(paginator.paginationPath, paginator.currentFilters|merge({page: i})) }}">{{ i }}</a></li> | |
{% endfor %} | |
<li class="active"><a>{{ paginator.currentPage }}</a></li> | |
{% if paginator.currentPage < paginator.maxPage %} | |
{% for i in range(paginator.currentPage+1, paginator.maxPage) %} | |
{% if ( loop.index <= paginator.nearbyPagesLimit and i <= paginator.maxPage ) %} | |
<li><a href="{{ path(paginator.paginationPath, paginator.currentFilters|merge({page: i})) }}">{{ i }}</a></li> | |
{% endif %} | |
{% endfor %} | |
{% if (paginator.maxPage - paginator.extremePagesLimit) > (paginator.currentPage + paginator.nearbyPagesLimit ) %} | |
<li><a>...</a></li> | |
{% endif %} | |
{% for i in range(paginator.maxPage-paginator.extremePagesLimit+1, paginator.maxPage) if ( i > paginator.currentPage+paginator.nearbyPagesLimit ) %} | |
<li><a href="{{ path(paginator.paginationPath, paginator.currentFilters|merge({page: i})) }}">{{ i }}</a></li> | |
{% endfor %} | |
{% endif %} | |
{% if paginator.currentPage < paginator.maxPage %} | |
<li><a href="{{ path(paginator.paginationPath, paginator.currentFilters|merge({page: paginator.currentPage+1})) }}">Next »</a></li> | |
{% else %} | |
<li class="disabled"><a>Next »</a></li> | |
{% endif %} | |
</ul> | |
{% endif %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/*Model/Helpers/paginator.php*/ | |
namespace Ruby\CheckbookBundle\Model\Helpers; | |
use Symfony\Component\HttpFoundation\Request; | |
use Doctrine\ORM\QueryBuilder; | |
/** | |
* Ruby\CheckbookBundle\Model\Helpers\Paginator | |
*/ | |
class Paginator | |
{ | |
//current displayed page | |
protected $currentPage; | |
//how many item in pagination on extreme side | |
protected $extremePagesLimit = 3; | |
//how many item in pagination on intern side | |
protected $nearbyPagesLimit = 2; | |
//route for link on view | |
protected $paginationPath; | |
//limit items on one page, default 10 | |
protected $limitPerPage = 10; | |
//query builder used for counting and set offset and limit | |
protected $queryBuilder; | |
//oject request from symfony2 | |
protected $request; | |
//how many items pulled by queryBuilder | |
protected $countItems; | |
//from countItems get number pages | |
protected $maxPage; | |
//information from request about all current parameter in url, used for link in view | |
protected $currentFilters; | |
public function __construct(Request $request) | |
{ | |
$this->request = $request; | |
//by default will try to get page parameter | |
$page = $this->request->get('page'); | |
if (isset($page)) { | |
$this->setCurrentPage($page); | |
} else { | |
$this->setCurrentPage(1); | |
} | |
$this->currentFilters = $request->query->all(); | |
} | |
public function setCurrentPage($value) | |
{ | |
$this->currentPage = $value; | |
return $this; | |
} | |
public function getCurrentPage() | |
{ | |
return $this->currentPage; | |
} | |
protected function setLimitPerPage($value) | |
{ | |
$value = intval($value); | |
if (empty($value)) { | |
$this->limitPerPage = 10; | |
} else { | |
$this->limitPerPage = $value; | |
} | |
return $this; | |
} | |
public function getLimitPerPage() | |
{ | |
return $this->limitPerPage; | |
} | |
public function applyOnQueryBuilder($limitPerPage, $queryBuilder, $paginationPath, $extremePagesLimit = null, $nearbyPagesLimit = null) | |
{ | |
$this->paginationPath = $paginationPath; | |
$this->extremePagesLimit = $extremePagesLimit ? $extremePagesLimit : $this->extremePagesLimit; | |
$this->nearbyPagesLimit = $nearbyPagesLimit ? $nearbyPagesLimit : $this->nearbyPagesLimit; | |
$this->setLimitPerPage($limitPerPage); | |
$this->queryBuilder = $queryBuilder; | |
$this->handlePageOutOfRange(); | |
$this->countItems = $this->getCountItems(); | |
$this->maxPage = $this->getMaxPage(); | |
$this->queryBuilder->setFirstResult($this->getOffset())->setMaxResults($this->getLimitPerPage()); | |
return $this; | |
} | |
protected function handlePageOutOfRange() | |
{ | |
if ($this->currentPage > $this->getMaxPage() || $this->currentPage < 0 || empty($this->currentPage)) { | |
$this->currentPage = 1; | |
} | |
} | |
public function getCountItems() | |
{ | |
if (!$this->countItems) { | |
return count($this->queryBuilder->getQuery()->getResult()); | |
} | |
return $this->countItems; | |
} | |
public function getMaxPage() | |
{ | |
if (!$this->maxPage) { | |
return ceil($this->getCountItems() / $this->limitPerPage); | |
} | |
return $this->maxPage; | |
} | |
public function getOffset() | |
{ | |
return $this->limitPerPage * ($this->currentPage - 1); | |
} | |
public function getExtremePagesLimit() | |
{ | |
return $this->extremePagesLimit; | |
} | |
public function getNearbyPagesLimit() | |
{ | |
return $this->nearbyPagesLimit; | |
} | |
public function getPaginationPath() | |
{ | |
return $this->paginationPath; | |
} | |
public function getCurrentFilters() | |
{ | |
return $this->currentFilters; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#config/service.yml | |
services: | |
model.helper.paginator: | |
class: Ruby\CheckbookBundle\Model\Helpers\Paginator | |
arguments: | |
- "@request" | |
scope: request |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment