Skip to content

Instantly share code, notes, and snippets.

/filter.diff Secret

Created January 14, 2016 16:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/4d35e5b89675f0b1aae1 to your computer and use it in GitHub Desktop.
Save anonymous/4d35e5b89675f0b1aae1 to your computer and use it in GitHub Desktop.
diff --git a/Changes b/Changes
index e7f4167..35fcc6f 100644
--- a/Changes
+++ b/Changes
@@ -1,5 +1,8 @@
6.41 2016-01-14
+ - Added filters attribute to Mojolicious::Validator.
+ - Added add_filter method to Mojolicious::Validator.
+ - Added filter method to Mojolicious::Validator::Validation.
6.40 2016-01-13
- Removed client_challenge, client_handshake, server_handshake and server_open
diff --git a/lib/Mojolicious.pm b/lib/Mojolicious.pm
index 11ab65a..2bd64a2 100644
--- a/lib/Mojolicious.pm
+++ b/lib/Mojolicious.pm
@@ -523,6 +523,12 @@ Validate values, defaults to a L<Mojolicious::Validator> object.
return $value ne 'foo';
});
+ # Add validation filter
+ $app->validator->add_filter(quotemeta => sub {
+ my ($validation, $name, $value) = @_;
+ return quotemeta $value;
+ });
+
=head1 METHODS
L<Mojolicious> inherits all methods from L<Mojo> and implements the following
diff --git a/lib/Mojolicious/Validator.pm b/lib/Mojolicious/Validator.pm
index 6d903e3..4699116 100644
--- a/lib/Mojolicious/Validator.pm
+++ b/lib/Mojolicious/Validator.pm
@@ -1,6 +1,7 @@
package Mojolicious::Validator;
use Mojo::Base -base;
+use Mojo::Util 'trim';
use Mojolicious::Validator::Validation;
has checks => sub {
@@ -12,8 +13,10 @@ has checks => sub {
upload => sub { !ref $_[2] || !$_[2]->isa('Mojo::Upload') }
};
};
+has filters => sub { {trim => \&_trim} };
-sub add_check { $_[0]->checks->{$_[1]} = $_[2] and return $_[0] }
+sub add_check { $_[0]->checks->{$_[1]} = $_[2] and return $_[0] }
+sub add_filter { $_[0]->filters->{$_[1]} = $_[2] and return $_[0] }
sub validation {
Mojolicious::Validator::Validation->new(validator => shift);
@@ -37,6 +40,8 @@ sub _size {
return $len < $min || $len > $max;
}
+sub _trim { trim $_[2] }
+
1;
=encoding utf8
@@ -94,6 +99,16 @@ between these two values.
Value needs to be a L<Mojo::Upload> object, representing a file upload.
+=head1 FILTERS
+
+These filters are available by default.
+
+=head2 trim
+
+ $validation->filter('trim');
+
+Trim whitespace characters from both ends of string value.
+
=head1 ATTRIBUTES
L<Mojolicious::Validator> implements the following attributes.
@@ -117,6 +132,12 @@ implements the following new ones.
Register a validation check.
+=head2 add_filter
+
+ $validator = $validator->add_filter(trim => sub {...});
+
+Register a new filter.
+
=head2 validation
my $validation = $validator->validation;
diff --git a/lib/Mojolicious/Validator/Validation.pm b/lib/Mojolicious/Validator/Validation.pm
index 31477c7..e587be1 100644
--- a/lib/Mojolicious/Validator/Validation.pm
+++ b/lib/Mojolicious/Validator/Validation.pm
@@ -57,6 +57,22 @@ sub every_param {
sub failed { [sort keys %{shift->{error}}] }
+sub filter {
+ my ($self, $filter) = (shift, shift);
+
+ return $self unless my $cb = $self->validator->filters->{$filter};
+ return $self unless defined(my $name = $self->topic);
+ my $output = $self->output;
+ return $self unless defined(my $value = $output->{$name});
+
+ $output->{$name}
+ = ref $value eq 'ARRAY'
+ ? [map { $self->$cb($name, $_, @_) } @$value]
+ : $self->$cb($name, $value, @_);
+
+ return $self;
+}
+
sub has_data { !!keys %{shift->input} }
sub has_error { $_[1] ? exists $_[0]{error}{$_[1]} : !!keys %{$_[0]{error}} }
@@ -196,6 +212,12 @@ Return a list of all names for values that failed validation.
# Names of all values that failed
say for @{$validation->failed};
+=head2 filter
+
+ $validation = $validation->filter('trim');
+
+Filter all values of the current L</"topic">.
+
=head2 has_data
my $bool = $validation->has_data;
diff --git a/t/mojolicious/validation_lite_app.t b/t/mojolicious/validation_lite_app.t
index 0659cd2..6c138b0 100644
--- a/t/mojolicious/validation_lite_app.t
+++ b/t/mojolicious/validation_lite_app.t
@@ -161,6 +161,16 @@ ok $validation->has_error, 'has error';
is_deeply $validation->error('bar'), [qw(size 1 1 6)], 'right error';
is_deeply $validation->failed, ['bar'], 'right names';
+# Trim
+$validation = $t->app->validation->input({foo => ' bar', baz => [' 0 ', 1]});
+ok $validation->required('foo')->filter('trim')->in('bar')->is_valid, 'valid';
+is_deeply $validation->output, {foo => 'bar'}, 'right result';
+ok $validation->optional('baz')->filter('trim')->like(qr/\d/)->is_valid,
+ 'valid';
+is_deeply $validation->output, {foo => 'bar', baz => [0, 1]}, 'right result';
+ok !$validation->in(23)->filter('trim')->is_valid, 'not valid';
+is_deeply $validation->output, {foo => 'bar'}, 'right result';
+
# Multiple empty values
$validation = $t->app->validation;
ok !$validation->has_data, 'no data';
@@ -178,6 +188,17 @@ ok $validation->required(0)->size(1, 1)->is_valid, 'valid';
is_deeply $validation->output, {0 => 0}, 'right result';
is $validation->param(0), 0, 'right value';
+# Custom filter
+$t->app->validator->add_filter(wrap => sub { join '', @_[3, 2, 4] });
+$validation = $t->app->validation->input({foo => [' bar', 'baz'], yada => 3});
+ok $validation->required('foo')->filter('wrap', 'a', 'b')->like(qr/^a.+b$/)
+ ->is_valid, 'valid';
+is_deeply $validation->output, {foo => ['a barb', 'abazb']}, 'right result';
+ok $validation->optional('yada')->filter('wrap', '3', '4')->in('334')->is_valid,
+ 'valid';
+is_deeply $validation->output, {foo => ['a barb', 'abazb'], yada => 334},
+ 'right result';
+
# Custom error
$validation = $t->app->validation->input({foo => 'bar'});
ok !$validation->required('foo')->has_error, 'no error';
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment