From c10c966cb03fc6daaa887f98311e8332074f93ca Mon Sep 17 00:00:00 2001 From: Jonathan Druart Date: Tue, 4 Oct 2016 11:55:25 +0100 Subject: [PATCH] Bug 17375: Search by dateofbirth - handle invalid dates MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prevent internal software error when searching patron with invalid birth date To reproduce: - Go to Home > Patron - Expand patron search (click on + at the left of the search button) - In drop down 'Search fields', select 'Date of birth' - Enter a valid date (e.g. 11.02.1995 if syspref 'dateformat' is set to dmydot) Result: Search works OK - Enter an invalid date, e.g. 11.02 or abcd... Result: Internal server error - Do a patron search with many results - Use filter on results screen, select 'Date of birth' as search field and enter an invalid date to search (e.g. 'a') Result: Endless message 'Processing' To test: - Apply patch - Repeat steps above - In both cases, you should get "No results" Signed-off-by: Marc VĂ©ron --- C4/Utils/DataTables/Members.pm | 31 +++++++++++++++++++++---------- members/member.pl | 4 ---- svc/members/search | 4 ---- 3 files changed, 21 insertions(+), 18 deletions(-) diff --git a/C4/Utils/DataTables/Members.pm b/C4/Utils/DataTables/Members.pm index d63ce51..487481f 100644 --- a/C4/Utils/DataTables/Members.pm +++ b/C4/Utils/DataTables/Members.pm @@ -20,7 +20,25 @@ sub search { $searchmember = $dt_params->{sSearch} // ''; } - my ($iTotalRecords, $iTotalDisplayRecords); + my ($sth, $query, $iTotalRecords, $iTotalDisplayRecords); + my $dbh = C4::Context->dbh; + # Get the iTotalRecords DataTable variable + $query = "SELECT COUNT(borrowers.borrowernumber) FROM borrowers"; + $sth = $dbh->prepare($query); + $sth->execute; + ($iTotalRecords) = $sth->fetchrow_array; + + if ( $searchfieldstype eq 'dateofbirth' ) { + # Return an empty list if the date of birth is not correctly formatted + $searchmember = eval { output_pref( { str => $searchmember, dateformat => 'iso', dateonly => 1 } ); }; + if ( $@ or not $searchmember ) { + return { + iTotalRecords => 0, + iTotalDisplayRecords => 0, + patrons => [], + }; + } + } # If branches are independent and user is not superlibrarian # The search has to be only on the user branch @@ -30,7 +48,6 @@ sub search { } - my $dbh = C4::Context->dbh; my $select = "SELECT borrowers.borrowernumber, borrowers.surname, borrowers.firstname, borrowers.streetnumber, borrowers.streettype, borrowers.address, @@ -126,7 +143,7 @@ sub search { $limit = "LIMIT $dt_params->{iDisplayStart},$dt_params->{iDisplayLength}"; } - my $query = join( + $query = join( " ", ($select ? $select : ""), ($from ? $from : ""), @@ -134,7 +151,7 @@ sub search { ($orderby ? $orderby : ""), ($limit ? $limit : "") ); - my $sth = $dbh->prepare($query); + $sth = $dbh->prepare($query); $sth->execute(@where_args); my $patrons = $sth->fetchall_arrayref({}); @@ -144,12 +161,6 @@ sub search { $sth->execute(@where_args); ($iTotalDisplayRecords) = $sth->fetchrow_array; - # Get the iTotalRecords DataTable variable - $query = "SELECT COUNT(borrowers.borrowernumber) FROM borrowers"; - $sth = $dbh->prepare($query); - $sth->execute; - ($iTotalRecords) = $sth->fetchrow_array; - # Get some information on patrons foreach my $patron (@$patrons) { ($patron->{overdues}, $patron->{issues}, $patron->{fines}) = diff --git a/members/member.pl b/members/member.pl index 5a8639d..cf00f91 100755 --- a/members/member.pl +++ b/members/member.pl @@ -64,10 +64,6 @@ if ( $quicksearch and $searchmember ) { my $searchfieldstype = $input->param('searchfieldstype') || 'standard'; -if ( $searchfieldstype eq "dateofbirth" ) { - $searchmember = output_pref({dt => dt_from_string($searchmember), dateformat => 'iso', dateonly => 1}); -} - $template->param( 'alphabet' => C4::Context->preference('alphabet') || join ' ', 'A' .. 'Z' ); my $view = $input->request_method() eq "GET" ? "show_form" : "show_results"; diff --git a/svc/members/search b/svc/members/search index 2599519..4f798ab 100755 --- a/svc/members/search +++ b/svc/members/search @@ -47,10 +47,6 @@ my $searchfieldstype = $input->param('searchfieldstype') || 'standard'; my $has_permission = $input->param('has_permission'); my $selection_type = $input->param('selection_type'); -if ( $searchfieldstype eq "dateofbirth" ) { - $searchmember = output_pref({dt => dt_from_string($searchmember), dateformat => 'iso', dateonly => 1}); -} - # variable information for DataTables (id) my $sEcho = $input->param('sEcho'); -- 2.1.4