From 22bf3b95635042492c0fa9ecaffea063b3d95f68 Mon Sep 17 00:00:00 2001 From: Shi Yao Wang Date: Mon, 4 Apr 2022 11:46:25 -0400 Subject: [PATCH] Bug 27113: Removes items in OPACHiddenItems from autocomplete Items specified in OPACHiddenItems preference are removed from search suggestions in OPAC. Test plan: 1- Search for an item. Notice that the autocomplete functionnality is not available. (See "Result" attachment) 2- Make sure that you are using Elasticsearch as your searching engine. (Preference->SearchEngine->ElasticSearch) 3- Apply the patch. 4- Run ./installer/data/mysql/updatedatabase.pl 5- Looks for the following preferences : - IntranetAutocompleteElasticSearch - OPACAutocompleteElasticSearch 6- Set their value to show. 7- Rebuild the OPAC and staff client CSS (This step is important because the autocomplete CSS is moved to the main SCSS file): Instructions here: https://wiki.koha-community.org/wiki/Working_with_SCSS_in_the_OPAC_and_staff_client 8- Search for an item and notice that the autocomplete functionnality is now available. 9- In the staff interface, go in "Search the catalog". 10- Notice that the buggy behavior is now fixed. 11- Search for an item with basic search and click on one of the options. 12- Notice it automatically sends you to the selected items page. 13- This time, search an item using the advanced search and click on one of the options. 14- Notice it just writes the chosen option in the input instead. 15- Go to Administration -> system preferences -> OPACHiddenItems. 16- Define a rule that applies to an existing item. 17- Search that item in OPAC and notice it doesn't give you the suggestion for that item. --- opac/svc/elasticsearch/opac-elasticsearch.pl | 91 ++++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/opac/svc/elasticsearch/opac-elasticsearch.pl b/opac/svc/elasticsearch/opac-elasticsearch.pl index 812b458855..245b0bbd94 100755 --- a/opac/svc/elasticsearch/opac-elasticsearch.pl +++ b/opac/svc/elasticsearch/opac-elasticsearch.pl @@ -9,6 +9,9 @@ use Unicode::Normalize; use CGI::Session; use Koha::SearchEngine::Elasticsearch::Browse; +use Koha::Items; +use C4::Context; + my $browser = Koha::SearchEngine::Elasticsearch::Browse->new( { index => 'biblios' } ); my $cgi = CGI->new; my $session = CGI::Session->load() or die CGI::Session->errstr(); @@ -33,12 +36,100 @@ if ($session->param("key") eq "autocomplete") { #search by many prefix fields if ($length > 1){ my $res = $browser->autocomplete_idx($ses, \@prefix, $session->param("analyzer"), $session->param("token_counter")); + + if (C4::Context->yaml_preference('OpacHiddenItems')) { + my @prefix = $res->{ "prefix" }; + @prefix = split(',', $prefix[0]); + + my %biblionumbers; + for (my $i = 0; $i < scalar @prefix; $i++) { + my @hits = @{$res->{ "$i" }->{ "hits" }->{ "hits" }}; + if (@hits) { + for (my $j = 0; $j < scalar @hits; $j++) { + # biblionumber->prefix position = hit position within prefix + $biblionumbers{ $hits[$j]->{ "_id" } }{ $i } = $j; + } + } + } + + if (%biblionumbers) { + my @biblionumbers = keys %biblionumbers; + my $autocomplete_items = Koha::Items->search({ + biblionumber => { -in => \@biblionumbers } + }); + my $filtered_items = $autocomplete_items->filter_by_visible_in_opac({ + patron => undef + }); + + foreach (@biblionumbers) { + my $biblionumber = $_; + my $item = $filtered_items->find({ + biblionumber => $biblionumber + }); + if (!$item) { + my %removelist = %{$biblionumbers{ $biblionumber }}; + foreach (keys %removelist) { + my $hits = $res->{ $_ }->{ "hits" }->{ "hits" }; + splice(@{$hits}, $removelist{ $_ }, 1); + $res->{ $_ }->{ "hits" }->{ "total" }--; + } + } + } + for (my $i = 0; $i < scalar @prefix; $i++) { + if ($res->{ $i }->{ "hits" }->{ "max_score" }) { + my $hits = $res->{ $i }->{ "hits" }->{ "hits" }; + my $maxscore = 0; + foreach ( @{$hits} ) { + my $score = $_->{"_score"}; + $maxscore = $score if ($maxscore < $score); + } + $res->{ $i }->{ "hits" }->{ "max_score" } = $maxscore; + } + } + } + } + print $cgi->header("application/json"); print to_json($res); } #search by one prefix field elsif ($length == 1) { my $res = $browser->autocomplete_one_idx($ses, $prefix[0], $session->param("analyzer"), $session->param("token_counter")); + + if (C4::Context->yaml_preference('OpacHiddenItems')) { + my $hits = $res->{ "hits" }->{ "hits" }; + if (@{$hits}) { + my @biblionumbers; + foreach ( @{$hits} ) { + push(@biblionumbers, $_->{"_id"}); + } + + my $autocomplete_items = Koha::Items->search({ + biblionumber => { -in => \@biblionumbers } + }); + my $filtered_items = $autocomplete_items->filter_by_visible_in_opac({ + patron => undef + }); + + for ( my $i = 0; $i < scalar @biblionumbers; $i++ ) { + my $item = $filtered_items->find({ + biblionumber => $biblionumbers[$i] + }); + if (!$item) { + splice(@{$hits}, $i, 1); + $res->{ "hits" }->{ "total" }--; + } + } + my $maxscore = 0; + foreach ( @{$hits} ) { + my $score = $_->{"_score"}; + $maxscore = $score if ($maxscore < $score); + } + $res->{ "hits" }->{ "max_score" } = $maxscore; + warn Data::Dumper->Dumper($res); + } + } + print $cgi->header("application/json"); print to_json($res); } -- 2.25.1