Número de páginas erróneo con pager_query y theme_pager y el uso de $count_query

Hoy me he encontrado con este problema, cuando intentas paginar una consulta que tiene una cláusula DISTINCT para eliminar duplicados (o un GROUP BY equivalente), el número de páginas resultantes en el theme_pager es incorrecto.

¿por qué pasa esto?

En realidad, lo que pasa es que el pager_query inicializa una serie de variables globales que utiliza el theme_pager, entre ellas, el total de elementos y el número de páginas totales. Estas variables globales se ven alteradas al realizar la consulta que cuenta los registros devueltos, ya que filtra el DISTINCT.

por ejemplo

Vamos a intentar sacar paginados todos los términos de taxonomía utilizados en la web, para ello unimos las tablas term_node, que tiene los términos usados en cada nodo y term_data, que contiene información de cada término, por ejemplo, su nombre.

<?php
$sql = "SELECT DISTINCT td.name AS term_name, t.tid
            FROM term_node t
           JOIN term_data td ON t.tid = td.tid";
$result = pager_query($sql, 20);
while ($data = db_fetch_object($result)) {
  echo l($data->term_name,"taxonomy/term/".$data->tid) . "<br/>";
}
print theme('pager');
?>

Aquí podéis ver el resultado, las primeras páginas sacan los términos correctamente, pero hay más páginas de las que debería y están vacías. Esto es porque al contar, ha eliminado el DISTINCT y muestra todas las categorías por cada nodo, sin eliminar los duplicados.

¿cómo se resuelve

Hay que utilizar el cuarto parámetro del pager_query, $count_query, y pasarle una consulta que devuelva el número de registros diferentes que devuelve la consulta con el DISTINCT.

el ejemplo solucionado

<?php
$sql = "SELECT DISTINCT td.name AS term_name, t.tid
            FROM term_node t
           JOIN term_data td ON t.tid = td.tid";
$sql_count = "SELECT COUNT(DISTINCT td.name, t.tid)
            FROM term_node t
           JOIN term_data td ON t.tid = td.tid";
$result = pager_query($sql, 20, 0, $sql_count);
while ($data = db_fetch_object($result)) {
  echo l($data->term_name,"taxonomy/term/".$data->tid) . "<br/>";
}
print theme('pager');
?>

Aquí podéis ver la diferencia, pagina basándose en el número correcto de resultados diferentes que devuelve la consulta.

La solución ideal sería que implementaran una substitución en el pager_query que no filtrara las cláusulas DISTINCT, y es una tarea que parecía que iban a implementar en Drupal 6, pero finalmente no aplicaron ninguna solución, veremos si facilitan la tarea en la 7.

Comentarios

Estoy trabajando con Drupal 6, donde tengo un blog, y necesito paginar resultados de a 3 por pagina, tenes idea como se hace esto...

En el panel de Administración, bajo las opciones de Contenido, tienes una entrada de menú llamada Opciones de envío, ahí puedes configurar el número de elementos que se ven en la página principal.

Otra opción es que uses Views y te crees una vista de 3 elementos con la paginación activada y los campos que necesites.

Añadir nuevo comentario