File Coverage

blib/lib/Rose/HTML/Form/Field/DateTime.pm
Criterion Covered Total %
statement 59 61 96.7
branch 16 20 80.0
condition 5 6 83.3
subroutine 15 15 100.0
pod 4 6 66.6
total 99 108 91.6


line stmt bran cond sub pod time code
1              
2             use strict;
3 6     6   42  
  6         12  
  6         177  
4             use Rose::HTML::Object::Errors qw(:field :date);
5 6     6   365  
  6         10  
  6         43  
6             use Rose::DateTime::Util();
7 6     6   448 use Rose::DateTime::Parser;
  6         468199  
  6         119  
8 6     6   2338  
  6         9189  
  6         151  
9             use base 'Rose::HTML::Form::Field::Text';
10 6     6   35  
  6         12  
  6         1571  
11             our $VERSION = '0.606';
12              
13             use Rose::Object::MakeMethods::Generic
14             (
15             'scalar --get_set_init' =>
16 6         34 [
17             'date_parser',
18             'output_format',
19             ]
20             );
21 6     6   37  
  6         10  
22             __PACKAGE__->add_required_html_attr(
23             {
24             size => 25,
25             });
26              
27              
28 18     18 0 223 {
29             my($self) = shift;
30              
31             my $parser = $self->date_parser;
32 4     4 1 10  
33             return $parser->time_zone(@_) if($parser->can('time_zone'));
34 4         14 return undef;
35             }
36 4 50       42  
37 0         0 {
38             my($self, $date) = @_;
39              
40             return undef unless(ref $date || (defined $date && length $date));
41              
42 348     348 1 602 my $dt;
43              
44 348 100 66     1316 local $@;
      100        
45             eval { $dt = $self->date_parser->parse_datetime($date) };
46 178         239  
47             return $dt;
48 178         229 }
49 178         287  
  178         434  
50              
51 178         77649 {
52             my($self, $date) = @_;
53             return $self->input_value_filtered unless($date);
54 5     5 0 44 return Rose::DateTime::Util::format_date($date, $self->output_format);
55             }
56              
57             {
58 32     32 1 60 my($self) = shift;
59 32 100       106  
60 23         133 no warnings 'uninitialized';
61             if($self->input_value !~ /\S/)
62             {
63             my $ok = $self->SUPER::validate(@_);
64             return $ok unless($ok);
65 33     33 1 61 }
66              
67 6     6   1663 my $date = $self->internal_value;
  6         11  
  6         811  
68 33 100       79  
69             if(UNIVERSAL::isa($date, 'DateTime'))
70 9         54 {
71 9 50       23 return $self->validate_with_validator($date) if($self->validator);
72             return 1;
73             }
74 33         142  
75             if($self->has_partial_value)
76 33 100       132 {
77             $self->add_error_id(FIELD_PARTIAL_VALUE);
78 17 50       67 return 0;
79 17         66 }
80              
81             my $input = $self->input_value_filtered;
82 16 100       45 no warnings 'uninitialized';
83             return 1 unless(length $input);
84 1         6  
85 1         5 $date = $self->date_parser->parse_datetime($input);
86              
87             unless(defined $date)
88 15         112 {
89 6     6   37 # XXX: Parser errors ar English-only right now...
  6         11  
  6         647  
90 15 100       77 # XXX: ...but it produces some horribly ugly errors.
91             #if($self->locale eq 'en')
92 7         18 #{
93             # $self->add_error($self->date_parser->error)
94 7 50       255 # if($self->date_parser->can('error'));
95             #}
96             #else
97             #{
98             $self->add_error_id(DATE_INVALID);
99             #}
100              
101             return 0;
102             }
103              
104             die "This should never be reached!";
105 7         61 }
106              
107             if(__PACKAGE__->localizer->auto_load_messages)
108 7         28 {
109             __PACKAGE__->localizer->load_all_messages;
110             }
111 0            
112             use utf8; # The __DATA__ section contains UTF-8 text
113              
114             1;
115              
116              
117             [% LOCALE en %]
118              
119 6     6   36 DATE_INVALID = "Invalid date."
  6         11  
  6         30  
120              
121             [% LOCALE de %]
122              
123             DATE_INVALID = "Ungültiges Datum."
124              
125             [% LOCALE fr %]
126              
127             DATE_INVALID = "Date invalide."
128              
129             [% LOCALE bg %]
130              
131             DATE_INVALID = "Невалидна дата."
132              
133             __END__
134              
135             =head1 NAME
136              
137             Rose::HTML::Form::Field::DateTime - Text field that inflates valid dates and times into L<DateTime> objects.
138              
139             =head1 SYNOPSIS
140              
141             $field =
142             Rose::HTML::Form::Field::DateTime->new(
143             label => 'Date',
144             name => 'date',
145             default => '12/31/2002 8pm');
146              
147             print $field->internal_value; # "2002-12-31T20:00:00"
148             print $field->output_value; # "2002-12-31 08:00:00 PM"
149              
150             $field->input_value('blah');
151              
152             # "Could not parse date: blah"
153             $field->validate or warn $field->error;
154              
155             $field->input_value('4/30/1980 5:30 p.m.');
156              
157             $dt = $field->internal_value; # DateTime object
158              
159             print $dt->hour; # 17
160             print $dt->day_name; # Wednesday
161              
162             print $field->html;
163             ...
164              
165             =head1 DESCRIPTION
166              
167             L<Rose::HTML::Form::Field::DateTime> is a subclass of L<Rose::HTML::Form::Field::Text> that allows only valid dates as input, which it then coerces to L<DateTime> objects. It overrides the L<validate()|Rose::HTML::Form::Field/validate>, L<inflate_value()|Rose::HTML::Form::Field/inflate_value>, and L<deflate_value()|Rose::HTML::Form::Field/deflate_value> methods of its parent class.
168              
169             Valid input is converted to the format "YYYY-MM-DD HH:MM:SS AM/PM" on output.
170              
171             =head1 OBJECT METHODS
172              
173             =over 4
174              
175             =item B<date_parser [PARSER]>
176              
177             Get or set the date parser object. This object must include a C<parse_datetime()> method that takes a single string as an argument and returns a L<DateTime> object, or undef if parsing fails.
178              
179             If the parser object has an C<error()> method, it will be called to set the error message after a failed parsing attempt.
180              
181             The parser object defaults to L<Rose::DateTime::Parser-E<gt>new()|Rose::DateTime::Parser/new>.
182              
183             =item B<output_format [FORMAT]>
184              
185             Get or set the format string passed to L<Rose::DateTime::Util>'s L<format_date|Rose::DateTime::Util/format_date> function in order to generate the field's output value. Defaults to "%Y-%m-%d %I:%M:%S %p"
186              
187             =item B<time_zone [TZ]>
188              
189             If the parser object has a L<time_zone()|/time_zone> method, this method simply calls it, passing all arguments. Otherwise, undef is returned.
190              
191             =back
192              
193             =head1 SEE ALSO
194              
195             Other examples of custom fields:
196              
197             =over 4
198              
199             =item L<Rose::HTML::Form::Field::Email>
200              
201             A text field that only accepts valid email addresses.
202              
203             =item L<Rose::HTML::Form::Field::Time>
204              
205             Uses inflate/deflate to coerce input into a fixed format.
206              
207             =item L<Rose::HTML::Form::Field::DateTime::Range>
208              
209             A compound field whose internal value consists of more than one object.
210              
211             =item L<Rose::HTML::Form::Field::PhoneNumber::US::Split>
212              
213             A simple compound field that coalesces multiple subfields into a single value.
214              
215             =item L<Rose::HTML::Form::Field::DateTime::Split::MonthDayYear>
216              
217             A compound field that uses inflate/deflate convert input from multiple subfields into a L<DateTime> object.
218              
219             =item L<Rose::HTML::Form::Field::DateTime::Split::MDYHMS>
220              
221             A compound field that includes other compound fields and uses inflate/deflate convert input from multiple subfields into a L<DateTime> object.
222              
223             =back
224              
225             =head1 AUTHOR
226              
227             John C. Siracusa (siracusa@gmail.com)
228              
229             =head1 LICENSE
230              
231             Copyright (c) 2010 by John C. Siracusa. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.