From 0ad732f46d91d6b73b28b3ba5009165293ff738c Mon Sep 17 00:00:00 2001 From: Demian Katz <demian.katz@villanova.edu> Date: Mon, 17 Dec 2018 15:25:32 -0500 Subject: [PATCH] Refactored historicloansAction pagination logic to helper class. - Inspired by Ere Maijala's work on #1268. --- .../Controller/MyResearchController.php | 107 +++++------- .../src/VuFind/ILS/PaginationHelper.php | 153 ++++++++++++++++++ 2 files changed, 191 insertions(+), 69 deletions(-) create mode 100644 module/VuFind/src/VuFind/ILS/PaginationHelper.php diff --git a/module/VuFind/src/VuFind/Controller/MyResearchController.php b/module/VuFind/src/VuFind/Controller/MyResearchController.php index 244b17acbc6..8adfeee7a11 100644 --- a/module/VuFind/src/VuFind/Controller/MyResearchController.php +++ b/module/VuFind/src/VuFind/Controller/MyResearchController.php @@ -32,6 +32,7 @@ use VuFind\Exception\Forbidden as ForbiddenException; use VuFind\Exception\ILS as ILSException; use VuFind\Exception\ListPermission as ListPermissionException; use VuFind\Exception\Mail as MailException; +use VuFind\ILS\PaginationHelper; use VuFind\Search\RecommendListener; use Zend\Stdlib\Parameters; use Zend\View\Model\ViewModel; @@ -47,6 +48,13 @@ use Zend\View\Model\ViewModel; */ class MyResearchController extends AbstractBase { + /** + * ILS Pagination Helper + * + * @var PaginationHelper + */ + protected $paginationHelper = null; + /** * Are we currently in a lightbox context? * @@ -1273,73 +1281,31 @@ class MyResearchController extends AbstractBase return $this->createViewModel(); } - // Get page and page size: - $page = (int)$this->params()->fromQuery('page', 1); + // Get paging setup: $config = $this->getConfig(); - $limit = isset($config->Catalog->historic_loan_page_size) - ? $config->Catalog->historic_loan_page_size : 50; - $ilsPaging = true; - if (isset($functionConfig['max_results'])) { - $limit = min([$functionConfig['max_results'], $limit]); - } elseif (isset($functionConfig['page_size'])) { - if (!in_array($limit, $functionConfig['page_size'])) { - $limit = $functionConfig['default_page_size'] - ?? $functionConfig['page_size'][0]; - } - } else { - $ilsPaging = false; - } - - // Get sort settings - $sort = false; - if (!empty($functionConfig['sort'])) { - $sort = $this->params()->fromQuery('sort'); - if (!isset($functionConfig['sort'][$sort])) { - if (isset($functionConfig['default_sort'])) { - $sort = $functionConfig['default_sort']; - } else { - reset($functionConfig['sort']); - $sort = key($functionConfig['sort']); - } - } - } - - // Configure call params - $params = [ - 'sort' => $sort - ]; - if ($ilsPaging) { - $params['page'] = $page; - $params['limit'] = $limit; - } + $pageOptions = $this->getPaginationHelper()->getOptions( + (int)$this->params()->fromQuery('page', 1), + $this->params()->fromQuery('sort'), + $config->Catalog->historic_loan_page_size ?? 50, + $functionConfig + ); // Get checked out item details: - $result = $catalog->getMyTransactionHistory($patron, $params); + $result + = $catalog->getMyTransactionHistory($patron, $pageOptions['ilsParams']); if (isset($result['success']) && !$result['success']) { $this->flashMessenger()->addErrorMessage($result['status']); return $this->createViewModel(); } - // Build paginator if needed: - if ($ilsPaging && $limit < $result['count']) { - $adapter = new \Zend\Paginator\Adapter\NullFill($result['count']); - $paginator = new \Zend\Paginator\Paginator($adapter); - $paginator->setItemCountPerPage($limit); - $paginator->setCurrentPageNumber($page); - $pageStart = $paginator->getAbsoluteItemNumber(1) - 1; - $pageEnd = $paginator->getAbsoluteItemNumber($limit) - 1; - } elseif ($limit > 0 && $limit < $result['count']) { - $adapter = new \Zend\Paginator\Adapter\ArrayAdapter( - $result['transactions'] - ); - $paginator = new \Zend\Paginator\Paginator($adapter); - $paginator->setItemCountPerPage($limit); - $paginator->setCurrentPageNumber($page); + $paginator = $this->getPaginationHelper()->getPaginator( + $pageOptions, $result['count'], $result['transactions'] + ); + if ($paginator) { $pageStart = $paginator->getAbsoluteItemNumber(1) - 1; - $pageEnd = $paginator->getAbsoluteItemNumber($limit) - 1; + $pageEnd = $paginator->getAbsoluteItemNumber($pageOptions['limit']) - 1; } else { - $paginator = false; $pageStart = 0; $pageEnd = $result['count']; } @@ -1347,25 +1313,15 @@ class MyResearchController extends AbstractBase $transactions = $hiddenTransactions = []; foreach ($result['transactions'] as $i => $current) { // Build record driver (only for the current visible page): - if ($ilsPaging || ($i >= $pageStart && $i <= $pageEnd)) { + if ($pageOptions['ilsPaging'] || ($i >= $pageStart && $i <= $pageEnd)) { $transactions[] = $this->getDriverForILSRecord($current); } else { $hiddenTransactions[] = $current; } } - // Handle view params for sorting - $sortList = []; - if (!empty($functionConfig['sort'])) { - foreach ($functionConfig['sort'] as $key => $value) { - $sortList[$key] = [ - 'desc' => $value, - 'url' => '?sort=' . urlencode($key), - 'selected' => $sort == $key - ]; - } - } - + $sortList = $pageOptions['sortList']; + $params = $pageOptions['ilsParams']; return $this->createViewModel( compact( 'transactions', 'paginator', 'params', @@ -1757,4 +1713,17 @@ class MyResearchController extends AbstractBase } return $view; } + + /** + * Get the ILS pagination helper + * + * @return PaginationHelper + */ + protected function getPaginationHelper() + { + if (null === $this->paginationHelper) { + $this->paginationHelper = new PaginationHelper(); + } + return $this->paginationHelper; + } } diff --git a/module/VuFind/src/VuFind/ILS/PaginationHelper.php b/module/VuFind/src/VuFind/ILS/PaginationHelper.php new file mode 100644 index 00000000000..30db96d6e36 --- /dev/null +++ b/module/VuFind/src/VuFind/ILS/PaginationHelper.php @@ -0,0 +1,153 @@ +<?php +/** + * ILS Pagination Helper + * + * This class helps build paginators for ILS-provided data. + * + * PHP version 7 + * + * Copyright (C) Villanova University 2018. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * 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 + * + * @category VuFind + * @package ILS_Drivers + * @author Andrew S. Nagy <vufind-tech@lists.sourceforge.net> + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development:plugins:ils_drivers Wiki + */ +namespace VuFind\ILS; + +/** + * ILS Pagination Helper + * + * This class helps build paginators for ILS-provided data. + * + * @category VuFind + * @package ILS_Drivers + * @author Ere Maijala <ere.maijala@helsinki.fi> + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development:plugins:ils_drivers Wiki + */ +class PaginationHelper +{ + /** + * Support method for getPagingSetup() -- validate the active sort option. + * + * @param array $functionConfig Function config returned from the ILS + */ + protected function validateSort($functionConfig, $sort) + { + // If sort is disabled, all settings are invalid... + if (empty($functionConfig['sort'])) { + return false; + } + // If provided setting is valid, use it... + if (isset($functionConfig['sort'][$sort])) { + return $sort; + } + // At this point, we need to find a reasonable value, either the configured + // default or the first valid sort value... + if (isset($functionConfig['default_sort'])) { + return $functionConfig['default_sort']; + } + reset($functionConfig['sort']); + return key($functionConfig['sort']); + } + + /** + * Support method for getPagingSetup() -- determine the list of sort options. + * + * @param array $functionConfig Function config returned from the ILS + * @param string $sort Currently active sort option + */ + protected function getSortList($functionConfig, $sort) + { + $sortList = []; + if (!empty($functionConfig['sort'])) { + foreach ($functionConfig['sort'] as $key => $value) { + $sortList[$key] = [ + 'desc' => $value, + 'url' => '?sort=' . urlencode($key), + 'selected' => $sort == $key + ]; + } + } + return $sortList; + } + + /** + * Get paging settings and request data for paged ILS requests. + * + * @param int $page Current page (1-based) + * @param string $sort Current sort setting (null for none) + * @param int $defaultPageSize Default page size + * @param array $functionConfig Function config returned from the ILS + * + * @return array + */ + public function getOptions($page, $sort, $defaultPageSize, + $functionConfig + ) { + // Get page and page size: + $limit = $defaultPageSize; + $ilsPaging = true; + if (isset($functionConfig['max_results'])) { + $limit = min([$functionConfig['max_results'], $limit]); + } elseif (isset($functionConfig['page_size'])) { + if (!in_array($limit, $functionConfig['page_size'])) { + $limit = $functionConfig['default_page_size'] + ?? $functionConfig['page_size'][0]; + } + } else { + $ilsPaging = false; + } + // Collect ILS call params + $ilsParams = ['sort' => $this->validateSort($functionConfig, $sort)]; + if ($ilsPaging) { + $ilsParams['page'] = $page; + $ilsParams['limit'] = $limit; + } + $sortList = $this->getSortList($functionConfig, $ilsParams['sort']); + return compact('page', 'limit', 'ilsPaging', 'ilsParams', 'sortList'); + } + + /** + * Build a paginator with the paging options and ILS results if necessary + * + * @param array $pageOptions Paging options and parameters (returned by the + * getOptions method) + * @param int $count Result count + * @param array $records Result records + * + * @return false|\Zend\Paginator\Paginator + */ + public function getPaginator($pageOptions, $count, $records) + { + $limit = $pageOptions['limit']; + if ($pageOptions['ilsPaging'] && $limit < $count) { + $adapter = new \Zend\Paginator\Adapter\NullFill($count); + } elseif ($limit > 0 && $limit < $count) { + $adapter = new \Zend\Paginator\Adapter\ArrayAdapter($records); + } else { + return false; + } + $paginator = new \Zend\Paginator\Paginator($adapter); + $paginator->setItemCountPerPage($limit); + $paginator->setCurrentPageNumber($pageOptions['page']); + return $paginator; + } +} \ No newline at end of file -- GitLab