From fe508be07afe38f6329e18ba80e53b5359436fbf Mon Sep 17 00:00:00 2001 From: Nick Clemens Date: Tue, 12 Apr 2022 18:28:00 +0000 Subject: [PATCH] Bug 17170: Add admin page for filters and ability to edit/save existing filters This patchset adds a new ability to save searches on the staff client, and display them in the results page on staff or opac as a new filter. New filters can be added from the resuilts page after a search, and there is an admin page for updating deleting and renaming filters There is a new permission to control management of these filters New filters can be added that are not displayed along with facets, this allows for building custom links using these filters to keep URLs shorter Due to bug 30528 testing in ES is recommended To test: 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 10 - Confirm click the [x] removes the filter 11 - Go to administration->search filters 12 - Confirm the filter appears 13 - Edit and mark as OPAC visible 14 - Test OPAC to ensure it shows and can be applied/removed 15 - Copy URL with filter applied 16 - In adminsitration mark filter as not visible on staff or opac 17 - Confirm link above still works 18 - Create a new staff with catalogue and search filters permission 19 - Ensure they can access/save filters 20 - Remove filter permission and ensure they cannot 21 - Disable system preference 22 - Confirm links to search filters page are removed from admin home and admin sidebar 23 - Confirm filters do not appear on results and cannot be created 24 - Enable pref 25 - Create a filter 26 - From search filters page, click 'Edit search' 27 - Confirm you are taken to advanced search page letting you know which filter you are editing 28 - Confirm you can change searhc options and save 29 - Confirm you can perform the search from this page Sponsored-by: Sponsored by: Round Rock Public Library [https://www.roundrocktexas.gov/departments/library/] Signed-off-by: Martin Renvoize Signed-off-by: Tomas Cohen Arazi --- admin/search_filters.pl | 60 +++++ catalogue/search.pl | 74 ++++-- .../prog/en/includes/admin-menu.inc | 3 + .../prog/en/modules/admin/admin-home.tt | 4 + .../prog/en/modules/admin/search_filters.tt | 226 +++++++++++++++++ .../prog/en/modules/catalogue/advsearch.tt | 231 ++++++++++++------ .../prog/en/modules/catalogue/results.tt | 2 - 7 files changed, 494 insertions(+), 106 deletions(-) create mode 100755 admin/search_filters.pl create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/admin/search_filters.tt diff --git a/admin/search_filters.pl b/admin/search_filters.pl new file mode 100755 index 0000000000..21645bd6c4 --- /dev/null +++ b/admin/search_filters.pl @@ -0,0 +1,60 @@ +#!/usr/bin/perl +# Copyright 2013 BibLibre +# +# This file is part of Koha +# +# Koha is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# Koha is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see . + +use Modern::Perl; +use CGI; + +use C4::Auth qw( get_template_and_user ); +use C4::Output qw( output_html_with_http_headers ); + +use Koha::SearchFilters; + +use Try::Tiny qw( catch try); + +my $cgi = CGI->new; + +my ($template, $borrowernumber, $cookie) = get_template_and_user({ + template_name => 'admin/search_filters.tt', + query => $cgi, + type => 'intranet', + flagsrequired => { parameters => 'manage_search_filters' }, +}); + +my $op = $cgi->param('op') || ''; + +if ($op eq 'del') { + my $id = $cgi->param('id'); + my $sf = Koha::SearchFilters->find($id); + $template->param(filter_not_found => 1) unless $sf; + if ($sf) { + try{ + $sf->delete(); + $template->param( filter_deleted => $sf->name ); + } catch { + $template->param( error => $_ ); + }; + } +} + +my $filters = Koha::SearchFilters->search(); + +$template->param( + filters_count => $filters->count, +); + +output_html_with_http_headers $cgi, $cookie, $template->output; diff --git a/catalogue/search.pl b/catalogue/search.pl index 7d351594d9..bf225911ef 100755 --- a/catalogue/search.pl +++ b/catalogue/search.pl @@ -177,7 +177,7 @@ my @nolimits = map uri_unescape($_), $cgi->multi_param('nolimit'); my %is_nolimit = map { $_ => 1 } @nolimits; @limits = grep { not $is_nolimit{$_} } @limits; if ( - !$cgi->param('edit_search') && + !$cgi->param('edit_search') && !$cgi->param('edit_filter') && ( (@limits>=1) || (defined $cgi->param("q") && $cgi->param("q") ne "" ) || ($cgi->param('limit-yr')) ) ) { $template_name = 'catalogue/results.tt'; @@ -262,32 +262,58 @@ $template->param( searchid => scalar $cgi->param('searchid'), ); # The following should only be loaded if we're bringing up the advanced search template if ( $template_type eq 'advsearch' ) { + my @operands; + my @operators; + my @indexes; my $expanded = $cgi->param('expanded_options'); if( $cgi->param('edit_search') ){ - my @operators = $cgi->multi_param('op'); - my @indexes = $cgi->multi_param('idx'); - my %limit_hash; - foreach my $limit (@limits){ - if ( $limit eq 'available' ){ - $template->param( limit_available => 1 ); - } else { - my ($index,$value) = split(':',$limit); - $value =~ s/"//g; - if ( $index =~ /mc-/ ){ - $limit_hash{$index . "_" . $value} = 1; - } else { - push @{$limit_hash{$index}}, $value; - } - } - }; - $expanded = 1 if scalar @operators || scalar @limits; - $template->param( operators => \@operators ); - $template->param( limits => \%limit_hash ); + @operands = $cgi->multi_param('q'); + @operators = $cgi->multi_param('op'); + @indexes = $cgi->multi_param('idx'); $template->param( - indexes => \@indexes, sort => $cgi->param('sort_by'), ); + # determine what to display next to the search boxes + } elsif ( $cgi->param('edit_filter') ){ + my $search_filter = Koha::SearchFilters->find( $cgi->param('edit_filter') ); + if( $search_filter ){ + my $query = decode_json( $search_filter->query ); + my $limits = decode_json( $search_filter->limits ); + @operands = @{ $query->{operands} }; + @indexes = @{ $query->{indexes} }; + @operators = @{ $query->{operators} }; + @limits = @{ $limits->{limits} }; + $template->param( edit_filter => $search_filter ); + } else { + $template->param( unknown_filter => 1 ); + } + } + + while( scalar @operands < 3 ){ + push @operands, ""; } + $template->param( operands => \@operands ); + $template->param( operators => \@operators ); + $template->param( indexes => \@indexes ); + + my %limit_hash; + foreach my $limit (@limits){ + if ( $limit eq 'available' ){ + $template->param( limit_available => 1 ); + } else { + my ($index,$value) = split(':',$limit); + $value =~ s/"//g; + if ( $index =~ /mc-/ ){ + $limit_hash{$index . "_" . $value} = 1; + } else { + push @{$limit_hash{$index}}, $value; + } + } + }; + $template->param( limits => \%limit_hash ); + + $expanded = 1 if scalar @operators || scalar @limits; + # load the servers (used for searching -- to do federated searching, etc.) my $primary_servers_loop;# = displayPrimaryServers(); $template->param(outer_servers_loop => $primary_servers_loop,); @@ -304,17 +330,11 @@ if ( $template_type eq 'advsearch' ) { $template->param( sort_by => $default_sort_by ); } - # determine what to display next to the search boxes - my @queries = $cgi->multi_param('q'); - while( scalar @queries < 3 ){ - push @queries, ""; - } $template->param(uc(C4::Context->preference("marcflavour")) =>1 ); # load the language limits (for search) my $languages_limit_loop = getLanguages($lang, 1); $template->param(search_languages_loop => $languages_limit_loop,); - $template->param( queries => \@queries ); # Expanded search options in advanced search: # use the global setting by default, but let the user override it diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/admin-menu.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/admin-menu.inc index 36ce065989..eb102b830f 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/includes/admin-menu.inc +++ b/koha-tmpl/intranet-tmpl/prog/en/includes/admin-menu.inc @@ -113,6 +113,9 @@ [% IF ( CAN_user_parameters_manage_item_search_fields ) %]
  • Item search fields
  • [% END %] + [% IF ( Koha.Preference('SavedSearchFilters') && CAN_user_parameters_manage_search_filters ) %] +
  • Search filters
  • + [% END %] [% IF ( CAN_user_parameters_manage_search_engine_config ) %]
  • Search engine configuration (Elasticsearch)
  • [% END %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/admin-home.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/admin-home.tt index 04330b82dd..50a4223677 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/admin-home.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/admin-home.tt @@ -203,6 +203,10 @@
    Item search fields
    Manage custom fields for item search
    [% END %] + [% IF Koha.Preference('SavedSearchFilters') && ( CAN_user_parameters_manage_search_filters ) %] +
    Search filters
    +
    Manage custom search filters
    + [% END %] [% IF ( CAN_user_parameters_manage_search_engine_config ) %]
    Search engine configuration (Elasticsearch)
    Manage indexes, facets, and their mappings to MARC fields and subfields
    diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/search_filters.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/search_filters.tt new file mode 100644 index 0000000000..37f830489a --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/search_filters.tt @@ -0,0 +1,226 @@ +[% USE raw %] +[% USE Asset %] +[% SET footerjs = 1 %] +[% USE AuthorisedValues %] +[% INCLUDE 'doc-head-open.inc' %] + Search filters › Administration › Koha + [% INCLUDE 'doc-head-close.inc' %] + + + + [% INCLUDE 'header.inc' %] + [% INCLUDE 'prefs-admin-search.inc' %] + + + +
    +
    +
    +
    + + [% IF filters_count %] +
    +

    Search filters

    + + + + + + + + + + + + + +
    IdNameQueryLimitsOPACStaff client 
    +
    + [% ELSE %] +
    + There are no search filters defined. +
    + [% END %] + +
    +
    + +
    + +
    +
    + + + +[% MACRO jsinclude BLOCK %] + [% Asset.js("js/admin-menu.js") | $raw %] + [% Asset.css("css/humanmsg.css") | $raw %] + [% Asset.js("lib/jquery/plugins/humanmsg.js") | $raw %] + [% INCLUDE 'datatables.inc' %] + + +[% END %] + +[% INCLUDE 'intranet-bottom.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/advsearch.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/advsearch.tt index 1b2272943b..16f3f1c781 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/advsearch.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/advsearch.tt @@ -51,33 +51,58 @@
    - +
    + [% ELSE %] + +

    Advanced search

    + + +
    +
    + +
    +
    + [% IF ( expanded_options ) %] + Fewer options +
    + [% ELSE %] + More options +
    + [% END %] + + + + + [% END %] [% IF ( outer_servers_loop ) %] @@ -115,66 +140,64 @@ [% END %] - +
    - Search for - [% FOREACH query IN queries %] - [% IF ( expanded_options ) %] - [% IF loop.first %] -
    - [% ELSE %] -
    - [% SET opindex = loop.index - 1 %] - - [% END # /IF loop.first %] + Search for + [% FOREACH query IN operands %] + [% IF ( expanded_options ) %] + [% IF loop.first %] +
    + [% ELSE %] +
    + [% SET opindex = loop.index - 1 %] + - [% IF ( expanded_options ) %] - [% IF ( loop.last ) %] - [+] - [% END %] - [% IF ( loop.first ) %] - + + + + [% END %] + + [% END %] + [% ELSE %] +
    + [% END %] + [% SET preselect = 'ms_' _ indexes.${loop.index}.replace(',','comma') %] + [% INCLUDE 'search_indexes.inc' %] + + [% IF ( expanded_options ) %] + [% IF ( loop.last ) %] + [+] + [% END %] + [% IF ( loop.first ) %] + + [% END %] + [% END %] +
    + [% END %] + [% IF Koha.Preference('SearchEngine') == 'Elasticsearch' %] + [% IF ( expanded_options ) %] +

    + [% IF Koha.Preference('ElasticsearchMARCFormat') == 'ARRAY' %] + [% END %] - [% END # /IF ( expanded_options ) %] -

    - [% END # /FOREACH query IN queries %] - - [% IF Koha.Preference('SearchEngine') == 'Elasticsearch' %] - [% IF ( expanded_options ) %] -

    - [% IF Koha.Preference('ElasticsearchMARCFormat') == 'ARRAY' %] - - [% END %] - - - -

    - [% ELSE %] - - [% END # /IF ( expanded_options ) %] - [% END #/IF Koha.Preference('SearchEngine') %] -

    - + + + +

    + [% ELSE %] + + [% END %] + [% END %] + + @@ -372,6 +395,8 @@ [% MACRO jsinclude BLOCK %] [% Asset.js("lib/hc-sticky.js") | $raw %] [% Asset.js("js/browser.js") | $raw %] + [% Asset.css("css/humanmsg.css") | $raw %] + [% Asset.js("lib/jquery/plugins/humanmsg.js") | $raw %] [% END %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/results.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/results.tt index 835ae10ca9..00b662e4dc 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/results.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/results.tt @@ -872,7 +872,6 @@ $("#replace_existing_filter").click(function(){ let id = $("#existing_filters").val(); let name = $("#existing_filters option[value="+id+"]").text(); - console.log(id,name); save_search_filter(name,id); }); function save_search_filter(name,id,opac,staff){ @@ -900,7 +899,6 @@ getFilters(); }) .fail(function(err) { - console.log(err); humanMsg.displayAlert( _("There was an error during saving:") + err.responseText, { className: 'humanError' } ); }); } -- 2.39.5