From 2bb9f7d3fcdf1454420f1147a8f9a4284754d2d5 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 --- Koha/SearchEngine/Search.pm | 79 ++++++++++++++++++++++++++++++++++++++++++++ t/Koha/SearchEngine/Search.t | 70 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 149 insertions(+) create mode 100644 t/Koha/SearchEngine/Search.t diff --git a/Koha/SearchEngine/Search.pm b/Koha/SearchEngine/Search.pm index d65dd368d7..67eb126234 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,82 @@ 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..e01ddaff0e --- /dev/null +++ b/t/Koha/SearchEngine/Search.t @@ -0,0 +1,70 @@ +#!/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.11.0