When we have a list of items, and there are a lot of them, pagination is a must. In DotKernel, this is how we implemented pagination, helped by the Zend_Paginator.

In Controller:

case 'product-list':
 $pageTitle = 'List Products';
 $page = (isset($request['page'])) ? $request['page'] : 1;
 $list = $productModel->getProductsList($page);
 $productView->productList('productList', $list, $page);
break;

In Model, we have:

/**
 * Get product list
 * @access public
 * @param int $page [optional]
 * @return array(array(), Zend_Paginator_Adapter())
 */
public function getProductsList($page=1)
{
 $select = $this->db->select()
                    ->from(array('a'=>'products'), array('id','title','created','active'));
 $paginatorAdapter = new Zend_Paginator_Adapter_DbSelect($select);
 ($page == 1) ?
         $select->limit($this->settings->results_per_page) :
         $select->limit($this->settings->results_per_page, ($page-1)*$this->settings->results_per_page);
 $data = $this->db->fetchAll($select);
 return array('data'=> $data,'paginatorAdapter'=> $paginatorAdapter);
}

You may note that for Zend_Paginator_Adapter we used the whole select query, and added limit only for the data we retrieve. This will return an array with 2 values: $data and $paginatorAdapter.
$data will be used in View to list the current records for the specific page.
$paginatorAdapter will be used as a parameter in View for the Zend_Paginator() class

In View there is:

/**
* Display product list
* @access public
* @param string $templateFile
* @param array $list
* @param int $page
* @return void
*/
public function productList($templateFile, $list, $page)
{
  $this->tpl->setFile('tpl_main', 'media/' . $templateFile . '.tpl');
  $this->tpl->setBlock('tpl_main', 'list', 'list_block');
  $this->tpl->paginator($list['paginatorAdapter'],$page);
  foreach ($list['data'] as $k => $v)
  {
    $this->tpl->setVar('ID', $v['id']);
    $this->tpl->setVar('TITLE', $v['title']);
    $this->tpl->setVar('CREATED', $v['created']);
    $this->tpl->parse('list_block', 'list', true);
  }
}

Method paginator from View has the following content

/**
* Create the pagination, based on how many data
* @access public
* @param array $data
* @param int $current_page [optional]
* @return string
*/
protected function paginator($adapter, $currentPage = 1)
 {            
 $paginator = new Zend_Paginator($adapter);
 $paginator->setItemCountPerPage($this->settings->results_per_page);
 $paginator->setCurrentPageNumber($currentPage);
 $paginator->setPageRange(10);
 $paginator->totalItems = $adapter->count();
 $page = $paginator->getPages();
 $this->setFile('page_file', 'paginator.tpl');
 $this->setVar('TOTAL_ITEMS', $paginator->totalItems);
 $this->setVar('TOTAL_PAGES', $paginator->count());
 $this->setBlock('page_file', 'first', 'first_row');
 $this->setBlock('page_file', 'previous', 'previous_row');
 $this->setBlock('page_file', 'next', 'next_row');
 $this->setBlock('page_file', 'current_page', 'current_row');
 $this->setBlock('page_file', 'other_page', 'other_row');        
 $this->setBlock('page_file', 'pages', 'pages_row');
 $this->setBlock('page_file', 'last', 'last_row');
 
 $param = Zend_Registry::get('param');
 $link = (array_key_exists('page',$param))'' : 'page/';        
 if ($page->first != $page->current)
 {
 $this->setVar('PREVIOUS_LINK',$link.($page->current-1));
 $this->parse('previous_row', 'previous', TRUE);
 $this->setVar('FIRST_LINK', $link.'1'); 
 $this->parse('first_row', 'first', TRUE); 
 }
 else
 {
 $this->parse('previous_row', ''); 
 $this->parse('first_row', ''); 
 }
 if ($page->last>0 && $page->last != $page->current)
 {
 $this->setVar('NEXT_LINK',$link.$page->next);
 $this->parse('next_row', 'next', TRUE);
 $this->setVar('LAST_LINK', $link.$page->last); 
 $this->parse('last_row', 'last', TRUE); 
 }
 else
 {
 $this->parse('next_row', '');
 $this->parse('last_row', ''); 
 }
 foreach ($page->pagesInRange as $val)
 {
 $this->setVar('PAGE_NUMBER', $val);
 $this->parse('other_row','');
 $this->parse('current_row','');
 if($val == $page->current)
 {
 $this->parse('current_row','current_page', TRUE);
 }
 else
 {
 $this->setVar('PAGE_LINK', $link.$val);
 $this->parse('other_row','other_page', TRUE);
 }                
 $this->parse('pages_row', 'pages', TRUE);
 }
 $this->parse('PAGINATION', 'page_file');
 }

The template file for pagination is paginator.tpl:

<table cellpadding="0" cellspacing="1">
 <tr>
 <td width="50">
 <span>{TOTAL_ITEMS} Items</span>
 </td>
 <td width="100">
 <span>Pages ({TOTAL_PAGES}): </span>
 </td>
 <td>
 <ul>
 <!-- BEGIN first -->
 <li>
 <a href="{FIRST_LINK}">First</a>
 </li>
 <!-- END first -->
 <!-- BEGIN previous -->
 <li>
 <a href="{PREVIOUS_LINK}"> &lt;&lt; </a>
 </li>
 <!-- END previous -->
 <!-- BEGIN pages -->
 <!-- BEGIN current_page -->
 <li>
 <p>{PAGE_NUMBER}</p>
 </li>
 <!-- END current_page -->
 <!-- BEGIN other_page -->
 <li>
 <a href="{PAGE_LINK}">{PAGE_NUMBER}</a>
 </li>
 <!-- END other_page -->
 <!-- END pages -->
 <!-- BEGIN next -->
 <li>
 <a href="{NEXT_LINK}"> &gt;&gt; </a>
 </li>
 <!-- END next -->
 <!-- BEGIN last -->
 <li>
 <a href="{LAST_LINK}">Last</a>
 </li>
 <!-- END last -->
 </ul>
 </td>
 </tr>
</table>

Also in index.php we have added a new line before instantiating Dot_Kernel class

$registry->param = $request;

For more details visit the trunk folder on DotKernel Repository

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>