Como implementar un paginador usando Zend_Paginator en Zend Framework 1.6RC
Una de las cosas nuevas que trae el Zend Framework 1.6RC es el Zend_Paginator, y una forma de implementarlo es la siguiente:
Model
Para este ejemplo, vamos a suponer que tenemos una tabla users con las columnas id y nombre en MySQL con el siguiente modelo simple.
class User extends Zend_Db_Table { protected $_name = 'users'; protected $_primary = 'id'; }
Controller
En nuestro controller, necesitamos obtener los datos del modelo, crear el paginador y la vista parcial de los controles del paginador.
class UsersController extends Zend_Controller_Action { public function indexAction() { // Set pagination settings $page = $this->_getParam('page', 1); $itemCountPerPage = 10; $pageRange = 10; // Get data $user_model = new User(); $users = $user_model->fetchAll()->toArray(); // Create paginator $paginator = Zend_Paginator::factory($users); $paginator->setItemCountPerPage($itemCountPerPage) ->setCurrentPageNumber($page) ->setPageRange($pageRange); // Create paginator control partial view Zend_View_Helper_PaginationControl::setDefaultViewPartial('users/_partials/search_pagination_control.phtml'); // Assign paginator to view $this->view->paginator = $paginator; }
View
Para este ejemplo, tenemos dos views, uno parcial en donde van los controles del paginador y el otro en donde va el paginador en si, empezamos con el view /views/users/index.phtml
<h1>Users</h1> <?php if (count($this->paginator)) { ?> <?php foreach ($this->paginator as $item) { ?> <?php echo $item['nombre']; ?><br /> <?php } ?> <?php } ?> <br /> <?php echo $this->paginationControl($this->paginator); ?>
La ultima función, es un Helper que renderea los controles del paginador, mandando llamar a la vista parcial que definimos en nuestro controlador, y va mas o menos asi:
<?php if ($this->pageCount): ?> <div id="paginationControl"> <!-- Previous page link --> <?php if (isset($this->previous)): ?> <a href="<?= $this->url(array('page' => $this->previous)); ?>">< Previous</a> | <?php else: ?> <span class="disabled">< Previous</span> | <?php endif; ?> <!-- Numbered page links --> <?php foreach ($this->pagesInRange as $page): ?> <?php if ($page != $this->current): ?> <a href="<?= $this->url(array('page' => $page)); ?>"><?= $page; ?></a> | <?php else: ?> <?= $page; ?> | <?php endif; ?> <?php endforeach; ?> <!-- Next page link --> <?php if (isset($this->next)): ?> <a href="<?= $this->url(array('page' => $this->next)); ?>">Next ></a> <?php else: ?> <span class="disabled">Next ></span> <?php endif; ?> </div> <?php endif; ?>
Nota: Este ejemplo fue tomado y adaptado del demo y source original del Zend_Paginator antes de su versión oficial
Tags: PHP, php5, zend, Zend Framework
Esta es una implementación rápida de un paginador en Zend, el siguiente paso es abstraer un poco mas el código del controller y crear Grid_Renderers (ya sea Componentes o Helpers o una combinación de ambos… o algo por el estilo) que automaticamente renderee el contenido y los controles del paginador segun algun template en un view, para mantener consistencia en el sitio, repetir menos código y hacer mas pequeños los controllers..
Se aceptan comentarios y aportaciones
Eh notado que este post es de los mas concurridos, así que ahi les va un tip mas que deje pasar…
El método factory() de la clase Zend_Paginator también hacepta un Zend_Selector como parámetro, si se fijan en el ejemplo en la linea en donde dice:
$users = $user_model->fetchAll()->toArray();
Esta mandando traer todos los records de la base de datos, y una vez que lo metemos al factory() del Zend_Paginator, esta haciendo la paginación.
Una mejor forma de hacerlo sería unicamente construyendo el selector usando Active Record ejemplo:
$users = $user_model->select()->from(’users’,$columns);
No es necesario poner ni limit ni offset ya que el Zend_Paginator se encargará de eso.