@@ -, +, @@ as filters when searching the catalog 1 - Apply patches and update database and restart all 2 - Enable new system preference 'SavedSearchFilters' 3 - As superlibrarian perform a search in staff client, something broad like 'a' 4 - Note new 'Save search as filter' link on results page 5 - Click it, save search as new filter, check 'Staff client' visibility 6 - Perform another search 7 - Note the filter now appears above facets 8 - Click to it filter results 9 - Note results are limited by the new filter, and it is checked in the facets --- C4/Search.pm | 7 +++++-- .../Elasticsearch/QueryBuilder.pm | 11 +++++++--- Koha/SearchFilter.pm | 10 ++++----- .../SearchEngine/Elasticsearch/QueryBuilder.t | 21 +++++++++++++++---- .../Koha/SearchEngine/Zebra/QueryBuilder.t | 21 +++++++++++++++---- 5 files changed, 51 insertions(+), 19 deletions(-) --- a/C4/Search.pm +++ a/C4/Search.pm @@ -1301,12 +1301,15 @@ sub buildQuery { $limit .= "$this_limit"; $limit_desc .= " $this_limit"; } elsif ( $this_limit =~ '^search_filter:' ) { + # Here we will get the query as a string, append to the limits, and pass through buildQuery + # again to clean the terms and handle nested filters $limit_cgi .= "&limit=" . uri_escape_utf8($this_limit); my ($filter_id) = ( $this_limit =~ /^search_filter:(.*)$/ ); my $search_filter = Koha::SearchFilters->find( $filter_id ); next unless $search_filter; - my $expanded = $search_filter->expand_filter; - my ( $error, undef, undef, undef, undef, $fixed_limit, undef, undef, undef ) = buildQuery ( undef, undef, undef, $expanded, undef, undef, $lang); + my ($expanded_lim, $query_lim) = $search_filter->expand_filter; + push @$expanded_lim, $query_lim; + my ( $error, undef, undef, undef, undef, $fixed_limit, undef, undef, undef ) = buildQuery ( undef, undef, undef, $expanded_lim, undef, undef, $lang); $limit .= " and " if $limit || $query; $limit .= "$fixed_limit"; $limit_desc .= " $limit"; --- a/Koha/SearchEngine/Elasticsearch/QueryBuilder.pm +++ a/Koha/SearchEngine/Elasticsearch/QueryBuilder.pm @@ -1070,13 +1070,18 @@ sub _fix_limit_special_cases { push @new_lim, "date-of-publication:[$start TO $end]"; } elsif( $l =~ /^search_filter:/ ){ + # Here we are going to get the query as a string, clean it, and take care of the part of the limit + # Calling build_query_compat here is avoided because we generate more complex query structures my ($filter_id) = ( $l =~ /^search_filter:(.*)$/ ); my $search_filter = Koha::SearchFilters->find( $filter_id ); next unless $search_filter; - my $expanded = $search_filter->expand_filter; - foreach my $e ( @{$self->_fix_limit_special_cases($expanded)} ) { - push @new_lim, $self->clean_search_term( $e ); + my ($expanded_lim,$query_lim) = $search_filter->expand_filter; + # In the case of nested filters we need to expand them all + foreach my $el ( @{$self->_fix_limit_special_cases($expanded_lim)} ){ + push @new_lim, $el; } + # We need to clean the query part as we have built a string from the original search + push @new_lim, $self->clean_search_term( $query_lim ); } elsif ( $l =~ /^yr,st-numeric[=:]/ ) { my ($date) = ( $l =~ /^yr,st-numeric[=:](.*)$/ ); --- a/Koha/SearchFilter.pm +++ a/Koha/SearchFilter.pm @@ -43,10 +43,10 @@ sub to_api_mapping { =head3 expand_filter - my $expanded_filter = $filter->expand_filter; + my ($expanded_limit, $query_limit) = $filter->expand_filter; - Returns the filter as an arrayref of limit queries suitable to - be passed to QueryBuilder + Returns the filter as an arrayref of limit queries, and the query parts combined + into a string suitable to be passed to QueryBuilder =cut @@ -74,9 +74,7 @@ sub expand_filter { $query_limit .= $limit; } - push @$limits, "(".$query_limit.")" if $query_limit; - - return $limits; + return ($limits, $query_limit); } =head2 Internal methods --- a/t/db_dependent/Koha/SearchEngine/Elasticsearch/QueryBuilder.t +++ a/t/db_dependent/Koha/SearchEngine/Elasticsearch/QueryBuilder.t @@ -785,7 +785,7 @@ subtest 'build_query_compat() SearchLimitLibrary tests' => sub { }; subtest "Handle search filters" => sub { - plan tests => 4; + plan tests => 7; my $qb; @@ -797,15 +797,28 @@ subtest "Handle search filters" => sub { my $filter = Koha::SearchFilter->new({ name => "test", query => q|{"operands":["cat","bat","rat"],"indexes":["kw","ti","au"],"operators":["AND","OR"]}|, - limits => q|{"limits":["mc-itype,phr:BK","available"]}|, + limits => q|{"limits":["mc-itype,phr:BK","mc-itype,phr:MU","available"]}|, })->store; my $filter_id = $filter->id; my ( undef, undef, undef, undef, undef, $limit, $limit_cgi, $limit_desc ) = $qb->build_query_compat( undef, undef, undef, ["search_filter:$filter_id"] ); - is( $limit,q{(itype:("BK")) AND (onloan:false) AND (((cat) AND title:(bat) OR author:(rat)))},"Limit correctly formed"); + is( $limit,q{(onloan:false) AND ((cat) AND title:(bat) OR author:(rat)) AND itype:(("BK") OR ("MU"))},"Limit correctly formed"); is( $limit_cgi,"&limit=search_filter%3A$filter_id","CGI limit is not expanded"); - is( $limit_desc,q{(itype:("BK")) AND (onloan:false) AND (((cat) AND title:(bat) OR author:(rat)))},"Limit description is correctly expanded"); + is( $limit_desc,q{(onloan:false) AND ((cat) AND title:(bat) OR author:(rat)) AND itype:(("BK") OR ("MU"))},"Limit description is correctly expanded"); + + $filter = Koha::SearchFilter->new({ + name => "test", + query => q|{"operands":["su:biography"],"indexes":[],"operators":[]}|, + limits => q|{"limits":[]}|, + })->store; + $filter_id = $filter->id; + + ( undef, undef, undef, undef, undef, $limit, $limit_cgi, $limit_desc ) = $qb->build_query_compat( undef, undef, undef, ["search_filter:$filter_id"] ); + + is( $limit,q{(subject:biography)},"Limit correctly formed for ccl type query"); + is( $limit_cgi,"&limit=search_filter%3A$filter_id","CGI limit is not expanded"); + is( $limit_desc,q{(subject:biography)},"Limit description is correctly handled for ccl type query"); }; --- a/t/db_dependent/Koha/SearchEngine/Zebra/QueryBuilder.t +++ a/t/db_dependent/Koha/SearchEngine/Zebra/QueryBuilder.t @@ -98,7 +98,7 @@ subtest 'build_query_compat() SearchLimitLibrary tests' => sub { }; subtest "Handle search filters" => sub { - plan tests => 4; + plan tests => 7; my $qb; @@ -110,14 +110,27 @@ subtest "Handle search filters" => sub { my $filter = Koha::SearchFilter->new({ name => "test", query => q|{"operands":["cat","bat","rat"],"indexes":["kw","ti","au"],"operators":["AND","OR"]}|, - limits => q|{"limits":["mc-itype,phr:BK","available"]}|, + limits => q|{"limits":["mc-itype,phr:BK","mc-itype,phr:MU","available"]}|, })->store; my $filter_id = $filter->id; my ( undef, undef, undef, undef, undef, $limit, $limit_cgi, $limit_desc ) = $qb->build_query_compat( undef, undef, undef, ["search_filter:$filter_id"] ); - is( $limit,q{(kw=(cat) AND ti=(bat) OR au=(rat)) and (mc-itype,phr=BK) and (( (allrecords,AlwaysMatches='') and (not-onloan-count,st-numeric >= 1) and (lost,st-numeric=0) ))},"Limit correctly formed"); + is( $limit,q{kw=(cat) AND ti=(bat) OR au=(rat) and (mc-itype,phr=BK or mc-itype,phr=MU) and (( (allrecords,AlwaysMatches='') and (not-onloan-count,st-numeric >= 1) and (lost,st-numeric=0) ))},"Limit correctly formed"); is( $limit_cgi,"&limit=search_filter%3A$filter_id","CGI limit is not expanded"); - is( $limit_desc,q{(kw=(cat) AND ti=(bat) OR au=(rat)) and (mc-itype,phr=BK) and (( (allrecords,AlwaysMatches='') and (not-onloan-count,st-numeric >= 1) and (lost,st-numeric=0) ))},"Limit description is correctly expanded"); + is( $limit_desc,q{kw=(cat) AND ti=(bat) OR au=(rat) and (mc-itype,phr=BK or mc-itype,phr=MU) and (( (allrecords,AlwaysMatches='') and (not-onloan-count,st-numeric >= 1) and (lost,st-numeric=0) ))},"Limit description is correctly expanded"); + + $filter = Koha::SearchFilter->new({ + name => "test", + query => q|{"operands":["su:biography"],"indexes":[],"operators":[]}|, + limits => q|{"limits":[]}|, + })->store; + $filter_id = $filter->id; + + ( undef, undef, undef, undef, undef, $limit, $limit_cgi, $limit_desc ) = $qb->build_query_compat( undef, undef, undef, ["search_filter:$filter_id"] ); + + is( $limit,q{(su=biography)},"Limit correctly formed for ccl type query"); + is( $limit_cgi,"&limit=search_filter%3A$filter_id","CGI limit is not expanded"); + is( $limit_desc,q{(su=biography)},"Limit description is correctly handled for ccl type query"); }; --