| 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 |