<?php
class SimPageNav
{
protected $id;
protected $startChar;
protected $prevChar;
protected $nextChar;
protected $endChar;
public function __construct($id = 'pagination pagination-sm', $startChar = '&laquo;', $prevChar  = '&lsaquo;', $nextChar  = '&rsaquo;', $endChar   = '&raquo;')
{
$this->id = $id;
$this->startChar = $startChar;
$this->prevChar  = $prevChar;
$this->nextChar  = $nextChar;
$this->endChar   = $endChar;
}
/**
* Получить HTML - код постраничной навигации
* @param int $all        - Полное кол-во элементов (Материалов в категории)
* @param int $limit      - Кол-во элементов на странице
* @param int $start      - Текущее смещение элементов
* @param int $linkLimit  - Количество ссылок в состоянии
* @param string $varName - Имя GET - переменной которая будет использоваться в постр. навигации.
* @return string
*/

public function getLinks($all, $limit, $start, $linkLimit = 10, $varName = 'page')
{
// Нихрена не делаем, если лимит больше или равен кол-ву всех элементов вообще,
// И если лимит = 0. 0 - будет означать "не разбивать н астраницы".

if ( $limit >= $all || $limit == 0 ) {
return NULL;
}
$pages = 0; // кол-во страниц в пагинации
$needChunk = 0; // индекс нужного в данный момент чанка
$queryVars = array(); // ассоц. массив полученный из строки запроса
$pagesArr = array(); // пременная для промежуточного хранения массива навигации
$htmlOut = ''; // HTML - код постраничной навигации
$link = NULL; // формируемая ссылка

// В этом блоке мы просто строим ссылку - такую же, как та, по которой
// пришли на данную страницу, но извлекаем из неё нашу GET-переменную:
$purl = parse_url('http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']);
if (isset($purl['query'])) { $pqu = $purl['query']; } else { $pqu = ''; }
parse_str($pqu, $queryVars); //   &$queryVars
// Убиваем нашу GET-переменную
if( isset($queryVars[$varName]) ) {
unset( $queryVars[$varName] );
}

// Формируем такую же ссылку, ведущую на эту же страницу:
$qe = http_build_query($queryVars);
if (empty($qe)) { $qee = ''; } else { $qee = '&'; }
$link  = $purl['path'].'?'.$qe.$qee;

$pages = ceil( $all / $limit ); // кол-во страниц
// Заполняем массив: ключ - это номер страницы, значение - это смещение для БД.
// Нумерация здесь нужна с единицы. А смещение с шагом = кол-ву материалов на странице.
for( $i = 0; $i < $pages; $i++) {
$pagesArr[$i+1] = $i * $limit+1;
}

// Теперь что бы на странице отображать нужное кол-во ссылок
// дробим массив со значениями [№ страницы] => "смещение" на
// Части (чанки)
$allPages = array_chunk($pagesArr, $linkLimit, true);
// Получаем индекс чанка в котором находится нужное смещение.
// И далее только из него сформируем список ссылок:
$needChunk = $this->searchPage( $allPages, $start );

// Формируем ссылки "В начало", "передыдущая"
if ( $start > 1 ) {
$htmlOut .= '<li><a href="'.$link.$varName.'=1">'.$this->startChar.'</a></li><li><a href="'.$link.$varName.'='.($start - $limit).'">'.$this->prevChar.'</a></li>';
} else {
$htmlOut .= '<li class="disabled"><a href="#">'.$this->startChar.'</a></li><li class="disabled"><a href="#">'.$this->prevChar.'</a></li>';
}

// Собсно выводим ссылки из нужного чанка
foreach( $allPages[$needChunk] AS $pageNum => $ofset )  {
// Делаем текущую страницу не активной:
if( $ofset == $start  ) {
$htmlOut .= '<li class="active"><a href="#">'. $pageNum .'</a></li>';
continue;
}
$htmlOut .= '<li><a href="'.$link.$varName.'='. $ofset .'">'. $pageNum . '</a></li>';
}

// Формируем ссылки "следующая", "в конец"
if ( ($all) >  $start) {
$apop = array_pop($allPages);
$apop2 = array_pop($apop);
$htmlOut .= '<li><a href="'.$link.$varName.'='.( $start + $limit).'">'.$this->nextChar.'</a></li><li><a href="'.$link.$varName.'='.$apop2.'">'.$this->endChar.'</a></li>';
} else {
$htmlOut .= '<li class="disabled"><a href="#">'.$this->nextChar.'</a></li><li class="disabled"><a href="#">'.$this->endChar.'</a></li>';
}
return '<div class="text-center mrgp"><ul class="'.$this->id.'">'.$htmlOut.'<ul></div>';
}

/**
* Ищет в каком чанке находится сраница со смещением $needPage
* @param array $pagesList массив чанков (массивов страниц разбитый по лимиту ссылок на странице)
* @param int $needPage - смещение
* @return number Ключ чанка в котором есть нужная страница
*/
protected function searchPage( array $pagesList, /*int*/$needPage )
{
foreach( $pagesList AS $chunk => $pages  ){
if( in_array($needPage, $pages) ){
return $chunk;
}
}
return 0;
}
}