diff --git a/config/vufind/searches.ini b/config/vufind/searches.ini index 274c11cda28e5c3a2a0e2d0804e6127614705bab..edd90ee5f4c6b1d2fda821f11764014db146f8d5 100644 --- a/config/vufind/searches.ini +++ b/config/vufind/searches.ini @@ -26,6 +26,13 @@ default_view = list default_limit = 20 ;limit_options = 10,20,40,60,80,100 +; This setting allows to limit pagination of a search result as deep pagination +; costs a lot of performance and most users are not very likely to navigate +; further down than 20 pages of a search result. +; This is especially useful to prevent webcrawlers from descending too deep and +; eating up search backend performance. Default is set to unlimited. +;result_limit = 400 + ; If this setting is true, boolean operators in searches (AND/OR/NOT) will only ; be recognized if they are ALL UPPERCASE. If set to false, they will be ; recognized regardless of case. If set to a comma-separated list of operators diff --git a/module/VuFind/src/VuFind/Search/Base/Options.php b/module/VuFind/src/VuFind/Search/Base/Options.php index 102d11380db23f0483a51996a995faee4a77d7ab..baf551397d1a495b057647b864a2ce80732bab49 100644 --- a/module/VuFind/src/VuFind/Search/Base/Options.php +++ b/module/VuFind/src/VuFind/Search/Base/Options.php @@ -212,6 +212,13 @@ abstract class Options implements TranslatorAwareInterface */ protected $configLoader; + /** + * Maximum number of results (no limit by default) + * + * @var int + */ + protected $resultLimit = -1; + /** * Constructor * @@ -724,8 +731,7 @@ abstract class Options implements TranslatorAwareInterface */ public function getVisibleSearchResultLimit() { - // No limit by default: - return -1; + return intval($this->resultLimit); } /** diff --git a/module/VuFind/src/VuFind/Search/Base/Results.php b/module/VuFind/src/VuFind/Search/Base/Results.php index 80bed2d0ea6cfd4a7da09eb535255a6945a132dd..7ada0ce8b4c575bf2f16dc33d35d9fdb312b9a1f 100644 --- a/module/VuFind/src/VuFind/Search/Base/Results.php +++ b/module/VuFind/src/VuFind/Search/Base/Results.php @@ -304,11 +304,17 @@ abstract class Results implements ServiceLocatorAwareInterface */ public function getStartRecord() { - if (!is_null($this->startRecordOverride)) { + if (null !== $this->startRecordOverride) { return $this->startRecordOverride; } $params = $this->getParams(); - return (($params->getPage() - 1) * $params->getLimit()) + 1; + $page = $params->getPage(); + $pageLimit = $params->getLimit(); + $resultLimit = $this->getOptions()->getVisibleSearchResultLimit(); + if ($resultLimit > -1 && $resultLimit < $page * $pageLimit) { + $page = ceil($resultLimit / $pageLimit); + } + return (($page - 1) * $pageLimit) + 1; } /** @@ -319,16 +325,19 @@ abstract class Results implements ServiceLocatorAwareInterface public function getEndRecord() { $total = $this->getResultTotal(); - $limit = $this->getParams()->getLimit(); - $page = $this->getParams()->getPage(); - if ($page * $limit > $total) { - // The end of the current page runs past the last record, use total - // results - return $total; + $params = $this->getParams(); + $page = $params->getPage(); + $pageLimit = $params->getLimit(); + $resultLimit = $this->getOptions()->getVisibleSearchResultLimit(); + + if ($resultLimit > -1 && $resultLimit < ($page * $pageLimit)) { + $record = $resultLimit; } else { - // Otherwise use the last record on this page - return $page * $limit; + $record = $page * $pageLimit; } + // If the end of the current page runs past the last record, use total + // results; otherwise use the last record on this page: + return ($record > $total) ? $total : $record; } /** diff --git a/module/VuFind/src/VuFind/Search/EDS/Options.php b/module/VuFind/src/VuFind/Search/EDS/Options.php index d3cd5e05a0fb7a557faa9fba3636d78252963b09..41327ea4fdc4eb328a223032a24600d0139dad5a 100644 --- a/module/VuFind/src/VuFind/Search/EDS/Options.php +++ b/module/VuFind/src/VuFind/Search/EDS/Options.php @@ -38,13 +38,6 @@ namespace VuFind\Search\EDS; */ class Options extends \VuFind\Search\Base\Options { - /** - * Maximum number of results - * - * @var int - */ - protected $resultLimit = 100; - /** * Available search mode options * @@ -127,6 +120,7 @@ class Options extends \VuFind\Search\Base\Options $this->searchIni = $this->facetsIni = 'EDS'; $searchSettings = $configLoader->get($this->searchIni); parent::__construct($configLoader); + $this->resultLimit = 100; $this->viewOptions = [ 'list|title' => 'Title View', 'list|brief' => 'Brief View', 'list|detailed' => 'Detailed View' @@ -237,18 +231,6 @@ class Options extends \VuFind\Search\Base\Options return 'eds-advanced'; } - /** - * If there is a limit to how many search results a user can access, this - * method will return that limit. If there is no limit, this will return - * -1. - * - * @return int - */ - public function getVisibleSearchResultLimit() - { - return $this->resultLimit; - } - /** * Set the search options from the Eds API Info methods results * diff --git a/module/VuFind/src/VuFind/Search/Primo/Options.php b/module/VuFind/src/VuFind/Search/Primo/Options.php index af7f763f49dc2e86133fd1626f36f5e0f311d54e..7236deb59cb0ee6eb5ec3f0a02ef4b99b0f25d31 100644 --- a/module/VuFind/src/VuFind/Search/Primo/Options.php +++ b/module/VuFind/src/VuFind/Search/Primo/Options.php @@ -38,13 +38,6 @@ namespace VuFind\Search\Primo; */ class Options extends \VuFind\Search\Base\Options { - /** - * Maximum number of results - * - * @var int - */ - protected $resultLimit = 3980; - /** * Advanced search operators * @@ -101,6 +94,8 @@ class Options extends \VuFind\Search\Base\Options // Result limit: if (isset($searchSettings->General->result_limit)) { $this->resultLimit = $searchSettings->General->result_limit; + } else { + $this->resultLimit = 3980; // default } // Search handler setup: @@ -140,18 +135,6 @@ class Options extends \VuFind\Search\Base\Options } } - /** - * If there is a limit to how many search results a user can access, this - * method will return that limit. If there is no limit, this will return - * -1. - * - * @return int - */ - public function getVisibleSearchResultLimit() - { - return intval($this->resultLimit); - } - /** * Return the route name for the search results action. * diff --git a/module/VuFind/src/VuFind/Search/Solr/Options.php b/module/VuFind/src/VuFind/Search/Solr/Options.php index efb5cbc75f62e6f234118a3350bc54e9745281ca..fde902c08f43ae092544e19320a5116253ce4be7 100644 --- a/module/VuFind/src/VuFind/Search/Solr/Options.php +++ b/module/VuFind/src/VuFind/Search/Solr/Options.php @@ -113,6 +113,10 @@ class Options extends \VuFind\Search\Base\Options $this->defaultFilters = $searchSettings->General->default_filters ->toArray(); } + // Result limit: + if (isset($searchSettings->General->result_limit)) { + $this->resultLimit = $searchSettings->General->result_limit; + } if (isset($searchSettings->Basic_Searches)) { foreach ($searchSettings->Basic_Searches as $key => $value) { $this->basicHandlers[$key] = $value; diff --git a/module/VuFind/src/VuFind/Search/Summon/Options.php b/module/VuFind/src/VuFind/Search/Summon/Options.php index 2d567d96b09e089e250eae440729bbbd5b76ea67..ee938d1227c4639a373e171de5971da61839b49b 100644 --- a/module/VuFind/src/VuFind/Search/Summon/Options.php +++ b/module/VuFind/src/VuFind/Search/Summon/Options.php @@ -38,13 +38,6 @@ namespace VuFind\Search\Summon; */ class Options extends \VuFind\Search\Base\Options { - /** - * Maximum number of results - * - * @var int - */ - protected $resultLimit = 400; - /** * Maximum number of topic recommendations to show (false for none) * @@ -119,6 +112,8 @@ class Options extends \VuFind\Search\Base\Options } if (isset($searchSettings->General->result_limit)) { $this->resultLimit = $searchSettings->General->result_limit; + } else { + $this->resultLimit = 400; // default } // Search handler setup: @@ -197,18 +192,6 @@ class Options extends \VuFind\Search\Base\Options return $this->emptySearchRelevanceOverride; } - /** - * If there is a limit to how many search results a user can access, this - * method will return that limit. If there is no limit, this will return - * -1. - * - * @return int - */ - public function getVisibleSearchResultLimit() - { - return intval($this->resultLimit); - } - /** * Get the maximum number of topic recommendations (false for none) *