166 lines
5.5 KiB
PHP
166 lines
5.5 KiB
PHP
<?php
|
|
|
|
/**
|
|
* @file classes/controllers/grid/feature/PagingFeature.php
|
|
*
|
|
* Copyright (c) 2014-2021 Simon Fraser University
|
|
* Copyright (c) 2000-2021 John Willinsky
|
|
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
|
|
*
|
|
* @class PagingFeature
|
|
*
|
|
* @ingroup controllers_grid_feature
|
|
*
|
|
* @brief Add paging functionality to grids.
|
|
*
|
|
*/
|
|
|
|
namespace PKP\controllers\grid\feature;
|
|
|
|
use APP\template\TemplateManager;
|
|
|
|
class PagingFeature extends GeneralPagingFeature
|
|
{
|
|
/**
|
|
* @see GridFeature::GridFeature()
|
|
* Constructor.
|
|
*
|
|
* @param string $id Feature identifier.
|
|
*/
|
|
public function __construct($id = 'paging')
|
|
{
|
|
parent::__construct($id);
|
|
}
|
|
|
|
|
|
//
|
|
// Extended methods from GridFeature.
|
|
//
|
|
/**
|
|
* @copydoc GridFeature::getJSClass()
|
|
*/
|
|
public function getJSClass()
|
|
{
|
|
return '$.pkp.classes.features.PagingFeature';
|
|
}
|
|
|
|
|
|
/**
|
|
* @copydoc GridFeature::fetchUIElements()
|
|
*/
|
|
public function fetchUIElements($request, $grid)
|
|
{
|
|
$options = $this->getOptions();
|
|
$templateMgr = TemplateManager::getManager($request);
|
|
$templateMgr->assign([
|
|
'iterator' => $this->getItemIterator(),
|
|
'currentItemsPerPage' => $options['currentItemsPerPage'],
|
|
'grid' => $grid,
|
|
]);
|
|
return ['pagingMarkup' => $templateMgr->fetch('controllers/grid/feature/gridPaging.tpl')];
|
|
}
|
|
|
|
|
|
//
|
|
// Hooks implementation.
|
|
//
|
|
/**
|
|
* @copydoc GridFeature::fetchRow()
|
|
* Check if user really deleted a row. Handle following cases:
|
|
* 1 - recently added requested row is on previous pages and its
|
|
* addition changes the current requested page items;
|
|
* 2 - deleted a row from a page that's not the last one;
|
|
* 3 - deleted the last row from a page that's not the last one;
|
|
*
|
|
* The solution is:
|
|
* 1 - fetch the first grid data row;
|
|
* 2 - fetch the last grid data row;
|
|
* 3 - send a request to refresh the entire grid usign the previous
|
|
* page.
|
|
*/
|
|
public function fetchRow($args)
|
|
{
|
|
$request = $args['request'];
|
|
$grid = $args['grid'];
|
|
$row = $args['row'];
|
|
$jsonMessage = $args['jsonMessage'];
|
|
$pagingAttributes = [];
|
|
|
|
if (is_null($row)) {
|
|
$gridData = $grid->getGridDataElements($request);
|
|
$iterator = $this->getItemIterator();
|
|
$rangeInfo = $grid->getGridRangeInfo($request, $grid->getId());
|
|
|
|
// Check if row was really deleted or if the requested row is
|
|
// just not inside the requested range.
|
|
$deleted = true;
|
|
$topLimitRowId = (int) $request->getUserVar('topLimitRowId');
|
|
$bottomLimitRowId = (int) $request->getUserVar('bottomLimitRowId');
|
|
|
|
reset($gridData);
|
|
$firstDataId = key($gridData);
|
|
next($gridData);
|
|
$secondDataId = key($gridData);
|
|
end($gridData);
|
|
$lastDataId = key($gridData);
|
|
|
|
if ($secondDataId == $topLimitRowId) {
|
|
$deleted = false;
|
|
// Case 1.
|
|
// Row was added but it's on previous pages, so the first
|
|
// item of the grid was moved to the second place by the added
|
|
// row. Render the first one that's currently not visible yet in
|
|
// grid.
|
|
$args = ['rowId' => $firstDataId];
|
|
$row = $grid->getRequestedRow($request, $args);
|
|
$pagingAttributes['newTopRow'] = $grid->renderRow($request, $row);
|
|
}
|
|
|
|
if ($firstDataId == $topLimitRowId && $lastDataId == $bottomLimitRowId) {
|
|
$deleted = false;
|
|
}
|
|
|
|
if ($deleted) {
|
|
if ((empty($gridData) ||
|
|
// When DAOResultFactory, it seems that if no items were found for the current
|
|
// range information, the last page is fetched, which give us grid data even if
|
|
// the current page is empty. So we check for iterator and rangeInfo current pages.
|
|
$iterator->getPage() != $rangeInfo->getPage())
|
|
&& $iterator->getPageCount() >= 1) {
|
|
// Case 3.
|
|
$pagingAttributes['loadLastPage'] = true;
|
|
} else {
|
|
if (count($gridData) >= $rangeInfo->getCount()) {
|
|
// Case 2.
|
|
// Get the last data element id of the current page.
|
|
end($gridData);
|
|
$firstRowId = key($gridData);
|
|
|
|
// Get the row and render it.
|
|
$args = ['rowId' => $firstRowId];
|
|
$row = $grid->getRequestedRow($request, $args);
|
|
$pagingAttributes['deletedRowReplacement'] = $grid->renderRow($request, $row);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Render the paging options, including updated markup.
|
|
$this->setOptions($request, $grid);
|
|
$pagingAttributes['pagingInfo'] = $this->getOptions();
|
|
|
|
// Add paging attributes to json so grid can update UI.
|
|
$additionalAttributes = $jsonMessage->getAdditionalAttributes();
|
|
$jsonMessage->setAdditionalAttributes(
|
|
array_merge(
|
|
$pagingAttributes,
|
|
$additionalAttributes
|
|
)
|
|
);
|
|
}
|
|
}
|
|
|
|
if (!PKP_STRICT_MODE) {
|
|
class_alias('\PKP\controllers\grid\feature\PagingFeature', '\PagingFeature');
|
|
}
|