From 7a9e149eb8fb2195a004044929af9665cb091f1d Mon Sep 17 00:00:00 2001
From: Nick Clemens <nick@bywatersolutions.com>
Date: Thu, 21 Jul 2022 18:16:22 +0000
Subject: [PATCH] Bug 31213: Auto search simple term quoted

This patch does a second search if the first had no results and was a simple single term search

We simply quote the term, rebuild the query, and rerun the search

This targets both Zebra and ES, but is more relevant for ES

To test:
0 - Have Koha running using ES
1 - Add titles your system "Ivy + Bean" "The 6:20 Man"
2 - Search for these titles without quotes - NO results under ES
3 - Search with quotes - you find them
4 - Apply patch, restart all
5 - Search again without quotes
6 - Success!
7 - Confirm search still works under Zebra

Signed-off-by: Sally <sally.healey@cheshiresharedservices.gov.uk>
Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com>
---
 catalogue/search.pl | 27 +++++++++++++++++++++++++++
 opac/opac-search.pl | 31 +++++++++++++++++++++++++++++++
 2 files changed, 58 insertions(+)

diff --git a/catalogue/search.pl b/catalogue/search.pl
index a7eac00b8b..be33c35e63 100755
--- a/catalogue/search.pl
+++ b/catalogue/search.pl
@@ -373,10 +373,12 @@ if ($indexes[0] && (!$indexes[1] || $params->{'scan'})) {
 my @operands = map uri_unescape($_), $cgi->multi_param('q');
 
 # if a simple search, display the value in the search box
+my $basic_search = 0;
 if ($operands[0] && !$operands[1]) {
     my $ms_query = $operands[0];
     $ms_query =~ s/ #\S+//;
     $template->param(ms_value => $ms_query);
+    $basic_search=1;
 }
 
 my $available;
@@ -523,6 +525,31 @@ for (my $i=0;$i<@servers;$i++) {
     my $server = $servers[$i];
     if ($server =~/biblioserver/) { # this is the local bibliographic server
         my $hits = $results_hashref->{$server}->{"hits"} // 0;
+        if ( $hits == 0 && $basic_search ){
+            $operands[0] = '"'.$operands[0].'"'; #quote it
+            ## I. BUILD THE QUERY
+            (
+                $error,             $query, $simple_query, $query_cgi,
+                $query_desc,        $limit, $limit_cgi,    $limit_desc,
+                $query_type
+              )
+              = $builder->build_query_compat( \@operators, \@operands, \@indexes, \@limits,
+                \@sort_by, $scan, $lang, { weighted_fields => $weight_search, whole_record => $whole_record });
+            my $quoted_results_hashref;
+            eval {
+                my $itemtypes = { map { $_->{itemtype} => $_ } @{ Koha::ItemTypes->search_with_localization->unblessed } };
+                ( $error, $quoted_results_hashref, $facets ) = $searcher->search_compat(
+                    $query,            $simple_query, \@sort_by,       ['biblioserver'],
+                    $results_per_page, $offset,       undef,           $itemtypes,
+                    $query_type,       $scan
+                );
+            };
+            my $quoted_hits = $quoted_results_hashref->{$server}->{"hits"} // 0;
+            if ( $quoted_hits ){
+                $results_hashref->{'biblioserver'} = $quoted_results_hashref->{'biblioserver'};
+                $hits = $quoted_hits;
+            }
+        }
         my $page = $cgi->param('page') || 0;
         my @newresults = searchResults({ 'interface' => 'intranet' }, $query_desc, $hits, $results_per_page, $offset, $scan,
                                        $results_hashref->{$server}->{"RECORDS"});
diff --git a/opac/opac-search.pl b/opac/opac-search.pl
index e3b8ea0a2c..d742800896 100755
--- a/opac/opac-search.pl
+++ b/opac/opac-search.pl
@@ -419,10 +419,12 @@ my @operands = $cgi->multi_param('q');
 $template->{VARS}->{querystring} = join(' ', @operands);
 
 # if a simple search, display the value in the search box
+my $basic_search = 0;
 if ($operands[0] && !$operands[1]) {
     my $ms_query = $operands[0];
     $ms_query =~ s/ #\S+//;
     $template->param(ms_value => $ms_query);
+    $basic_search=1;
 }
 
 # limits are use to limit to results to a pre-defined category such as branch or language
@@ -608,6 +610,35 @@ for (my $i=0;$i<@servers;$i++) {
     my $server = $servers[$i];
     if ($server && $server =~/biblioserver/) { # this is the local bibliographic server
         $hits = $results_hashref->{$server}->{"hits"};
+        if ( $hits == 0 && $basic_search ){
+            $operands[0] = '"'.$operands[0].'"'; #quote it
+            ## I. BUILD THE QUERY
+            ( $error,$query,$simple_query,$query_cgi,$query_desc,$limit,$limit_cgi,$limit_desc,$query_type)
+              = $builder->build_query_compat(
+                \@operators,
+                \@operands,
+                \@indexes,
+                \@limits,
+                \@sort_by,
+                0,
+                $lang,
+                {
+                    suppress => $suppress,
+                    is_opac => 1,
+                    weighted_fields => $weight_search
+                }
+            );
+            my $quoted_results_hashref;
+            my $itemtypes_nocategory = { map { $_->{itemtype} => $_ } @{ Koha::ItemTypes->search_with_localization->unblessed } };
+            eval {
+                ($error, $quoted_results_hashref, $facets) = $searcher->search_compat($query,$simple_query,\@sort_by,\@servers,$results_per_page,$offset,undef,$itemtypes_nocategory,$query_type,$scan,1);
+            };
+            my $quoted_hits = $quoted_results_hashref->{$server}->{"hits"} // 0;
+            if ( $quoted_hits ){
+                $results_hashref->{'biblioserver'} = $quoted_results_hashref->{'biblioserver'};
+                $hits = $quoted_hits;
+            }
+        }
         my $page = $cgi->param('page') || 0;
         my @newresults = searchResults( $search_context, $query_desc, $hits, $results_per_page, $offset, $scan,
                                         $results_hashref->{$server}->{"RECORDS"}, $variables);
-- 
2.20.1