From ebc2db76d28b44032340bbcd0c654999d880dad4 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 hidden and suppressed items from OPAC autocomplete Items specified in OPACHiddenItems preference and items affected by OpacSuppression 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. 18- Go to Administration -> system preferences -> OpacSuppression and set it to "hide". 19- Add or edit a record and set 942$n field to yes. 20- Search that entry in OPAC and notice it doesn't give you the suggestion for that entry. --- 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..ad1c4b4568 100755 --- a/opac/svc/elasticsearch/opac-elasticsearch.pl +++ b/opac/svc/elasticsearch/opac-elasticsearch.pl @@ -9,6 +9,10 @@ use Unicode::Normalize; use CGI::Session; use Koha::SearchEngine::Elasticsearch::Browse; +use Koha::Items; +use C4::Context; +use C4::Biblio qw ( GetMarcBiblio ); + 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 +37,27 @@ 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->preference('OpacSuppression') || C4::Context->yaml_preference('OpacHiddenItems')) { + my @prefix = $res->{ "prefix" }; + @prefix = split(',', $prefix[0]); + + for (my $i = 0; $i < scalar @prefix; $i++) { + filterAutocomplete($res->{ $i }->{ 'hits' }); + } + } + 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->preference('OpacSuppression') || C4::Context->yaml_preference('OpacHiddenItems')) { + filterAutocomplete($res->{ 'hits' }); + } + print $cgi->header("application/json"); print to_json($res); } @@ -52,6 +71,78 @@ if ($iskey == 0) { response404JSON(); } +sub filterAutocomplete { + my $hits = $_[0]; + my $hitlist = $hits->{ "hits" }; + if (@{$hitlist}) { + # Remove item inside hits in elasticsearch response if the item has + # marc field 942$n set to true and OpacSuppression preference on + if (C4::Context->preference('OpacSuppression')) { + for ( my $i = 0; $i < scalar @{$hitlist}; $i++ ) { + my $record = GetMarcBiblio({ + biblionumber => $hitlist->[$i]->{ "_id" }, + opac => 1 + }); + my $opacsuppressionfield = '942'; + my $opacsuppressionfieldvalue = $record->field($opacsuppressionfield); + if ( $opacsuppressionfieldvalue && + $opacsuppressionfieldvalue->subfield("n") && + $opacsuppressionfieldvalue->subfield("n") == 1) { + # if OPAC suppression by IP address + if (C4::Context->preference('OpacSuppressionByIPRange')) { + my $IPAddress = $ENV{'REMOTE_ADDR'}; + my $IPRange = C4::Context->preference('OpacSuppressionByIPRange'); + if ($IPAddress !~ /^$IPRange/) { + splice(@{$hitlist}, $i, 1); + $i--; + $hits->{ "total" }--; + } + } else { + splice(@{$hitlist}, $i, 1); + $i--; + $hits->{ "total" }--; + } + } + } + } + # Remove item inside hits in elasticsearch response if the item is + # declared hidden in OPACHiddenItems preference + if (C4::Context->yaml_preference('OpacHiddenItems')) { + my @biblionumbers; + foreach (@{$hitlist}) { + 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 @{$hitlist}; $i++ ) { + my $item = $filtered_items->find({ + biblionumber => $hitlist->[$i]->{ "_id" } + }); + if (!$item) { + splice(@{$hitlist}, $i, 1); + $i--; + $hits->{ "total" }--; + } + } + } + # Adjust the max_score inside hits in elasticsearch response + my $maxscore = 0; + foreach ( @{$hitlist} ) { + my $score = $_->{"_score"}; + $maxscore = $score if ($maxscore < $score); + } + if ($maxscore == 0) { + $hits->{ "max_score" } = undef; + } else { + $hits->{ "max_score" } = $maxscore; + } + } +} + sub response404JSON { my $res = CGI->new; my $json = JSON->new->utf8; -- 2.25.1