Pull to refresh

Делаем постраничную навигацию в Zend Framework

Reading time5 min
Views1K
Когда я был совсем маленький, не знал, что такое Zend_paginator, да и вообще что такое Zend.
Создание постраничной навигации было для меня не то чтобы проблемой, но занятием, по крайней мере, рутинным и противным. Однако при изучении ZF, я обнаружил замечательную вещь. Итак, давайте по-немногу разбиратся.

За основу возьмём статью, которая была написанна ранее, и на основе её попытаемся сделать гостевую книгу с постраничной навигашкой.

Начнём с базы данных:
для простоты мы возьём всего 3 поля id, name, message
получается такой вот дамп:
CREATE TABLE `guestbook` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(16) default NULL,
`message` text,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=cp1251 AUTO_INCREMENT=1 ;

структура каталогов
Мы имеем такую вот структуру.
Из нового здесь появилось только my_pagination.phtml — файл хелпера, в котором содержится вид нашей «навигашки», но о нём чуть пожже.

В файле Guestbook.php содержится указание таблицы, с которой мы будем работать.
/application/models/Guestbook.php
<?php
class Guestbook extends Zend_Db_Table
{
protected $_name = 'guestbook';
}


Файл IndexController содержит 3 метода: indexAction, addAction и init.
/application/controllers/IndexController.php
<?php
class IndexController extends Zend_Controller_Action
{
function indexAction(){
$gb = new Guestbook();
$num = 10;
$page = $this->_getParam('page');
if($page<1 or empty($page)){$page = 1;}
$select = $gb->select()->from('guestbook',array('count'=>'COUNT(*)'))->order('id DESC ');
$total = $this->view->table = $gb->fetchRow($select)->toArray();
$start = $page*$num-$num;
$select = $gb->select()->from('guestbook')->order('id DESC ')->limit($start,$num);
$result = $this->view->table = $gb->fetchAll($select)->toArray();
$paginator = new Zend_Paginator(new Zend_Paginator_Adapter_array($result));
$paginator->setCurrentPageNumber($this->_getParam($page));
$paginator->setItemCountPerPage($num);
$paginator->setView($this->view);
Zend_View_Helper_PaginationControl::setDefaultViewPartial('/my_pagination.phtml');
$this->view->paginator = $paginator;
}
function addAction(){
if($this->_request->isPost()){
$filter = new Zend_Filter_StripTags();
$name = trim($filter->filter($this->_request->getPost('name')));
$message = trim($filter->filter($this->_request->getPost('message')));
if(!empty($name) && !empty($message)){
$data = array(
'name' => $name,
'message' => $message
);
$gb = new Guestbook();
$gb->insert($data);
$this->_redirect('/');
}
} else $this->view->errorMessage = "Вы не заполнили все поля, пожалуйста попробуйте ещё раз.";
}
function init(){
Zend_Loader::loadClass('Zend_Filter_StripTags');
Zend_Loader::loadClass('Guestbook');
Zend_Loader::loadClass('Zend_Paginator');
Zend_Loader::loadClass('Zend_Paginator_Adapter_array');
Zend_Loader::loadClass('Zend_View_Helper_PaginationControl');
}
}


Методы addAction и init рассматривать не будем, ибо там всё банально. Нас интересует indexAction, его мы рассмотрим подробнее.
$gb = new Guestbook();
$num = 10;
$page = $this->_getParam('page');
if($page<1 or empty($page)){$page = 1;}
$select = $gb->select()->from('guestbook',array('count'=>'COUNT(*)'))->order('id DESC ');
$total = $this->view->table = $gb->fetchRow($select)->toArray();
$start = $page*$num-$num;
$select = $gb->select()->from('guestbook')->order('id DESC ')->limit($start,$num);
$result = $this->view->table = $gb->fetchAll($select)->toArray();

  • Здесь мы получаем обьект класса GuestBook,
  • устанавливаем нужное число постов на странице,
  • получаем номер страницы,
  • страница не может быть меньше единицы или пустой,
  • выбираем количество постов,
  • высчитываем, откуда нужно начать выбирать посты в limit
  • выбираем все записи, упорядоченные по id от высчитанного нами $start до нужной страницы. При этом преобразовываем то, что у нас получилось, в массив $result.


$paginator = new Zend_Paginator(new Zend_Paginator_Adapter_array($result));
Создаём объект $paginator с указанием его адаптера.

$paginator->setCurrentPageNumber($page)
Здесь мы устанавливаем номер текущей страницы, который будет передаваться ссылке как параметр (/index/page/<номер страницы>).

$paginator->setView($this->view);
Устанавливаем вид для пагинатора, так как вид у нас тот, который использует данный экшен пишем $this->view.

$paginator->setItemCountPerPage($num);
Устанавливаем количество постов на одной странице. По умолчанию оно и так равно десяти (здесь это сделано для примера).

Zend_View_Helper_PaginationControl::setDefaultViewPartial('/my_pagination.phtml');
$this->view->paginator = $paginator;

Здесь мы подключаем файл хелпера и передаём виду наш пагинатор. В файле index.phtml к нему можно будет обратится так $this->paginator.

/application/scripts/index/index.phtml
<?php
if (count($this->paginator)): ?>
<?php foreach ($this->paginator as $item):?>
<?= $item['name']; ?><br>
<?= $item['message']; ?>

<?php endforeach; ?>
<?php endif; ?>

<?= $this->paginationControl($this->paginator, 'Sliding', '/my_pagination.phtml'); ?>


Здесь нет ничего необычного кроме:
<?= $this->paginationControl($this->paginator, 'Sliding', '/my_pagination.phtml'); ?>
Вместо Sliding здесь могут стоять следующие параметры:
  • All — показывать все номера страниц,
  • Elastic — увеличивает/уменьшает номера страниц в зависимости от того, на какой странице находится пользователь
  • Jumping — когда пользователь листает страницы, текущая страница перемещается к концу ряда
  • Sliding — номер текущей страницы находится в центре ряда, на мой взгляд самый распространённый и удобный способ

$this->paginator наш обьект с пагинатором — третьим параметром указывается путь к файлу my_pagination.phtml.
Примерный вид его может быть таким:

/application/scripts/my_pagination.phtml
<?php
if ($this->pageCount): ?>
<?php if (isset($this->previous)): ?>
< Previous |
<?php else: ?>
< Previous |
<?php endif; ?>
<?php foreach ($this->pagesInRange as $page): ?>
<?php if ($page != $this->current): ?>
<?= $page; ?> |
<?php else: ?>
<?= $page; ?> |
<?php endif; ?>
<?php endforeach; ?>
<?php if (isset($this->next)): ?>
><?php else: ?>
<?php endif; ?>
<?php endif; ?>


Здесь
  • $this->pageCount — общее количество страниц
  • $this->previous — предыдущая страница
  • $this->current — текущая страница
  • $this->next — следующая страница

<a hreеf="<?=$this->url(array('page' => $this->next)); ?>">>
Например, эта строка формирует ссылку для следующей страницы при промощи метода хелперов url(), где параметром передаётся ассоциативный массив, из которого и формируется путь.

На этом тема пагинаторов и постраничной навигации, конечно, не кончается. Я показал всего лишь самый простой способ сделать постраничную навигацию, думаю, это пригодится начинающим в освоении Zend Framework.
Tags:
Hubs:
+1
Comments8

Articles