En algún momento puede que te encuentres con un tipo de datos que no está cubierto por los adaptadores incluidos. En ese caso, necesitarás escribir el tuyo propio.
Para hacerlo, debes implementar
Zend_Paginator_Adapter_Interface. Hay dos
métodos necesarios para hacerlo:
count()
getItems($offset, $itemCountPerPage)
Además, querrás implementar un constructor que reciba tu origen de datos como parámetro y lo almacene como una propiedad protegida o privada. Cómo quieras hacer esto en concreto depende de ti.
Si alguna vez has usado la interfaz SPL Countable,
estarás familiarizado con count(). Tal como se usa con
Zend_Paginator, este es el número total de elementos
en la colección de datos.
Además, la instancia de Zend_Paginator proporciona un método
countAllItems() que actúa como proxy hacia el método
count() del adaptador.
El método getItems() es solo ligeramente más
complicado. Para esto, a tu adaptador se le proporciona un offset y
el número de elementos a mostrar por página. Debes devolver el
fragmento apropiado de datos. Para un array, eso sería:
return array_slice($this->_array, $offset, $itemCountPerPage);
Echa un vistazo a los adaptadores incluidos (todos los cuales implementan
Zend_Paginator_Adapter_Interface) para tener ideas de cómo
podrías implementar el tuyo propio.
Crear tu propio estilo de desplazamiento requiere que implementes
Zend_Paginator_ScrollingStyle_Interface, que define
un único método, getPages(). Específicamente,
public function getPages(Zend_Paginator $paginator, $pageRange = null);
Este método debe calcular un límite inferior y superior para los números de página dentro del rango de las llamadas páginas "locales" (es decir, páginas que están cerca de la página actual).
A menos que extienda otro estilo de desplazamiento (ver
Zend_Paginator_ScrollingStyle_Elastic como ejemplo),
tu estilo de desplazamiento personalizado inevitablemente terminará con algo
similar a la siguiente línea de código:
return $paginator->getPagesInRange($lowerBound, $upperBound);
No hay nada especial en esta llamada; es simplemente un método de conveniencia para comprobar la validez del límite inferior y superior y devolver un array del rango al paginador.
Cuando estés listo para usar tu nuevo estilo de desplazamiento, necesitarás
indicarle a Zend_Paginator en qué directorio buscar. Para
hacerlo, haz lo siguiente:
$prefix = 'My_Paginator_ScrollingStyle'; $path = 'My/Paginator/ScrollingStyle/'; Zend_Paginator::addScrollingStylePrefixPath($prefix, $path);
Se le puede indicar a Zend_Paginator que almacene en caché los datos que ya ha
devuelto, evitando que el adaptador los obtenga cada vez que se usan.
Para indicarle al paginador que almacene en caché automáticamente los datos del adaptador, simplemente pasa a
su método setCache() una instancia de Zend_Cache_Core.
$paginator = Zend_Paginator::factory($someData);
$fO = array('lifetime' => 3600, 'automatic_serialization' => true);
$bO = array('cache_dir'=>'/tmp');
$cache = Zend_cache::factory('Core', 'File', $fO, $bO);
Zend_Paginator::setCache($cache);
Mientras Zend_Paginator tenga una instancia de
Zend_Cache_Core, los datos se almacenarán en caché. A veces
querrás no almacenar en caché los datos aunque ya hayas pasado una instancia de caché. Deberías
entonces usar setCacheEnable() para eso.
$paginator = Zend_Paginator::factory($someData); // $cache is a Zend_Cache_Core instance Zend_Paginator::setCache($cache); // ... later on the script $paginator->setCacheEnable(false); // cache is now disabled
Cuando se establece una caché, los datos se almacenan y se extraen de ella
automáticamente. Puede ser útil entonces vaciar la caché manualmente. Puedes hacerlo
llamando a clearPageItemCache($pageNumber).
Si no pasas ningún parámetro, se vaciará toda la caché. Opcionalmente puedes
pasar un parámetro que represente el número de página a vaciar en la caché:
$paginator = Zend_Paginator::factory($someData); Zend_Paginator::setCache($cache); $items = $paginator->getCurrentItems(); // page 1 is now in cache $page3Items = $paginator->getItemsByPage(3); // page 3 is now in cache // clear the cache of the results for page 3 $paginator->clearPageItemCache(3); // clear all the cache data $paginator->clearPageItemCache();
Cambiar el número de elementos por página vaciará toda la caché ya que se habría vuelto inválida:
$paginator = Zend_Paginator::factory($someData); Zend_Paginator::setCache($cache); // fetch some items $items = $paginator->getCurrentItems(); // all the cache data will be flushed: $paginator->setItemCountPerPage(2);
También es posible ver los datos en caché y solicitarlos directamente.
getPageItemCache() se puede usar para eso:
$paginator = Zend_Paginator::factory($someData); $paginator->setItemCountPerPage(3); Zend_Paginator::setCache($cache); // fetch some items $items = $paginator->getCurrentItems(); $otherItems = $paginator->getItemsPerPage(4); // see the cached items as a two-dimension array: var_dump($paginator->getPageItemCache());
Dependiendo de tu aplicación, es posible que quieras paginar objetos, cuya estructura
interna de datos es igual a la de los adaptadores existentes, pero no quieras romper tu
encapsulación para permitir el acceso a estos datos. En otros casos un objeto puede estar en una
relación "tiene-un adaptador", en lugar de la relación "es-un adaptador" que
Zend_Paginator_Adapter_Abstract promueve. Para estos casos puedes
usar la interfaz Zend_Paginator_AdapterAggregate que se comporta
de forma muy similar a la interfaz IteratorAggregate de la
extensión SPL de PHP.
interface Zend_Paginator_AdapterAggregate
{
/**
* Return a fully configured Paginator Adapter from this method.
*
* @return Zend_Paginator_Adapter_Abstract
*/
public function getPaginatorAdapter();
}
La interfaz es bastante pequeña y solo espera que devuelvas una instancia de
Zend_Paginator_Adapter_Abstract. Una instancia de Adapter Aggregate es
entonces reconocida tanto por Zend_Paginator::factory() como por el
constructor de Zend_Paginator y gestionada en consecuencia.