File Coverage

blib/lib/Class/CGI/DateTime.pm
Criterion Covered Total %
statement 43 43 100.0
branch 8 8 100.0
condition n/a
subroutine 7 7 100.0
pod 2 3 66.6
total 60 61 98.3


line stmt bran cond sub pod time code
1             package Class::CGI::DateTime;
2              
3 3     3   32378 use base 'Class::CGI::Handler';
  3         8  
  3         2768  
4              
5 3     3   8770 use warnings;
  3         8  
  3         63  
6 3     3   17 use strict;
  3         11  
  3         77  
7 3     3   4126 use DateTime;
  3         638946  
  3         1667  
8              
9             =head1 NAME
10              
11             Class::CGI::DateTime - Fetch DateTime objects directly from your forms.
12              
13             =head1 VERSION
14              
15             Version 0.02
16              
17             =cut
18              
19             our $VERSION = '0.02';
20              
21             =head1 SYNOPSIS
22              
23             use Class::CGI
24             handlers => {
25             date => 'Class::CGI::DateTime',
26             order_date => 'Class::CGI::DateTime',
27             };
28             my $cgi = Class::CGI->new;
29             my $date = $cgi->param('date');
30             my $order_date = $cgi->param('order_date');
31              
32             if ( my %errors = $cgi->errors ) { ... }
33              
34             =head1 DESCRIPTION
35              
36             A common problem with Web programming is handling dates correctly. This
37             C handler attempts to do that for you in a standard way by
38             allowing you to have separate day, month and year dropdowns but request a
39             "date" parameter and get the correct object back, safely validated and
40             untainted.
41              
42             Multiple dates may be used in a single form and you can even specify hours,
43             minutes, timezones, and so on.
44              
45             =head2 Basic Usage
46              
47             If you have a form with C<<
48             C, you can fetch these into a C object with this:
49              
50             use Class::CGI
51             handlers => {
52             date => 'Class::CGI::DateTime',
53             };
54             my $cgi = Class::CGI->new;
55             my $date = $cgi->param('date');
56              
57             The value of each parameter should correspond to allowed values for that
58             parameter to the C constructor.
59              
60             =head2 Multiple dates in a form
61              
62             If you need more than one date object embedded in a form, additional date
63             objects may be specified by prefixing the form parameter names with a unique
64             identifier followed by a dot ("."). For example, to fetch a date and an order
65             date, you can do the following:
66              
67             use Class::CGI
68             handlers => {
69             date => 'Class::CGI::DateTime',
70             order_date => 'Class::CGI::DateTime',
71             };
72             my $cgi = Class::CGI->new;
73             my $date = $cgi->param('date');
74             my $order_date = $cgi->param('order_date');
75              
76             The C parameter will be created from the C, C and C
77             parameters in the C object. The C parameter will
78             be created from the C, C and
79             C parameters.
80              
81             =head2 Different parameters
82              
83             $cgi->args( date => { params => [qw/ day hour minute /] } );
84              
85             You cannot change the parameter names (e.g., no changing "day" to "jour" or
86             something like that), but you can specify additional parameters which the
87             C constructor expects. Each parameter's value must correspond to
88             the allowed values for the C object. You do this by setting the
89             requested parameters in C's C method. The key is the date
90             parameter you wish to specify the arguments for and the value should be a
91             hashref with a key of "params" and a value being an array reference specifying
92             the names of the parameters desired.
93              
94             For example, if your HTML form has day, month, year and timezone, you might do
95             this:
96              
97             use Class::CGI
98             handlers => {
99             date => 'Class::CGI::DateTime',
100             };
101             my $cgi = Class::CGI->new;
102             $cgi->args(
103             date => { params => [qw/ day month year time_zone /] }
104             );
105             my $date = $cgi->param('date');
106              
107             The allowed parameter names, as specified from the C documentation,
108             are:
109              
110             =over 4
111              
112             =item * year
113              
114             =item * month
115              
116             =item * day
117              
118             =item * hour
119              
120             =item * minute
121              
122             =item * second
123              
124             =item * nanosecond
125              
126             =item * time_zone
127              
128             =back
129              
130             =head2 Error handling
131              
132             As usual, any errors reported by C will be in the
133             C C method. However, the validation errors reported by
134             the C object are generally aimed at programmers, not users of your
135             software. Thus, you'll want to provide more user friendly error messages.
136             For example:
137              
138             if ( my %error_for = $cgi->errors ) {
139             if ( exists $error_for{order_date} ) {
140             $error_for{order_date} = "You must enter a valid order date";
141             }
142             }
143              
144             If a date is required, it's easy to handle this:
145              
146             use Class::CGI
147             handlers => {
148             date => 'Class::CGI::DateTime',
149             order_date => 'Class::CGI::DateTime',
150             };
151             my $cgi = Class::CGI->new;
152             $cgi->required( qw/date order_date/ );
153             my $date = $cgi->param('date');
154             my $order_date = $cgi->param('order_date');
155              
156             C will not create a date object if any of the required
157             components (day, month, year and so on) are missing. Further, a descriptive
158             error message will be set.
159              
160             Also note that at the present time, C only ensures that
161             we can create a valid C object. Application-specific validation
162             (such as ensuring the date is in the future) belongs in your application and
163             should be handled there.
164              
165             =cut
166              
167             sub handle {
168 7     7 1 11661 my $self = shift;
169 7         24 my $cgi = $self->cgi;
170 7         43 my $param = $self->param;
171              
172 7         35 my @params = $self->components;
173              
174             # original param name and param value
175 7         27 my %args = map { /([[:word:]]+)$/; $1, $cgi->raw_param($_) } @params;
  36         529  
  36         103  
176              
177             # untaint them puppies
178 7         145 while ( my ( $arg, $value ) = each %args ) {
179 36 100       66 if ( 'time_zone' eq $arg ) {
180 3         11 $value =~ /^(floating|local|\+[[:digit:]]+|[[:word:]]+\/[[:word:]]+)$/;
181 3         17 $args{$arg} = $1;
182             }
183             else {
184 33         78 $value =~ /^(\d+)$/;
185 33         142 $args{$arg} = $1;
186             }
187             }
188 7         10 my $datetime;
189            
190 7         11 eval { $datetime = DateTime->new(%args) };
  7         46  
191              
192 7 100       21311 if (my $error = $@) {
193 1         4 $cgi->add_error( $param, 'You must supply a valid date' );
194             }
195 7         106 return $datetime;
196             }
197              
198             sub components {
199 9     9 0 23 my $self = shift;
200 9         26 my $cgi = $self->cgi;
201 9         38 my $param = $self->param;
202              
203 9         43 my $requested_params = $cgi->args($param);
204 3         13 my @params = $requested_params
205 9 100       102 ? @{ $requested_params->{params} }
206             : qw(day month year);
207              
208 9 100       28 if ( 'date' ne $param ) {
209 3         6 @params = map {"$param.$_"} @params;
  14         36  
210             }
211 9         54 return @params;
212             }
213              
214             sub has_param {
215 2     2 1 4806 my $self = shift;
216 2         7 return $self->has_virtual_param( $self->param, $self->components );
217             }
218              
219             =head1 AUTHOR
220              
221             Curtis "Ovid" Poe, C<< >>
222              
223             =head1 BUGS
224              
225             Please report any bugs or feature requests to
226             C, or through the web interface at
227             L.
228             I will be notified, and then you'll automatically be notified of progress on
229             your bug as I make changes.
230              
231             =head1 SEE ALSO
232              
233             =over 4
234              
235             =item *
236             DateTime - A date and time object
237              
238             =back
239              
240             =head1 ACKNOWLEDGEMENTS
241              
242             Adam Kennedy (Alias): for suggesting a better interface.
243              
244             =head1 COPYRIGHT & LICENSE
245              
246             Copyright 2006 Curtis "Ovid" Poe, all rights reserved.
247              
248             This program is free software; you can redistribute it and/or modify it
249             under the same terms as Perl itself.
250              
251             =cut
252              
253             1;