pics/models/PageIndex.php
Aaron van Geffen cba42a9129 Refactor GenericTable to use PageIndex rather than inherit from it
This has on my todo list for years... I'm glad to finally get around to it.
2021-02-17 20:43:30 +01:00

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;
}
}