5 * A better result pager.
8 * - "Prev" and "next" buttons are outside
9 * - No "first" and "last", but "1" and "$totalNumOfPages"
10 * - two previous and two next pages are shown as buttons
11 * - When current page is <= 5, first 5 pages are shown
12 * - ".." is only shown for at least two skipped pages
15 * [<< prev] [1] [2] [3] [next >>]
16 * [<< prev] [1] [2] [3] [4] [5] [next >>]
17 * [<< prev] [1] [2] [3] [4] [5] ... [8] [next >>]
18 * [<< prev] [1] ... [4] [5] [6] [7] [8] ... [10] [next >>]
20 * replace ".." with actual link when between previous and next is only one
29 * @param integer $itemCount Number of items in total
30 * @param integer $perPage Number of items on one page
31 * @param integer $currentPage Current page, beginning with 1
32 * @param string $filename URL the page number shall be appended
34 public function __construct($itemCount, $perPage, $currentPage, $filename)
37 if (strpos($filename, '%d') !== false) {
41 $numPages = ceil($itemCount / $perPage);
42 $this->numPages = $numPages;
48 $numPages - 1 => true,
51 if ($currentPage <= 6) {
56 if ($currentPage >= $numPages - 5) {
57 $pages[$numPages - 2] = true;
58 $pages[$numPages - 3] = true;
59 $pages[$numPages - 4] = true;
61 for ($n = $currentPage - 2; $n <= $currentPage + 2; $n++) {
64 foreach (array_keys($pages) as $key) {
65 if ($key < 1 || $key > $numPages) {
69 if ($currentPage >= 7 && !isset($pages[4])) {
72 if ($currentPage <= $numPages - 6 && !isset($pages[$numPages - 3])) {
73 $pages[$numPages - 2] = null;
77 foreach ($pages as $pageNum => &$value) {
78 if ($pageNum == $currentPage) {
79 $value = ['active'=> false, 'title' => $pageNum];
80 } else if ($value !== null) {
81 $value = $this->makeLink($pageNum, $filename);
83 $value = ['active'=> false, 'title' => '…'];
87 $prev = ['active'=> false, 'title' => '« prev'];
88 if ($currentPage > 1) {
89 $prev = $this->makeLink($currentPage - 1, $filename, '« prev');
91 $next = ['active'=> false, 'title' => 'next »'];
92 if ($currentPage < $numPages) {
93 $next = $this->makeLink($currentPage + 1, $filename, 'next »');
95 //first and last are for opensearch
96 $first = ['active'=> false, 'title' => 'first'];
97 if ($currentPage > 1) {
98 $first = $this->makeLink(1, $filename, 'first');
100 $last = ['active'=> false, 'title' => 'last'];
101 if ($numPages > 1 && $currentPage < $numPages) {
102 $last = $this->makeLink($numPages, $filename, 'last');
114 protected function makeLink($pageNum, $filename, $title = null)
116 $title = $title === null ? $pageNum : $title;
117 $url = $filename . '&page=' . $pageNum;
122 'html' => '<a href="' . htmlspecialchars($url)
123 . '" title="Page ' . $pageNum . '">'
124 . htmlspecialchars($title)
129 public function getLinks()
134 public function getFullUrls()
137 foreach ($this->links as $key => $link) {
138 if ($key == 'pages') {
141 if ($link['active']) {
142 $arUrls[$key] = str_replace(
144 Helper::fullUrl('/' . $link['url'])
151 public function numPages()
153 return $this->numPages;
154 return $this->pager->numPages();