diff --git a/Changes b/Changes new file mode 100644 index 0000000..62bdfe5 --- /dev/null +++ b/Changes @@ -0,0 +1,4 @@ +Revision history for Mojolicious::Plugin::ValidateTiny + +0.07 + First version, released on an unsuspecting world. diff --git a/MANIFEST b/MANIFEST new file mode 100644 index 0000000..72aafd2 --- /dev/null +++ b/MANIFEST @@ -0,0 +1,5 @@ +Changes +MANIFEST +Makefile.PL +README.pod +lib/Mojolicious/Plugin/ValidateTiny.pm diff --git a/Makefile.PL b/Makefile.PL index 7568a60..6b6b941 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -13,6 +13,9 @@ WriteMakefile( 'Mojolicious' => 2.42, 'Validate::Tiny' => 0.08 }, - test => { TESTS => 't/*.t' }, PREREQ_PRINT => 1, + test => { TESTS => 't/*.t' }, + dist => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', }, + clean => { FILES => 'Mojolicious-Plugin-ValidateTiny-*' }, + ); diff --git a/README.pod b/README.pod index a1a2ee6..ff4d770 100644 --- a/README.pod +++ b/README.pod @@ -1,3 +1,4 @@ + =head1 NAME Mojolicious::Plugin::ValidateTiny - Mojolicious Plugin @@ -10,20 +11,50 @@ Mojolicious::Plugin::ValidateTiny - Mojolicious Plugin # Mojolicious::Lite plugin 'ValidateTiny'; - sub action { + sub action { my $self = shift; - - my $validate_rules = {}; + my $validate_rules = [ + # All of these are required + [qw/name email pass pass2/] => is_required(), + + # pass2 must be equal to pass + pass2 => is_equal('pass'), + + # custom sub validates an email address + email => sub { + my ( $value, $params ) = @_; + Email::Valid->address($value) ? undef : 'Invalid email'; + } + ]; + return unless $self->do_validation($validate_rules); + + ... Do something ... + } - if ( my $params = $self->validate($validate_rules) ) { + + sub action2 { + my $self = shift; + + my $validate_rules = { + checks => [...], + fields => [...], + filters => [...] + }; + if ( my $filtered_params = $self->do_validation($validate_rules) ) { # all $params are validated and filters are applyed - ... do you action ... + ... do your action ... + + } else { - $self->render(status => '403', text => 'FORBIDDEN'); + my $errors = $self->validator_error; # hash with errors + my $pass_error = $self->validator_error('password'); # password error text + my $any_error = $self->validator_any_error; # any error text + + $self->render( status => '403', text => $any_error ); } } - + __DATA__ @@ user.html.ep @@ -41,44 +72,98 @@ Mojolicious::Plugin::ValidateTiny - Mojolicious Plugin =head1 DESCRIPTION - L is a L support in L. +L is a L support for L. + +=head1 OPTIONS + +=head2 C (default 0) -=head1 METHODS +If "explicit" is true then for every field must be provided check rule - L inherits all methods from - L and implements the following new ones. +=head2 C (default 1) -=head2 C +If "autofields" then validator will automatically create fields list based on passed checks. +So, you can pass: + [ + user => is_required(), + pass => is_required(), + ] - $plugin->register; +instead of - Register plugin in L application. + { + fields => ['user', 'pass'], + checks => [ + user => is_required(), + pass => is_required(), + ] + } + +=head2 C (default []) +Is an arrayref with a list of fields that will be never checked. + +For example, if you use "Mojolicious::Plugin::CSRFProtect" then you should add "csrftoken" to exclude list. =head1 HELPERS -=head2 validate +=head2 C + +Validates parameters with provided rules and automatically set errors. - $self->validate($validate_rules); +$VALIDATE_RULES - Validate::Tiny rules in next form - Validate parameters with provided validator and automatically set errors. + { + checks => $CHECKS, # Required + fields => [], # Optional (will check all GET+POST parameters) + filters => [], # Optional + } + +You can pass only "checks" arrayref to "do_validation". +In this case validator will take all GET+POST parameters as "fields" + +returns false if validation failed +returns true if validation succeded + + $self->do_validation($VALIDATE_RULES) + $self->do_validation($CHECKS); + + +=head2 C + +Check if there are any errors. -=head2 validator_has_errors + if ($self->validator_has_errors) { + $self->render_text( $self->validator_any_error ); + } %= if (validator_has_errors) {
Please, correct the errors below.
% } -Check if there are any errors. +=head2 C -=head2 validator_error +Returns the appropriate error. + + my $errors_hash = $self->validator_error(); + my $username_error = $self->validator_error('username'); <%= validator_error 'username' %> + +=head2 C + +Returns any of the existing errors. This method is usefull if you want return only one error. + +=head1 AUTHOR + +Viktor Turskyi + +=head1 BUGS - Render the appropriate error. +Please report any bugs or feature requests to Github L =head1 SEE ALSO - L, L, L +L, L, L =cut \ No newline at end of file diff --git a/lib/Mojolicious/Plugin/ValidateTiny.pm b/lib/Mojolicious/Plugin/ValidateTiny.pm index 4c5e571..f367bfc 100644 --- a/lib/Mojolicious/Plugin/ValidateTiny.pm +++ b/lib/Mojolicious/Plugin/ValidateTiny.pm @@ -4,17 +4,10 @@ use Mojo::Base 'Mojolicious::Plugin'; use v5.10; use strict; use warnings; - use Carp qw/croak/; - use Validate::Tiny; -use Mojo::Util qw/camelize/; -use v5.10; - -our $VERSION = '0.06'; -# TODO check in after_static_dispatch hook that there are params and should be validated -# in after_dispatch hook check that in action validation was called +our $VERSION = '0.07'; sub register { my ( $self, $app, $conf ) = @_; @@ -27,10 +20,6 @@ sub register { exclude => [], %{ $conf || {} } }; - if ( $conf->{autorules} && ref $conf->{autorules} ne 'CODE' ) { - $conf->{autorules} = 0; - } - # Helper do_validation $app->helper( do_validation => sub { @@ -38,7 +27,7 @@ sub register { croak "ValidateTiny: Wrong validatation rules" unless ref($rules) ~~ [ 'ARRAY', 'HASH' ]; - $c->stash('is_validate_tiny_called', 1); + $c->stash('was_validate_tiny_called', 1); $rules = { checks => $rules } if ref $rules eq 'ARRAY'; $rules->{fields} ||= []; @@ -106,9 +95,9 @@ sub register { return 1; } ); - # Helper validator_errors + # Helper validator_error $app->helper( - validator_errors => sub { + validator_error => sub { my ( $c, $name ) = @_; my $errors = $c->stash('validate_tiny_errors'); @@ -138,7 +127,7 @@ sub register { after_dispatch => sub { my ($c) = @_; my $stash = $c->stash; - return 1 if $stash->{is_validate_tiny_called}; + return 1 if $stash->{was_validate_tiny_called}; if ( $stash->{controller} && $stash->{action} ) { $log->debug("ValidateTiny: No validation in [$stash->{controller}#$stash->{action}]"); @@ -164,25 +153,46 @@ Mojolicious::Plugin::ValidateTiny - Mojolicious Plugin # Mojolicious::Lite plugin 'ValidateTiny'; - sub action { + sub action { + my $self = shift; + my $validate_rules = [ + # All of these are required + [qw/name email pass pass2/] => is_required(), + + # pass2 must be equal to pass + pass2 => is_equal('pass'), + + # custom sub validates an email address + email => sub { + my ( $value, $params ) = @_; + Email::Valid->address($value) ? undef : 'Invalid email'; + } + ]; + return unless $self->do_validation($validate_rules); + + ... Do something ... + } + + + sub action2 { my $self = shift; - # Validate $self->param() - my $validate_rules = {}; - if ( my $params = $self->do_validation($validate_rules) ) { + my $validate_rules = { + checks => [...], + fields => [...], + filters => [...] + }; + if ( my $filtered_params = $self->do_validation($validate_rules) ) { # all $params are validated and filters are applyed - ... do you action ... + ... do your action ... - # Validate custom data - my $rules = {...}; - my $data = {...}; - if ( my $data = $self->do_validation($rules, $data) ) { - - } else { - my $errors_hash = $self->validator_error(); - } + } else { - $self->render(status => '403', text => 'FORBIDDEN'); + my $errors = $self->validator_error; # hash with errors + my $pass_error = $self->validator_error('password'); # password error text + my $any_error = $self->validator_any_error; # any error text + + $self->render( status => '403', text => $any_error ); } } @@ -204,32 +214,38 @@ Mojolicious::Plugin::ValidateTiny - Mojolicious Plugin =head1 DESCRIPTION -L is a L support in L. +L is a L support for L. -=head1 METHODS - -L inherits all methods from -L and implements the following new ones. - -=head2 C +=head1 OPTIONS - $plugin->register; +=head2 C (default 0) -Register plugin in L application. +If "explicit" is true then for every field must be provided check rule -=head1 OPTIONS +=head2 C (default 1) -=head2 C +If "autofields" then validator will automatically create fields list based on passed checks. +So, you can pass: + [ + user => is_required(), + pass => is_required(), + ] -DEFAULT 0 +instead of -=head2 C + { + fields => ['user', 'pass'], + checks => [ + user => is_required(), + pass => is_required(), + ] + } -DEFAULT 1 +=head2 C (default []) -=head2 C +Is an arrayref with a list of fields that will be never checked. -DEFAULT [] +For example, if you use "Mojolicious::Plugin::CSRFProtect" then you should add "csrftoken" to exclude list. =head1 HELPERS @@ -245,7 +261,7 @@ $VALIDATE_RULES - Validate::Tiny rules in next form filters => [], # Optional } -You can pass only "checks" array to "do_validation". +You can pass only "checks" arrayref to "do_validation". In this case validator will take all GET+POST parameters as "fields" returns false if validation failed @@ -259,6 +275,10 @@ returns true if validation succeded Check if there are any errors. + if ($self->validator_has_errors) { + $self->render_text( $self->validator_any_error ); + } + %= if (validator_has_errors) {
Please, correct the errors below.
% } @@ -276,6 +296,13 @@ Returns the appropriate error. Returns any of the existing errors. This method is usefull if you want return only one error. +=head1 AUTHOR + +Viktor Turskyi + +=head1 BUGS + +Please report any bugs or feature requests to Github L =head1 SEE ALSO