Clase para paginar un array en php

He creado la siguiente clase (CPaginas) ya que no he encontrado una equivalente y generica para mostrar por paginas el contenido de cualquier array. La clase CPaginas sirve para paginar cualquier array. El pseudo algoritmo seria el siguiente:
- Obtener array indexado en enteros
- Construir un objeto pagina con el array obtenido
- Recuperar el array reducido
$arItems[0]=array(...);
$arItems[1]=array(...);
$arItems[.]=array(...);
$arItems[i]=array(...);
$arItems[.]=array(...);
$arItems[n]=array(...);
La forma de usar la clase CPaginas
//Cualquier modelo
$oModelo = new MModelo();
//Obtenemos un listado desde el modelo
$arTabla = $oModelo->get_tabla();
//Pagina pedida $arUriParams[3]=$_GET['page'];
$iPagina = $arUriParams[3];
//El listado es un array indexado por enteros
//$sUrl = 'www.midomino.com/coches/?page=' el link con el que se generaran los botones de navegacion
$oPagina = new CPaginas($arTabla, $iPagina, $sUrl, 8);
//Reutilizamos el array dejando solo los items que le corresponde
//a la pagina $iPagina
$arTabla = $oPagina->get_items_to_show();
$sBotones = $oPagina->get_botones_in_html();
//Ahora solo queda recorrer $arTabla e ir imprimiendo su
//contenido en pantalla y hacer un echo $sBotones;
El código de la clase CPaginas:
class CPaginas
{
private $_arItems;
/**
* Los items por pagina que se deberan mostrar
*
* @var mixed
*/
private $_iItemsPagina;
private $_iPagina;
private $_iNumPaginas;
private $_isExacto = true;
private $_sUrl;
//$arItems: El array que se troceara en paginas
//$iPagina: La pagina a mostrar
//$sUrl: Es la url con la que se crearan los botones ejemplo: www.midominio.com/coches/electricos?page=
//$iItemsPagina: La cantidad de items por pagina a mostrar
public function __construct($arItems, $iPagina=1, $sUrl="", $iItemsPagina=15)
{
$this->_arItems = $arItems;
$this->_iItemsPagina = $iItemsPagina;
$this->_iPagina = $this->avoid_not_number($iPagina);
$this->_iNumPaginas = $this->num_paginas_resultantes();
$this->_sUrl = $sUrl;
}
private function avoid_not_number($string)
{
$iEntero = $string;
if(!is_numeric($iEntero))
{
$iEntero = 1;
}
return $iEntero;
}
private function get_array_items()
{
$arResultado = array();
$arItems = $this->_arItems;
$iItemsPagina = $this->_iItemsPagina;
$iPagina = $this->_iPagina;
$iNumPaginas = $this->_iNumPaginas;
//Si la pagina recibida esta en el rango
if($iPagina > 0 && $iPagina <= $iNumPaginas) { //iKeyInicio = 8 x (4-1) = 24 $iKeyInicio = $iItemsPagina * ($iPagina - 1); //iKeyFinal = 24 + (8 - 1) = 24 + 7 = 31 //En caso de resto == 0 y que la pagina actual no sea //la ultima se puede aplicar el key Final asi $iKeyFinal = $iKeyInicio + ($iItemsPagina - 1); //Si la pagina actual es la ultima if($iPagina == $iNumPaginas && !$this->_isExacto)
{
//Las paginas que respetan los items/pagina
$iPaginasCompletas = $iNumPaginas - 1;
//El numero de items distribuidos en estas paginas
$iItemsDistribuidos = $iPaginasCompletas * $iItemsPagina;
$iItemsUltimaPagina = count($arItems) - $iItemsDistribuidos;
$iKeyFinal = $iKeyInicio + ($iItemsUltimaPagina - 1);
}
$k = 0;
for($i=$iKeyInicio; $i<=$iKeyFinal; $i++) { $arResultado[$k] = $arItems[$i]; $k++; } //bug($arResultado, 'get_array_items'); } else //La pagina pedida no esta en el rango { $arResultado = null; } return $arResultado; } private function num_paginas_resultantes() { $arItems = $this->_arItems;
$iItemsPagina = $this->_iItemsPagina;
$iTotalItems = count($arItems);
$iNumPaginas = intval( $iTotalItems / $iItemsPagina);
$iResto = $iTotalItems % $iItemsPagina;
//Si el resto es mayor que cero es porque se necesita
//una pagina mas
if($iResto > 0)
{
//Con esto indico que la ultima pagina no tendra
//un listado respetando "itemps/pagina" sino que sera menor
$this->_isExacto = false;
$iNumPaginas++;
}
// bug($iNumPaginas);
return $iNumPaginas;
}
private function get_array_navegacion()
{
$arBotones = array();
$iNumPaginas = $this->_iNumPaginas;
$iPaginaActual = $this->_iPagina;
//Hay al menos una pagina
if($iNumPaginas > 0)
{
switch($iPaginaActual)
{
//En caso que se pase una pagina 0 o negativa (Fuera de rango)
case($iPaginaActual < 1): $arBotones = "Error: pagina fuera de rango"; break; //Si solo existe una unica pagina case ($iPaginaActual==1 && $iNumPaginas==1): //No hay botones de ningun tipo $arBotones = null; break; //Si estamos en la primera y hay mas de una case ($iPaginaActual==1 && $iNumPaginas>1):
$arBotones['nav_numeros'] = $this->get_botones_numero();
$arBotones['nav_siguiente'] = $this->get_botones_siguiente();
break;
//Si no es ni la primera ni la ultima
case ($iPaginaActual>1 && $iPaginaActual<$iNumPaginas): $arBotones['nav_anterior'] = $this->get_botones_anterior();
$arBotones['nav_numeros'] = $this->get_botones_numero();
$arBotones['nav_siguiente'] = $this->get_botones_siguiente();
break;
//Si es la ultima
case ($iPaginaActual>1 && $iPaginaActual==$iNumPaginas):
$arBotones['nav_anterior'] = $this->get_botones_anterior();
$arBotones['nav_numeros'] = $this->get_botones_numero();
break;
//Si es mayor a la ultima (fuera de rango)
case ($iPaginaActual>$iNumPaginas):
$arBotones = "Error: pagina fuera de rango pagina actual:$iPaginaActual, total paginas:$iNumPaginas";
default:
}
}
return $arBotones;
}
private function get_botones_numero()
{
$arBoton = array();
$iPaginaNoBoton = $this->_iPagina;
$iNumPaginas = $this->_iNumPaginas;
$sUrl = $this->_sUrl;
for($i=1; $i<=$iNumPaginas; $i++)
{
if($i != $iPaginaNoBoton)
{
//bug($sUrl,'url en get_botones numero');
$sTmpUrl = $sUrl . $i ."/"; ;
$sBotonAnchor = "<span> <a href="\"$sTmpUrl\"">$i</a> </span>";
}
else
{
$sBotonAnchor = "<span class="\"stlPaginaActual\"">$iPaginaNoBoton</span>";
}
$arBoton[$i] = $sBotonAnchor;
}
return $arBoton;
}
private function get_botones_anterior()
{
$arBoton = array('inicio'=>"",'final'=>"");
$iPaginaActual = $this->_iPagina;
$iNumPaginas = $this->_iNumPaginas;
$sUrl = $this->_sUrl;
//Pagina 1
$sTmpUrl = $sUrl . 1 . "/";
$arBoton['inicio'] = "<span> <a href="\"$sTmpUrl\"">|<</a> </span>";
//Pagina anterior a la actual si la actual es > 1
$sTmpUrl = $sUrl . ($iPaginaActual-1). "/";
$arBoton['anterior'] = "<span> <a href="\"$sTmpUrl\""><<</a> </span>";
return $arBoton;
}
private function get_botones_siguiente()
{
$arBoton = array('siguiente'=>"",'final'=>"");
$iPaginaActual = $this->_iPagina;
$iUltimaPagina = $this->_iNumPaginas;
$sUrl = $this->_sUrl;
//Solo hay siguiente si la pagina_actual es menor a la ultima pagina (o total de paginas)
if($iPaginaActual<$iUltimaPagina)
{
$sTmpUrl = $sUrl . ($iPaginaActual+1). "/";
$arBoton['siguiente'] = "<span> <a href="\"$sTmpUrl\"">>></a> </span>";
}
$sTmpUrl = $sUrl . $iUltimaPagina . "/";
$arBoton['final'] = "<span> <a href="\"$sTmpUrl\"">>|</a> </span>";
return $arBoton;
}
public function get_items_to_show()
{
return $this->get_array_items();
}
public function get_botones_to_show()
{
return $this->get_array_navegacion();
}
public function get_botones_in_html()
{
$sBotonesHtml = "";
$arBotones = $this->get_array_navegacion();
//bug($arBotones,'arbotones en get_botones_in_html');
//Navegacion inicio anterior
if(!empty($arBotones['nav_anterior']))
{
$sBotonesHtml .= $arBotones['nav_anterior']['inicio'];
$sBotonesHtml .= $arBotones['nav_anterior']['anterior'];
}
//Navegacion numeros paginas
if(!empty($arBotones['nav_numeros']))
{
foreach($arBotones['nav_numeros'] as $sBoton)
{
$sBotonesHtml .= $sBoton;
}
}
//Navegacion siguiente final
if(!empty($arBotones['nav_siguiente']))
{
$sBotonesHtml.= $arBotones['nav_siguiente']['siguiente'];
$sBotonesHtml.= $arBotones['nav_siguiente']['final'];
}
return $sBotonesHtml;
}
}
Autor: Eduardo A. F.
Publicado: 17-04-2011 19:27
Actualizado: 02-07-2011 15:47