goPaginator: отрисовка пагинатора

Начинаю раздел goLibs с выкладыванием простеньких вспомогательных классиков. Первым на очереди идёт goPaginator. Можно просмотреть исходный код или скачать ZIP.

Основная задача библиотеки — отрисовка пагинатора и помощь в выборки данных для текущей страницы. Простейший пример (более развёрнутый пример можно пощупать здесь):

/* Общее количество элементов в списке, разбиваемым на страницы */
$countElements = query('SELECT COUNT(*) FROM `table`');
if ($countElements == 0) {
	echo 'Список пуст';
	return;
}
 
$pager = new goPaginator($countElements); // Создаём объект пагинатора
 
echo $pager; // Выводим пагинатор сверху
 
/* Выборка и вывод элементов для текущей страницы */
$sql = 'SELECT * FROM `table` ORDER BY `id` ASC LIMIT '.$pager->getSqlLimits();
$elements = query($sql);
foreach ($elements as $element) { /* Выводим элементы */ }
 
echo $pager; // Пагинатор снизу

В простейшем случае номер текущей страницы берётся из GET-параметра page. Номера страниц в пагинаторе так же передаются через ?page=X. Если page не указан, считается, что это первая страница. Так же номер страницы приводится к допустимому диапазону (от 1 до ОбщегоКоличестваСтраниц).

Общий вид пагинатора: ← 1 2 3 ... 7 [8] 9 ... 15 16 17 →.

Расчёт и отрисовку пагинатора можно настраивать через параметры, полный список которых даётся в разделе список параметров.

Методы объекта goPaginator

__construct(int $countElements [, array $params])
int $countElements: общее количество элементов в списке. Например, в списке 100 элементов, они выводятся по 10 на страницу, в итоге получается 10 страниц.
array $params: ассоциативный массив параметров отрисовки. Описание дано в разделе список параметров.
Может выбрасывать исключения RuntimeException в случаях, когда список пуст ($countElement = 0) и задан неверный параметр.

string draw(void)
Отрисовка пагинатора. Тоже самое действие повешено и на __toString().
echo $pager->draw(); // Отрисовать пагинатор
echo $pager;         // Аналогично

string getSqlLimits(void)
Строка для вставки в раздел LIMIT запроса на выборку элементов текущей страницы. Для выборки элементов на 5-ю страницу по 20 штук, это будет 80,20.
$sql = 'SELECT * FROM `table` ORDER BY `id` ASC LIMIT '.$pager->getSqlLimits();

void setParam(string $name, mixed $value)
mixed getParam(string $name)
void resetParam(mixed $name)
Установка, получение и сброс к значению по умолчанию параметра отрисовки. Более подробно см. список параметров.
Могут генерировать RuntimeException при неверном имени параметра.

void setCountElement(int $countElement)
int getCountElement(void)
Установить/получить общее количество элементов. RuntimeException если $countElement < 1.

int getCurrentPage(void)
Получить номер текущей страницы.

int getCountPage(void)
Получить общее количество страниц, на которые разбивается список.

int getSizeCurrentPage(void)
Получить размер текущей страницы. Для большинства страниц размер один и задаётся параметром pageSize, однако у последней страницы он может быть меньше. Если 25 элементов разбить по 10 на страницу, получится 3 страницы с количеством элементов: 10, 10 и 5.

int getFirstElement(void)
Получить номер первого элемента на текущей странице.

Список параметров отрисовки

Параметры задаются через конструктор или setParam. Для не заданных параметров используется значение по умолчанию.

Имя параметра Тип Описание По умолчанию
pageSize int Размер страницы (количество элементов на каждой странице) 20
pageVar string Имя GET-параметра из которого берётся page.
См. также параметр currentPage.
«page»
currentPage int Жёсткое указание номера текущей страницы.
Не указан: номер берётся из GET (см. pageVar).
maxPage int Максимально возможное количество страниц.
Используется для снижения нагрузки на базу.
Чтобы выводит все сбросьте параметр в false.
100
drawOne bool Выводить ли пагинатор если только одна страница. false
title string Надпись в пагинаторе перед списком страниц «Страницы:»
arr bool Выводить ли стрелки вперёд/назад. true
solid bool Выводить полный список страниц, сколько бы их ни было false
line int При разбиении списка, по сколько страниц выводить в блоке.
Пример (3): 1 2 3 … 4 [5] 6 … 9 10 11
Не актуально при solid = true
3
space string Разделитель между блоками страниц «...»
listtag string Имя тега в который заключается список страниц.
См. вёрстка пагинатора
Не указан: ни во что не заключается
litag string Имя тега в который заключается ссылка на страницу.

«span»
asep string Разделитель между ссылками на страницы.
Пример (« | »): 1 | 2 | 3 | 4 | 5
tag string Имя тега в который заключается весь пагинатор. «div»
css string CSS-класс пагинатора.
См. вёрстка пагинатора
«paginator»
urlPrefix string См. формирование ссылок
urlPostfix string См. формирование ссылок

По умолчанию ссылка берётся из GET-параметра page. Если он не указана, подразумевается первая страница. При формировании ссылок на страницы, номера так же вставляются в ?page=, кроме того сохраняются все остальные GET-параметры. Т.е. если пагинатор выводился на странице index.php?x=1&page=5&y=2, то ссылка на 3-ю страницу будет index.php?x=1&y=2&page=3.

Имя GET-параметра можно изменить с помощью параметра pageVar.

В более сложных случаях можно задействовать параметры urlPrefix и urlPostfix. Тогда ссылки будут иметь вид $urlPrefix.$page.$urlPostfix.

Допустим, у нас ЧПУ и не используются GET-параметры. А адрес страницы имеет вид /news/archive/$numberPage/.

 
$currentPage = getCurrentPage(); // Имя текущей страницы придётся определить самим.
$params = array(
	'currentPage' => $currentPage,
	'urlPrefix'   => '/news/archive/',
	'urlPostfix'  => '/',
);
$pager = new goPaginator($countElements, $params);
 
echo $pager;

Теперь ссылки будут формироваться так как нам нужно.

Для ещё более сложных случаев можно использовать перегрузку методов.

Вёрстка пагинатора

Оторажение пагинатора настраивается через CSS и параметры отображения.

Примерный вид вёрстки:

<div class="paginator">
	<span class="title">Страницы:</span>
	<span class="arr">&larr;</span>
	<span&gt;
		<span><a href="?page=1">1</a></span>
		<span class="current"><a href="?page=2">2</a></span>
		<span><a href="?page=3">3</a></span>
		<span class="space">...</span>
		<span><a href="?page=37">37</a></span>
		<span><a href="?page=38">38</a></span>
		<span><a href="?page=39">39</a></span>
	</span>
	<span class="arr"><a href="?page=2">&rarr;</a></span>
</div>

CSS-класс current указывает текущую страницу.

Параметры, которыми можно повлиять на вёрстку:

tag, css: тег и его CSS-класс в который заключается пагиантор. Если tag не указан, ни во что не заключается.

listtag, litag, теги в которые заключается весь блок списка страниц и каждая страница соответственно. В примере, они оба <span>. Как вариант, для более семантической вёрстки, можно заменить на <ul> и <li>.

Так же на вёрстку влияют title, arr, solid, line, space, asep. См. раздел параметры отображения.

Перегрузка методов

Все публичные методы помечены, как final, большинство остальных закрыты (private), как и свойства. Три метода помечены, как protected и с помощью их переопределения можно наследовать пагинаторы с более сложным поведением.

int defineCurrentPage(void)
Определяет и возвращает текущую страницу.

string makePageLink(int $pageNumber)
Формирует и возвращает ссылку на страницу $pageNumber.

string makeHtml(void)
Формирует и возвращает html-вёрстку пагинатора.

Некоторые замечания

Пагинатор не работает с пустыми списками. Если $countElements = 0, генерируется исключение.

Все установки (setParam(), setCountElements()) следует делать до отрисовки пагинатора и вызовов get*-методов, иначе установки не возымеют эффекта.

$pager = new goPaginator($count);
$pager->setParam('pageSize', 20);
echo $pager; // по 20 на странице
$pager->setParam('pageSize', 10); // ничего не даст
echo $pager; // всё равно по 20

13 комментариев »

  • Ты охуенен! Коммитить будешь или нет?

    adw0rd, 14.07.2009, 23:30

  • Да ну, зачем? :)

    vasa_c, 15.07.2009, 0:06

  • Вся надежда только на тебя! :)

    adw0rd, 15.07.2009, 0:26

  • охуительно!

    Timur, 15.07.2009, 19:47

  • Отлично ! + всё настраивается, только как я понял можно указывать только имя $_GET массива , а если страница передаётся другим параметром ? Это надо учесть

    Troy, 26.08.2009, 13:39

  • Можно так же явно указать параметр «currentPage» или переопределить метод defineCurrentPage

    vasa_c, 5.09.2009, 16:18

  • спасибо

    разработчик сайтов на joomla, 3.06.2010, 15:02

  • Спасибо, бодрый класс.
    ВОпрос только, а можно как то сделать чтоб ссылка на первую страницу была не /catalog/1/ и чисто /catalog/? Просто использую вариант с чпу, нехорошо что 2 одинаковые будут страницы.

    Сергей, 29.03.2011, 22:35

  • Сергей, уже даже и не помню.
    Боюсь, что без допиливания, к сожалению, никак.

    vasa_c, 3.04.2011, 11:48

  • Сергей, как переписать функцию protected function makePageLink примерно так :

    protected function makePageLink($pageNumber)
    {
    if($pageNumber == 1)
    {
    return $this->urlPrefix;
    }
    else
    {
    return $this->urlPrefix.$pageNumber.$this->urlPostfix;
    }
    }

    cossack, 14.04.2011, 19:03

  • Пропустил слово в предыдущем посте. Читать «как вариант переписать функцию protected function makePageLink примерно так».

    cossack, 14.04.2011, 19:04

  • блин вот заюзал эту штуку ииии!!!! !!!!

    и блядь все еще зол))

    ну кто же так делает то!

    final public function setCountElements($count)
    {
    if ($count countElements = $count;
    return true;
    }

    а именно

    if ($count <= 0) {
    throw new RuntimeException('goPaginator: count=' . $count);
    }

    ? :-)

    два часа построчно дебажил ибо все дебаги были отключены на продакшене))

    не рсовал бы пейжер да и все … :)

    гоТру!

    phpude, 28.07.2011, 11:37

  • Я так понимаю count общее количество записей из базы считается каждый GET заново, нельзя как нибудь иначе?

    zerg, 5.08.2012, 23:04

Leave a comment