File Coverage

blib/lib/Catalyst/Plugin/FormValidator/Simple.pm
Criterion Covered Total %
statement 9 35 25.7
branch 0 14 0.0
condition 0 15 0.0
subroutine 3 7 42.8
pod 0 4 0.0
total 12 75 16.0


line stmt bran cond sub pod time code
1             package Catalyst::Plugin::FormValidator::Simple;
2 1     1   51804 use strict;
  1         3  
  1         48  
3 1     1   6 use base qw/Catalyst::Plugin::FormValidator/;
  1         2  
  1         693  
4             # doesn't use parent module at all, but this is required for Catalyst::Plugin::FillInForm
5              
6 1     1   2810 use MRO::Compat;
  1         6750  
  1         867  
7             require FormValidator::Simple;
8              
9             our $VERSION = '0.15';
10              
11             sub setup {
12 0     0 0   my $self = shift;
13 0           $self->maybe::next::method(@_);
14 0           my $setting = $self->config->{validator};
15 0 0 0       my $plugins = $setting && exists $setting->{plugins}
16             ? $setting->{plugins}
17             : [];
18 0           FormValidator::Simple->import(@$plugins);
19 0 0 0       if ( $setting && exists $setting->{messages} ) {
20 0           FormValidator::Simple->set_messages( $setting->{messages} );
21             }
22 0 0 0       if ( $setting && exists $setting->{options} ) {
23 0           FormValidator::Simple->set_option( %{ $setting->{options} } );
  0            
24             }
25 0 0 0       if ( $setting && exists $setting->{message_format} ) {
26 0           FormValidator::Simple->set_message_format( $setting->{message_format} );
27             }
28 0 0 0       if ( $setting && exists $setting->{message_decode_from} ) {
29 0           FormValidator::Simple->set_message_decode_from( $setting->{message_decode_from} );
30             }
31             }
32              
33             sub prepare {
34 0     0 0   my $c = shift;
35 0           $c = $c->maybe::next::method(@_);
36 0           $c->{validator} = FormValidator::Simple->new;
37 0           return $c;
38             }
39              
40             sub form {
41 0     0 0   my $c = shift;
42 0 0         if ($_[0]) {
43 0 0         my $form = $_[1] ? [@_] : $_[0];
44 0           $c->{validator}->check($c->req, $form);
45             }
46 0           return $c->{validator}->results;
47             }
48              
49             sub set_invalid_form {
50 0     0 0   my $c = shift;
51 0           $c->{validator}->set_invalid(@_);
52 0           return $c->{validator}->results;
53             }
54              
55             1;
56             __END__
57              
58             =head1 NAME
59              
60             Catalyst::Plugin::FormValidator::Simple - Validator for Catalyst with FormValidator::Simple
61              
62             =head1 SYNOPSIS
63              
64             use Catalyst qw/FormValidator::Simple FillInForm/;
65              
66             # set option
67             MyApp->config->{validator} = {
68             plugins => ['CreditCard', 'Japanese'],
69             options => { charset => 'euc'},
70             }
71              
72             in your controller
73              
74             sub defaulti : Private {
75              
76             my ($self, $c) = @_;
77              
78             $c->form(
79             param1 => [qw/NOT_BLANK ASCII/, [qw/LENGTH 4 10/]],
80             param2 => [qw/NOT_BLANK/, [qw/JLENGTH 4 10/]],
81             mail1 => [qw/NOT_BLANK EMAIL_LOOSE/],
82             mail2 => [qw/NOT_BLANK EMAIL_LOOSE/],
83             { mail => [qw/mail1 mail2/] } => ['DUPLICATION'],
84             );
85              
86             print $c->form->valid('param1');
87              
88             if ( some condition... ) {
89              
90             $c->form(
91             other_param => [qw/NOT_INT/],
92             );
93             }
94              
95             if ( some condition... ) {
96              
97             # set your original invalid type.
98             $c->set_invalid_form( param3 => 'MY_ERROR' );
99              
100             }
101              
102             if ( $c->form->has_error ) {
103            
104             if ( $c->form->missing('param1') ) {
105             ...
106             }
107              
108             if ( $c->form->invalid( param1 => 'ASCII' ) ) {
109             ...
110             }
111              
112             if ( $c->form->invalid( param3 => 'MY_ERROR' ) ) {
113             ...
114             }
115              
116             }
117             }
118              
119             =head1 DESCRIPTION
120              
121             This plugin allows you to validate request parameters with FormValidator::Simple.
122             See L<FormValidator::Simple> for more information.
123              
124             This behaves like as L<Catalyst::Plugin::FormValidator>.
125              
126             =head1 CONFIGURATION
127              
128             set config with 'validator' key.
129              
130             MyApp->config->{validator} = { ... };
131              
132             or
133              
134             MyApp->config(
135             validator => { ... },
136             );
137              
138             =head2 PLUGINS
139              
140             If you want to use some plugins for FormValidator::Simple, you can set like following.
141              
142             MyApp->config(
143             validator => {
144             plugins => [qw/Japanese CreditCard DBIC::Unique/],
145             },
146             );
147              
148             In this example, FormValidator::Simple::Plugin::Japanese, FormValidator::Simple::Plugin::CreditCard,
149             and FormValidator::Simple::Plugin::DBIC::Unique are loaded.
150              
151             =head2 OPTIONS
152              
153             When you set some options needed by specific validations, do like this.
154              
155             MyApp->config(
156             validator => {
157             plugins => [qw/Japanese CreditCard DBIC::Unique/],
158             options => {
159             charset => 'euc',
160             dbic_base_class => 'MyApp::Model::DBIC',
161             },
162             },
163             );
164              
165             'charset' is necessary for Plugin::Japanese, and 'dbic_cbase_class' is used in Plugin::DBIC::Unique.
166              
167             =head1 VALIDATION
168              
169             use 'form' method, see L<FormValidator::Simple> in detail.
170              
171             sub do_add : Local {
172             my ( $self, $c ) = @_;
173              
174             # execute validation.
175             $c->form(
176             name => [qw/NOT_BLANK ASCII/, [qw/LENGTH 0 20/] ],
177             email => [qw/NOT_BLANK EMAIL_LOOSE/, [qw/LENGTH 0 20/] ],
178             { unique => [qw/name email/] } => [qw/DBIC_UNIQUE User name email/],
179             );
180              
181             if ( ... ) {
182              
183             # execute validation one more time in specific condition.
184             $c->form(
185             ...
186             );
187              
188             }
189              
190             # See Catalyst::Plugin::RequestToken for '$c->validate_token'
191             if ( $c->validate_token ) {
192              
193             # you can force to set invalid data.
194             $c->set_invalid_form( token => 'TOKEN' );
195              
196             }
197              
198             # check result.
199             # you can pick up result-object with 'form' method
200              
201             my $result = $c->form;
202              
203             if ( $result->has_error ) {
204              
205             # this is same as
206             # if ( $result->has_missing or $result->has_invalid )
207              
208             $c->detach('add');
209              
210             }
211              
212             }
213              
214             =head1 HANDLING SUCCESSFUL RESULT
215              
216             After it passes all validations, you may wanna put input-data into database.
217             It's a elegant way to use [ L<Class::DBI> and L<Class::DBI::FromForm> ] or [ L<DBIx::Class> and L<DBIx::Class::WebForm> ].
218              
219             sub do_add : Local {
220             my ( $self, $c ) = @_;
221              
222             $c->form(
223             name => [qw/NOT_BLANK/],
224             email => [qw/NOT_BLANK/],
225             );
226              
227             my $result = $c->form;
228             if ( $result->has_error ) {
229             $c->detach('add');
230             }
231              
232             my $user = MyProj::Model::DBIC::User->create_from_form($result);
233            
234             # this behaves like this...
235             # MyProj::Model::DBIC::User->create({
236             # name => $result->valid('name'),
237             # email => $result->valid('email'),
238             # });
239             #
240             # if the key exists as the table's column, set the value with 'valid'
241             }
242              
243             Here, I explain about 'valid' method. If the value indicated with key-name passes validations,
244             You can get the data with 'valid',
245              
246             my $result = $c->form(
247             name => [qw/NOT_BLANK/],
248             email => [qw/NOT_BLANK/],
249             );
250              
251             print $result->valid('name');
252              
253             print $result->valid('email');
254              
255             But, this is for only single key validation normally.
256              
257             my $result = $c->form(
258             name => [qw/NOT_BLANK/], # single key validation
259             { mail_dup => [qw/email email2/] } => ['DUPLICATION'] # multiple keys one
260             );
261              
262             print $result->valid('name'); # print out the value of 'name'
263              
264             print $result->valid('mail_dup'); # no value.
265              
266             There are exceptions. These are 'DATETIME', 'DATE'.
267              
268             my $result = $c->form(
269             { created_on => [qw/created_year created_month created_day/] }
270             =>
271             [qw/DATETIME/],
272             );
273              
274             print $result->valid('created_on'); #print out datetime string like "2005-11-23 00:00:00".
275              
276             If you set some class around datetime in configuration. It returns object of the class you indicate.
277             You can choose from L<Time::Piece> and L<DateTime>. For example...
278              
279             MyApp->config(
280             validator => {
281             plugins => [...],
282             options => {
283             datetime_class => 'Time::Piece',
284             },
285             },
286             );
287              
288             or
289              
290             MyApp->config(
291             validator => {
292             plugins => [...],
293             options => {
294             datetime_class => 'DateTime',
295             time_zone => 'Asia/Tokyo',
296             },
297             },
298             );
299              
300             then
301              
302             my $result = $c->form(
303             { created_on => [qw/created_year created_month created_day/] }
304             =>
305             [qw/DATETIME/],
306             );
307              
308             my $dt = $result->valid('created_on');
309              
310             print $dt->ymd;
311              
312             MyProj::Model::CDBI::User->create_from_form($result);
313              
314             This may be useful when you define 'has_a' relation for datetime columns.
315             For example, in your table class inherits 'Class::DBI'
316              
317             __PACKAGE__->has_a( created_on => 'DateTime',
318             inflate => ...,
319             deflate => ...,
320             );
321              
322             And see also L<Class::DBI::Plugin::TimePiece>, L<Class::DBI::Plugin::DateTime>.
323              
324             =head1 MESSAGE HANDLING
325              
326             in template file, you can handle it in detail.
327              
328             [% IF c.form.has_error %]
329             <p>Input Error</p>
330             <ul>
331             [% IF c.form.missing('name') %]
332             <li>input name!</li>
333             [% END %]
334             [% IF c.form.invalid('name') %]
335             <li>name is wrong</li>
336             [% END %]
337             [% IF c.form.invalid('name', 'ASCII') %]
338             <li>input name with ascii code.</li>
339             [% END %]
340             [% IF c.form.invalid('name', 'LENGTH') %]
341             <li>wrong length for name.</li>
342             [% END %]
343             </ul>
344             [% END %]
345              
346             or, make it more easy.
347              
348             [% IF c.form.has_error %]
349             <p>Input Error</p>
350             <ul>
351             [% FOREACH key IN c.form.error %]
352             [% FOREACH type IN c.form.error(key) %]
353             <li>Invalid: [% key %] - [% type %]</li>
354             [% END %]
355             [% END %]
356             </li>
357             [% END %]
358              
359             And you can also use messages configuration as hash reference.
360              
361             MyApp->config(
362             validator => {
363             plugins => [...],
364             messages => {
365             user => {
366             name => {
367             NOT_BLANK => 'Input name!',
368             ASCII => 'Input name with ascii code!',
369             },
370             email => {
371             DEFAULT => 'email is wrong.!',
372             NOT_BLANK => 'input email.!'
373             },
374             },
375             company => {
376             name => {
377             NOT_BLANK => 'Input name!',
378             },
379             },
380             },
381             },
382             );
383              
384             or YAML file. set file name
385              
386             MyApp->config(
387             validator => {
388             plugins => [...],
389             messages => 'conf/messages.yml',
390             },
391             );
392              
393             and prepare yaml file like following,
394              
395             DEFAULT:
396             name:
397             DEFAULT: name is invalid
398             user:
399             name:
400             NOT_BLANK: Input name!
401             ASCII: Input name with ascii code!
402             email:
403             DEFAULT: Email is wrong!
404             NOT_BLANK: Input email!
405             company:
406             name:
407             NOT_BLANK: Input name!
408              
409             the format is...
410              
411             Action1_Name:
412             Key1_Name:
413             Validation1_Name: Message
414             Validation2_Name: Message
415             Key2_Name:
416             Validation1_Name: Message
417             Action2_Name:
418             Key1_Name:
419             ...
420            
421             After messages configuration, call messages() method from result-object.
422             and set action-name as argument.
423              
424             [% IF c.form.has_error %]
425             <ul>
426             [% FOREACH message IN c.form.messages('user') %]
427             <li>[% message %]</li>
428             [% END %]
429             </ul>
430             [% END %]
431              
432             you can set each message format
433              
434             MyApp->config(
435             validator => {
436             messages => 'messages.yml',
437             message_format => '<p>%s</p>'
438             },
439             );
440              
441             [% IF c.form.has_error %]
442             [% c.form.messages('user').join("\n") %]
443             [% END %]
444              
445             =head1 SEE ALSO
446              
447             L<FormValidator::Simple>
448              
449             L<Catalyst>
450              
451             =head1 AUTHOR
452              
453             Lyo Kato E<lt>lyo.kato@gmail.comE<gt>
454              
455             =head1 COPYRIGHT AND LICENSE
456              
457             Copyright(C) 2005 by Lyo Kato
458              
459             This library is free software; you can redistribute it and/or
460             modify it under the same terms as Perl itself.
461              
462             =cut
463