'pagination pagination-centered clearfix']; protected $infoTag = 'div'; protected $infoAttribs = ['class' => 'pull-left']; protected $ippControlTag = 'div'; protected $ippControlClass = 'input-mini'; protected $ippControlName = 'paginator-ipp'; protected $ippControlAttribs = ['class' => 'pull-right']; protected $ippTemplate = 'Items per page: %control%'; protected $infoTemplate = 'Showing %firstItemNumber% - %lastItemNumber% of %totalItemCount%'; protected $pagesTag = 'ul'; protected $pageTag = 'li'; protected $firstPageTitle = '« First'; protected $previousPageTitle = '< Previous'; protected $nextPageTitle = 'Next > '; protected $lastPageTitle = 'Last »'; function __invoke(array $options = []) { return $this->pagination($options); } public function setOptions(array $options = []) { foreach ($options as $name => $value) { if (!property_exists($this, $name)) { throw new Exception('Undefined pagination property: ' . $name); } $this->$name = $value; } return $this; } public function pagination(array $options = []) { $this->setOptions($options); return $this; } public function isEmpty() { return $this->pageCount <= 1 || $this->totalItemCount <= reset($this->ippList); } protected function openTag($tag, array $attribs = []) { return '<' . $tag . $this->_renderAttribs($attribs) . '>'; } protected function closeTag($tag) { return ''; } protected function _renderAttribs(array $attribs) { $xhtml = ''; foreach ((array) $attribs as $key => $val) { $key = htmlspecialchars($key, ENT_COMPAT, 'UTF-8'); if (is_array($val)) { $val = implode(' ', $val); } $val = htmlspecialchars($val, ENT_COMPAT, 'UTF-8'); $xhtml .= " $key=\"$val\""; } return $xhtml; } public function openContainer() { return $this->openTag($this->containerTag, $this->containerAttribs); } public function closeContainer() { return $this->closeTag($this->containerTag); } public function renderInfo() { $placeholders = get_object_vars($this); $placeholders = array_filter($placeholders, 'is_numeric'); return $this->openTag($this->infoTag, $this->infoAttribs) . Qs_String::fill($this->infoTemplate, $placeholders) . $this->closeTag($this->infoTag); } public function renderPages() { $html = ''; if ($this->pageCount <= 1) { return $html; } $html .= $this->openTag($this->pagesTag); $html .= $this->renderFirstPage(); $html .= $this->renderPreviousPage(); foreach ($this->pagesInRange as $number) { $html .= $this->renderPage($number); } $html .= $this->renderNextPage(); $html .= $this->renderLastPage(); $html .= $this->closeTag($this->pagesTag); return $html; } protected function renderHtmlContainer($tag, $attributes, $html) { return $this->openTag($tag, $attributes) . $html . $this->closeTag($tag); } public function renderFirstPage() { return $this->renderPage(self::PAGE_FIRST); } public function renderPreviousPage() { return $this->renderPage(self::PAGE_PREVIOUS); } public function renderNextPage() { return $this->renderPage(self::PAGE_NEXT); } public function renderLastPage() { return $this->renderPage(self::PAGE_LAST); } public function getPageUrl($number) { if ($this->first == $number) { return $this->firstUrl; } return str_replace($this->pagePlaceholder, $number, $this->url); } public function renderPage($number) { $type = self::TYPE_LINK; $class = null; switch ($number) { case self::PAGE_FIRST: $number = $this->first; $title = $this->firstPageTitle; if ($this->first == $this->current) { $type = self::TYPE_TEXT; $class = $this->classDisabled; } break; case self::PAGE_PREVIOUS: $number = $this->previous; $title = $this->previousPageTitle; if (null === $this->previous) { $type = self::TYPE_TEXT; $class = $this->classDisabled; } break; case self::PAGE_NEXT: $number = $this->next; $title = $this->nextPageTitle; if (null === $this->next) { $type = self::TYPE_TEXT; $class = $this->classDisabled; } break; case self::PAGE_LAST: $number = $this->last; $title = $this->lastPageTitle; if ($this->current == $this->last) { $type = self::TYPE_TEXT; $class = $this->classDisabled; } break; default: $title = $number; if ($number == $this->current) { $type = self::TYPE_TEXT; $class = $this->classActive; } break; } if (self::TYPE_LINK == $type) { return $this->renderHtmlContainer( $this->pageTag, [], $this->renderHtmlContainer('a', ['href' => $this->getPageUrl($number)], $this->view->escape($title)) ); } return $this->renderHtmlContainer( $this->pageTag, ['class' => $class], $this->renderHtmlContainer('span', [], $this->view->escape($title)) ); } public function renderIppControl() { $html = ''; if (!$this->changeableIpp) { return $html; } $html .= $this->openTag($this->ippControlTag, $this->ippControlAttribs); $control = $this->view->formSelect( $this->ippControlName, $this->ipp, [ 'value' => $this->ipp, 'class' => $this->ippControlClass, 'onchange' => 'qs.paginator.setIpp(this.value);', ], array_combine($this->ippList, $this->ippList) ); $html .= Qs_String::fill($this->ippTemplate, compact('control')); $html .= $this->closeTag($this->ippControlTag); return $html; } public function __toString() { $html = ''; if ($this->isEmpty()) { return $html; } $html .= $this->openContainer(); $html .= $this->renderInfo(); $html .= $this->renderPages(); $html .= $this->renderIppControl(); $html .= $this->closeContainer(); return $html; } }