first commit
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file classes/controllers/grid/feature/CollapsibleGridFeature.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 CollapsibleGridFeature
|
||||
*
|
||||
* @ingroup controllers_grid_feature
|
||||
*
|
||||
* @brief Add collapse and expand functionality to grids.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\feature;
|
||||
|
||||
use APP\template\TemplateManager;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\NullAction;
|
||||
|
||||
class CollapsibleGridFeature extends GridFeature
|
||||
{
|
||||
/**
|
||||
* @copydoc GridFeature::GridFeature()
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct($id = 'collapsible')
|
||||
{
|
||||
parent::__construct($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copyDoc GridFeature::getJSClass()
|
||||
*/
|
||||
public function getJSClass()
|
||||
{
|
||||
return '$.pkp.classes.features.CollapsibleGridFeature';
|
||||
}
|
||||
|
||||
/**
|
||||
* @copyDoc GridFeature::fetchUIElement()
|
||||
*/
|
||||
public function fetchUIElements($request, $grid)
|
||||
{
|
||||
$controlLink = new LinkAction(
|
||||
'expandGridControlLink',
|
||||
new NullAction(),
|
||||
null,
|
||||
'expand_all'
|
||||
);
|
||||
|
||||
$templateMgr = TemplateManager::getManager($request);
|
||||
$templateMgr->assign('controlLink', $controlLink);
|
||||
$markup = $templateMgr->fetch('controllers/grid/feature/collapsibleGridFeature.tpl');
|
||||
|
||||
return ['collapsibleLink' => $markup];
|
||||
}
|
||||
}
|
||||
|
||||
if (!PKP_STRICT_MODE) {
|
||||
class_alias('\PKP\controllers\grid\feature\CollapsibleGridFeature', '\CollapsibleGridFeature');
|
||||
}
|
||||
@@ -0,0 +1,195 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file classes/controllers/grid/feature/GeneralPagingFeature.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 GeneralPagingFeature
|
||||
*
|
||||
* @ingroup controllers_grid_feature
|
||||
*
|
||||
* @brief Base class that implements common functionality for
|
||||
* paging features.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\feature;
|
||||
|
||||
use APP\core\Application;
|
||||
use PKP\controllers\grid\GridHandler;
|
||||
use PKP\core\ArrayItemIterator;
|
||||
use PKP\core\ItemIterator;
|
||||
use PKP\handler\PKPHandler;
|
||||
|
||||
class GeneralPagingFeature extends GridFeature
|
||||
{
|
||||
/** @var ItemIterator */
|
||||
private $_itemIterator;
|
||||
|
||||
/** @var int itemsPerPage */
|
||||
private $_itemsPerPage;
|
||||
|
||||
/**
|
||||
* @see GridFeature::GridFeature()
|
||||
*
|
||||
* @param string $id Feature identifier.
|
||||
* @param null|int $itemsPerPage Optional Number of items to show at
|
||||
* the first time.
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct($id, $itemsPerPage = null)
|
||||
{
|
||||
$this->_itemsPerPage = $itemsPerPage;
|
||||
parent::__construct($id);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Getters and setters.
|
||||
//
|
||||
/**
|
||||
* Get item iterator.
|
||||
*
|
||||
* @return ItemIterator
|
||||
*/
|
||||
public function getItemIterator()
|
||||
{
|
||||
return $this->_itemIterator;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Extended GridFeature methods.
|
||||
//
|
||||
/**
|
||||
* @copydoc GridFeature::setOptions()
|
||||
*/
|
||||
public function setOptions($request, $grid)
|
||||
{
|
||||
// Get the default items per page setting value.
|
||||
$rangeInfo = PKPHandler::getRangeInfo($request, $grid->getId());
|
||||
$iterator = $this->getItemIterator();
|
||||
$defaultItemsPerPage = $rangeInfo->getCount();
|
||||
|
||||
// Check for a component level items per page setting.
|
||||
$componentItemsPerPage = $request->getUserVar($this->_getItemsPerPageParamName($grid->getId()));
|
||||
if (!$componentItemsPerPage) {
|
||||
$componentItemsPerPage = $this->_itemsPerPage;
|
||||
}
|
||||
|
||||
if ($componentItemsPerPage) {
|
||||
$currentItemsPerPage = $componentItemsPerPage;
|
||||
} else {
|
||||
$currentItemsPerPage = $defaultItemsPerPage;
|
||||
}
|
||||
|
||||
$this->addOptions([
|
||||
'itemsPerPageParamName' => $this->_getItemsPerPageParamName($grid->getId()),
|
||||
'defaultItemsPerPage' => $defaultItemsPerPage,
|
||||
'currentItemsPerPage' => $currentItemsPerPage,
|
||||
'itemsTotal' => $iterator->getCount(),
|
||||
'pageParamName' => PKPHandler::getPageParamName($grid->getId()),
|
||||
'currentPage' => $iterator->getPage()
|
||||
]);
|
||||
|
||||
parent::setOptions($request, $grid);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Hooks implementation.
|
||||
//
|
||||
/**
|
||||
* @copydoc GridFeature::gridInitialize()
|
||||
* The feature will know about the current filter
|
||||
* value so it can request grid refreshes keeping
|
||||
* the filter.
|
||||
*/
|
||||
public function getGridDataElements($args)
|
||||
{
|
||||
$filter = $args['filter'];
|
||||
|
||||
if (is_array($filter) && !empty($filter)) {
|
||||
$this->addOptions(['filter' => json_encode($filter)]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @copydoc GridFeature::setGridDataElements()
|
||||
*/
|
||||
public function setGridDataElements($args)
|
||||
{
|
||||
$grid = & $args['grid'];
|
||||
$data = & $args['data'];
|
||||
|
||||
if (is_array($data)) {
|
||||
$request = Application::get()->getRequest();
|
||||
$rangeInfo = $grid->getGridRangeInfo($request, $grid->getId());
|
||||
$itemIterator = new ArrayItemIterator($data, $rangeInfo->getPage(), $rangeInfo->getCount());
|
||||
$this->_itemIterator = $itemIterator;
|
||||
$data = $itemIterator->toArray();
|
||||
} elseif ($data instanceof ItemIterator) {
|
||||
$this->_itemIterator = $data;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridFeature::getRequestArgs()
|
||||
*/
|
||||
public function getRequestArgs($args)
|
||||
{
|
||||
$grid = $args['grid'];
|
||||
$requestArgs = & $args['requestArgs'];
|
||||
|
||||
// Add paging info so grid actions will not lose paging context.
|
||||
// Only works if grid link actions use the getRequestArgs
|
||||
// returned content.
|
||||
$request = Application::get()->getRequest();
|
||||
$rangeInfo = $grid->getGridRangeInfo($request, $grid->getId());
|
||||
$requestArgs[GridHandler::getPageParamName($grid->getId())] = $rangeInfo->getPage();
|
||||
$requestArgs[$this->_getItemsPerPageParamName($grid->getId())] = $rangeInfo->getCount();
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridFeature::getGridRangeInfo()
|
||||
*/
|
||||
public function getGridRangeInfo($args)
|
||||
{
|
||||
$request = $args['request'];
|
||||
$grid = $args['grid'];
|
||||
$rangeInfo = $args['rangeInfo'];
|
||||
|
||||
// Add grid level items per page setting, if any.
|
||||
$itemsPerPage = $request->getUserVar($this->_getItemsPerPageParamName($grid->getId()));
|
||||
if ($this->_itemsPerPage) {
|
||||
$itemsPerPage = $this->_itemsPerPage;
|
||||
} // Feature config overrides.
|
||||
if ($itemsPerPage) {
|
||||
$rangeInfo->setCount($itemsPerPage);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Private helper methods.
|
||||
//
|
||||
/**
|
||||
* Get the range info items per page parameter name.
|
||||
*
|
||||
* @param string $rangeName
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function _getItemsPerPageParamName($rangeName)
|
||||
{
|
||||
return $rangeName . 'ItemsPerPage';
|
||||
}
|
||||
}
|
||||
|
||||
if (!PKP_STRICT_MODE) {
|
||||
class_alias('\PKP\controllers\grid\feature\GeneralPagingFeature', '\GeneralPagingFeature');
|
||||
}
|
||||
@@ -0,0 +1,301 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file classes/controllers/grid/feature/GridFeature.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 GridFeature
|
||||
*
|
||||
* @ingroup controllers_grid_feature
|
||||
*
|
||||
* @brief Base grid feature class. A feature is a type of plugin specific
|
||||
* to the grid widgets. It provides several hooks to allow injection of
|
||||
* additional grid functionality. This class implements template methods
|
||||
* to be extended by subclasses.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\feature;
|
||||
use PKP\controllers\grid\GridHandler;
|
||||
use PKP\core\PKPRequest;
|
||||
|
||||
class GridFeature
|
||||
{
|
||||
/** @var string */
|
||||
public $_id;
|
||||
|
||||
/** @var array */
|
||||
public $_options;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $id Feature id.
|
||||
*/
|
||||
public function __construct($id)
|
||||
{
|
||||
$this->setId($id);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Getters and setters.
|
||||
//
|
||||
/**
|
||||
* Get feature id.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getId()
|
||||
{
|
||||
return $this->_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set feature id.
|
||||
*
|
||||
* @param string $id
|
||||
*/
|
||||
public function setId($id)
|
||||
{
|
||||
$this->_id = $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get feature js class options.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getOptions()
|
||||
{
|
||||
return $this->_options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add feature js class options.
|
||||
*
|
||||
* @param array $options $optionId => $optionValue
|
||||
*/
|
||||
public function addOptions($options)
|
||||
{
|
||||
assert(is_array($options));
|
||||
$this->_options = array_merge((array) $this->getOptions(), $options);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Protected methods to be used or extended by subclasses.
|
||||
//
|
||||
/**
|
||||
* Set feature js class options. Extend this method to
|
||||
* define more feature js class options.
|
||||
*
|
||||
* @param PKPRequest $request
|
||||
* @param GridHandler $grid
|
||||
*/
|
||||
public function setOptions($request, $grid)
|
||||
{
|
||||
$renderedElements = $this->fetchUIElements($request, $grid);
|
||||
if ($renderedElements) {
|
||||
foreach ($renderedElements as $id => $markup) {
|
||||
$this->addOptions([$id => $markup]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch any user interface elements that
|
||||
* this feature needs to add its functionality
|
||||
* into the grid. Use this only for ui elements
|
||||
* that grid will not fetch itself.
|
||||
*
|
||||
* @param PKPRequest $request
|
||||
* @param GridHandler $grid The grid that this
|
||||
* feature is attached to.
|
||||
*
|
||||
* @return array It is expected that the array
|
||||
* returns data in this format:
|
||||
* $elementId => $elementMarkup
|
||||
*/
|
||||
public function fetchUIElements($request, $grid)
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the java script feature class.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getJSClass()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Public hooks to be implemented in subclasses.
|
||||
//
|
||||
/**
|
||||
* Hook called every time grid request args are
|
||||
* required. Note that if the specific grid implementation
|
||||
* extends the getRequestArgs method, this hook will only
|
||||
* be called if the extending method call its parent.
|
||||
*
|
||||
* @param array $args
|
||||
* 'grid' => GridHandler
|
||||
* 'requestArgs' => array
|
||||
*/
|
||||
public function getRequestArgs($args)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook called every time the grid range info is
|
||||
* retrieved.
|
||||
*
|
||||
* @param array $args
|
||||
* 'request' => PKPRequest
|
||||
* 'grid' => GridHandler
|
||||
* 'rangeInfo' => DBResultRange
|
||||
*/
|
||||
public function getGridRangeInfo($args)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook called when grid data is retrieved.
|
||||
*
|
||||
* @param array $args
|
||||
* 'request' => PKPRequest
|
||||
* 'grid' => GridHandler
|
||||
* 'gridData' => mixed (array or ItemIterator)
|
||||
* 'filter' => array
|
||||
*/
|
||||
public function getGridDataElements($args)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook called before grid data is setted.
|
||||
*
|
||||
* @param array $args
|
||||
* 'grid' => GridHandler
|
||||
* 'data' => mixed (array or ItemIterator)
|
||||
*/
|
||||
public function setGridDataElements($args)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook called every time grid initialize a row object.
|
||||
*
|
||||
* @param array $args
|
||||
* 'grid' => GridHandler,
|
||||
* 'row' => GridRow
|
||||
*/
|
||||
public function getInitializedRowInstance($args)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook called on grid category row initialization.
|
||||
*
|
||||
* @param array $args 'request' => PKPRequest
|
||||
* 'grid' => CategoryGridHandler
|
||||
* 'categoryId' => int
|
||||
* 'row' => GridCategoryRow
|
||||
*/
|
||||
public function getInitializedCategoryRowInstance($args)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook called on grid's initialization.
|
||||
*
|
||||
* @param array $args Contains the grid handler referenced object
|
||||
* in 'grid' array index.
|
||||
*/
|
||||
public function gridInitialize($args)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook called on grid's data loading.
|
||||
*
|
||||
* @param array $args
|
||||
* 'request' => PKPRequest,
|
||||
* 'grid' => GridHandler,
|
||||
* 'gridData' => array
|
||||
*/
|
||||
public function loadData($args)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook called on grid fetching.
|
||||
*
|
||||
* @param array $args 'grid' => GridHandler
|
||||
*/
|
||||
public function fetchGrid($args)
|
||||
{
|
||||
$grid = & $args['grid'];
|
||||
$request = & $args['request'];
|
||||
|
||||
$this->setOptions($request, $grid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook called after a group of rows is fetched.
|
||||
*
|
||||
* @param array $args
|
||||
* 'request' => PKPRequest
|
||||
* 'grid' => GridHandler
|
||||
* 'jsonMessage' => JSONMessage
|
||||
*/
|
||||
public function fetchRows($args)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook called after a row is fetched.
|
||||
*
|
||||
* @param array $args
|
||||
* 'request' => PKPRequest
|
||||
* 'grid' => GridHandler
|
||||
* 'row' => mixed GridRow or null
|
||||
* 'jsonMessage' => JSONMessage
|
||||
*/
|
||||
public function fetchRow($args)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook called when save grid items sequence
|
||||
* is requested.
|
||||
*
|
||||
* @param array $args 'request' => PKPRequest,
|
||||
* 'grid' => GridHandler
|
||||
*/
|
||||
public function saveSequence($args)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
if (!PKP_STRICT_MODE) {
|
||||
class_alias('\PKP\controllers\grid\feature\GridFeature', '\GridFeature');
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file classes/controllers/grid/feature/InfiniteScrollingFeature.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 InfiniteScrollingFeature
|
||||
*
|
||||
* @ingroup controllers_grid_feature
|
||||
*
|
||||
* @brief Add infinite scrolling functionality to grids. It doesn't support
|
||||
* category grids.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\feature;
|
||||
|
||||
use APP\template\TemplateManager;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\NullAction;
|
||||
|
||||
class InfiniteScrollingFeature extends GeneralPagingFeature
|
||||
{
|
||||
/**
|
||||
* @copydoc GeneralPagingFeature::GeneralPagingFeature()
|
||||
* Constructor.
|
||||
*
|
||||
* @param null|mixed $itemsPerPage
|
||||
*/
|
||||
public function __construct($id = 'infiniteScrolling', $itemsPerPage = null)
|
||||
{
|
||||
parent::__construct($id, $itemsPerPage);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Extended methods from GridFeature.
|
||||
//
|
||||
/**
|
||||
* @copydoc GridFeature::getJSClass()
|
||||
*/
|
||||
public function getJSClass()
|
||||
{
|
||||
return '$.pkp.classes.features.InfiniteScrollingFeature';
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridFeature::fetchUIElements()
|
||||
*/
|
||||
public function fetchUIElements($request, $grid)
|
||||
{
|
||||
$options = $this->getOptions();
|
||||
|
||||
$shown = $options['currentItemsPerPage'] * $options['currentPage'];
|
||||
if ($shown > $options['itemsTotal']) {
|
||||
$shown = $options['itemsTotal'];
|
||||
}
|
||||
|
||||
$moreItemsLinkAction = false;
|
||||
if ($shown < $options['itemsTotal']) {
|
||||
$moreItemsLinkAction = new LinkAction(
|
||||
'moreItems',
|
||||
new NullAction(),
|
||||
__('grid.action.moreItems'),
|
||||
'more_items'
|
||||
);
|
||||
}
|
||||
|
||||
$templateMgr = TemplateManager::getManager($request);
|
||||
$templateMgr->assign([
|
||||
'iterator' => $this->getItemIterator(),
|
||||
'shown' => $shown,
|
||||
'grid' => $grid,
|
||||
'moreItemsLinkAction' => $moreItemsLinkAction,
|
||||
]);
|
||||
|
||||
return [
|
||||
'pagingMarkup' => $templateMgr->fetch('controllers/grid/feature/infiniteScrolling.tpl'),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Hooks implementation.
|
||||
//
|
||||
/**
|
||||
* @copydoc GridFeature::fetchRows()
|
||||
*/
|
||||
public function fetchRows($args)
|
||||
{
|
||||
$request = $args['request'];
|
||||
$grid = $args['grid'];
|
||||
$jsonMessage = $args['jsonMessage'];
|
||||
|
||||
// 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 = (array) $jsonMessage->getAdditionalAttributes();
|
||||
$jsonMessage->setAdditionalAttributes(
|
||||
array_merge(
|
||||
$pagingAttributes,
|
||||
$additionalAttributes
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridFeature::fetchRow()
|
||||
* Check if user really deleted a row and fetch the last one from
|
||||
* the current page.
|
||||
*/
|
||||
public function fetchRow($args)
|
||||
{
|
||||
$request = $args['request'];
|
||||
$grid = $args['grid'];
|
||||
$row = $args['row'];
|
||||
$jsonMessage = $args['jsonMessage'];
|
||||
$pagingAttributes = [];
|
||||
|
||||
// Render the paging options, including updated markup.
|
||||
$this->setOptions($request, $grid);
|
||||
$pagingAttributes['pagingInfo'] = $this->getOptions();
|
||||
|
||||
if (is_null($row)) {
|
||||
$gridData = $grid->getGridDataElements($request);
|
||||
|
||||
// Get the last data element id of the current page.
|
||||
end($gridData);
|
||||
$lastRowId = key($gridData);
|
||||
|
||||
// Get the row and render it.
|
||||
$args = ['rowId' => $lastRowId];
|
||||
$row = $grid->getRequestedRow($request, $args);
|
||||
$pagingAttributes['deletedRowReplacement'] = $grid->renderRow($request, $row);
|
||||
} else {
|
||||
// No need for paging markup.
|
||||
unset($pagingAttributes['pagingInfo']['pagingMarkup']);
|
||||
}
|
||||
|
||||
// Add paging attributes to json so grid can update UI.
|
||||
$additionalAttributes = $jsonMessage->getAdditionalAttributes();
|
||||
|
||||
// Unset sequence map until we support that.
|
||||
unset($additionalAttributes['sequenceMap']);
|
||||
$jsonMessage->setAdditionalAttributes(
|
||||
array_merge(
|
||||
$pagingAttributes,
|
||||
$additionalAttributes
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (!PKP_STRICT_MODE) {
|
||||
class_alias('\PKP\controllers\grid\feature\InfiniteScrollingFeature', '\InfiniteScrollingFeature');
|
||||
}
|
||||
@@ -0,0 +1,191 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file classes/controllers/grid/feature/OrderCategoryGridItemsFeature.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 OrderCategoryGridItemsFeature
|
||||
*
|
||||
* @ingroup controllers_grid_feature
|
||||
*
|
||||
* @brief Implements category grid ordering functionality.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\feature;
|
||||
use PKP\controllers\grid\GridHandler;
|
||||
use PKP\core\PKPRequest;
|
||||
|
||||
class OrderCategoryGridItemsFeature extends OrderItemsFeature
|
||||
{
|
||||
public const ORDER_CATEGORY_GRID_CATEGORIES_ONLY = 1;
|
||||
public const ORDER_CATEGORY_GRID_CATEGORIES_ROWS_ONLY = 2;
|
||||
public const ORDER_CATEGORY_GRID_CATEGORIES_AND_ROWS = 3;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param int $typeOption Defines which grid elements will
|
||||
* be orderable (categories and/or rows).
|
||||
* @param bool $overrideRowTemplate This feature uses row
|
||||
* actions and it will force the usage of the gridRow.tpl.
|
||||
* If you want to use a different grid row template file, set this flag to
|
||||
* false and make sure to use a template file that adds row actions.
|
||||
* @param GridHandler $grid The grid this feature is to be part of
|
||||
*/
|
||||
public function __construct($typeOption = self::ORDER_CATEGORY_GRID_CATEGORIES_AND_ROWS, $overrideRowTemplate = true, $grid = null)
|
||||
{
|
||||
parent::__construct($overrideRowTemplate);
|
||||
|
||||
if ($grid) {
|
||||
$grid->_constants['ORDER_CATEGORY_GRID_CATEGORIES_ONLY'] = self::ORDER_CATEGORY_GRID_CATEGORIES_ONLY;
|
||||
$grid->_constants['ORDER_CATEGORY_GRID_CATEGORIES_ROWS_ONLY'] = self::ORDER_CATEGORY_GRID_CATEGORIES_ROWS_ONLY;
|
||||
$grid->_constants['ORDER_CATEGORY_GRID_CATEGORIES_AND_ROWS'] = self::ORDER_CATEGORY_GRID_CATEGORIES_AND_ROWS;
|
||||
}
|
||||
|
||||
$this->addOptions(['type' => $typeOption]);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Getters and setters.
|
||||
//
|
||||
/**
|
||||
* Return this feature type.
|
||||
*
|
||||
* @return int One of the ORDER_CATEGORY_GRID_... constants
|
||||
*/
|
||||
public function getType()
|
||||
{
|
||||
$options = $this->getOptions();
|
||||
return $options['type'];
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Extended methods from GridFeature.
|
||||
//
|
||||
/**
|
||||
* @see GridFeature::getJSClass()
|
||||
*/
|
||||
public function getJSClass()
|
||||
{
|
||||
return '$.pkp.classes.features.OrderCategoryGridItemsFeature';
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Hooks implementation.
|
||||
//
|
||||
/**
|
||||
* @see OrderItemsFeature::getInitializedRowInstance()
|
||||
*/
|
||||
public function getInitializedRowInstance($args)
|
||||
{
|
||||
if ($this->getType() != self::ORDER_CATEGORY_GRID_CATEGORIES_ONLY) {
|
||||
parent::getInitializedRowInstance($args);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see GridFeature::getInitializedCategoryRowInstance()
|
||||
*/
|
||||
public function getInitializedCategoryRowInstance($args)
|
||||
{
|
||||
if ($this->getType() != self::ORDER_CATEGORY_GRID_CATEGORIES_ROWS_ONLY) {
|
||||
$row = & $args['row'];
|
||||
$this->addRowOrderAction($row);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see GridFeature::saveSequence()
|
||||
*/
|
||||
public function saveSequence($args)
|
||||
{
|
||||
$request = & $args['request'];
|
||||
$grid = & $args['grid'];
|
||||
|
||||
$data = json_decode($request->getUserVar('data'));
|
||||
$gridCategoryElements = $grid->getGridDataElements($request);
|
||||
|
||||
if ($this->getType() != self::ORDER_CATEGORY_GRID_CATEGORIES_ROWS_ONLY) {
|
||||
$categoriesData = [];
|
||||
foreach ($data as $categoryData) {
|
||||
$categoriesData[] = $categoryData->categoryId;
|
||||
}
|
||||
|
||||
// Save categories sequence.
|
||||
$firstSeqValue = $grid->getDataElementSequence(reset($gridCategoryElements));
|
||||
foreach ($gridCategoryElements as $rowId => $element) {
|
||||
$rowPosition = array_search($rowId, $categoriesData);
|
||||
$newSequence = $firstSeqValue + $rowPosition;
|
||||
$currentSequence = $grid->getDataElementSequence($element);
|
||||
if ($newSequence != $currentSequence) {
|
||||
$grid->setDataElementSequence($request, $rowId, $element, $newSequence);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Save rows sequence, if this grid has also orderable rows inside each category.
|
||||
$this->_saveRowsInCategoriesSequence($request, $grid, $gridCategoryElements, $data);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Private helper methods.
|
||||
//
|
||||
/**
|
||||
* Save row elements sequence inside categories.
|
||||
*
|
||||
* @param PKPRequest $request
|
||||
* @param GridHandler $grid
|
||||
* @param array $gridCategoryElements
|
||||
*/
|
||||
public function _saveRowsInCategoriesSequence($request, &$grid, $gridCategoryElements, $data)
|
||||
{
|
||||
if ($this->getType() != self::ORDER_CATEGORY_GRID_CATEGORIES_ONLY) {
|
||||
foreach ($gridCategoryElements as $categoryId => $element) {
|
||||
$gridRowElements = $grid->getGridCategoryDataElements($request, $element);
|
||||
if (!$gridRowElements) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get the correct rows sequence data.
|
||||
/** @var ?array */
|
||||
$rowsData = null;
|
||||
foreach ($data as $categoryData) {
|
||||
if ($categoryData->categoryId == $categoryId) {
|
||||
$rowsData = $categoryData->rowsId;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
unset($rowsData[0]); // remove the first element, it is always the parent category ID
|
||||
$gridRowElement = reset($gridRowElements);
|
||||
$firstSeqValue = $grid->getDataElementInCategorySequence($categoryId, $gridRowElement);
|
||||
foreach ($gridRowElements as $rowId => $element) {
|
||||
$newSequence = array_search($rowId, $rowsData);
|
||||
$currentSequence = $grid->getDataElementInCategorySequence($categoryId, $element);
|
||||
if ($newSequence != $currentSequence) {
|
||||
$grid->setDataElementInCategorySequence($categoryId, $element, $newSequence);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!PKP_STRICT_MODE) {
|
||||
class_alias('\PKP\controllers\grid\feature\OrderCategoryGridItemsFeature', '\OrderCategoryGridItemsFeature');
|
||||
foreach ([
|
||||
'ORDER_CATEGORY_GRID_CATEGORIES_ONLY',
|
||||
'ORDER_CATEGORY_GRID_CATEGORIES_ROWS_ONLY',
|
||||
'ORDER_CATEGORY_GRID_CATEGORIES_AND_ROWS',
|
||||
] as $constantName) {
|
||||
define($constantName, constant('\OrderCategoryGridItemsFeature::' . $constantName));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file classes/controllers/grid/feature/OrderGridItemsFeature.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 OrderGridItemsFeature
|
||||
*
|
||||
* @ingroup controllers_grid_feature
|
||||
*
|
||||
* @brief Implements grid ordering functionality.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\feature;
|
||||
|
||||
class OrderGridItemsFeature extends OrderItemsFeature
|
||||
{
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @copydoc OrderItemsFeature::OrderItemsFeature()
|
||||
*
|
||||
* @param null|mixed $nonOrderableItemsMessage
|
||||
*/
|
||||
public function __construct($overrideRowTemplate = true, $nonOrderableItemsMessage = null)
|
||||
{
|
||||
parent::__construct($overrideRowTemplate, $nonOrderableItemsMessage);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Extended methods from GridFeature.
|
||||
//
|
||||
/**
|
||||
* @see GridFeature::getJSClass()
|
||||
*/
|
||||
public function getJSClass()
|
||||
{
|
||||
return '$.pkp.classes.features.OrderGridItemsFeature';
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Hooks implementation.
|
||||
//
|
||||
/**
|
||||
* @see GridFeature::saveSequence()
|
||||
*
|
||||
* @param array $args
|
||||
*/
|
||||
public function saveSequence($args)
|
||||
{
|
||||
$request = & $args['request'];
|
||||
$grid = & $args['grid'];
|
||||
|
||||
$data = json_decode($request->getUserVar('data'));
|
||||
|
||||
$gridElements = $grid->getGridDataElements($request);
|
||||
if (empty($gridElements)) {
|
||||
return;
|
||||
}
|
||||
$firstSeqValue = $grid->getDataElementSequence(reset($gridElements));
|
||||
foreach ($gridElements as $rowId => $element) {
|
||||
$rowPosition = array_search($rowId, $data);
|
||||
$newSequence = $firstSeqValue + $rowPosition;
|
||||
$currentSequence = $grid->getDataElementSequence($element);
|
||||
if ($newSequence != $currentSequence) {
|
||||
$grid->setDataElementSequence($request, $rowId, $element, $newSequence);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!PKP_STRICT_MODE) {
|
||||
class_alias('\PKP\controllers\grid\feature\OrderGridItemsFeature', '\OrderGridItemsFeature');
|
||||
}
|
||||
@@ -0,0 +1,217 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file classes/controllers/grid/feature/OrderItemsFeature.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 OrderItemsFeature
|
||||
*
|
||||
* @ingroup controllers_grid_feature
|
||||
*
|
||||
* @brief Base class for grid widgets ordering functionality.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\feature;
|
||||
|
||||
use APP\template\TemplateManager;
|
||||
use PKP\controllers\grid\GridRow;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\NullAction;
|
||||
|
||||
class OrderItemsFeature extends GridFeature
|
||||
{
|
||||
/** @var bool */
|
||||
public $_overrideRowTemplate;
|
||||
|
||||
/** @var string */
|
||||
public $_nonOrderableItemMessage;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param bool $overrideRowTemplate This feature uses row
|
||||
* actions and it will force the usage of the gridRow.tpl.
|
||||
* If you want to use a different grid row template file, set this flag to
|
||||
* false and make sure to use a template file that adds row actions.
|
||||
* @param string $nonOrderableItemMessage optional A translated message to be used
|
||||
* when user tries to move a non orderable grid item.
|
||||
*/
|
||||
public function __construct($overrideRowTemplate, $nonOrderableItemMessage = null)
|
||||
{
|
||||
parent::__construct('orderItems');
|
||||
|
||||
$this->setOverrideRowTemplate($overrideRowTemplate);
|
||||
$this->setNonOrderableItemMessage($nonOrderableItemMessage);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Getters and setters.
|
||||
//
|
||||
/**
|
||||
* Set override row template flag.
|
||||
*/
|
||||
public function setOverrideRowTemplate($overrideRowTemplate)
|
||||
{
|
||||
$this->_overrideRowTemplate = $overrideRowTemplate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get override row template flag.
|
||||
*
|
||||
* @param GridRow $gridRow
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getOverrideRowTemplate(&$gridRow)
|
||||
{
|
||||
// Make sure we don't return the override row template
|
||||
// flag to objects that are not instances of GridRow class.
|
||||
if ($gridRow instanceof GridRow) {
|
||||
return $this->_overrideRowTemplate;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set non orderable item message.
|
||||
*
|
||||
* @param string $nonOrderableItemMessage Message already translated.
|
||||
*/
|
||||
public function setNonOrderableItemMessage($nonOrderableItemMessage)
|
||||
{
|
||||
$this->_nonOrderableItemMessage = $nonOrderableItemMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get non orderable item message.
|
||||
*
|
||||
* @return string Message already translated.
|
||||
*/
|
||||
public function getNonOrderableItemMessage()
|
||||
{
|
||||
return $this->_nonOrderableItemMessage;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Extended methods from GridFeature.
|
||||
//
|
||||
/**
|
||||
* @see GridFeature::setOptions()
|
||||
*/
|
||||
public function setOptions($request, $grid)
|
||||
{
|
||||
parent::setOptions($request, $grid);
|
||||
|
||||
$router = $request->getRouter();
|
||||
$this->addOptions([
|
||||
'saveItemsSequenceUrl' => $router->url($request, null, null, 'saveSequence', null, $grid->getRequestArgs()),
|
||||
'csrfToken' => $request->getSession()->getCsrfToken(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see GridFeature::fetchUIElements()
|
||||
*/
|
||||
public function fetchUIElements($request, $grid)
|
||||
{
|
||||
$templateMgr = TemplateManager::getManager($request);
|
||||
$UIElements = [];
|
||||
if ($this->isOrderActionNecessary()) {
|
||||
$templateMgr->assign('gridId', $grid->getId());
|
||||
$UIElements['orderFinishControls'] = $templateMgr->fetch('controllers/grid/feature/gridOrderFinishControls.tpl');
|
||||
}
|
||||
$nonOrderableItemMessage = $this->getNonOrderableItemMessage();
|
||||
if ($nonOrderableItemMessage) {
|
||||
$templateMgr->assign('orderMessage', $nonOrderableItemMessage);
|
||||
$UIElements['orderMessage'] = $templateMgr->fetch('controllers/grid/feature/gridOrderNonOrderableMessage.tpl');
|
||||
}
|
||||
|
||||
return $UIElements;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Hooks implementation.
|
||||
//
|
||||
/**
|
||||
* @see GridFeature::getInitializedRowInstance()
|
||||
*/
|
||||
public function getInitializedRowInstance($args)
|
||||
{
|
||||
$row = & $args['row'];
|
||||
if ($args['grid']->getDataElementSequence($row->getData()) !== false) {
|
||||
$this->addRowOrderAction($row);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see GridFeature::gridInitialize()
|
||||
*/
|
||||
public function gridInitialize($args)
|
||||
{
|
||||
$grid = & $args['grid'];
|
||||
|
||||
if ($this->isOrderActionNecessary()) {
|
||||
$grid->addAction(
|
||||
new LinkAction(
|
||||
'orderItems',
|
||||
new NullAction(),
|
||||
__('grid.action.order'),
|
||||
'order_items'
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Protected methods.
|
||||
//
|
||||
/**
|
||||
* Add grid row order action.
|
||||
*
|
||||
* @param GridRow $row
|
||||
*/
|
||||
public function addRowOrderAction($row)
|
||||
{
|
||||
if ($this->getOverrideRowTemplate($row)) {
|
||||
$row->setTemplate('controllers/grid/gridRow.tpl');
|
||||
}
|
||||
|
||||
$row->addAction(
|
||||
new LinkAction(
|
||||
'moveItem',
|
||||
new NullAction(),
|
||||
'',
|
||||
'order_items'
|
||||
),
|
||||
GridRow::GRID_ACTION_POSITION_ROW_LEFT
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// Protected template methods.
|
||||
//
|
||||
/**
|
||||
* Return if this feature will use
|
||||
* a grid level order action. Default is
|
||||
* true, override it if needed.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isOrderActionNecessary()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!PKP_STRICT_MODE) {
|
||||
class_alias('\PKP\controllers\grid\feature\OrderItemsFeature', '\OrderItemsFeature');
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file classes/controllers/grid/feature/OrderListbuilderItemsFeature.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 OrderListbuilderItemsFeature
|
||||
*
|
||||
* @ingroup controllers_grid_feature
|
||||
*
|
||||
* @brief Implements listbuilder ordering functionality.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\feature;
|
||||
|
||||
class OrderListbuilderItemsFeature extends OrderItemsFeature
|
||||
{
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(false);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Extended methods from GridFeature.
|
||||
//
|
||||
/**
|
||||
* @see GridFeature::getJSClass()
|
||||
*/
|
||||
public function getJSClass()
|
||||
{
|
||||
return '$.pkp.classes.features.OrderListbuilderItemsFeature';
|
||||
}
|
||||
}
|
||||
|
||||
if (!PKP_STRICT_MODE) {
|
||||
class_alias('\PKP\controllers\grid\feature\OrderListbuilderItemsFeature', '\OrderListbuilderItemsFeature');
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
<?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');
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
/**
|
||||
* @file classes/controllers/grid/feature/selectableItems/ItemSelectionGridColumn.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 ItemSelectionGridColumn
|
||||
*
|
||||
* @ingroup classes_controllers_grid_feature_selectableItems
|
||||
*
|
||||
* @brief Implements a column with checkboxes to select grid items.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\feature\selectableItems;
|
||||
|
||||
use PKP\controllers\grid\ColumnBasedGridCellProvider;
|
||||
use PKP\controllers\grid\GridColumn;
|
||||
|
||||
class ItemSelectionGridColumn extends GridColumn
|
||||
{
|
||||
/** @var string */
|
||||
public $_selectName;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $selectName The name of the form parameter
|
||||
* to which the selected files will be posted.
|
||||
*/
|
||||
public function __construct($selectName)
|
||||
{
|
||||
assert(is_string($selectName) && !empty($selectName));
|
||||
$this->_selectName = $selectName;
|
||||
|
||||
$cellProvider = new ColumnBasedGridCellProvider();
|
||||
parent::__construct(
|
||||
'select',
|
||||
'common.select',
|
||||
null,
|
||||
'controllers/grid/gridRowSelectInput.tpl',
|
||||
$cellProvider,
|
||||
['width' => 3]
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Getters and Setters
|
||||
//
|
||||
/**
|
||||
* Get the select name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSelectName()
|
||||
{
|
||||
return $this->_selectName;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Public methods
|
||||
//
|
||||
/**
|
||||
* Method expected by ColumnBasedGridCellProvider
|
||||
* to render a cell in this column.
|
||||
*
|
||||
* @see ColumnBasedGridCellProvider::getTemplateVarsFromRowColumn()
|
||||
*/
|
||||
public function getTemplateVarsFromRow($row)
|
||||
{
|
||||
// Return the data expected by the column's cell template.
|
||||
return [
|
||||
'elementId' => $row->getId(),
|
||||
'selectName' => $this->getSelectName(),
|
||||
'selected' => $row->getFlag('selected')];
|
||||
}
|
||||
}
|
||||
|
||||
if (!PKP_STRICT_MODE) {
|
||||
class_alias('\PKP\controllers\grid\feature\selectableItems\ItemSelectionGridColumn', '\ItemSelectionGridColumn');
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file classes/controllers/grid/feature/selectableItems/SelectableItemsFeature.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 SelectableItemsFeature
|
||||
*
|
||||
* @ingroup controllers_grid_feature_selectableItems
|
||||
*
|
||||
* @brief Implements grid widgets selectable items functionality.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\feature\selectableItems;
|
||||
|
||||
use PKP\controllers\grid\feature\GridFeature;
|
||||
|
||||
class SelectableItemsFeature extends GridFeature
|
||||
{
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct('selectableItems');
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Hooks implementation.
|
||||
//
|
||||
/**
|
||||
* @see GridFeature::gridInitialize()
|
||||
*/
|
||||
public function gridInitialize($args)
|
||||
{
|
||||
$grid = $args['grid'];
|
||||
|
||||
// Add checkbox column to the grid.
|
||||
$grid->addColumn(new ItemSelectionGridColumn($grid->getSelectName()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see GridFeature::getInitializedRowInstance()
|
||||
*/
|
||||
public function getInitializedRowInstance($args)
|
||||
{
|
||||
/** @var \PKP\controllers\grid\CategoryGridHandler|\PKP\controllers\grid\GridHandler */
|
||||
$grid = $args['grid'];
|
||||
/** @var \PKP\controllers\grid\GridRow */
|
||||
$row = $args['row'];
|
||||
|
||||
if ($grid instanceof \PKP\controllers\grid\CategoryGridHandler) {
|
||||
$categoryId = $grid->getCurrentCategoryId();
|
||||
$row->addFlag('selected', (bool) $grid->isDataElementInCategorySelected($categoryId, $row->getData()));
|
||||
} else {
|
||||
$row->addFlag('selected', (bool) $grid->isDataElementSelected($row->getData()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!PKP_STRICT_MODE) {
|
||||
class_alias('\PKP\controllers\grid\feature\selectableItems\SelectableItemsFeature', '\SelectableItemsFeature');
|
||||
}
|
||||
Reference in New Issue
Block a user