Bug 17375: Search by dateofbirth - handle invalid dates
authorJonathan Druart <jonathan.druart@bugs.koha-community.org>
Tue, 4 Oct 2016 10:55:25 +0000 (11:55 +0100)
committerKyle M Hall <kyle@bywatersolutions.com>
Thu, 27 Oct 2016 13:18:32 +0000 (13:18 +0000)
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 <veron@veron.ch>
Signed-off-by: Lucio Moraes <lmoraes@catalyst.net.nz>

Signed-off-by: Nick Clemens <nick@bywatersolutions.com>

Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>

C4/Utils/DataTables/Members.pm
members/member.pl
svc/members/search

index d63ce51..487481f 100644 (file)
@@ -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}) =
index 5a8639d..cf00f91 100755 (executable)
@@ -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";
index 2599519..4f798ab 100755 (executable)
@@ -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');