Skip to content

Instantly share code, notes, and snippets.

@atillay
Last active October 11, 2022 07:25
Show Gist options
  • Save atillay/f309aff35a6e4dd19a16c92caa8669ab to your computer and use it in GitHub Desktop.
Save atillay/f309aff35a6e4dd19a16c92caa8669ab to your computer and use it in GitHub Desktop.
Symfony 4 Pagination Service
{% set _currentPage = app.request.query.get('p') ?: 1 %}
{% set _currentRoute = app.request.attributes.get('_route') %}
{% set _currentParams = app.request.query.all %}
{% if lastPage > 1 %}
<nav>
<ul class="pagination">
{% if _currentPage > 1 %}
<li class="page-item">
<a class="page-link" href="{{ path(_currentRoute, _currentParams|merge({p: _currentPage - 1})) }}" aria-label="Previous">
<span aria-hidden="true">&laquo;</span>
<span class="sr-only">Previous</span>
</a>
</li>
{% endif %}
{% for i in 1..lastPage %}
<li class="page-item {% if i == _currentPage %}active{% endif %}">
<a class="page-link" href="{{ path(_currentRoute, _currentParams|merge({p: i})) }}">{{ i }}</a>
</li>
{% endfor %}
{% if _currentPage < lastPage %}
<li class="page-item">
<a class="page-link" href="{{ path(_currentRoute, _currentParams|merge({p: _currentPage + 1})) }}" aria-label="Next">
<span aria-hidden="true">&raquo;</span>
<span class="sr-only">Next</span>
</a>
</li>
{% endif %}
</ul>
</nav>
{% endif %}
<?php
namespace App\Controller;
use App\Entity\Demo;
use App\Service\PaginationService;
use Symfony\Component\HttpFoundation\Request;
class DemoController extends AdminController
{
const ITEMS_PER_PAGE = 50;
public function index(Request $request, PaginationService $pagination)
{
$query = $this->em->getRepository(Demo::class)->getQuery();
$results = $pagination->paginate($query, $request, self::ITEMS_PER_PAGE);
return $this->render('admin/school/index.html.twig', [
'schools' => $schools,
'lastPage' => $pagination->lastPage($results)
]);
}
}
<?php
namespace App\Service;
use Doctrine\ORM\Query;
use Doctrine\ORM\QueryBuilder;
use Doctrine\ORM\Tools\Pagination\Paginator;
use Symfony\Component\HttpFoundation\Request;
class PaginationService
{
/**
* @param QueryBuilder|Query $query
* @param Request $request
* @param int $limit
* @return Paginator
*/
public function paginate($query, Request $request, int $limit): Paginator
{
$currentPage = $request->query->getInt('p') ?: 1;
$paginator = new Paginator($query);
$paginator
->getQuery()
->setFirstResult($limit * ($currentPage - 1))
->setMaxResults($limit);
return $paginator;
}
/**
* @param Paginator $paginator
* @return int
*/
public function lastPage(Paginator $paginator): int
{
return ceil($paginator->count() / $paginator->getQuery()->getMaxResults());
}
/**
* @param Paginator $paginator
* @return int
*/
public function total(Paginator $paginator): int
{
return $paginator->count();
}
/**
* @param Paginator $paginator
* @return bool
*/
public function currentPageHasNoResult(Paginator $paginator): bool
{
return !$paginator->getIterator()->count();
}
}
@sharipovmarat
Copy link

SF4 use like this...
$query = $this->getDoctrine()->getManager()->getRepository(Demo::class)->createQueryBuilder('d');

@julkwel
Copy link

julkwel commented Jan 10, 2021

Some improve for extrem pagination

{% set _currentPage = app.request.query.get('p') ?: 1 %}
{% set _currentRoute = app.request.attributes.get('_route') %}
{% set _currentParams = app.request.query.all %}
{% set nearbyPagesLimit = 4 %}
{% if lastPage > 1 %}
    <div class="col-md-12">
        <nav>
            <ul class="pagination">
                {% if _currentPage > 1 %}
                    <li class="page-item">
                        <a class="page-link"
                           href="{{ path(_currentRoute, _currentParams|merge({p: _currentPage - 1})) }}"
                           aria-label="Previous">
                            <span aria-hidden="true">&laquo;</span>
                            <span class="sr-only">Précedent</span>
                        </a>
                    </li>
                {% endif %}
                {% for i in 1..lastPage %}
                    {% if 0 == (_currentPage - nearbyPagesLimit) - loop.index %} {# dot before #}
                        <li class="disabled"><a class="page-link"  href="#">...</a></li>
                    {% elseif 0 == (_currentPage + nearbyPagesLimit) - loop.index %} {# dot after #}
                        <li class="disabled"><a class="page-link" href="#">...</a></li>
                    {% elseif 0 < (_currentPage - nearbyPagesLimit) - loop.index %} {# hide all before #}
                    {% elseif 0 > (_currentPage + nearbyPagesLimit) - loop.index %} {# hide all after #}
                    {% else %}
                        <li {% if _currentPage == loop.index  %} class="page-item active"{% endif %}>
                            <a class="page-link" href="{{ path(_currentRoute, _currentParams|merge({p: i})) }}">{{ loop.index }}</a>
                        </li>
                    {% endif %}
                {% endfor %}
                {% if _currentPage < lastPage %}
                    <li class="page-item">
                        <a class="page-link"
                           href="{{ path(_currentRoute, _currentParams|merge({p: _currentPage + 1})) }}"
                           aria-label="Next">
                            <span aria-hidden="true">&raquo;</span>
                            <span class="sr-only">Suivant</span>
                        </a>
                    </li>
                {% endif %}
            </ul>
        </nav>
    </div>
{% endif %}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment