forked from Public/pics
Aaron van Geffen
cba42a9129
This has on my todo list for years... I'm glad to finally get around to it.
217 lines
5.4 KiB
PHP
217 lines
5.4 KiB
PHP
<?php
|
|
/*****************************************************************************
|
|
* PageIndex.php
|
|
* Contains key class PageIndex.
|
|
*
|
|
* Kabuki CMS (C) 2013-2015, Aaron van Geffen
|
|
*****************************************************************************/
|
|
|
|
class PageIndex
|
|
{
|
|
protected $base_url;
|
|
protected $current_page = 1;
|
|
protected $index_class = 'pagination';
|
|
protected $items_per_page = 0;
|
|
protected $needsPageIndex = false;
|
|
protected $num_pages = 1;
|
|
protected $page_index = [];
|
|
protected $page_slug = '%AMP%page=%PAGE%';
|
|
protected $recordCount = 0;
|
|
protected $sort_direction = null;
|
|
protected $sort_order = null;
|
|
protected $start = 0;
|
|
|
|
public function __construct($options)
|
|
{
|
|
static $neededKeys = ['base_url', 'items_per_page', 'recordCount'];
|
|
foreach ($neededKeys as $key)
|
|
{
|
|
if (!isset($options[$key]))
|
|
throw new Exception('PageIndex: argument ' . $key . ' missing in options');
|
|
|
|
$this->$key = $options[$key];
|
|
}
|
|
|
|
static $optionalKeys = ['index_class', 'page_slug', 'sort_direction', 'sort_order', 'start'];
|
|
foreach ($optionalKeys as $key)
|
|
if (isset($options[$key]))
|
|
$this->$key = $options[$key];
|
|
|
|
$this->generatePageIndex();
|
|
}
|
|
|
|
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 = 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 == 0)
|
|
{
|
|
$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->getLink(($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->getLink(($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->getLink(($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->getLink(($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->getLink(($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)
|
|
{
|
|
$url = $this->base_url;
|
|
$amp = strpos($this->base_url, '?') ? '&' : '?';
|
|
|
|
if (!empty($start))
|
|
{
|
|
$page = $start !== '%d' ? ($start / $this->items_per_page) + 1 : $start;
|
|
$url .= strtr($this->page_slug, ['%PAGE%' => $page, '%AMP%' => $amp]);
|
|
$amp = '&';
|
|
}
|
|
if (!empty($order))
|
|
{
|
|
$url .= $amp . 'order=' . $order;
|
|
$amp = '&';
|
|
}
|
|
if (!empty($dir))
|
|
{
|
|
$url .= $amp . 'dir=' . $dir;
|
|
$amp = '&';
|
|
}
|
|
|
|
return $url;
|
|
}
|
|
|
|
public function getArray()
|
|
{
|
|
return $this->page_index;
|
|
}
|
|
|
|
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;
|
|
}
|
|
}
|