blib/lib/FormValidator/Simple.pm | |||
---|---|---|---|
Criterion | Covered | Total | % |
statement | 105 | 110 | 95.4 |
branch | 20 | 26 | 76.9 |
condition | 9 | 19 | 47.3 |
subroutine | 23 | 23 | 100.0 |
pod | 1 | 8 | 12.5 |
total | 158 | 186 | 84.9 |
line | stmt | bran | cond | sub | pod | time | code |
---|---|---|---|---|---|---|---|
1 | package FormValidator::Simple; | ||||||
2 | 22 | 22 | 1053661 | use strict; | |||
22 | 53 | ||||||
22 | 954 | ||||||
3 | 22 | 22 | 125 | use base qw/Class::Accessor::Fast Class::Data::Inheritable Class::Data::Accessor/; | |||
22 | 39 | ||||||
22 | 22938 | ||||||
4 | 22 | 22 | 239782 | use Class::Inspector; | |||
22 | 115266 | ||||||
22 | 967 | ||||||
5 | 22 | 22 | 25233 | use UNIVERSAL::require; | |||
22 | 60138 | ||||||
22 | 953 | ||||||
6 | 22 | 22 | 806 | use Scalar::Util qw/blessed/; | |||
22 | 46 | ||||||
22 | 2596 | ||||||
7 | 22 | 22 | 21720 | use FormValidator::Simple::Results; | |||
22 | 89 | ||||||
22 | 219 | ||||||
8 | 22 | 22 | 869 | use FormValidator::Simple::Exception; | |||
22 | 47 | ||||||
22 | 352 | ||||||
9 | 22 | 22 | 15806 | use FormValidator::Simple::Data; | |||
22 | 64 | ||||||
22 | 290 | ||||||
10 | 22 | 22 | 14287 | use FormValidator::Simple::Profile; | |||
22 | 130 | ||||||
22 | 300 | ||||||
11 | 22 | 22 | 717 | use FormValidator::Simple::Validator; | |||
22 | 46 | ||||||
22 | 120 | ||||||
12 | 22 | 22 | 563 | use FormValidator::Simple::Constants; | |||
22 | 46 | ||||||
22 | 1311 | ||||||
13 | 22 | 22 | 15990 | use FormValidator::Simple::Messages; | |||
22 | 78 | ||||||
22 | 260 | ||||||
14 | |||||||
15 | our $VERSION = '0.29'; | ||||||
16 | |||||||
17 | __PACKAGE__->mk_classaccessors(qw/data prof results/); | ||||||
18 | __PACKAGE__->mk_classaccessor( messages => FormValidator::Simple::Messages->new ); | ||||||
19 | |||||||
20 | sub import { | ||||||
21 | 22 | 22 | 233 | my $class = shift; | |||
22 | 22 | 301 | foreach my $plugin (@_) { | ||||
23 | 2 | 4 | my $plugin_class; | ||||
24 | 2 | 100 | 12 | if ($plugin =~ /^\+(.*)/) { | |||
25 | 1 | 4 | $plugin_class = $1; | ||||
26 | } else { | ||||||
27 | 1 | 5 | $plugin_class = "FormValidator::Simple::Plugin::$plugin"; | ||||
28 | } | ||||||
29 | 2 | 10 | $class->load_plugin($plugin_class); | ||||
30 | } | ||||||
31 | } | ||||||
32 | |||||||
33 | sub load_plugin { | ||||||
34 | 2 | 2 | 0 | 6 | my ($proto, $plugin) = @_; | ||
35 | 2 | 33 | 14 | my $class = ref $proto || $proto; | |||
36 | 2 | 50 | 18 | unless (Class::Inspector->installed($plugin)) { | |||
37 | 0 | 0 | FormValidator::Simple::Exception->throw( | ||||
38 | qq/$plugin isn't installed./ | ||||||
39 | ); | ||||||
40 | } | ||||||
41 | 2 | 206 | $plugin->require; | ||||
42 | 2 | 50 | 392 | if ($@) { | |||
43 | 0 | 0 | FormValidator::Simple::Exception->throw( | ||||
44 | qq/Couldn't require "$plugin", "$@"./ | ||||||
45 | ); | ||||||
46 | } | ||||||
47 | { | ||||||
48 | 22 | 22 | 7759 | no strict 'refs'; | |||
22 | 51 | ||||||
22 | 31626 | ||||||
2 | 4 | ||||||
49 | 2 | 43 | push @FormValidator::Simple::Validator::ISA, $plugin; | ||||
50 | } | ||||||
51 | } | ||||||
52 | |||||||
53 | sub set_option { | ||||||
54 | 56 | 56 | 0 | 112 | my $class = shift; | ||
55 | 56 | 369 | while ( my ($key, $val) = splice @_, 0, 2 ) { | ||||
56 | 3 | 31 | FormValidator::Simple::Validator->options->{$key} = $val; | ||||
57 | } | ||||||
58 | } | ||||||
59 | |||||||
60 | sub set_messages { | ||||||
61 | 4 | 4 | 0 | 662 | my ($proto, $file) = @_; | ||
62 | 4 | 66 | 30 | my $class = ref $proto || $proto; | |||
63 | 4 | 100 | 30 | if (blessed $proto) { | |||
64 | 1 | 8 | $proto->messages(FormValidator::Simple::Messages->new)->load($file); | ||||
65 | 1 | 50 | 4 | if ($proto->results) { | |||
66 | 1 | 9 | $proto->results->message($proto->messages); | ||||
67 | } else { | ||||||
68 | 0 | 0 | $proto->results( FormValidator::Simple::Results->new( | ||||
69 | messages => $proto->messages, | ||||||
70 | ) ); | ||||||
71 | } | ||||||
72 | } else { | ||||||
73 | 3 | 26 | $class->messages->load($file); | ||||
74 | } | ||||||
75 | } | ||||||
76 | |||||||
77 | sub set_message_decode_from { | ||||||
78 | 1 | 1 | 0 | 13 | my ($self, $decode_from) = @_; | ||
79 | 1 | 7 | $self->messages->decode_from($decode_from); | ||||
80 | } | ||||||
81 | |||||||
82 | sub set_message_format { | ||||||
83 | 2 | 2 | 0 | 8655 | my ($proto, $format) = @_; | ||
84 | 2 | 50 | 13 | $format ||= ''; | |||
85 | 2 | 14 | $proto->messages->format($format); | ||||
86 | } | ||||||
87 | |||||||
88 | sub new { | ||||||
89 | 55 | 55 | 1 | 5408 | my $proto = shift; | ||
90 | 55 | 33 | 283 | my $class = ref $proto || $proto; | |||
91 | 55 | 181 | my $self = bless { }, $class; | ||||
92 | 55 | 197 | $self->_init(@_); | ||||
93 | 55 | 448 | return $self; | ||||
94 | } | ||||||
95 | |||||||
96 | sub _init { | ||||||
97 | 55 | 55 | 126 | my ($self, @args) = @_; | |||
98 | 55 | 107 | my $class = ref $self; | ||||
99 | 55 | 231 | $class->set_option(@args); | ||||
100 | 55 | 285 | $self->results( FormValidator::Simple::Results->new( | ||||
101 | messages => $self->messages, | ||||||
102 | ) ); | ||||||
103 | } | ||||||
104 | |||||||
105 | sub set_invalid { | ||||||
106 | 1 | 1 | 0 | 3 | my ($self, $name, $type) = @_; | ||
107 | 1 | 50 | 6 | unless (ref $self) { | |||
108 | 0 | 0 | FormValidator::Simple::Exception->throw( | ||||
109 | qq/set_invalid is instance method./ | ||||||
110 | ); | ||||||
111 | } | ||||||
112 | 1 | 50 | 33 | 9 | unless ($name && $type) { | ||
113 | 0 | 0 | FormValidator::Simple::Exception->throw( | ||||
114 | qq/set_invalid needs two arguments./ | ||||||
115 | ); | ||||||
116 | } | ||||||
117 | 1 | 6 | $self->results->set_result($name, $type, FALSE); | ||||
118 | } | ||||||
119 | |||||||
120 | sub check { | ||||||
121 | 55 | 55 | 0 | 2370706 | my ($proto, $input, $prof, $options) = @_; | ||
122 | 55 | 50 | 374 | $options ||= {}; | |||
123 | 55 | 100 | 453 | my $self = blessed $proto ? $proto : $proto->new(%$options); | |||
124 | |||||||
125 | 55 | 384 | my $data = FormValidator::Simple::Data->new($input); | ||||
126 | 55 | 555 | my $prof_setting = FormValidator::Simple::Profile->new($prof); | ||||
127 | |||||||
128 | 55 | 207 | my $profile_iterator = $prof_setting->iterator; | ||||
129 | |||||||
130 | PROFILE: | ||||||
131 | 55 | 308 | while ( my $profile = $profile_iterator->next ) { | ||||
132 | |||||||
133 | 101 | 290 | my $name = $profile->name; | ||||
134 | 101 | 574 | my $keys = $profile->keys; | ||||
135 | 101 | 547 | my $constraints = $profile->constraints; | ||||
136 | |||||||
137 | 101 | 642 | my $params = $data->param($keys); | ||||
138 | |||||||
139 | 101 | 316 | $self->results->register($name); | ||||
140 | |||||||
141 | 101 | 100 | 2294 | $self->results->record($name)->data( @$params == 1 ? $params->[0] : ''); | |||
142 | |||||||
143 | 101 | 2005 | my $constraint_iterator = $constraints->iterator; | ||||
144 | 101 | 100 | 305 | if ( scalar @$params == 1 ) { | |||
145 | 79 | 100 | 66 | 488 | unless ( defined $params->[0] && $params->[0] ne '' ) { | ||
146 | 10 | 50 | 38 | if ( $constraints->needs_blank_check ) { | |||
147 | 10 | 80 | $self->results->record($name)->is_blank( TRUE ); | ||||
148 | } | ||||||
149 | 10 | 127 | next PROFILE; | ||||
150 | } | ||||||
151 | } | ||||||
152 | |||||||
153 | CONSTRAINT: | ||||||
154 | 91 | 350 | while ( my $constraint = $constraint_iterator->next ) { | ||||
155 | |||||||
156 | 109 | 374 | my ($result, $data) = $constraint->check($params); | ||||
157 | |||||||
158 | 109 | 336 | $self->results->set_result($name, $constraint->name, $result); | ||||
159 | |||||||
160 | 109 | 100 | 2462 | $self->results->record($name)->data($data) if $data; | |||
161 | } | ||||||
162 | |||||||
163 | } | ||||||
164 | 55 | 671 | return $self->results; | ||||
165 | } | ||||||
166 | |||||||
167 | 1; | ||||||
168 | |||||||
169 | =head1 NAME | ||||||
170 | |||||||
171 | FormValidator::Simple - validation with simple chains of constraints | ||||||
172 | |||||||
173 | =head1 SYNOPSIS | ||||||
174 | |||||||
175 | my $query = CGI->new; | ||||||
176 | $query->param( param1 => 'ABCD' ); | ||||||
177 | $query->param( param2 => 12345 ); | ||||||
178 | $query->param( mail1 => 'lyo.kato@gmail.com' ); | ||||||
179 | $query->param( mail2 => 'lyo.kato@gmail.com' ); | ||||||
180 | $query->param( year => 2005 ); | ||||||
181 | $query->param( month => 11 ); | ||||||
182 | $query->param( day => 27 ); | ||||||
183 | |||||||
184 | my $result = FormValidator::Simple->check( $query => [ | ||||||
185 | param1 => ['NOT_BLANK', 'ASCII', ['LENGTH', 2, 5]], | ||||||
186 | param2 => ['NOT_BLANK', 'INT' ], | ||||||
187 | mail1 => ['NOT_BLANK', 'EMAIL_LOOSE'], | ||||||
188 | mail2 => ['NOT_BLANK', 'EMAIL_LOOSE'], | ||||||
189 | { mails => ['mail1', 'mail2' ] } => ['DUPLICATION'], | ||||||
190 | { date => ['year', 'month', 'day'] } => ['DATE'], | ||||||
191 | ] ); | ||||||
192 | |||||||
193 | if ( $result->has_error ) { | ||||||
194 | my $tt = Template->new({ INCLUDE_PATH => './tmpl' }); | ||||||
195 | $tt->process('template.html', { result => $result }); | ||||||
196 | } | ||||||
197 | |||||||
198 | template example | ||||||
199 | |||||||
200 | [% IF result.has_error %] | ||||||
201 | Found Input Error |
||||||
202 | |
||||||
203 | |||||||
204 | [% IF result.missing('param1') %] | ||||||
205 | |
||||||
206 | [% END %] | ||||||
207 | |||||||
208 | [% IF result.invalid('param1') %] | ||||||
209 | |
||||||
210 | [% END %] | ||||||
211 | |||||||
212 | [% IF result.invalid('param1', 'ASCII') %] | ||||||
213 | |
||||||
214 | [% END %] | ||||||
215 | |||||||
216 | [% IF result.invalid('param1', 'LENGTH') %] | ||||||
217 | |
||||||
218 | [% END %] | ||||||
219 | |||||||
220 | |||||||
221 | [% END %] | ||||||
222 | |||||||
223 | example2 | ||||||
224 | |||||||
225 | [% IF result.has_error %] | ||||||
226 | |
||||||
227 | [% FOREACH key IN result.error %] | ||||||
228 | [% FOREACH type IN result.error(key) %] | ||||||
229 | |
||||||
230 | [% END %] | ||||||
231 | [% END %] | ||||||
232 | |||||||
233 | [% END %] | ||||||
234 | |||||||
235 | =head1 DESCRIPTION | ||||||
236 | |||||||
237 | This module provides you a sweet way of form data validation with simple constraints chains. | ||||||
238 | You can write constraints on single line for each input data. | ||||||
239 | |||||||
240 | This idea is based on Sledge::Plugin::Validator, and most of validation code is borrowed from this plugin. | ||||||
241 | |||||||
242 | (Sledge is a MVC web application framework: http://sl.edge.jp [Japanese] ) | ||||||
243 | |||||||
244 | The result object this module returns behaves like L |
||||||
245 | |||||||
246 | =head1 HOW TO SET PROFILE | ||||||
247 | |||||||
248 | FormValidator::Simple->check( $q => [ | ||||||
249 | #profile | ||||||
250 | ] ); | ||||||
251 | |||||||
252 | Use 'check' method. | ||||||
253 | |||||||
254 | A hash reference includes input data, or an object of some class that has a method named 'param', for example L |
||||||
255 | |||||||
256 | And set profile as array reference into second argument. Profile consists of some pairs of input data and constraints. | ||||||
257 | |||||||
258 | my $q = CGI->new; | ||||||
259 | $q->param( param1 => 'hoge' ); | ||||||
260 | |||||||
261 | FormValidator::Simple->check( $q => [ | ||||||
262 | param1 => [ ['NOT_BLANK'], ['LENGTH', 4, 10] ], | ||||||
263 | ] ); | ||||||
264 | |||||||
265 | In this case, param1 is the name of a form element. and the array ref "[ ['NOT_BLANK']... ]" is a constraints chain. | ||||||
266 | |||||||
267 | Write constraints chain as arrayref, and you can set some constraints into it. In the last example, two constraints | ||||||
268 | 'NOT_BLANK', and 'LENGTH' are set. Each constraints is should be set as arrayref, but in case the constraint has no | ||||||
269 | argument, it can be written as scalar text. | ||||||
270 | |||||||
271 | FormValidator::Simple->check( $q => [ | ||||||
272 | param1 => [ 'NOT_BLANK', ['LENGTH', 4, 10] ], | ||||||
273 | ] ); | ||||||
274 | |||||||
275 | Now, in this sample 'NOT_BLANK' constraint is not an arrayref, but 'LENGTH' isn't. Because 'LENGTH' has two arguments, 4 and 10. | ||||||
276 | |||||||
277 | =head2 MULTIPLE DATA VALIDATION | ||||||
278 | |||||||
279 | When you want to check about multiple input data, do like this. | ||||||
280 | |||||||
281 | my $q = CGI->new; | ||||||
282 | $q->param( mail1 => 'lyo.kato@gmail.com' ); | ||||||
283 | $q->param( mail2 => 'lyo.kato@gmail.com' ); | ||||||
284 | |||||||
285 | my $result = FormValidator::Simple->check( $q => [ | ||||||
286 | { mails => ['mail1', 'mail2'] } => [ 'DUPLICATION' ], | ||||||
287 | ] ) | ||||||
288 | |||||||
289 | [% IF result.invalid('mails') %] | ||||||
290 | mail1 and mail2 aren't same. |
||||||
291 | [% END %] | ||||||
292 | |||||||
293 | and here's an another example. | ||||||
294 | |||||||
295 | my $q = CGI->new; | ||||||
296 | $q->param( year => 2005 ); | ||||||
297 | $q->param( month => 12 ); | ||||||
298 | $q->param( day => 27 ); | ||||||
299 | |||||||
300 | my $result = FormValidator::Simple->check( $q => [ | ||||||
301 | { date => ['year', 'month', 'day'] } => [ 'DATE' ], | ||||||
302 | ] ); | ||||||
303 | |||||||
304 | [% IF result.invalid('date') %] | ||||||
305 | Set correct date. |
||||||
306 | [% END %] | ||||||
307 | |||||||
308 | =head2 FLEXIBLE VALIDATION | ||||||
309 | |||||||
310 | my $valid = FormValidator::Simple->new(); | ||||||
311 | |||||||
312 | $valid->check( $q => [ | ||||||
313 | param1 => [qw/NOT_BLANK ASCII/, [qw/LENGTH 4 10/] ], | ||||||
314 | ] ); | ||||||
315 | |||||||
316 | $valid->check( $q => [ | ||||||
317 | param2 => [qw/NOT_BLANK/], | ||||||
318 | ] ); | ||||||
319 | |||||||
320 | my $results = $valid->results; | ||||||
321 | |||||||
322 | if ( found some error... ) { | ||||||
323 | $results->set_invalid('param3' => 'MY_ERROR'); | ||||||
324 | } | ||||||
325 | |||||||
326 | template example | ||||||
327 | |||||||
328 | [% IF results.invalid('param1') %] | ||||||
329 | ... | ||||||
330 | [% END %] | ||||||
331 | [% IF results.invalid('param2') %] | ||||||
332 | ... | ||||||
333 | [% END %] | ||||||
334 | [% IF results.invalid('param3', 'MY_ERROR') %] | ||||||
335 | ... | ||||||
336 | [% END %] | ||||||
337 | |||||||
338 | =head1 HOW TO SET OPTIONS | ||||||
339 | |||||||
340 | Option setting is needed by some validation, especially in plugins. | ||||||
341 | |||||||
342 | You can set them in two ways. | ||||||
343 | |||||||
344 | FormValidator::Simple->set_option( | ||||||
345 | dbic_base_class => 'MyProj::Model::DBIC', | ||||||
346 | charset => 'euc', | ||||||
347 | ); | ||||||
348 | |||||||
349 | or | ||||||
350 | |||||||
351 | $valid = FormValidator::Simple->new( | ||||||
352 | dbic_base_class => 'MyProj::Model::DBIC', | ||||||
353 | charset => 'euc', | ||||||
354 | ); | ||||||
355 | |||||||
356 | $valid->check(...) | ||||||
357 | |||||||
358 | =head1 VALIDATION COMMANDS | ||||||
359 | |||||||
360 | You can use follow variety validations. | ||||||
361 | and each validations can be used as negative validation with 'NOT_' prefix. | ||||||
362 | |||||||
363 | FormValidator::Simple->check( $q => [ | ||||||
364 | param1 => [ 'INT', ['LENGTH', 4, 10] ], | ||||||
365 | param2 => [ 'NOT_INT', ['NOT_LENGTH', 4, 10] ], | ||||||
366 | ] ); | ||||||
367 | |||||||
368 | =over 4 | ||||||
369 | |||||||
370 | =item SP | ||||||
371 | |||||||
372 | check if the data has space or not. | ||||||
373 | |||||||
374 | =item INT | ||||||
375 | |||||||
376 | check if the data is integer or not. | ||||||
377 | |||||||
378 | =item UINT | ||||||
379 | |||||||
380 | unsigined integer check. | ||||||
381 | for example, if -1234 is input, the validation judges it invalid. | ||||||
382 | |||||||
383 | =item DECIMAL | ||||||
384 | |||||||
385 | $q->param( 'num1' => '123.45678' ); | ||||||
386 | |||||||
387 | my $result = FormValidator::Simple->check( $q => [ | ||||||
388 | num1 => [ ['DECIMAL', 3, 5] ], | ||||||
389 | ] ); | ||||||
390 | |||||||
391 | each numbers (3,5) mean maximum digits before/after '.' | ||||||
392 | |||||||
393 | =item ASCII | ||||||
394 | |||||||
395 | check is the data consists of only ascii code. | ||||||
396 | |||||||
397 | =item LENGTH | ||||||
398 | |||||||
399 | check the length of the data. | ||||||
400 | |||||||
401 | my $result = FormValidator::Simple->check( $q => [ | ||||||
402 | param1 => [ ['LENGTH', 4] ], | ||||||
403 | ] ); | ||||||
404 | |||||||
405 | check if the length of the data is 4 or not. | ||||||
406 | |||||||
407 | my $result = FormValidator::Simple->check( $q => [ | ||||||
408 | param1 => [ ['LENGTH', 4, 10] ], | ||||||
409 | ] ); | ||||||
410 | |||||||
411 | when you set two arguments, it checks if the length of data is in | ||||||
412 | the range between 4 and 10. | ||||||
413 | |||||||
414 | =item HTTP_URL | ||||||
415 | |||||||
416 | verify it is a http(s)-url | ||||||
417 | |||||||
418 | my $result = FormValidator::Simple->check( $q => [ | ||||||
419 | param1 => [ 'HTTP_URL' ], | ||||||
420 | ] ); | ||||||
421 | |||||||
422 | =item SELECTED_AT_LEAST | ||||||
423 | |||||||
424 | verify the quantity of selected parameters is counted over allowed minimum. | ||||||
425 | |||||||
426 | Music | ||||||
427 | Movie | ||||||
428 | Game | ||||||
429 | |||||||
430 | my $result = FormValidator::Simple->check( $q => [ | ||||||
431 | hobby => ['NOT_BLANK', ['SELECTED_AT_LEAST', 2] ], | ||||||
432 | ] ); | ||||||
433 | |||||||
434 | =item REGEX | ||||||
435 | |||||||
436 | check with regular expression. | ||||||
437 | |||||||
438 | my $result = FormValidator::Simple->check( $q => [ | ||||||
439 | param1 => [ ['REGEX', qr/^hoge$/ ] ], | ||||||
440 | ] ); | ||||||
441 | |||||||
442 | =item DUPLICATION | ||||||
443 | |||||||
444 | check if the two data are same or not. | ||||||
445 | |||||||
446 | my $result = FormValidator::Simple->check( $q => [ | ||||||
447 | { duplication_check => ['param1', 'param2'] } => [ 'DUPLICATION' ], | ||||||
448 | ] ); | ||||||
449 | |||||||
450 | =item EMAIL | ||||||
451 | |||||||
452 | check with L |
||||||
453 | |||||||
454 | =item EMAIL_MX | ||||||
455 | |||||||
456 | check with L |
||||||
457 | |||||||
458 | =item EMAIL_LOOSE | ||||||
459 | |||||||
460 | check with L |
||||||
461 | |||||||
462 | =item EMAIL_LOOSE_MX | ||||||
463 | |||||||
464 | check with L |
||||||
465 | |||||||
466 | =item DATE | ||||||
467 | |||||||
468 | check with L |
||||||
469 | |||||||
470 | my $result = FormValidator::Simple->check( $q => [ | ||||||
471 | { date => [qw/year month day/] } => [ 'DATE' ] | ||||||
472 | ] ); | ||||||
473 | |||||||
474 | =item TIME | ||||||
475 | |||||||
476 | check with L |
||||||
477 | |||||||
478 | my $result = FormValidator::Simple->check( $q => [ | ||||||
479 | { time => [qw/hour min sec/] } => ['TIME'], | ||||||
480 | ] ); | ||||||
481 | |||||||
482 | =item DATETIME | ||||||
483 | |||||||
484 | check with L |
||||||
485 | |||||||
486 | my $result = FormValidator::Simple->check( $q => [ | ||||||
487 | { datetime => [qw/year month day hour min sec/] } => ['DATETIME'] | ||||||
488 | ] ); | ||||||
489 | |||||||
490 | =item DATETIME_STRPTIME | ||||||
491 | |||||||
492 | check with L |
||||||
493 | |||||||
494 | my $q = CGI->new; | ||||||
495 | $q->param( datetime => '2006-04-26T19:09:21+0900' ); | ||||||
496 | |||||||
497 | my $result = FormValidator::Simple->check( $q => [ | ||||||
498 | datetime => [ [ 'DATETIME_STRPTIME', '%Y-%m-%dT%T%z' ] ], | ||||||
499 | ] ); | ||||||
500 | |||||||
501 | =item DATETIME_FORMAT | ||||||
502 | |||||||
503 | check with DateTime::Format::***. for example, L |
||||||
504 | L |
||||||
505 | |||||||
506 | my $q = CGI->new; | ||||||
507 | $q->param( datetime => '2004-04-26 19:09:21' ); | ||||||
508 | |||||||
509 | my $result = FormValidator::Simple->check( $q => [ | ||||||
510 | datetime => [ [qw/DATETIME_FORMAT MySQL/] ], | ||||||
511 | ] ); | ||||||
512 | |||||||
513 | =item GREATER_THAN | ||||||
514 | |||||||
515 | numeric comparison | ||||||
516 | |||||||
517 | my $result = FormValidator::Simple->check( $q => [ | ||||||
518 | age => [ ['GREATER_THAN', 25] ], | ||||||
519 | ] ); | ||||||
520 | |||||||
521 | =item LESS_THAN | ||||||
522 | |||||||
523 | numeric comparison | ||||||
524 | |||||||
525 | my $result = FormValidator::Simple->check( $q => [ | ||||||
526 | age => [ ['LESS_THAN', 25] ], | ||||||
527 | ] ); | ||||||
528 | |||||||
529 | =item EQUAL_TO | ||||||
530 | |||||||
531 | numeric comparison | ||||||
532 | |||||||
533 | my $result = FormValidator::Simple->check( $q => [ | ||||||
534 | age => [ ['EQUAL_TO', 25] ], | ||||||
535 | ] ); | ||||||
536 | |||||||
537 | =item BETWEEN | ||||||
538 | |||||||
539 | numeric comparison | ||||||
540 | |||||||
541 | my $result = FormValidator::Simple->check( $q => [ | ||||||
542 | age => [ ['BETWEEN', 20, 25] ], | ||||||
543 | ] ); | ||||||
544 | |||||||
545 | =item ANY | ||||||
546 | |||||||
547 | check if there is not blank data in multiple data. | ||||||
548 | |||||||
549 | my $result = FormValidator::Simple->check( $q => [ | ||||||
550 | { some_data => [qw/param1 param2 param3/] } => ['ANY'] | ||||||
551 | ] ); | ||||||
552 | |||||||
553 | =item IN_ARRAY | ||||||
554 | |||||||
555 | check if the food ordered is in menu | ||||||
556 | |||||||
557 | my $result = FormValidator::Simple->check( $q => [ | ||||||
558 | food => [ ['IN_ARRAY', qw/noodle soba spaghetti/] ], | ||||||
559 | ] }; | ||||||
560 | |||||||
561 | =back | ||||||
562 | |||||||
563 | =head1 HOW TO LOAD PLUGINS | ||||||
564 | |||||||
565 | use FormValidator::Simple qw/Japanese CreditCard/; | ||||||
566 | |||||||
567 | L |
||||||
568 | |||||||
569 | or use 'load_plugin' method. | ||||||
570 | |||||||
571 | use FormValidator::Simple; | ||||||
572 | FormValidator::Simple->load_plugin('FormValidator::Simple::Plugin::CreditCard'); | ||||||
573 | |||||||
574 | If you want to load plugin which name isn't in FormValidator::Simple::Plugin namespace, use +. | ||||||
575 | |||||||
576 | use FormValidator::Simple qw/+MyApp::ValidatorPlugin/; | ||||||
577 | |||||||
578 | =head1 MESSAGE HANDLING | ||||||
579 | |||||||
580 | You can custom your own message with key and type. | ||||||
581 | |||||||
582 | [% IF result.has_error %] | ||||||
583 | [% FOREACH key IN result.error %] | ||||||
584 | [% FOREACH type IN result.error(key) %] | ||||||
585 | error message:[% type %] - [% key %] |
||||||
586 | [% END %] | ||||||
587 | [% END %] | ||||||
588 | [% END %] | ||||||
589 | |||||||
590 | And you can also set messages configuration before. | ||||||
591 | You can prepare configuration as hash reference. | ||||||
592 | |||||||
593 | FormValidator::Simple->set_messages( { | ||||||
594 | action1 => { | ||||||
595 | name => { | ||||||
596 | NOT_BLANK => 'input name!', | ||||||
597 | LENGTH => 'input name (length should be between 0 and 10)!', | ||||||
598 | }, | ||||||
599 | email => { | ||||||
600 | DEFAULT => 'input correct email address!', | ||||||
601 | }, | ||||||
602 | }, | ||||||
603 | } ); | ||||||
604 | |||||||
605 | or a YAML file. | ||||||
606 | |||||||
607 | # messages.yml | ||||||
608 | DEFAULT: | ||||||
609 | name: | ||||||
610 | DEFAULT: name is invalid! | ||||||
611 | action1: | ||||||
612 | name: | ||||||
613 | NOT_BLANK: input name! | ||||||
614 | LENGTH: input name(length should be between 0 and 10)! | ||||||
615 | email: | ||||||
616 | DEFAULT: input correct email address! | ||||||
617 | action2: | ||||||
618 | name: | ||||||
619 | DEFAULT: ... | ||||||
620 | |||||||
621 | # in your perl-script, set the file's path. | ||||||
622 | FormValidator::Simple->set_messages('messages.yml'); | ||||||
623 | |||||||
624 | DEFAULT is a special type. | ||||||
625 | If it can't find setting for indicated validation-type, it uses message set for DEFAULT. | ||||||
626 | |||||||
627 | after setting, execute check(), | ||||||
628 | |||||||
629 | my $result = FormValidator::Simple->check( $q => [ | ||||||
630 | name => [qw/NOT_BLANK/, [qw/LENGTH 0 10/] ], | ||||||
631 | email => [qw/NOT_BLANK EMAIL_LOOSE/, [qw/LENGTH 0 20/] ], | ||||||
632 | ] ); | ||||||
633 | |||||||
634 | # matching result and messages for indicated action. | ||||||
635 | my $messages = $result->messages('action1'); | ||||||
636 | |||||||
637 | foreach my $message ( @$messages ) { | ||||||
638 | print $message, "\n"; | ||||||
639 | } | ||||||
640 | |||||||
641 | # or you can get messages as hash style. | ||||||
642 | # each fieldname is the key | ||||||
643 | my $field_messages = $result->field_messages('action1'); | ||||||
644 | if ($field_messages->{name}) { | ||||||
645 | foreach my $message ( @{ $field_messages->{name} } ) { | ||||||
646 | print $message, "\n"; | ||||||
647 | } | ||||||
648 | } | ||||||
649 | |||||||
650 | When it can't find indicated action, name, and type, it searches proper message from DEFAULT action. | ||||||
651 | If in template file, | ||||||
652 | |||||||
653 | [% IF result.has_error %] | ||||||
654 | [% FOREACH msg IN result.messages('action1') %] | ||||||
655 | [% msg %] |
||||||
656 | [% END %] | ||||||
657 | [% END %] | ||||||
658 | |||||||
659 | you can set each message format. | ||||||
660 | |||||||
661 | FormValidator::Simple->set_message_format(' %s '); |
||||||
662 | my $result = FormValidator::Simple->check( $q => [ | ||||||
663 | ...profile | ||||||
664 | ] ); | ||||||
665 | |||||||
666 | [% IF result.has_error %] | ||||||
667 | [% result.messages('action1').join("\n") %] | ||||||
668 | [% END %] | ||||||
669 | |||||||
670 | =head1 RESULT HANDLING | ||||||
671 | |||||||
672 | See L |
||||||
673 | |||||||
674 | =head1 FLAGGED UTF-8 | ||||||
675 | |||||||
676 | If you set encoding like follows, it automatically decode the | ||||||
677 | result messages. | ||||||
678 | |||||||
679 | FormValidtor::Simple->set_mesasges_decode_from('utf-8'); | ||||||
680 | |||||||
681 | =head1 SEE ALSO | ||||||
682 | |||||||
683 | L |
||||||
684 | |||||||
685 | http://sl.edge.jp/ (Japanese) | ||||||
686 | |||||||
687 | http://sourceforge.jp/projects/sledge | ||||||
688 | |||||||
689 | =head1 AUTHOR | ||||||
690 | |||||||
691 | Lyo Kato E |
||||||
692 | |||||||
693 | =head1 COPYRIGHT AND LICENSE | ||||||
694 | |||||||
695 | This library is free software. | ||||||
696 | You can redistribute it and/or modify it under the same terms as perl itself. | ||||||
697 | |||||||
698 | =cut | ||||||
699 |