diff --git a/Koha/SearchEngine/Elasticsearch/Search.pm b/Koha/SearchEngine/Elasticsearch/Search.pm index 42326e3573..9696e1457a 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 578ae8979c..b3a1230f97 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 1d504d384f..990471a690 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 9dba9f3202..cf34a6f55a 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' + } + ]; +}