You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
240 lines
6.9 KiB
240 lines
6.9 KiB
<?php
|
|
/*
|
|
** Zabbix
|
|
** Copyright (C) 2001-2023 Zabbix SIA
|
|
**
|
|
** This program is free software; you can redistribute it and/or modify
|
|
** it under the terms of the GNU General Public License as published by
|
|
** the Free Software Foundation; either version 2 of the License, or
|
|
** (at your option) any later version.
|
|
**
|
|
** This program is distributed in the hope that it will be useful,
|
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
** GNU General Public License for more details.
|
|
**
|
|
** You should have received a copy of the GNU General Public License
|
|
** along with this program; if not, write to the Free Software
|
|
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
**/
|
|
|
|
|
|
/**
|
|
* Pager helper for data pagination.
|
|
*/
|
|
class CPagerHelper {
|
|
|
|
/**
|
|
* Number of page buttons (use odd number).
|
|
*/
|
|
const RANGE = 11;
|
|
|
|
/**
|
|
* Create paging line based on count of data rows and trim data rows accordingly.
|
|
*
|
|
* @param int $page page to display
|
|
* @param array $rows data rows
|
|
* @param string $sort_order data sort order: ZBX_SORT_UP or ZBX_SORT_DOWN
|
|
* @param CUrl $url data list URL
|
|
*
|
|
* @return CTag paging line
|
|
*/
|
|
public static function paginate($page, &$rows, $sort_order, CUrl $url) {
|
|
$data = self::prepareData($page, count($rows));
|
|
|
|
$paging = self::render($data['page'], $data['num_rows'], $data['num_pages'], clone $url,
|
|
$data['limit_exceeded'], $data['rows_per_page']
|
|
);
|
|
|
|
$start = ($data['page'] - 1) * $data['rows_per_page'];
|
|
$end = min($data['num_rows'], $start + $data['rows_per_page']);
|
|
$offset = ($sort_order == ZBX_SORT_DOWN) ? $data['offset_down'] : $data['offset_up'];
|
|
|
|
// Trim given rows for the current page.
|
|
$rows = array_slice($rows, $start + $offset, $end - $start, true);
|
|
|
|
return $paging;
|
|
}
|
|
|
|
/**
|
|
* Reset page number.
|
|
*/
|
|
public static function resetPage() {
|
|
CProfile::delete('web.pager.entity');
|
|
CProfile::delete('web.pager.page');
|
|
}
|
|
|
|
/**
|
|
* Save page number for given entity.
|
|
*
|
|
* @param string $entity
|
|
* @param int $page
|
|
*/
|
|
public static function savePage($entity, $page) {
|
|
CProfile::update('web.pager.entity', $entity, PROFILE_TYPE_STR);
|
|
CProfile::update('web.pager.page', $page, PROFILE_TYPE_INT);
|
|
}
|
|
|
|
/**
|
|
* Load stored page number for given entity.
|
|
*
|
|
* @param string $entity
|
|
* @param mixed $first_page substitute return value for the first page
|
|
*
|
|
* @return mixed page number (or the $first_page if wasn't stored or first page was stored)
|
|
*/
|
|
public static function loadPage($entity, $first_page = 1) {
|
|
if ($entity !== CProfile::get('web.pager.entity')) {
|
|
return $first_page;
|
|
}
|
|
|
|
$page = CProfile::get('web.pager.page', 1);
|
|
|
|
return ($page == 1) ? $first_page : $page;
|
|
}
|
|
|
|
/**
|
|
* Prepare data for a given page number and the number of data rows.
|
|
*
|
|
* @param int $page
|
|
* @param int $num_rows
|
|
*
|
|
* @return array
|
|
*/
|
|
protected static function prepareData($page, $num_rows) {
|
|
$rows_per_page = CWebUser::$data['rows_per_page'];
|
|
|
|
$offset_down = 0;
|
|
$limit_exceeded = ($num_rows > CSettingsHelper::get(CSettingsHelper::SEARCH_LIMIT));
|
|
|
|
if ($limit_exceeded) {
|
|
$offset_down = $num_rows - CSettingsHelper::get(CSettingsHelper::SEARCH_LIMIT);
|
|
$num_rows = CSettingsHelper::get(CSettingsHelper::SEARCH_LIMIT);
|
|
}
|
|
|
|
$num_pages = max(1, (int) ceil($num_rows / $rows_per_page));
|
|
$page = max(1, min($num_pages, $page));
|
|
|
|
return [
|
|
'page' => $page,
|
|
'num_rows' => $num_rows,
|
|
'num_pages' => $num_pages,
|
|
'offset_up' => 0,
|
|
'offset_down' => $offset_down,
|
|
'rows_per_page' => $rows_per_page,
|
|
'limit_exceeded' => $limit_exceeded
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Render paging line.
|
|
*
|
|
* @param int $page page number
|
|
* @param int $num_rows number of rows
|
|
* @param int $num_pages number of pages
|
|
* @param CUrl $url data list URL
|
|
* @param bool $limit_exceeded true, if data list size exceeded the configuration search limit
|
|
* @param int $rows_per_page number of rows per page
|
|
*
|
|
* @return CTag
|
|
*/
|
|
protected static function render($page, $num_rows, $num_pages, CUrl $url, $limit_exceeded, $rows_per_page) {
|
|
$total = $limit_exceeded ? $num_rows.'+' : $num_rows;
|
|
$start = ($page - 1) * $rows_per_page;
|
|
$end = min($num_rows, $start + $rows_per_page);
|
|
|
|
if ($num_pages == 1) {
|
|
$table_stats = _s('Displaying %1$s of %2$s found', $num_rows, $total);
|
|
}
|
|
else {
|
|
$table_stats = _s('Displaying %1$s to %2$s of %3$s found', $start + 1, $end, $total);
|
|
}
|
|
|
|
return (new CDiv())
|
|
->addClass(ZBX_STYLE_TABLE_PAGING)
|
|
->addItem(
|
|
(new CTag('nav', true))
|
|
->addClass(ZBX_STYLE_PAGING_BTN_CONTAINER)
|
|
->setAttribute('role', 'navigation')
|
|
->setAttribute('aria-label', _x('Pager', 'page navigation'))
|
|
->addItem(self::createLinks($page, $num_pages, $url))
|
|
->addItem(
|
|
(new CDiv())
|
|
->addClass(ZBX_STYLE_TABLE_STATS)
|
|
->addItem($table_stats)
|
|
)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Create paging tags for paging line.
|
|
*
|
|
* @param int $page page number
|
|
* @param int $num_pages number of pages
|
|
* @param CUrl $url data list URL
|
|
*
|
|
* @return array
|
|
*/
|
|
protected static function createLinks($page, $num_pages, CUrl $url) {
|
|
$tags = [];
|
|
|
|
if ($num_pages > 1) {
|
|
$end_page = min($num_pages, max(self::RANGE, $page + floor(self::RANGE / 2)));
|
|
$start_page = max(1, $end_page - self::RANGE + 1);
|
|
|
|
if ($start_page > 1) {
|
|
$url->removeArgument('page');
|
|
$tags[] = (new CLink(_x('First', 'page navigation'), $url->getUrl()))
|
|
->setAttribute('aria-label', _('Go to first page'));
|
|
}
|
|
|
|
if ($page > 1) {
|
|
if ($page == 2) {
|
|
$url->removeArgument('page');
|
|
}
|
|
else {
|
|
$url->setArgument('page', $page - 1);
|
|
}
|
|
$tags[] = (new CLink((new CSpan())->addClass(ZBX_STYLE_ARROW_LEFT), $url->getUrl()))
|
|
->setAttribute('aria-label', _s('Go to previous page, %1$s', $page - 1));
|
|
}
|
|
|
|
for ($i = $start_page; $i <= $end_page; $i++) {
|
|
if ($i == 1) {
|
|
$url->removeArgument('page');
|
|
}
|
|
else {
|
|
$url->setArgument('page', $i);
|
|
}
|
|
|
|
$link = new CLink($i, $url->getUrl());
|
|
if ($i == $page) {
|
|
$link
|
|
->addClass(ZBX_STYLE_PAGING_SELECTED)
|
|
->setAttribute('aria-label', _s('Go to page %1$s, current page', $i))
|
|
->setAttribute('aria-current', 'true');
|
|
}
|
|
else {
|
|
$link->setAttribute('aria-label', _s('Go to page %1$s', $i));
|
|
}
|
|
|
|
$tags[] = $link;
|
|
}
|
|
|
|
if ($page < $num_pages) {
|
|
$url->setArgument('page', $page + 1);
|
|
$tags[] = (new CLink((new CSpan())->addClass(ZBX_STYLE_ARROW_RIGHT), $url->getUrl()))
|
|
->setAttribute('aria-label', _s('Go to next page, %1$s', $page + 1));
|
|
}
|
|
|
|
if ($end_page < $num_pages) {
|
|
$url->setArgument('page', $num_pages);
|
|
$tags[] = (new CLink(_x('Last', 'page navigation'), $url->getUrl()))
|
|
->setAttribute('aria-label', _s('Go to last page, %1$s', $num_pages));
|
|
}
|
|
}
|
|
|
|
return $tags;
|
|
}
|
|
}
|