Changeset 10735
- Timestamp:
- 04/29/08 17:50:13 (5 years ago)
- Location:
- lang/perl/FormValidator-LazyWay/trunk/lib/FormValidator
- Files:
-
- 2 modified
-
LazyWay.pm (modified) (6 diffs)
-
LazyWay/Results.pm (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
lang/perl/FormValidator-LazyWay/trunk/lib/FormValidator/LazyWay.pm
r10731 r10735 6 6 use UNIVERSAL::require; 7 7 use base qw/Class::Accessor::Fast/; 8 use Perl6::Junction 'any'; 8 use Perl6::Junction qw/any none/; 9 use FormValidator::LazyWay::Rules; 9 10 use FormValidator::LazyWay::Results; 10 11 … … 59 60 $self->_check_profile_syntax($profile); 60 61 62 my $results = FormValidator::LazyWay::Results->new(); 63 61 64 my $static = { 62 65 constraints => $self->{constraints}, … … 65 68 config => $self->config, 66 69 }; 67 68 return FormValidator::LazyWay::Results->new( $input , $profile, $static ) ; 70 $results = $self->_process( $input, $profile, $static, $results ); 71 72 return $results; 69 73 } 70 74 … … 200 204 } 201 205 206 sub _conv_message { 207 my $self = shift; 208 my $config = shift; 209 my $arg = shift; 210 my $messages = shift; 211 my $field = shift; 212 my $label = shift; 213 my $type = shift; 214 my $lang = shift; 215 my $message = $config->{messages}{$lang}{invalid}{$label} || $messages->{$label}{$lang}; 216 my $args = $arg->{$type}{$field}{$label} || {}; 217 218 foreach my $key ( keys %{$args} ) { 219 my $regexp = '\$_\[' . $key . '\]'; 220 my $value = $args->{$key}; 221 $message =~ s/$regexp/$value/g; 222 } 223 224 return $message; 225 } 226 227 sub _process { 228 my $self = shift; 229 230 my $input = shift; # 入力値 231 my $profile = shift; # プロファイル 232 my $static = shift; # スタティックデータ 233 my $results = shift; # Results object 234 235 my $constraints = $static->{constraints}; 236 my $messages = $static->{messages}; 237 my $config = $static->{config}; 238 my $args = $static->{args}; 239 240 my %data = $self->_get_input_as_hash($input); 241 my %valid = %data; 242 my $lang = $profile->{lang} || $config->{lang} || 'en'; 243 my $error_messages = {}; 244 my @missings = (); 245 my @unknown = (); 246 my %invalid = (); 247 248 if ( defined $profile->{defaults} ) { 249 foreach my $field ( keys %{ $profile->{defaults} } ) { 250 $valid{$field} ||= $profile->{defaults}{$field}; 251 } 252 } 253 254 # Remove all empty fields 255 for my $field ( keys %valid ) { 256 if ( ref $valid{$field} ) { 257 next if ref $valid{$field} ne 'ARRAY'; 258 for ( my $i = 0; $i < scalar @{ $valid{$field} }; $i++ ) { 259 $valid{$field}->[$i] = undef 260 unless ( defined $valid{$field}->[$i] 261 and length $valid{$field}->[$i] 262 and $valid{$field}->[$i] !~ /^\x00$/ ); 263 } 264 265 # If all fields are empty, we delete it. 266 delete $valid{$field} 267 unless grep { defined $_ } @{ $valid{$field} }; 268 } 269 else { 270 delete $valid{$field} 271 unless ( defined $valid{$field} 272 and length $valid{$field} 273 and $valid{$field} !~ /^\x00$/ ); 274 } 275 } 276 277 my %required = map { $_ => 1 } _arrayify( $profile->{required} ); 278 my %optional = map { $_ => 1 } _arrayify( $profile->{optional} ); 279 280 my %required_one_or_more 281 = map { $_ => 1 } _arrayify( $profile->{required_one_or_more} ); 282 my %optional_one_or_more 283 = map { $_ => 1 } _arrayify( $profile->{optional_one_or_more} ); 284 285 # Find unknown 286 @unknown = grep { not( exists $optional{$_} or exists $required{$_} ) } 287 keys %valid; 288 289 # and remove them from the list 290 for my $field (@unknown) { 291 delete $valid{$field}; 292 } 293 294 # Check for required fields 295 for my $field ( keys %required ) { 296 push @missings, $field unless exists $valid{$field}; 297 delete $valid{$field} unless exists $valid{$field}; 298 } 299 300 # Check must_be_plural 301 # TODO : even user set too much prameters which generate missing error which look strange.... 302 foreach my $field ( keys %{ $profile->{must_be_plural} } ) { 303 if ( ref $valid{$field} eq 'ARRAY' ) { 304 unless ( 305 scalar @{ $valid{$field} } 306 == $profile->{must_be_plural}{$field} ) 307 { 308 push @missings, $field; 309 delete $valid{$field}; 310 } 311 } 312 else { 313 push @missings, $field; 314 delete $valid{$field}; 315 316 } 317 } 318 319 for my $field ( keys %required ) { 320 my $is_invalid = 0; 321 # if no valud do not need to check it 322 next if any(@missings) eq $field; 323 324 my $validators 325 = any( @{ $profile->{use_loose} } ) eq $field 326 ? $constraints->{loose}{$field} 327 : $constraints->{strict}{$field}; 328 329 my $type = {}; 330 if ( any( @{ $profile->{use_loose} } ) eq $field ) { 331 $validators = $constraints->{loose}{$field}; 332 $type->{$field} = 'loose'; 333 } 334 else { 335 $validators = $constraints->{strict}{$field}; 336 $type->{$field} = 'strict'; 337 } 338 339 # regexp_map try~ 340 if ( !defined $validators ) { 341 foreach my $regexp ( keys %{ $constraints->{regex_map} } ) { 342 if ( $field =~ qr/$regexp/ ) { 343 $validators = $constraints->{regex_map}{$regexp}; 344 $type->{$field} = 'regex_map'; 345 } 346 } 347 } 348 349 if ( ! defined $validators ) { 350 warn 'you should set ' . $field . ' validate method'; 351 } 352 else { 353 354 foreach my $name ( keys %{$validators} ) { 355 if ( ref $valid{$field} eq 'ARRAY' ) { 356 for my $v ( @{ $valid{$field} } ) { 357 if ($validators->{$name}{method}->( $valid{$field} ) ) 358 { 359 360 # ok! 361 } 362 else { 363 $invalid{$field}{ $validators->{$name}{label} } 364 = 1; 365 $error_messages->{$field} = [] 366 unless exists $error_messages->{$field}; 367 push @{ $error_messages->{$field} }, 368 $self->_conv_message( $config ,$args, $messages, $field, $validators->{$name}{label}, $type->{$field} , $lang ); 369 $is_invalid++; 370 last; 371 } 372 } 373 374 if ( !defined $profile->{must_be_plural}{$field} 375 && none( @{ $profile->{may_be_plural} } ) eq $field ) 376 { 377 $valid{$field} = $valid{$field}[0]; 378 last; 379 } 380 381 } 382 else { 383 if ( $validators->{$name}{method}->( $valid{$field} ) ) { 384 385 # return alwasy array ref when may_be_plural is seted. 386 if ( any( @{ $profile->{may_be_plural} } ) eq $field ) 387 { 388 my $value = $valid{$field}; 389 $valid{$field} = []; 390 push @{ $valid{$field} }, $value; 391 } 392 393 } 394 else { 395 $invalid{$field}{ $validators->{$name}{label} } = 1; 396 $error_messages->{$field} = [] 397 unless exists $error_messages->{$field}; 398 push @{ $error_messages->{$field} }, 399 $self->_conv_message( $config , $args, $messages, $field, $validators->{$name}{label}, $type->{$field} , $lang ); 400 $is_invalid++; 401 } 402 } 403 } 404 } 405 406 delete $valid{$field} if $is_invalid; 407 } 408 409 foreach my $field ( keys %{ $error_messages} ) { 410 local $" = ','; 411 my $tmp = "@{$error_messages->{$field}}" ; 412 my $mes = $config->{messages}{ $lang }{ invalid_message } || FormValidator::LazyWay::Rules->mes_invalid->{ $lang }; 413 $mes =~ s/__rule__/$tmp/g; 414 my $label = $config->{labels}{ $lang }{$field} || $field; 415 $mes =~ s/__field__/$label/g; 416 $error_messages->{$field} = $mes; 417 } 418 419 # FIXME : Just for now. 420 # invalid , missing もそうだけど、 __field__ とかの置き換えするとかで、フィールド名も表示できたほがいいよな。 421 if ( scalar @missings ) { 422 for my $missing (@missings) { 423 $error_messages->{$missing} = 'missing.'; 424 } 425 } 426 427 428 $results->{valid} = \%valid; 429 $results->{invalid} = \%invalid; 430 $results->{missing} = \@missings; 431 $results->{unknown} = \@unknown; 432 $results->{error_messages} = $error_messages; 433 434 $results->{has_missing} = scalar @missings ? 1 : 0; 435 $results->{has_invalid} = keys %invalid ? 1 : 0; 436 $results->{has_error} = $results->{has_missing} || $results->{has_invalid} ? 1 : 0; 437 438 #inverted truth-value. 439 $results->{success} = $results->{has_error} ? 0 : 1; 440 441 $results; 442 } 443 444 # takes string or array ref as input 445 # returns array 446 sub _arrayify { 447 448 # if the input is undefined, return an empty list 449 my $val = shift; 450 defined $val or return (); 451 452 # if it's a reference, return an array unless it points to an empty array. -mls 453 if ( ref $val eq 'ARRAY' ) { 454 $^W = 0; # turn off warnings about undef 455 return ( any(@$val) ne undef ) ? @$val : (); 456 } 457 458 # if it's a string, return an array unless the string is missing or empty. -mls 459 else { 460 return ( length $val ) ? ($val) : (); 461 } 462 } 463 464 # Figure out whether the data is a hash reference of a param-capable object and return it has a hash 465 sub _get_input_as_hash { 466 my ( $self, $data ) = @_; 467 require Scalar::Util; 468 469 # This checks whether we have an object that supports param 470 if ( Scalar::Util::blessed($data) && $data->can('param') ) { 471 my %return; 472 for my $k ( $data->param() ) { 473 474 # we expect param to return an array if there are multiple values 475 my @v; 476 477 # CGI::Simple requires us to call 'upload()' to get upload data, 478 # while CGI/Apache::Request return it on calling 'param()'. 479 # 480 # This seems quirky, but there isn't a way for us to easily check if 481 # "this field contains a file upload" or not. 482 if ( $data->isa('CGI::Simple') ) { 483 @v = $data->upload($k) || $data->param($k); 484 } 485 else { 486 @v = $data->param($k); 487 } 488 489 # we expect param to return an array if there are multiple values 490 $return{$k} = scalar(@v) > 1 ? \@v : $v[0]; 491 } 492 return %return; 493 } 494 495 # otherwise, it's already a hash reference 496 elsif ( ref $data eq 'HASH' ) { 497 498 # be careful to actually copy array references 499 my %copy = %$data; 500 for ( grep { ref $data->{$_} eq 'ARRAY' } keys %$data ) { 501 my @array_copy = @{ $data->{$_} }; 502 $copy{$_} = \@array_copy; 503 } 504 505 return %copy; 506 } 507 else { 508 die 509 "FormValidator::LazyWay->validate() or check() called with invalid input data structure."; 510 } 511 } 512 202 513 1; 203 514 … … 212 523 This is yet another form validator! 213 524 214 Most of validator is made for a form but not forms on a site. That is why I made this. This module let you allow to set validation for globally. 525 Most of validator is made for a form but not forms on a site. 526 That is why I made this. This module let you allow to set validation for globally. 215 527 216 528 =head1 METHOD … … 225 537 226 538 =head2 constraints 539 540 =head2 _conv_message 541 542 =head2 _process 543 544 =head2 _arrayify 545 546 =head2 _get_input_as_hash 227 547 228 548 =head1 INTERNALS -
lang/perl/FormValidator-LazyWay/trunk/lib/FormValidator/LazyWay/Results.pm
r10729 r10735 4 4 use warnings; 5 5 use base qw/Class::Accessor::Complex/; 6 use Perl6::Junction qw/any none/;7 6 use Carp; 8 7 use Data::Dumper; 9 use FormValidator::LazyWay::Rules;10 8 11 9 __PACKAGE__->mk_accessors( … … 32 30 sub new { 33 31 my $class = shift; 34 my $input = shift;35 my $profile = shift;36 my $static = shift;37 32 38 33 my $self = bless {}, $class; 39 34 $self->{custom_invalid} = []; 40 $self->_process( $input, $profile , $static );41 35 return $self; 42 36 } 43 37 44 sub _conv_message {45 my $self = shift;46 my $config = shift;47 my $arg = shift;48 my $messages = shift;49 my $field = shift;50 my $label = shift;51 my $type = shift;52 my $lang = shift;53 my $message = $config->{messages}{$lang}{invalid}{$label} || $messages->{$label}{$lang};54 my $args = $arg->{$type}{$field}{$label} || {};55 56 foreach my $key ( keys %{$args} ) {57 my $regexp = '\$_\[' . $key . '\]';58 my $value = $args->{$key};59 $message =~ s/$regexp/$value/g;60 }61 62 return $message;63 }64 65 sub _process {66 my $self = shift;67 68 my $input = shift; # 入力値69 my $profile = shift; # プロファイル70 my $static = shift; # スタティックデータ71 my $constraints = $static->{constraints};72 my $messages = $static->{messages};73 my $config = $static->{config};74 my $args = $static->{args};75 76 my %data = $self->_get_input_as_hash($input);77 my %valid = %data;78 my $lang = $profile->{lang} || $config->{lang} || 'en';79 my $error_messages = {};80 my @missings = ();81 my @unknown = ();82 my %invalid = ();83 84 if ( defined $profile->{defaults} ) {85 foreach my $field ( keys %{ $profile->{defaults} } ) {86 $valid{$field} ||= $profile->{defaults}{$field};87 }88 }89 90 # Remove all empty fields91 for my $field ( keys %valid ) {92 if ( ref $valid{$field} ) {93 next if ref $valid{$field} ne 'ARRAY';94 for ( my $i = 0; $i < scalar @{ $valid{$field} }; $i++ ) {95 $valid{$field}->[$i] = undef96 unless ( defined $valid{$field}->[$i]97 and length $valid{$field}->[$i]98 and $valid{$field}->[$i] !~ /^\x00$/ );99 }100 101 # If all fields are empty, we delete it.102 delete $valid{$field}103 unless grep { defined $_ } @{ $valid{$field} };104 }105 else {106 delete $valid{$field}107 unless ( defined $valid{$field}108 and length $valid{$field}109 and $valid{$field} !~ /^\x00$/ );110 }111 }112 113 my %required = map { $_ => 1 } _arrayify( $profile->{required} );114 my %optional = map { $_ => 1 } _arrayify( $profile->{optional} );115 116 my %required_one_or_more117 = map { $_ => 1 } _arrayify( $profile->{required_one_or_more} );118 my %optional_one_or_more119 = map { $_ => 1 } _arrayify( $profile->{optional_one_or_more} );120 121 # Find unknown122 @unknown = grep { not( exists $optional{$_} or exists $required{$_} ) }123 keys %valid;124 125 # and remove them from the list126 for my $field (@unknown) {127 delete $valid{$field};128 }129 130 # Check for required fields131 for my $field ( keys %required ) {132 push @missings, $field unless exists $valid{$field};133 delete $valid{$field} unless exists $valid{$field};134 }135 136 # Check must_be_plural137 # TODO : even user set too much prameters which generate missing error which look strange....138 foreach my $field ( keys %{ $profile->{must_be_plural} } ) {139 if ( ref $valid{$field} eq 'ARRAY' ) {140 unless (141 scalar @{ $valid{$field} }142 == $profile->{must_be_plural}{$field} )143 {144 push @missings, $field;145 delete $valid{$field};146 }147 }148 else {149 push @missings, $field;150 delete $valid{$field};151 152 }153 }154 155 for my $field ( keys %required ) {156 my $is_invalid = 0;157 # if no valud do not need to check it158 next if any(@missings) eq $field;159 160 my $validators161 = any( @{ $profile->{use_loose} } ) eq $field162 ? $constraints->{loose}{$field}163 : $constraints->{strict}{$field};164 165 my $type = {};166 if ( any( @{ $profile->{use_loose} } ) eq $field ) {167 $validators = $constraints->{loose}{$field};168 $type->{$field} = 'loose';169 }170 else {171 $validators = $constraints->{strict}{$field};172 $type->{$field} = 'strict';173 }174 175 # regexp_map try~176 if ( !defined $validators ) {177 foreach my $regexp ( keys %{ $constraints->{regex_map} } ) {178 if ( $field =~ qr/$regexp/ ) {179 $validators = $constraints->{regex_map}{$regexp};180 $type->{$field} = 'regex_map';181 }182 }183 }184 185 if ( ! defined $validators ) {186 warn 'you should set ' . $field . ' validate method';187 }188 else {189 190 foreach my $name ( keys %{$validators} ) {191 if ( ref $valid{$field} eq 'ARRAY' ) {192 for my $v ( @{ $valid{$field} } ) {193 if ($validators->{$name}{method}->( $valid{$field} ) )194 {195 196 # ok!197 }198 else {199 $invalid{$field}{ $validators->{$name}{label} }200 = 1;201 $error_messages->{$field} = []202 unless exists $error_messages->{$field};203 push @{ $error_messages->{$field} },204 $self->_conv_message( $config ,$args, $messages, $field, $validators->{$name}{label}, $type->{$field} , $lang );205 $is_invalid++;206 last;207 }208 }209 210 if ( !defined $profile->{must_be_plural}{$field}211 && none( @{ $profile->{may_be_plural} } ) eq $field )212 {213 $valid{$field} = $valid{$field}[0];214 last;215 }216 217 }218 else {219 if ( $validators->{$name}{method}->( $valid{$field} ) ) {220 221 # return alwasy array ref when may_be_plural is seted.222 if ( any( @{ $profile->{may_be_plural} } ) eq $field )223 {224 my $value = $valid{$field};225 $valid{$field} = [];226 push @{ $valid{$field} }, $value;227 }228 229 }230 else {231 $invalid{$field}{ $validators->{$name}{label} } = 1;232 $error_messages->{$field} = []233 unless exists $error_messages->{$field};234 push @{ $error_messages->{$field} },235 $self->_conv_message( $config , $args, $messages, $field, $validators->{$name}{label}, $type->{$field} , $lang );236 $is_invalid++;237 }238 }239 }240 }241 242 delete $valid{$field} if $is_invalid;243 }244 245 foreach my $field ( keys %{ $error_messages} ) {246 local $" = ',';247 my $tmp = "@{$error_messages->{$field}}" ;248 my $mes = $config->{messages}{ $lang }{ invalid_message } || FormValidator::LazyWay::Rules->mes_invalid->{ $lang };249 $mes =~ s/__rule__/$tmp/g;250 my $label = $config->{labels}{ $lang }{$field} || $field;251 $mes =~ s/__field__/$label/g;252 $error_messages->{$field} = $mes;253 }254 255 # FIXME : Just for now.256 # invalid , missing もそうだけど、 __field__ とかの置き換えするとかで、フィールド名も表示できたほがいいよな。257 if ( scalar @missings ) {258 for my $missing (@missings) {259 $error_messages->{$missing} = 'missing.';260 }261 }262 263 264 $self->{valid} = \%valid;265 $self->{invalid} = \%invalid;266 $self->{missing} = \@missings;267 $self->{unknown} = \@unknown;268 $self->{error_messages} = $error_messages;269 270 $self->{has_missing} = scalar @missings ? 1 : 0;271 $self->{has_invalid} = keys %invalid ? 1 : 0;272 $self->{has_error} = $self->{has_missing} || $self->{has_invalid} ? 1 : 0;273 274 #inverted truth-value.275 $self->{success} = $self->{has_error} ? 0 : 1;276 277 }278 279 # takes string or array ref as input280 # returns array281 sub _arrayify {282 283 # if the input is undefined, return an empty list284 my $val = shift;285 defined $val or return ();286 287 # if it's a reference, return an array unless it points to an empty array. -mls288 if ( ref $val eq 'ARRAY' ) {289 $^W = 0; # turn off warnings about undef290 return ( any(@$val) ne undef ) ? @$val : ();291 }292 293 # if it's a string, return an array unless the string is missing or empty. -mls294 else {295 return ( length $val ) ? ($val) : ();296 }297 }298 299 # Figure out whether the data is a hash reference of a param-capable object and return it has a hash300 sub _get_input_as_hash {301 my ( $self, $data ) = @_;302 require Scalar::Util;303 304 # This checks whether we have an object that supports param305 if ( Scalar::Util::blessed($data) && $data->can('param') ) {306 my %return;307 for my $k ( $data->param() ) {308 309 # we expect param to return an array if there are multiple values310 my @v;311 312 # CGI::Simple requires us to call 'upload()' to get upload data,313 # while CGI/Apache::Request return it on calling 'param()'.314 #315 # This seems quirky, but there isn't a way for us to easily check if316 # "this field contains a file upload" or not.317 if ( $data->isa('CGI::Simple') ) {318 @v = $data->upload($k) || $data->param($k);319 }320 else {321 @v = $data->param($k);322 }323 324 # we expect param to return an array if there are multiple values325 $return{$k} = scalar(@v) > 1 ? \@v : $v[0];326 }327 return %return;328 }329 330 # otherwise, it's already a hash reference331 elsif ( ref $data eq 'HASH' ) {332 333 # be careful to actually copy array references334 my %copy = %$data;335 for ( grep { ref $data->{$_} eq 'ARRAY' } keys %$data ) {336 my @array_copy = @{ $data->{$_} };337 $copy{$_} = \@array_copy;338 }339 340 return %copy;341 }342 else {343 die344 "FormValidator::LazyWay->validate() or check() called with invalid input data structure.";345 }346 }347 38 1; 348 39 … … 354 45 355 46 =head2 new 47 48 =head2 custom_invalid 356 49 357 50 =head1 ACCESSORS
![(please configure the [header_logo] section in trac.ini)](/share/chrome/site/your_project_logo.png)