.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.40) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" ======================================================================== .\" .IX Title "FormValidator::Simple 3pm" .TH FormValidator::Simple 3pm "2021-01-07" "perl v5.32.0" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" FormValidator::Simple \- validation with simple chains of constraints .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 8 \& my $query = CGI\->new; \& $query\->param( param1 => \*(AqABCD\*(Aq ); \& $query\->param( param2 => 12345 ); \& $query\->param( mail1 => \*(Aqlyo.kato@gmail.com\*(Aq ); \& $query\->param( mail2 => \*(Aqlyo.kato@gmail.com\*(Aq ); \& $query\->param( year => 2005 ); \& $query\->param( month => 11 ); \& $query\->param( day => 27 ); \& \& my $result = FormValidator::Simple\->check( $query => [ \& param1 => [\*(AqNOT_BLANK\*(Aq, \*(AqASCII\*(Aq, [\*(AqLENGTH\*(Aq, 2, 5]], \& param2 => [\*(AqNOT_BLANK\*(Aq, \*(AqINT\*(Aq ], \& mail1 => [\*(AqNOT_BLANK\*(Aq, \*(AqEMAIL_LOOSE\*(Aq], \& mail2 => [\*(AqNOT_BLANK\*(Aq, \*(AqEMAIL_LOOSE\*(Aq], \& { mails => [\*(Aqmail1\*(Aq, \*(Aqmail2\*(Aq ] } => [\*(AqDUPLICATION\*(Aq], \& { date => [\*(Aqyear\*(Aq, \*(Aqmonth\*(Aq, \*(Aqday\*(Aq] } => [\*(AqDATE\*(Aq], \& ] ); \& \& if ( $result\->has_error ) { \& my $tt = Template\->new({ INCLUDE_PATH => \*(Aq./tmpl\*(Aq }); \& $tt\->process(\*(Aqtemplate.html\*(Aq, { result => $result }); \& } .Ve .PP template example .PP .Vb 3 \& [% IF result.has_error %] \&

Found Input Error

\& \& [% END %] .Ve .PP example2 .PP .Vb 9 \& [% IF result.has_error %] \& \& [% END %] .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" This module provides you a sweet way of form data validation with simple constraints chains. You can write constraints on single line for each input data. .PP This idea is based on Sledge::Plugin::Validator, and most of validation code is borrowed from this plugin. .PP (Sledge is a \s-1MVC\s0 web application framework: http://sl.edge.jp [Japanese] ) .PP The result object this module returns behaves like Data::FormValidator::Results. .SH "HOW TO SET PROFILE" .IX Header "HOW TO SET PROFILE" .Vb 3 \& FormValidator::Simple\->check( $q => [ \& #profile \& ] ); .Ve .PP Use 'check' method. .PP A hash reference includes input data, or an object of some class that has a method named 'param', for example \s-1CGI\s0, is needed as first argument. .PP And set profile as array reference into second argument. Profile consists of some pairs of input data and constraints. .PP .Vb 2 \& my $q = CGI\->new; \& $q\->param( param1 => \*(Aqhoge\*(Aq ); \& \& FormValidator::Simple\->check( $q => [ \& param1 => [ [\*(AqNOT_BLANK\*(Aq], [\*(AqLENGTH\*(Aq, 4, 10] ], \& ] ); .Ve .PP In this case, param1 is the name of a form element. and the array ref \*(L"[ ['\s-1NOT_BLANK\s0']... ]\*(R" is a constraints chain. .PP Write constraints chain as arrayref, and you can set some constraints into it. In the last example, two constraints \&'\s-1NOT_BLANK\s0', and '\s-1LENGTH\s0' are set. Each constraints is should be set as arrayref, but in case the constraint has no argument, it can be written as scalar text. .PP .Vb 3 \& FormValidator::Simple\->check( $q => [ \& param1 => [ \*(AqNOT_BLANK\*(Aq, [\*(AqLENGTH\*(Aq, 4, 10] ], \& ] ); .Ve .PP Now, in this sample '\s-1NOT_BLANK\s0' constraint is not an arrayref, but '\s-1LENGTH\s0' isn't. Because '\s-1LENGTH\s0' has two arguments, 4 and 10. .SS "\s-1MULTIPLE DATA VALIDATION\s0" .IX Subsection "MULTIPLE DATA VALIDATION" When you want to check about multiple input data, do like this. .PP .Vb 3 \& my $q = CGI\->new; \& $q\->param( mail1 => \*(Aqlyo.kato@gmail.com\*(Aq ); \& $q\->param( mail2 => \*(Aqlyo.kato@gmail.com\*(Aq ); \& \& my $result = FormValidator::Simple\->check( $q => [ \& { mails => [\*(Aqmail1\*(Aq, \*(Aqmail2\*(Aq] } => [ \*(AqDUPLICATION\*(Aq ], \& ] ) \& \& [% IF result.invalid(\*(Aqmails\*(Aq) %] \&

mail1 and mail2 aren\*(Aqt same.

\& [% END %] .Ve .PP and here's an another example. .PP .Vb 4 \& my $q = CGI\->new; \& $q\->param( year => 2005 ); \& $q\->param( month => 12 ); \& $q\->param( day => 27 ); \& \& my $result = FormValidator::Simple\->check( $q => [ \& { date => [\*(Aqyear\*(Aq, \*(Aqmonth\*(Aq, \*(Aqday\*(Aq] } => [ \*(AqDATE\*(Aq ], \& ] ); \& \& [% IF result.invalid(\*(Aqdate\*(Aq) %] \&

Set correct date.

\& [% END %] .Ve .SS "\s-1FLEXIBLE VALIDATION\s0" .IX Subsection "FLEXIBLE VALIDATION" .Vb 1 \& my $valid = FormValidator::Simple\->new(); \& \& $valid\->check( $q => [ \& param1 => [qw/NOT_BLANK ASCII/, [qw/LENGTH 4 10/] ], \& ] ); \& \& $valid\->check( $q => [ \& param2 => [qw/NOT_BLANK/], \& ] ); \& \& my $results = $valid\->results; \& \& if ( found some error... ) { \& $results\->set_invalid(\*(Aqparam3\*(Aq => \*(AqMY_ERROR\*(Aq); \& } .Ve .PP template example .PP .Vb 9 \& [% IF results.invalid(\*(Aqparam1\*(Aq) %] \& ... \& [% END %] \& [% IF results.invalid(\*(Aqparam2\*(Aq) %] \& ... \& [% END %] \& [% IF results.invalid(\*(Aqparam3\*(Aq, \*(AqMY_ERROR\*(Aq) %] \& ... \& [% END %] .Ve .SH "HOW TO SET OPTIONS" .IX Header "HOW TO SET OPTIONS" Option setting is needed by some validation, especially in plugins. .PP You can set them in two ways. .PP .Vb 4 \& FormValidator::Simple\->set_option( \& dbic_base_class => \*(AqMyProj::Model::DBIC\*(Aq, \& charset => \*(Aqeuc\*(Aq, \& ); .Ve .PP or .PP .Vb 4 \& $valid = FormValidator::Simple\->new( \& dbic_base_class => \*(AqMyProj::Model::DBIC\*(Aq, \& charset => \*(Aqeuc\*(Aq, \& ); \& \& $valid\->check(...) .Ve .SH "VALIDATION COMMANDS" .IX Header "VALIDATION COMMANDS" You can use follow variety validations. and each validations can be used as negative validation with '\s-1NOT_\s0' prefix. .PP .Vb 4 \& FormValidator::Simple\->check( $q => [ \& param1 => [ \*(AqINT\*(Aq, [\*(AqLENGTH\*(Aq, 4, 10] ], \& param2 => [ \*(AqNOT_INT\*(Aq, [\*(AqNOT_LENGTH\*(Aq, 4, 10] ], \& ] ); .Ve .IP "\s-1SP\s0" 4 .IX Item "SP" check if the data has space or not. .IP "\s-1INT\s0" 4 .IX Item "INT" check if the data is integer or not. .IP "\s-1UINT\s0" 4 .IX Item "UINT" unsigined integer check. for example, if \-1234 is input, the validation judges it invalid. .IP "\s-1DECIMAL\s0" 4 .IX Item "DECIMAL" .Vb 1 \& $q\->param( \*(Aqnum1\*(Aq => \*(Aq123.45678\*(Aq ); \& \& my $result = FormValidator::Simple\->check( $q => [ \& num1 => [ [\*(AqDECIMAL\*(Aq, 3, 5] ], \& ] ); .Ve .Sp each numbers (3,5) mean maximum digits before/after '.' .IP "\s-1ASCII\s0" 4 .IX Item "ASCII" check is the data consists of only ascii code. .IP "\s-1LENGTH\s0" 4 .IX Item "LENGTH" check the length of the data. .Sp .Vb 3 \& my $result = FormValidator::Simple\->check( $q => [ \& param1 => [ [\*(AqLENGTH\*(Aq, 4] ], \& ] ); .Ve .Sp check if the length of the data is 4 or not. .Sp .Vb 3 \& my $result = FormValidator::Simple\->check( $q => [ \& param1 => [ [\*(AqLENGTH\*(Aq, 4, 10] ], \& ] ); .Ve .Sp when you set two arguments, it checks if the length of data is in the range between 4 and 10. .IP "\s-1HTTP_URL\s0" 4 .IX Item "HTTP_URL" verify it is a http(s)\-url .Sp .Vb 3 \& my $result = FormValidator::Simple\->check( $q => [ \& param1 => [ \*(AqHTTP_URL\*(Aq ], \& ] ); .Ve .IP "\s-1SELECTED_AT_LEAST\s0" 4 .IX Item "SELECTED_AT_LEAST" verify the quantity of selected parameters is counted over allowed minimum. .Sp .Vb 3 \& Music \& Movie \& Game \& \& my $result = FormValidator::Simple\->check( $q => [ \& hobby => [\*(AqNOT_BLANK\*(Aq, [\*(AqSELECTED_AT_LEAST\*(Aq, 2] ], \& ] ); .Ve .IP "\s-1REGEX\s0" 4 .IX Item "REGEX" check with regular expression. .Sp .Vb 3 \& my $result = FormValidator::Simple\->check( $q => [ \& param1 => [ [\*(AqREGEX\*(Aq, qr/^hoge$/ ] ], \& ] ); .Ve .IP "\s-1DUPLICATION\s0" 4 .IX Item "DUPLICATION" check if the two data are same or not. .Sp .Vb 3 \& my $result = FormValidator::Simple\->check( $q => [ \& { duplication_check => [\*(Aqparam1\*(Aq, \*(Aqparam2\*(Aq] } => [ \*(AqDUPLICATION\*(Aq ], \& ] ); .Ve .IP "\s-1EMAIL\s0" 4 .IX Item "EMAIL" check with Email::Valid. .IP "\s-1EMAIL_MX\s0" 4 .IX Item "EMAIL_MX" check with Email::Valid, including mx check. .IP "\s-1EMAIL_LOOSE\s0" 4 .IX Item "EMAIL_LOOSE" check with Email::Valid::Loose. .IP "\s-1EMAIL_LOOSE_MX\s0" 4 .IX Item "EMAIL_LOOSE_MX" check with Email::Valid::Loose, including mx check. .IP "\s-1DATE\s0" 4 .IX Item "DATE" check with Date::Calc .Sp .Vb 3 \& my $result = FormValidator::Simple\->check( $q => [ \& { date => [qw/year month day/] } => [ \*(AqDATE\*(Aq ] \& ] ); .Ve .IP "\s-1TIME\s0" 4 .IX Item "TIME" check with Date::Calc .Sp .Vb 3 \& my $result = FormValidator::Simple\->check( $q => [ \& { time => [qw/hour min sec/] } => [\*(AqTIME\*(Aq], \& ] ); .Ve .IP "\s-1DATETIME\s0" 4 .IX Item "DATETIME" check with Date::Calc .Sp .Vb 3 \& my $result = FormValidator::Simple\->check( $q => [ \& { datetime => [qw/year month day hour min sec/] } => [\*(AqDATETIME\*(Aq] \& ] ); .Ve .IP "\s-1DATETIME_STRPTIME\s0" 4 .IX Item "DATETIME_STRPTIME" check with DateTime::Format::Strptime. .Sp .Vb 2 \& my $q = CGI\->new; \& $q\->param( datetime => \*(Aq2006\-04\-26T19:09:21+0900\*(Aq ); \& \& my $result = FormValidator::Simple\->check( $q => [ \& datetime => [ [ \*(AqDATETIME_STRPTIME\*(Aq, \*(Aq%Y\-%m\-%dT%T%z\*(Aq ] ], \& ] ); .Ve .IP "\s-1DATETIME_FORMAT\s0" 4 .IX Item "DATETIME_FORMAT" check with DateTime::Format::***. for example, DateTime::Format::HTTP, DateTime::Format::Mail, DateTime::Format::MySQL and etc. .Sp .Vb 2 \& my $q = CGI\->new; \& $q\->param( datetime => \*(Aq2004\-04\-26 19:09:21\*(Aq ); \& \& my $result = FormValidator::Simple\->check( $q => [ \& datetime => [ [qw/DATETIME_FORMAT MySQL/] ], \& ] ); .Ve .IP "\s-1GREATER_THAN\s0" 4 .IX Item "GREATER_THAN" numeric comparison .Sp .Vb 3 \& my $result = FormValidator::Simple\->check( $q => [ \& age => [ [\*(AqGREATER_THAN\*(Aq, 25] ], \& ] ); .Ve .IP "\s-1LESS_THAN\s0" 4 .IX Item "LESS_THAN" numeric comparison .Sp .Vb 3 \& my $result = FormValidator::Simple\->check( $q => [ \& age => [ [\*(AqLESS_THAN\*(Aq, 25] ], \& ] ); .Ve .IP "\s-1EQUAL_TO\s0" 4 .IX Item "EQUAL_TO" numeric comparison .Sp .Vb 3 \& my $result = FormValidator::Simple\->check( $q => [ \& age => [ [\*(AqEQUAL_TO\*(Aq, 25] ], \& ] ); .Ve .IP "\s-1BETWEEN\s0" 4 .IX Item "BETWEEN" numeric comparison .Sp .Vb 3 \& my $result = FormValidator::Simple\->check( $q => [ \& age => [ [\*(AqBETWEEN\*(Aq, 20, 25] ], \& ] ); .Ve .IP "\s-1ANY\s0" 4 .IX Item "ANY" check if there is not blank data in multiple data. .Sp .Vb 3 \& my $result = FormValidator::Simple\->check( $q => [ \& { some_data => [qw/param1 param2 param3/] } => [\*(AqANY\*(Aq] \& ] ); .Ve .IP "\s-1IN_ARRAY\s0" 4 .IX Item "IN_ARRAY" check if the food ordered is in menu .Sp .Vb 3 \& my $result = FormValidator::Simple\->check( $q => [ \& food => [ [\*(AqIN_ARRAY\*(Aq, qw/noodle soba spaghetti/] ], \& ] }; .Ve .SH "HOW TO LOAD PLUGINS" .IX Header "HOW TO LOAD PLUGINS" .Vb 1 \& use FormValidator::Simple qw/Japanese CreditCard/; .Ve .PP FormValidator::Simple::Plugin::Japanese, FormValidator::Simple::Plugin::CreditCard are loaded. .PP or use 'load_plugin' method. .PP .Vb 2 \& use FormValidator::Simple; \& FormValidator::Simple\->load_plugin(\*(AqFormValidator::Simple::Plugin::CreditCard\*(Aq); .Ve .PP If you want to load plugin which name isn't in FormValidator::Simple::Plugin namespace, use +. .PP .Vb 1 \& use FormValidator::Simple qw/+MyApp::ValidatorPlugin/; .Ve .SH "MESSAGE HANDLING" .IX Header "MESSAGE HANDLING" You can custom your own message with key and type. .PP .Vb 7 \& [% IF result.has_error %] \& [% FOREACH key IN result.error %] \& [% FOREACH type IN result.error(key) %] \&

error message:[% type %] \- [% key %]

\& [% END %] \& [% END %] \& [% END %] .Ve .PP And you can also set messages configuration before. You can prepare configuration as hash reference. .PP .Vb 11 \& FormValidator::Simple\->set_messages( { \& action1 => { \& name => { \& NOT_BLANK => \*(Aqinput name!\*(Aq, \& LENGTH => \*(Aqinput name (length should be between 0 and 10)!\*(Aq, \& }, \& email => { \& DEFAULT => \*(Aqinput correct email address!\*(Aq, \& }, \& }, \& } ); .Ve .PP or a \s-1YAML\s0 file. .PP .Vb 10 \& # messages.yml \& DEFAULT: \& name: \& DEFAULT: name is invalid! \& action1: \& name: \& NOT_BLANK: input name! \& LENGTH: input name(length should be between 0 and 10)! \& email: \& DEFAULT: input correct email address! \& action2: \& name: \& DEFAULT: ... \& \& # in your perl\-script, set the file\*(Aqs path. \& FormValidator::Simple\->set_messages(\*(Aqmessages.yml\*(Aq); .Ve .PP \&\s-1DEFAULT\s0 is a special type. If it can't find setting for indicated validation-type, it uses message set for \s-1DEFAULT.\s0 .PP after setting, execute \fBcheck()\fR, .PP .Vb 4 \& my $result = FormValidator::Simple\->check( $q => [ \& name => [qw/NOT_BLANK/, [qw/LENGTH 0 10/] ], \& email => [qw/NOT_BLANK EMAIL_LOOSE/, [qw/LENGTH 0 20/] ], \& ] ); \& \& # matching result and messages for indicated action. \& my $messages = $result\->messages(\*(Aqaction1\*(Aq); \& \& foreach my $message ( @$messages ) { \& print $message, "\en"; \& } \& \& # or you can get messages as hash style. \& # each fieldname is the key \& my $field_messages = $result\->field_messages(\*(Aqaction1\*(Aq); \& if ($field_messages\->{name}) { \& foreach my $message ( @{ $field_messages\->{name} } ) { \& print $message, "\en"; \& } \& } .Ve .PP When it can't find indicated action, name, and type, it searches proper message from \s-1DEFAULT\s0 action. If in template file, .PP .Vb 5 \& [% IF result.has_error %] \& [% FOREACH msg IN result.messages(\*(Aqaction1\*(Aq) %] \&

[% msg %]

\& [% END %] \& [% END %] .Ve .PP you can set each message format. .PP .Vb 4 \& FormValidator::Simple\->set_message_format(\*(Aq

%s

\*(Aq); \& my $result = FormValidator::Simple\->check( $q => [ \& ...profile \& ] ); \& \& [% IF result.has_error %] \& [% result.messages(\*(Aqaction1\*(Aq).join("\en") %] \& [% END %] .Ve .SH "RESULT HANDLING" .IX Header "RESULT HANDLING" See FormValidator::Simple::Results .SH "FLAGGED UTF\-8" .IX Header "FLAGGED UTF-8" If you set encoding like follows, it automatically decode the result messages. .PP .Vb 1 \& FormValidtor::Simple\->set_mesasges_decode_from(\*(Aqutf\-8\*(Aq); .Ve .SH "SEE ALSO" .IX Header "SEE ALSO" Data::FormValidator .PP http://sl.edge.jp/ (Japanese) .PP http://sourceforge.jp/projects/sledge .SH "AUTHOR" .IX Header "AUTHOR" Lyo Kato .SH "COPYRIGHT AND LICENSE" .IX Header "COPYRIGHT AND LICENSE" This library is free software. You can redistribute it and/or modify it under the same terms as perl itself.