diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-results.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-results.tt
index 7eed38bb72..e60f65d100 100644
--- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-results.tt
+++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-results.tt
@@ -159,6 +159,10 @@
[% END # / IF total %]
[% END # / IF searchdesc %]
+ [% IF ( total && some_results_hidden ) %]
+
Some results are hidden due to library policy.
+ [% END %]
+
[% IF ( DidYouMean ) %]
diff --git a/opac/opac-search.pl b/opac/opac-search.pl
index 8bba940881..41a7ef589a 100755
--- a/opac/opac-search.pl
+++ b/opac/opac-search.pl
@@ -664,7 +664,59 @@ for ( my $i = 0 ; $i < @servers ; $i++ ) {
$results_hashref->{$server}->{"RECORDS"}, $variables
);
unless (@newresults) {
- $template->param( no_page_results => 1 );
+
+ # This page has hits, but every one of them is hidden from the OPAC
+ # (OpacHiddenItemsHidesRecord). Rather than showing a dead end, look
+ # a few pages ahead for one with something to show and jump straight
+ # there. The lookahead is capped so a library with many consecutive
+ # hidden pages doesn't turn this search into a long chain of extra
+ # search-engine queries.
+ my $found_offset;
+ my $skipped_hidden_page = 0;
+ my $lookahead_offset = $offset;
+ for ( 1 .. 3 ) {
+ $lookahead_offset += $results_per_page;
+ last if $lookahead_offset >= $hits;
+
+ my $lookahead_results_hashref;
+ my $itemtypes_nocategory =
+ { map { $_->{itemtype} => $_ } @{ Koha::ItemTypes->search_with_localization->unblessed } };
+ eval {
+ ( $error, $lookahead_results_hashref, undef ) = $searcher->search_compat(
+ $query, $simple_query, \@sort_by, \@servers, $results_per_page, $lookahead_offset,
+ undef, $itemtypes_nocategory, $query_type, $scan, 1
+ );
+ };
+ my @lookahead_results = searchResults(
+ $search_context, $query_desc, $hits, $results_per_page, $lookahead_offset, $scan,
+ $lookahead_results_hashref->{$server}->{"RECORDS"}, $variables
+ );
+ if (@lookahead_results) {
+ $found_offset = $lookahead_offset;
+ last;
+ }
+ $skipped_hidden_page = 1;
+ }
+
+ if ( defined $found_offset
+ && $format ne 'rss'
+ && $format ne 'opensearchdescription'
+ && $format ne 'atom' )
+ {
+ $cgi->param( offset => $found_offset );
+ $cgi->param( hidden_notice => 1 );
+ print $cgi->redirect( '/cgi-bin/koha/opac-search.pl?' . $cgi->query_string() );
+ exit;
+ }
+
+ $template->param(
+ no_page_results => 1,
+ some_results_hidden => $skipped_hidden_page,
+ );
+ }
+
+ if ( $cgi->param('hidden_notice') ) {
+ $template->param( some_results_hidden => 1 );
}
my $art_req_itypes;