From 7081126af63d05be32f7345f0543b2cba08a9d34 Mon Sep 17 00:00:00 2001 From: David Cook Date: Thu, 15 Sep 2022 04:36:32 +0000 Subject: [PATCH] Bug 23817: Normalize phone number when searching This patch rewrites the phone number DBIC query when sent from DataTables like in the Patron module. Test plan: 0. Apply patch and koha-plack --restart kohadev 1. Go to http://localhost:8081/cgi-bin/koha/members/memberentry.pl?op=modify&destination=circ&borrowernumber=51 2. Input '1-(234)-567-8901' into the 'Primary phone' field 3. Note on the next screen the phone number is shown as '1-(234)-567-8901' 4. Go to http://localhost:8081/cgi-bin/koha/members/members-home.pl 5. Choose "Search field" of "All phones" 6. Search for '12345678901' 7. Note you are taken to http://localhost:8081/cgi-bin/koha/members/moremember.pl?borrowernumber=51 8. Try out different permutations like '234 567 8901' or '5678901' 9. Note that every permutation works to find the borrower --- Koha/REST/Plugin/Objects.pm | 7 +++ Koha/REST/V1/Patrons.pm | 55 +++++++++++++++++++ .../prog/en/includes/patron-search.inc | 4 +- 3 files changed, 65 insertions(+), 1 deletion(-) diff --git a/Koha/REST/Plugin/Objects.pm b/Koha/REST/Plugin/Objects.pm index 94baf03753b..a1313957dbf 100644 --- a/Koha/REST/Plugin/Objects.pm +++ b/Koha/REST/Plugin/Objects.pm @@ -256,6 +256,13 @@ controller, and thus shouldn't be called twice in it. $c->stash('koha.pagination.base_total' => $result_set->count); $c->stash('koha.pagination.query_params' => $args); + # Pre-process DBIC queries if controller supports it + if ( $reserved_params->{'x-koha-request-id'} ){ + if ($c->can('preprocess_dbic_for_datatables')){ + $c->preprocess_dbic_for_datatables($filtered_params,$attributes); + } + } + # Generate the resultset my $objects_rs = $result_set->search( $filtered_params, $attributes ); # Stash the page total if requires, total otherwise diff --git a/Koha/REST/V1/Patrons.pm b/Koha/REST/V1/Patrons.pm index 1852d7ccd29..9fd60e02e6c 100644 --- a/Koha/REST/V1/Patrons.pm +++ b/Koha/REST/V1/Patrons.pm @@ -470,4 +470,59 @@ sub guarantors_can_see_checkouts { }; } +sub _parse_dbic_query_for_dt { + my ($q_params,$collector) = @_; + my %allowed_keys = ( + 'me.phone' => 1, + 'me.phonepro' => 1, + 'me.B_phone' => 1, + 'me.altcontactphone' => 1, + 'me.mobile' => 1, + ); + if(ref($q_params) && ref($q_params) eq 'HASH') { + foreach my $key (keys %{$q_params}) { + if ($allowed_keys{$key}){ + my $query = $q_params->{$key}; + if ($query->{'like'}){ + my $like = $query->{'like'}; + #NOTE: Remove the hashref, and add a data structure to add to the WHERE clause via the attributes... + delete $q_params->{$key}; + my $collection = \["regexp_replace($key,?,?) LIKE ?","[^0-9]","",$like]; + push(@$collector,$collection); + } + } + else { + $q_params->{$key} = _parse_dbic_query_for_dt($q_params->{$key},$collector); + } + } + return $q_params; + } elsif (ref($q_params) && ref($q_params) eq 'ARRAY') { + foreach my $param (@$q_params){ + $param = _parse_dbic_query_for_dt($param,$collector); + } + return $q_params; + } else { + return $q_params; + } +} + +=head3 preprocess_dbic_for_datatables + +Method for preprocessing DBIC queries sent from DataTables, so a WHERE +clause can be injected into the query if one doesn't already exist. + +=cut + +sub preprocess_dbic_for_datatables { + my ($c,$q_params,$attributes) = @_; + my @collector = (); + my $rewritten_q_params = _parse_dbic_query_for_dt($q_params,\@collector); + unless ($attributes->{where}){ + foreach my $collection (@collector){ + push(@{$attributes->{where}},$collection); + } + } + return 1; +} + 1; diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/patron-search.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/patron-search.inc index 6ae5ebb9e28..89dad14bdad 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/includes/patron-search.inc +++ b/koha-tmpl/intranet-tmpl/prog/en/includes/patron-search.inc @@ -308,7 +308,9 @@ if ( !search_fields ) { search_fields = "[% Koha.Preference('DefaultPatronSearchFields') || 'firstname,middle_name,surname,othernames,cardnumber,userid' | html %]"; } - + if (search_fields == 'phone,phonepro,B_phone,altcontactphone,mobile'){ + patterns = [pattern.replace(/[^\+0-9]/g,'')]; + } let subquery_and = []; patterns.forEach(function(pattern,i){ let sub_or = []; -- 2.39.5