File Coverage

blib/lib/Apache/Voodoo/Validate/date.pm
Criterion Covered Total %
statement 50 59 84.7
branch 24 36 66.6
condition 21 48 43.7
subroutine 7 7 100.0
pod 0 2 0.0
total 102 152 67.1


line stmt bran cond sub pod time code
1             package Apache::Voodoo::Validate::date;
2              
3             $VERSION = "3.0200";
4              
5 2     2   12 use strict;
  2         4  
  2         73  
6 2     2   12 use warnings;
  2         3  
  2         57  
7              
8 2     2   10 use base("Apache::Voodoo::Validate::Plugin");
  2         3  
  2         1989  
9              
10             sub config {
11 5     5 0 9 my ($self,$c) = @_;
12 5         5 my @e;
13              
14 5 100       12 if (defined($c->{valid})) {
15 4 50       19 if ($c->{valid} =~ /^(past|future)$/ ) {
    0          
16 4         9 $self->{valid} = $c->{valid};
17             }
18             elsif (ref($c->{valid}) ne "CODE") {
19 0         0 push(@e,"'valid' must be either 'past','future', or a subroutine reference");
20             }
21             }
22              
23 5 100       12 if (defined($c->{now})) {
24 2 50       6 if (ref($c->{now}) eq "CODE") {
25 2         4 $self->{now} = $c->{now};
26             }
27             else {
28 0         0 push(@e,"'now' must be a subroutine reference");
29             }
30             }
31             else {
32 3         10 $self->{now} = \&_default_now;
33             }
34              
35 5 50       11 if (defined($c->{parser})) {
36 0 0       0 if (ref($c->{parser}) eq "CODE") {
37 0         0 $self->{parser} = $c->{parser};
38             }
39             else {
40 0         0 push(@e,"'parser' must be a subroutine reference");
41             }
42             }
43             else {
44 5         9 $self->{parser} = \&_default_parser;
45             }
46              
47 5         15 return @e;
48             }
49              
50             sub valid {
51 12     12 0 16 my ($self,$v) = @_;
52              
53 12         13 my $e;
54 12         47 my ($y,$m,$d) = $self->{parser}->($v);
55              
56 12 100 66     158 if (defined($y) &&
      66        
      33        
      33        
      33        
57             defined($m) &&
58             defined($d) &&
59             $y =~ /^\d+$/ &&
60             $m =~ /^\d+$/ &&
61             $d =~ /^\d+$/) {
62              
63 10         38 $v = sprintf("%04d-%02d-%02d",$y,$m,$d);
64              
65 10 100       27 if (defined($self->{'valid'})) { # supresses warnings.
66 8 100 100     40 if ($self->{'valid'} eq "past" && $v gt $self->{now}->()) {
    100 100        
67 1         6 $e = 'PAST';
68             }
69             elsif ($self->{'valid'} eq "future" && $v le $self->{now}->()) {
70 1         6 $e = 'FUTURE';
71             }
72             }
73             }
74             else {
75 2         4 $e = 'BAD';
76             }
77              
78 12         61 return $v,$e;
79             }
80              
81             sub _default_now {
82 2     2   233 my @tp = localtime();
83 2         20 return sprintf("%04d-%02d-%02d",$tp[5]+1900,$tp[4]+1,$tp[3]);
84             }
85              
86             sub _default_parser {
87 12     12   18 my $date = shift;
88              
89             # Number of days in each month
90 12         84 my %md = (1 => 31,
91             2 => 29,
92             3 => 31,
93             4 => 30,
94             5 => 31,
95             6 => 30,
96             7 => 31,
97             8 => 31,
98             9 => 30,
99             10 => 31,
100             11 => 30,
101             12 => 31);
102              
103             # Split the date up into month day year
104 12         13 my ($m,$d,$y);
105              
106 12 100       53 if ($date =~ /^\d?\d\/\d?\d\/\d{4}$/) {
    100          
107 9         26 ($m,$d,$y) = split("/",$date, 3);
108             }
109             elsif ($date =~ /^\d{4}-\d?\d-\d?\d$/) {
110 2         8 ($y,$m,$d) = split("-",$date, 3);
111             }
112             else {
113 1         3 return undef;
114             }
115              
116             #Strip off any leading 0s
117 11         25 $m *= 1;
118 11         11 $d *= 1;
119 11         14 $y *= 1;
120              
121             # If the month isn't within a valid range return
122 11 100 33     192 if ($m !~ /^\d+$/ || $m < 1 || $m > 12) {
      66        
123 1         4 return undef;
124             }
125              
126             # Check to see if the day is valid on leap years
127 10 50 33     22 if ($m == 2 && $d == 29) {
128 0 0 0     0 unless (($y%4 == 0 && $y%100 != 0) || $y%400 == 0){
      0        
129 0         0 return undef;
130             }
131             }
132              
133             # If the day isn't within a valid range return
134 10 50 33     85 if ($d !~ /^\d+$/ || $d < 1 || $d > $md{$m}) {
      33        
135 0         0 return undef;
136             }
137              
138             # make sure the year is four digits
139 10 50 33     76 if ($y !~ /^\d+$/ || $y < 1000 || $y > 9999) {
      33        
140 0         0 return undef;
141             }
142              
143 10         39 return $y,$m,$d;
144             }
145              
146             1;
147              
148             ################################################################################
149             # Copyright (c) 2005-2010 Steven Edwards (maverick@smurfbane.org).
150             # All rights reserved.
151             #
152             # You may use and distribute Apache::Voodoo under the terms described in the
153             # LICENSE file include in this package. The summary is it's a legalese version
154             # of the Artistic License :)
155             #
156             ################################################################################