$key = $options[$key]; } static $optionalKeys = ['index_class', 'linkBuilder', 'page_slug', 'sort_direction', 'sort_order', 'start']; foreach ($optionalKeys as $key) if (isset($options[$key])) $this->$key = $options[$key]; $this->generatePageIndex(); } private function buildLink($start = null, $order = null, $dir = null) { if (isset($this->linkBuilder)) return call_user_func($this->linkBuilder, $start, $order, $dir); else return $this->getLink($start, $order, $dir); } protected function generatePageIndex() { /* Example 1: [1] [2] [3] [...] [c-2] [c-1] [c] [c+1] [c+2] [...] [n-2] [n-1] [n] \---------/ \-------------------------/ \-------------/ lower current/contiguous pages upper Example 2: [1] [2] [3] [4] [5] [c] [6] [7] [...] [n/2] [...] [n-2] [n-1] [n] \---------/ \-----------------/ \---/ \-------------/ lower current/cont. pgs. center upper */ $this->num_pages = max(1, ceil($this->recordCount / $this->items_per_page)); $this->current_page = min(ceil($this->start / $this->items_per_page) + 1, $this->num_pages); if ($this->num_pages <= 1) { $this->needsPageIndex = false; return; } $lowerLower = 1; $lowerUpper = min($this->num_pages, 3); $contigLower = max($lowerUpper + 1, max($this->current_page - 2, 1)); $contigUpper = min($this->current_page + 2, $this->num_pages); $center = floor($this->num_pages / 2); $upperLower = max($contigUpper + 1, max(0, $this->num_pages - 2)); $upperUpper = $this->num_pages; $this->page_index = []; // Lower pages for ($p = $lowerLower; $p <= $lowerUpper; $p++) $this->page_index[$p] = [ 'index' => $p, 'is_selected' => $this->current_page == $p, 'href'=> $this->buildLink(($p - 1) * $this->items_per_page, $this->sort_order, $this->sort_direction), ]; // The center of the page index. if ($center > $lowerUpper && $center < $contigLower) { // Gap? if ($lowerUpper != $center) $this->page_index[] = '...'; $this->page_index[$center] = [ 'index' => $center, 'is_selected' => $this->current_page == $center, 'href'=> $this->buildLink(($center - 1) * $this->items_per_page, $this->sort_order, $this->sort_direction), ]; } // Gap? if ($contigLower != $p) $this->page_index[] = '...'; // contig pages for ($p = $contigLower; $p <= $contigUpper; $p++) $this->page_index[$p] = [ 'index' => $p, 'is_selected' => $this->current_page == $p, 'href'=> $this->buildLink(($p - 1) * $this->items_per_page, $this->sort_order, $this->sort_direction), ]; // The center of the page index. if ($center > $contigUpper && $center < $upperLower) { // Gap? if ($contigUpper != $center) $this->page_index[] = '...'; $this->page_index[$center] = [ 'index' => $center, 'is_selected' => $this->current_page == $center, 'href'=> $this->buildLink(($center - 1) * $this->items_per_page, $this->sort_order, $this->sort_direction), ]; } // Gap? if ($upperLower != $p) $this->page_index[] = '...'; // Upper pages for ($p = $upperLower; $p <= $upperUpper; $p++) $this->page_index[$p] = [ 'index' => $p, 'is_selected' => $this->current_page == $p, 'href'=> $this->buildLink(($p - 1) * $this->items_per_page, $this->sort_order, $this->sort_direction), ]; // Previous page? if ($this->current_page > 1) $this->page_index['previous'] = $this->page_index[$this->current_page - 1]; // Next page? if ($this->current_page < $this->num_pages) $this->page_index['next'] = $this->page_index[$this->current_page + 1]; } public function getLink($start = null, $order = null, $dir = null) { $page = !is_string($start) ? ($start / $this->items_per_page) + 1 : $start; $url = $this->base_url . str_replace('%PAGE%', $page, $this->page_slug); $urlParams = []; if (!empty($order)) $urlParams['order'] = $order; if (!empty($dir)) $urlParams['dir'] = $dir; if (!empty($urlParams)) { $queryString = (strpos($uri, '?') !== false ? '&' : '?'); $queryString .= http_build_query($urlParams); $url .= $queryString; } return $url; } public function getPageIndex() { return $this->page_index; } public function getItemsPerPage() { return $this->items_per_page; } public function getSortOrder() { return $this->sort_order; } public function getSortDirection() { return $this->sort_direction; } public function getPageIndexClass() { return $this->index_class; } public function getCurrentPage() { return $this->current_page; } public function getNumberOfPages() { return $this->num_pages; } public function getRecordCount() { return $this->recordCount; } }