From 8a7ef9b6420d560651fbcd4b8dc8fc9603e2fba9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20V=C3=A9ron?= Date: Thu, 1 Oct 2015 18:08:17 +0200 Subject: [PATCH] Bug 14936 - Add validation for date strings to Koha::DateUtils To test: - Apply patch - prove t/DateUtils.t Bonus test: Apply patch(es) from Bug(s) that are blocked by this Bug and test as appropriate. --- Koha/DateUtils.pm | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++- t/DateUtils.t | 23 ++++++++++++++- 2 files changed, 104 insertions(+), 2 deletions(-) diff --git a/Koha/DateUtils.pm b/Koha/DateUtils.pm index 7a98120..d48af41 100644 --- a/Koha/DateUtils.pm +++ b/Koha/DateUtils.pm @@ -26,7 +26,7 @@ use base 'Exporter'; use version; our $VERSION = qv('1.0.0'); our @EXPORT = ( - qw( dt_from_string output_pref format_sqldatetime ) + qw( dt_from_string output_pref format_sqldatetime is_formatted_date_string ) ); =head1 DateUtils @@ -273,4 +273,85 @@ sub format_sqldatetime { return q{}; } + +=head2 is_formatted_date_string + +$dt = is_formatted_date_string($date_string, [$format]); + +Passed a date string returns 1 if it is formatted following fhe format passed +(default to the system preferences, otherwise 0. If the date string is empty +or starts with 0000-0, 0 is returned. + +=cut + +sub is_formatted_date_string { + my ( $date_string, $date_format ) = @_; + + return 0 if $date_string and $date_string =~ m|^0000-0|; + return 0 unless $date_string; + + $date_format = C4::Context->preference('dateformat') unless $date_format; + + my $regex; + + if ( $date_format eq 'metric' ) { + # metric format is "dd/mm/yyyy[ hh:mm:ss]" + $regex = qr| + (?\d{2}) + / + (?\d{2}) + / + (?\d{4}) + |xms; + } + elsif ( $date_format eq 'us' ) { + # us format is "mm/dd/yyyy[ hh:mm:ss]" + $regex = qr| + (?\d{2}) + / + (?\d{2}) + / + (?\d{4}) + |xms; + } + elsif ( $date_format eq 'iso' or $date_format eq 'sql' ) { + # iso or sql format are yyyy-dd-mm[ hh:mm:ss]"; + $regex = qr| + (?\d{4}) + - + (?\d{2}) + - + (?\d{2}) + |xms; + } + else { + warn "Invalid dateformat parameter ($date_format)"; + return 0; + } + + # Add the faculative time part [hh:mm[:ss]] + my $time_re .= qr| + ( + \s* + (?\d{2}) + : + (?\d{2}) + ( + : + (?\d{2}) + )? + )? + |xms; + $regex .= $time_re; + + if ( $date_string =~ $regex ) { + return 1; + } + else { + return 0; + } + + return 0; +} + 1; diff --git a/t/DateUtils.t b/t/DateUtils.t index 4f7c773..454d4fe 100755 --- a/t/DateUtils.t +++ b/t/DateUtils.t @@ -3,7 +3,7 @@ use DateTime; use DateTime::TimeZone; use C4::Context; -use Test::More tests => 55; +use Test::More tests => 68; use Test::MockModule; use Time::HiRes qw/ gettimeofday /; use t::lib::Mocks; @@ -215,3 +215,24 @@ is( output_pref( { dt => $dt, dateonly => 1 } ), '01/01/1900', 'dt_from_string s # fallback $dt = dt_from_string('2015-01-31 01:02:03'); is( output_pref( {dt => $dt} ), '31/01/2015 01:02', 'dt_from_string should fallback to sql format' ); + +# test formatting of date strings + +is( is_formatted_date_string('0000-00-00', 'iso'), 0, 'is_formatted_date_string should return 0 for 0000-00-00'); +is( is_formatted_date_string('', 'iso'), 0, 'is_formatted_date_string should return 0 for empty string'); +is( is_formatted_date_string('baddate', 'iso'), 0, 'is_formatted_date_string should return 0 for baddate'); +is( is_formatted_date_string('11/06/1955', 'badformat'), 0, 'is_formatted_date_string should return 0 for unknown format'); + +is( is_formatted_date_string('1955-06-11', 'iso'), 1, 'is_formatted_date_string should return 1 for 1955/06/11 iso'); +is( is_formatted_date_string('1955-06-11 12:00', 'iso'), 1, 'is_formatted_date_string should return 1 for 1955/06/11 12:00 iso'); +is( is_formatted_date_string('11/06/1955', 'iso'), 0, 'is_formatted_date_string should return 0 for 11/06/1955 iso'); + +is( is_formatted_date_string('06/11/1955', 'us'), 1, 'is_formatted_date_string should return 1 for 06/11/1955 us'); +is (is_formatted_date_string('06/11/1955 12:00', 'us'), 1, 'is_formatted_date_string should return 1 for 06/11/1955 12:00 us'); +is( is_formatted_date_string('06-11-1955', 'us'), 0, 'is_formatted_date_string should return 0 for 06-11-1955 us'); + +is( is_formatted_date_string('11/06/1955', 'metric'), 1, 'is_formatted_date_string should return 1 for 06/11/1955 metric'); +is (is_formatted_date_string('11/06/1955 12:00', 'metric'), 1, 'is_formatted_date_string should return 1 for 11/06/1955 12:00 us'); +is( is_formatted_date_string('06-11-1955', 'metric'), 0, 'is_formatted_date_string should return 0 for 06-11-1955 metric'); + + -- 1.7.10.4