From c25535107d74f1757ae7ffa2b83204ae332baacb Mon Sep 17 00:00:00 2001 From: David Cook Date: Thu, 24 Oct 2024 01:33:44 +0000 Subject: [PATCH] Bug 14007: Filter search result values to remove OpacHiddenItems values This change filters the values from the OpacHiddenItems syspref out of their corresponding search results facets. Note: This does not mean that all values from hidden items are filtered out of facets. Rather, it just means that facet data that matches OpacHiddenItems is filtered out. This is an imperfect fix, but it is a practical fix that has been requested by more than one library. Test plan: 0. Apply the patch and koha-plack --restart kohadev 1. Go to http://localhost:8081/cgi-bin/koha/catalogue/detail.pl?biblionumber=29 2. Add an item with an item type of "Maps" 3. Go to http://localhost:8081/cgi-bin/koha/admin/preferences.pl?op=search&searchfield=OpacHiddenItems 4. Fill in OpacHiddenItems with the following: itype: ['MP'] 5. Go to http://localhost:8080/cgi-bin/koha/opac-search.pl?idx=&q=test&weight_search=1 6. Note that "Maps" does not appear in the "Item types" facet 7. Go to http://localhost:8081/cgi-bin/koha/catalogue/search.pl?q=test 8. Note that "Maps" does appear in the "Item types" facet 9. ***Repeat this test plan using both Elasticsearch and Zebra indexing*** 10. prove -v t/Koha/SearchEngine/Search.t Signed-off-by: David Nind Signed-off-by: Kyle M Hall --- Koha/SearchEngine/Elasticsearch/Search.pm | 8 ++- Koha/SearchEngine/Search.pm | 50 +++++++++++++++ Koha/SearchEngine/Zebra/Search.pm | 9 ++- t/Koha/SearchEngine/Search.t | 75 ++++++++++++++++++++++- 4 files changed, 138 insertions(+), 4 deletions(-) diff --git a/Koha/SearchEngine/Elasticsearch/Search.pm b/Koha/SearchEngine/Elasticsearch/Search.pm index 42326e3573d..9696e1457ab 100644 --- a/Koha/SearchEngine/Elasticsearch/Search.pm +++ b/Koha/SearchEngine/Elasticsearch/Search.pm @@ -183,7 +183,13 @@ sub search_compat { my %result; $result{biblioserver}{hits} = $hits->{'total'}; $result{biblioserver}{RECORDS} = \@records; - return (undef, \%result, $self->_convert_facets($results->{aggregations})); + + my $facets = $self->_convert_facets( $results->{aggregations} ); + if ( C4::Context->interface eq 'opac' ) { + my $rules = C4::Context->yaml_preference('OpacHiddenItems'); + $facets = Koha::SearchEngine::Search->post_filter_opac_facets( { facets => $facets, rules => $rules } ); + } + return (undef, \%result, $facets); } =head2 search_auth_compat diff --git a/Koha/SearchEngine/Search.pm b/Koha/SearchEngine/Search.pm index 578ae8979c9..b3a1230f978 100644 --- a/Koha/SearchEngine/Search.pm +++ b/Koha/SearchEngine/Search.pm @@ -179,4 +179,54 @@ sub pagination_bar { } +=head2 post_filter_opac_facets + + if ( C4::Context->interface eq 'opac' ) { + my $rules = C4::Context->yaml_preference('OpacHiddenItems'); + $facets = Koha::SearchEngine::Search->post_filter_facets({ facets => $facets, rules => $rules }); + } + +=cut + +sub post_filter_opac_facets { + my ( $class, $args ) = @_; + my $facets = $args->{facets}; + my $rules = $args->{rules}; + if ( $rules && $facets ) { + + #Build a hashmap of the rules to provide efficient lookups + my $rule_map = {}; + my @keys = keys %$rules; + foreach my $key (@keys) { + $rule_map->{$key} = {}; + foreach my $rule_value ( @{ $rules->{$key} } ) { + $rule_map->{$key}->{$rule_value} = 1; + } + } + + #Iterate through the facets + foreach my $facet_type (@$facets) { + my $type_link_value = $facet_type->{type_link_value}; + my $rule_map_by_type = $rule_map->{$type_link_value}; + + #If the facet type has a rule map, process the facets + if ($rule_map_by_type) { + + #Filter out any facet which has a value in the rule map + my @filtered_facets = (); + foreach my $facet ( @{ $facet_type->{facets} } ) { + my $facet_link_value = $facet->{facet_link_value}; + if ($facet_link_value) { + if ( !$rule_map_by_type->{$facet_link_value} ) { + push( @filtered_facets, $facet ); + } + } + } + $facet_type->{facets} = \@filtered_facets; + } + } + } + return $facets; +} + 1; diff --git a/Koha/SearchEngine/Zebra/Search.pm b/Koha/SearchEngine/Zebra/Search.pm index 1d504d384fd..990471a6909 100644 --- a/Koha/SearchEngine/Zebra/Search.pm +++ b/Koha/SearchEngine/Zebra/Search.pm @@ -60,9 +60,14 @@ This passes straight through to C4::Search::getRecords. =cut sub search_compat { - shift; # get rid of $self + shift; # get rid of $self - return C4::Search::getRecords(@_); + my ( $error, $results_hashref, $facets ) = C4::Search::getRecords(@_); + if ( C4::Context->interface eq 'opac' ) { + my $rules = C4::Context->yaml_preference('OpacHiddenItems'); + $facets = Koha::SearchEngine::Search->post_filter_opac_facets( { facets => $facets, rules => $rules } ); + } + return ( $error, $results_hashref, $facets ); } =head2 simple_search_compat diff --git a/t/Koha/SearchEngine/Search.t b/t/Koha/SearchEngine/Search.t index 9dba9f32021..cf34a6f55ad 100755 --- a/t/Koha/SearchEngine/Search.t +++ b/t/Koha/SearchEngine/Search.t @@ -17,7 +17,7 @@ use Modern::Perl; -use Test::More tests => 1; +use Test::More tests => 2; use Test::Exception; use t::lib::Mocks; @@ -85,3 +85,76 @@ subtest "pagination_bar tests" => sub { is( @$PAGE_NUMBERS, 20, "If past first ten pages we show 20 pages" ); }; + +subtest "post_filter_opac_facets" => sub { + plan tests => 4; + + my $facets = _get_mock_facet_data(); + my $rules = { 'itype' => ['MP'] }; + + my $filtered_facets = Koha::SearchEngine::Search->post_filter_opac_facets( { facets => $facets, rules => $rules } ); + is( scalar @$filtered_facets, 2, 'Facet type length the same' ); + is( scalar @{ $filtered_facets->[0]->{facets} }, 3, 'author facet length the same' ); + is( scalar @{ $filtered_facets->[1]->{facets} }, 1, 'itype facet has been filtered' ); + is( $filtered_facets->[1]->{facets}->[0]->{facet_link_value}, 'BK', 'correct itype facet has been filtered' ); +}; + +sub _get_mock_facet_data { + my $facets = [ + { + 'type_label_Authors' => 1, + 'facets' => [ + { + 'facet_link_value' => 'Farley, David', + 'type_link_value' => 'author', + 'facet_title_value' => 'Farley, David', + 'facet_count' => 1, + 'facet_label_value' => 'Farley, David' + }, + { + 'facet_label_value' => 'Humble, Jez', + 'facet_count' => 1, + 'facet_title_value' => 'Humble, Jez', + 'type_link_value' => 'author', + 'facet_link_value' => 'Humble, Jez' + }, + { + 'facet_count' => 1, + 'facet_title_value' => 'Martin, Robert C.', + 'facet_label_value' => 'Martin, Robert C.', + 'type_link_value' => 'author', + 'facet_link_value' => 'Martin, Robert C.' + } + ], + 'av_cat' => '', + 'order' => 1, + 'label' => 'Authors', + 'type_id' => 'author_id', + 'type_link_value' => 'author' + }, + { + 'type_label_Item types' => 1, + 'facets' => [ + { + 'type_link_value' => 'itype', + 'facet_link_value' => 'BK', + 'facet_count' => 4, + 'facet_title_value' => 'BK', + 'facet_label_value' => 'Books' + }, + { + 'facet_title_value' => 'MP', + 'facet_count' => 1, + 'facet_label_value' => 'Maps', + 'type_link_value' => 'itype', + 'facet_link_value' => 'MP' + } + ], + 'order' => 2, + 'av_cat' => undef, + 'type_id' => 'itype_id', + 'type_link_value' => 'itype', + 'label' => 'Item types' + } + ]; +} -- 2.39.5 (Apple Git-154)