Symfony

Com paginar els resultats amb Doctrine

Una de les preguntes freqüents quan realitzem un projecte en Symfony, és com aconseguir integrar un sistema de paginació quan estem realitzant una consulta a base de dades mitjançant el ORM Doctrine.

Drauta agencia digitalDrauta

Com paginar els resultats amb Doctrine

Doctrine i Symfony

És un procés senzill, però hauria de ser-ho més. Segurament aquest sigui el motiu que existeixin Bundles que faciliten aquesta tasca.

Aquest article utilitzarà el sistema de paginació integrat a Doctrine sense la necessitat d'instal·lar cap Bundle a part.

El primer que farem serà anar al repositori de l'entitat que volem llistar de forma paginada i integrem el següent mètode:

<?PHP
use Doctrine\ORM\Tools\Pagination\Paginator;

….

public function paginate($dql, $page = 1, $limit = 3)
{
    $paginator = new Paginator($dql);

    $paginator->getQuery()
        ->setFirstResult($limit * ($page - 1)) // Offset
        ->setMaxResults($limit); // Limit

    return $paginator;
}
?>

Simplement li passem una consulta que construirem amb el QueryBuilder de Doctrine, la pàgina actual i el nombre de resultats que vulguem mostrar per pàgina.

Ara també dins del repositori crearem un nou mètode que és el que realitzarà la consulta:

<?php
public function getAllPers($currentPage = 1, $limit = 3)
{
    // Create our query
    $query = $this->createQueryBuilder('p')
        ->getQuery();


    $paginator = $this->paginate($query, $currentPage, $limit);

    return array('paginator' => $paginator, 'query' => $query);
}

 ?>

Aquest mètode simplement ens retorna tots els resultats d'una entitat paginats.

Ara en el controlador:

<?php
/**
 * Lists all inmueble entities.
 *
 */
public function indexAction($currentPage = 1)
{

  $em = $this->getDoctrine()->getManager();


  $limit = 1;
  $inmuebles = $em->getRepository('DawInmobiliariaBundle:Inmueble')->getAllPers($currentPage, $limit);
  $inmueblesResultado = $inmuebles['paginator'];
  $inmueblesQueryCompleta =  $inmuebles['query'];

  $maxPages = ceil($inmuebles['paginator']->count() / $limit);

  return $this->render('inmueble/index.html.twig', array(
        'inmuebles' => $inmueblesResultado,
        'maxPages'=>$maxPages,
        'thisPage' => $currentPage,
        'all_items' => $inmueblesQueryCompleta
    ) );
}
 ?>

Si ens fiem al controlador li hem passat un paràmetre amb la pàgina actual. Això ho definim quan creem la ruta:

inmueble_index:
     path:     /{currentPage}/index
     defaults: { _controller: "DawInmobiliariaBundle:Inmueble:index" }
     methods:  GET

Finalment a la plantilla on estem vomitant el resultat enganxem:

{% if maxPages > 1 %}
    <ul>
        {%if thisPage > 1 %}
            <li >
                <a href="{{ path('inmueble_index', {currentPage: thisPage-1 < 1 ? 1 : thisPage-1}) }}">«</a>
            </li>
        {% endif %}

        {# Render each page number #}
        {% for i in 1..maxPages %}
            <li>
                <a href="{{ path('inmueble_index', {currentPage: i}) }}">{{ i }}</a>
            </li>
        {% endfor %}

        {# `»` arrow #}
        {%if thisPage < maxPages %}
            <li>
                <a href="{{ path('inmueble_index', {currentPage: thisPage+1 <= maxPages ? thisPage+1 : thisPage}) }}">»</a>
            </li>
        {% endif %}
    </ul>
{% endif %}

Això és tot. A primera vista sembla un sistema tediós, però Symfony és un Framework molt potent, amb unes bases molt solgudes. La qüestió és trobar mecanismes que mitjançant aquestes bases puguem agilitzar processos.

No hem d'oblidar que només pel fet de tenir una API de formularis vinculada amb Doctrine ho converteixen en un Framework impressionant.

Vols començar un nou projecte amb nosaltres?

Necessites un servei per a la teva web? Descobreix com et podem ajudar i no dubtis en contactar amb nosaltres.