Desarrollo de Aplicaciones

Cómo paginar los resultados con Doctrine

Una de las preguntas frecuentes cuando realizamos un proyecto en Symfony, es cómo conseguir integrar un sistema de paginación cuando estamos realizando una consulta a base de datos mediante el ORM Doctrine.

Cómo paginar los resultados con Doctrine

Doctrine y Symfony

Es un proceso sencillo, pero debería serlo más. Seguramente este sea el motivo de que existan Bundles que facilitan esa labor.

Este artículo va a utilizar el sistema de paginación integrado en Doctrine sin la necesidad de instalar ningún Bundle a parte.

Lo primero vamos al repositorio de la entidad que queremos listar de forma paginada e integramos el siguiente método:

<?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;
}
?>

Simplemente le pasamos una consulta que construiremos con el QueryBuilder de Doctrine, la página actual y el número de resultados que queramos mostrar por página.

Ahora también dentro del repositorio creamos un nuevo método que es el que realizará 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);
}

 ?>

Este método simplemente nos devuelve todos los resultados de una entidad paginados.

Ahora 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 nos fiamos al controlador le hemos pasado un parámetro con la página actual. Esto lo definimos cuando creamos la ruta:

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

Finalmente en la plantilla donde estamos vomitando el resultado enganchamos:

{% 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 %}

Eso es todo. A primera vista parece un sistema tedioso, pero Symfony es un Framework muy potente, con unas bases muy solidas. La cuestión es encontrar mecanismos que mediante estas bases podamos agilizar procesos.

No debemos olvidar que solo por el hecho de tener una API de formularios vinculada con Doctrine lo convierten en un Framework impresionante.

Comparte este artículo

Artículos Relacionados