From 4bf2af8f8b7f18415417d0872039b7e7f01cd873 Mon Sep 17 00:00:00 2001
From: David Gustafsson <david.gustafsson@ub.gu.se>
Date: Wed, 31 Jan 2018 16:00:26 +0100
Subject: [PATCH] Bug 20114: Build better $query_cgi

Build a more complete $query_cgi fixing issues with pagination after
performing either an advanced search or visiting a search link from
biblio details.

To test:
1) Go to the details page for a biblio.
2) Click a link that will produce enough hits to trigger pagination.
3) Try going to next page.
4) This will produce a search error.
5) Apply patch.
6) Repeat steps 1 to 3.
7) Pagination should now work as expected.

Sponsored-by: Gothenburg University Library
---
 Koha/SearchEngine/Elasticsearch/QueryBuilder.pm | 62 +++++++++++++++++++++----
 1 file changed, 52 insertions(+), 10 deletions(-)

diff --git a/Koha/SearchEngine/Elasticsearch/QueryBuilder.pm b/Koha/SearchEngine/Elasticsearch/QueryBuilder.pm
index 95cc86ab78..55b8d259b2 100644
--- a/Koha/SearchEngine/Elasticsearch/QueryBuilder.pm
+++ b/Koha/SearchEngine/Elasticsearch/QueryBuilder.pm
@@ -45,6 +45,7 @@ use JSON;
 use List::MoreUtils qw/ each_array /;
 use Modern::Perl;
 use URI::Escape;
+use URI::QueryParam;
 
 use C4::Context;
 use Koha::Exceptions;
@@ -196,9 +197,29 @@ reproduce this search, and C<$query_desc> set to something else.
 =cut
 
 sub build_query_compat {
-    my ( $self, $operators, $operands, $indexes, $orig_limits, $sort_by, $scan,
-        $lang, $params )
-      = @_;
+    my (
+        $self,
+        $operators,
+        $operands,
+        $indexes,
+        $orig_limits,
+        $sort_by,
+        $scan,
+        $lang,
+        $params
+    ) = @_;
+
+    # TODO: $params?
+    my $query_cgi = $self->_build_query_query_string(
+        {
+            'operators' => $operators,
+            'operands' => $operands,
+            'indexes' => $indexes,
+            'sort_by' => $sort_by
+        }
+    );
+    my $limit_cgi = $orig_limits && @{$orig_limits} ?
+        "&" . $self->_build_limit_query_string({ 'limits' => $orig_limits }) : '';
 
 #die Dumper ( $self, $operators, $operands, $indexes, $orig_limits, $sort_by, $scan, $lang );
     my @sort_params  = $self->_convert_sort_fields(@$sort_by);
@@ -235,17 +256,11 @@ sub build_query_compat {
     $options{expanded_facet} = $params->{expanded_facet};
     my $query = $self->build_query( $query_str, %options );
 
-    #die Dumper($query);
-    # We roughly emulate the CGI parameters of the zebra query builder
-    my $query_cgi;
-    $query_cgi = 'idx=kw&q=' . uri_escape_utf8( $operands->[0] ) if @$operands;
     my $simple_query;
     $simple_query = $operands->[0] if @$operands == 1;
     my $query_desc   = $simple_query;
     my $limit        = $self->_join_queries( $self->_convert_index_strings(@$limits));
-    my $limit_cgi = ( $orig_limits and @$orig_limits )
-      ? '&limit=' . join( '&limit=', map { uri_escape_utf8($_) } @$orig_limits )
-      : '';
+
     my $limit_desc;
     $limit_desc = "$limit" if $limit;
     return (
@@ -254,6 +269,33 @@ sub build_query_compat {
     );
 }
 
+sub _build_query_query_string {
+    my ( $self, $query_parts ) = @_;
+    my $uri = URI->new("", "http");
+    my $next = each_array(
+        @{$query_parts->{operands}},
+        @{$query_parts->{operators}},
+        @{$query_parts->{indexes}}
+    );
+    while (my ($operand, $operator, $index) = $next->()) {
+        last if !$operand; # TODO: Is this sane???
+        $uri->query_param_append('idx' => $index) if $index;
+        $uri->query_param_append('q' => $operand) if $operand;
+        $uri->query_param_append('op' => $operator) if $operator;
+    }
+    if ($query_parts->{sort_by}) {
+        $uri->query_param('sort_by' => $query_parts->{sort_by});
+    }
+    return $uri->query;
+}
+
+sub _build_limit_query_string {
+    my ($self, $query_parts) = @_;
+    my $uri = URI->new("", "http");
+    $uri->query_param('limit' => $query_parts->{limits});
+    return $uri->query;
+}
+
 =head2 build_authorities_query
 
     my $query = $builder->build_authorities_query(\%search);
-- 
2.11.0