From 98e778335015dc822bdd8a053d1c45d9b8eb7b3f Mon Sep 17 00:00:00 2001 From: Nick Clemens Date: Mon, 7 Oct 2019 14:19:07 +0000 Subject: [PATCH] Bug 23763: Create a pagination_bar routine To test: prove -v t/Koha/SearchEngine/Search.t Signed-off-by: David Nind Signed-off-by: Katrin Fischer JD amended patch: perltidy Signed-off-by: Jonathan Druart --- Koha/SearchEngine/Search.pm | 103 +++++++++++++++++++++++++++++++++++ t/Koha/SearchEngine/Search.t | 87 +++++++++++++++++++++++++++++ 2 files changed, 190 insertions(+) create mode 100644 t/Koha/SearchEngine/Search.t diff --git a/Koha/SearchEngine/Search.pm b/Koha/SearchEngine/Search.pm index d65dd368d7..0b7222741a 100644 --- a/Koha/SearchEngine/Search.pm +++ b/Koha/SearchEngine/Search.pm @@ -46,6 +46,7 @@ Creates a new C of whatever the relevant type is. use Modern::Perl; use C4::Context; use C4::Biblio qw//; +use POSIX qw(ceil floor); sub new { my $engine = C4::Context->preference("SearchEngine") // 'Zebra'; @@ -76,4 +77,106 @@ sub extract_biblionumber { return $record->subfield( $biblionumbertagfield, $biblionumbertagsubfield ); } +=head2 pagination_bar + +my ( $PAGE_NUMBERS, $hits_to_paginate, $pages, $current_page_number, + $previous_page_offset, $next_page_offset, $last_page_offset ) = Koha::SearchEngine::Search->pagination_bar( + { + hits => $hits, + max_result_window => $max_result_window, + results_per_page => $results_per_page, + offset => $offset, + sort_by => \@sort_by + } + ); + +Returns the variables needed for the page-nubers.inc to build search results + +=cut + +sub pagination_bar { + my ( $self, $params ) = @_; + my $hits = $params->{hits}; + my $results_per_page = $params->{results_per_page}; + my $offset = $params->{offset}; + my $sort_by = $params->{sort_by}; + my @page_numbers; + my $max_result_window = $params->{max_result_window}; + my $hits_to_paginate = + ( $max_result_window && $max_result_window < $hits ) + ? $max_result_window + : $hits; + + # total number of pages there will be + my $pages = ceil( $hits_to_paginate / $results_per_page ); + my $last_page_offset = ( $pages - 1 ) * $results_per_page; + + # default page number + my $current_page_number = 1; + $current_page_number = ( $offset / $results_per_page + 1 ) if $offset; + my $previous_page_offset; + if ( $offset >= $results_per_page ) { + $previous_page_offset = $offset - $results_per_page; + } + my $next_page_offset = $offset + $results_per_page; + + # If we're within the first 10 pages, keep it simple + if ( $current_page_number < 10 ) { + + # just show the first 10 pages + # Loop through the pages + my $pages_to_show = 10; + $pages_to_show = $pages if $pages < 10; + for ( my $i = 1 ; $i <= $pages_to_show ; $i++ ) { + + # the offset for this page + my $this_offset = + ( ( $i * $results_per_page ) - $results_per_page ); + + # the page number for this page + my $this_page_number = $i; + + # put it in the array + push @page_numbers, { + offset => $this_offset, + pg => $this_page_number, + + # it should only be highlighted if it's the current page + highlight => $this_page_number == $current_page_number, + sort_by => join ' ', + @$sort_by + }; + } + } + + # now, show up to twenty pages, with the current one smack in the middle + # near the end of search results we will show 10 below and as many remaining above + else { + for ( + my $i = $current_page_number ; + $i <= ( $current_page_number + 19 ) ; + $i++ + ) + { + my $this_offset = + ( ( ( $i - 9 ) * $results_per_page ) - $results_per_page ); + my $this_page_number = $i - 9; + if ( $this_page_number <= $pages ) { + push @page_numbers, + { + offset => $this_offset, + pg => $this_page_number, + highlight => $this_page_number == $current_page_number, + sort_by => join ' ', + @$sort_by + }; + } + } + } + + return ( \@page_numbers, $hits_to_paginate, $pages, $current_page_number, + $previous_page_offset, $next_page_offset, $last_page_offset ); + +} + 1; diff --git a/t/Koha/SearchEngine/Search.t b/t/Koha/SearchEngine/Search.t new file mode 100644 index 0000000000..c7b779a3f5 --- /dev/null +++ b/t/Koha/SearchEngine/Search.t @@ -0,0 +1,87 @@ +#!/usr/bin/perl +# +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# Koha 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 Koha; if not, see . + +use Modern::Perl; + +use Test::More tests => 5; +use Test::Exception; + +use t::lib::Mocks; + +use Test::MockModule; + +use MARC::Record; +use Try::Tiny; + +use Koha::SearchEngine::Search; + +subtest "pagination_bar tests" => sub { + plan tests => 14; + + my @sort_by = ('relevance_dsc'); + + my ( $PAGE_NUMBERS, $hits_to_paginate, $pages, $current_page_number, + $previous_page_offset, $next_page_offset, $last_page_offset ) + = Koha::SearchEngine::Search->pagination_bar( + { + hits => 500, + max_result_window => 1000, + results_per_page => 20, + offset => 160, + sort_by => \@sort_by + } + ); + is( $hits_to_paginate, 500, + "We paginate all hits if less than max_result_window" ); + is( $pages, 25, "We have hits/hits_to_paginate pages" ); + is( $current_page_number, 9, + "We calculate current page by offset/results_per_page plus 1" ); + is( $previous_page_offset, 140, + "Previous page is current offset minus reults per page" ); + is( $next_page_offset, 180, + "Next page is current offset plus reults per page" ); + is( $last_page_offset, 480, + "Last page is pages minus 1 times reults per page" ); + is( @$PAGE_NUMBERS, 10, "If on first ten pages we only show 10 pages" ); + + ( + $PAGE_NUMBERS, $hits_to_paginate, $pages, $current_page_number, + $previous_page_offset, $next_page_offset, $last_page_offset + ) + = Koha::SearchEngine::Search->pagination_bar( + { + hits => 500, + max_result_window => 480, + results_per_page => 20, + offset => 240, + sort_by => \@sort_by + } + ); + is( $hits_to_paginate, 480, + "We paginate all hits if less than max_result_window" ); + is( $pages, 24, "We have hits/hits_to_paginate pages" ); + is( $current_page_number, 13, + "We calculate current page by offset/results_per_page plus 1" ); + is( $previous_page_offset, 220, + "Previous page is current offset minus reults per page" ); + is( $next_page_offset, 260, + "Next page is current offset plus reults per page" ); + is( $last_page_offset, 460, + "Last page is pages minus 1 times reults per page" ); + is( @$PAGE_NUMBERS, 20, "If past first ten pages we show 20 pages" ); + +}; -- 2.39.5