File Coverage

blib/lib/Mojolicious/Validator.pm
Criterion Covered Total %
statement 43 43 100.0
branch 12 14 85.7
condition 8 11 72.7
subroutine 17 17 100.0
pod 4 4 100.0
total 84 89 94.3


line stmt bran cond sub pod time code
1             package Mojolicious::Validator;
2 51     51   470 use Mojo::Base -base;
  51         156  
  51         442  
3              
4 51     51   457 use Mojo::DynamicMethods;
  51         215  
  51         422  
5 51     51   405 use Mojo::Util qw(trim);
  51         212  
  51         2934  
6 51     51   25321 use Mojolicious::Validator::Validation;
  51         217  
  51         407  
7              
8             has checks => sub { {} };
9             has filters => sub { {comma_separated => \&_comma_separated, not_empty => \&_not_empty, trim => \&_trim} };
10              
11             sub add_check {
12 61     61 1 139 my ($self, $name, $cb) = @_;
13 61         159 $self->checks->{$name} = $cb;
14 61         215 Mojo::DynamicMethods::register 'Mojolicious::Validator::Validation', $self, $name, $cb;
15 61         105 return $self;
16             }
17              
18 1 50   1 1 5 sub add_filter { $_[0]->filters->{$_[1]} = $_[2] and return $_[0] }
19              
20             sub new {
21 10     10 1 91 my $self = shift->SUPER::new(@_);
22              
23 10         82 $self->add_check(equal_to => \&_equal_to);
24 10         63 $self->add_check(in => \&_in);
25 10     6   92 $self->add_check(like => sub { $_[2] !~ $_[3] });
  6         50  
26 10         103 $self->add_check(num => \&_num);
27 10         85 $self->add_check(size => \&_size);
28 10   66 12   106 $self->add_check(upload => sub { !ref $_[2] || !$_[2]->isa('Mojo::Upload') });
  12         89  
29              
30 10         80 return $self;
31             }
32              
33 108     108 1 586 sub validation { Mojolicious::Validator::Validation->new(validator => shift) }
34              
35 7 50   7   54 sub _comma_separated { defined $_[2] ? split(/\s*,\s*/, $_[2], -1) : undef }
36              
37             sub _equal_to {
38 3     3   8 my ($v, $name, $value, $to) = @_;
39 3 100       8 return 1 unless defined(my $other = $v->input->{$to});
40 2         9 return $value ne $other;
41             }
42              
43             sub _in {
44 9     9   25 my ($v, $name, $value) = (shift, shift, shift);
45 9   100     47 $value eq $_ && return undef for @_;
46 3         12 return 1;
47             }
48              
49 11 100   11   34 sub _not_empty { length $_[2] ? $_[2] : () }
50              
51             sub _num {
52 17     17   42 my ($v, $name, $value, $min, $max) = @_;
53 17 100       105 return 1 if $value !~ /^-?[0-9]+$/;
54 16   66     120 return defined $min && $min > $value || defined $max && $max < $value;
55             }
56              
57             sub _size {
58 11     11   29 my ($v, $name, $value, $min, $max) = @_;
59 11 100       36 my $len = ref $value ? $value->size : length $value;
60 11   66     86 return (defined $min && $len < $min) || (defined $max && $len > $max);
61             }
62              
63 16 100   16   49 sub _trim { defined $_[2] ? trim $_[2] : undef }
64              
65             1;
66              
67             =encoding utf8
68              
69             =head1 NAME
70              
71             Mojolicious::Validator - Validate values
72              
73             =head1 SYNOPSIS
74              
75             use Mojolicious::Validator;
76              
77             my $validator = Mojolicious::Validator->new;
78             my $v = $validator->validation;
79             $v->input({foo => 'bar'});
80             $v->required('foo')->like(qr/ar$/);
81             say $v->param('foo');
82              
83             =head1 DESCRIPTION
84              
85             L validates values for L.
86              
87             =head1 CHECKS
88              
89             These validation checks are available by default.
90              
91             =head2 equal_to
92              
93             $v = $v->equal_to('foo');
94              
95             String value needs to be equal to the value of another field.
96              
97             =head2 in
98              
99             $v = $v->in('foo', 'bar', 'baz');
100              
101             String value needs to match one of the values in the list.
102              
103             =head2 like
104              
105             $v = $v->like(qr/^[A-Z]/);
106              
107             String value needs to match the regular expression.
108              
109             =head2 num
110              
111             $v = $v->num;
112             $v = $v->num(2, 5);
113             $v = $v->num(-3, 7);
114             $v = $v->num(2, undef);
115             $v = $v->num(undef, 5);
116              
117             String value needs to be a non-fractional number (positive or negative) and if provided in the given range.
118              
119             =head2 size
120              
121             $v = $v->size(2, 5);
122             $v = $v->size(2, undef);
123             $v = $v->size(undef, 5);
124              
125             String value length or size of L object in bytes needs to be between these two values.
126              
127             =head2 upload
128              
129             $v = $v->upload;
130              
131             Value needs to be a L object, representing a file upload.
132              
133             =head1 FILTERS
134              
135             These filters are available by default.
136              
137             =head2 comma_separated
138              
139             $v = $v->optional('foo', 'comma_separated');
140              
141             Split string of comma separated values into separate values.
142              
143             =head2 not_empty
144              
145             $v = $v->optional('foo', 'not_empty');
146              
147             Remove empty string values and treat them as if they had not been submitted.
148              
149             =head2 trim
150              
151             $v = $v->optional('foo', 'trim');
152              
153             Trim whitespace characters from both ends of string value with L.
154              
155             =head1 ATTRIBUTES
156              
157             L implements the following attributes.
158              
159             =head2 checks
160              
161             my $checks = $validator->checks;
162             $validator = $validator->checks({size => sub ($v, $name, $value, @args) {...}});
163              
164             Registered validation checks, by default only L, L, L, L, L and
165             L are already defined.
166              
167             =head2 filters
168              
169             my $filters = $validator->filters;
170             $validator = $validator->filters({trim => sub {...}});
171              
172             Registered filters, by default only L, L and L are already defined.
173              
174             =head1 METHODS
175              
176             L inherits all methods from L and implements the following new ones.
177              
178             =head2 add_check
179              
180             $validator = $validator->add_check(size => sub ($v, $name, $value, @args) {...});
181              
182             Register a validation check.
183              
184             $validator->add_check(foo => sub ($v, $name, $value, @args) {
185             ...
186             return undef;
187             });
188              
189             =head2 add_filter
190              
191             $validator = $validator->add_filter(trim => sub ($v, $name, $value) {...});
192              
193             Register a new filter.
194              
195             $validator->add_filter(foo => sub ($v, $name, $value) {
196             ...
197             return $value;
198             });
199              
200             =head2 new
201              
202             my $validator = Mojolicious::Validator->new;
203              
204             Construct a new L object.
205              
206             =head2 validation
207              
208             my $v = $validator->validation;
209              
210             Build L object to perform validations.
211              
212             my $v = $validator->validation;
213             $v->input({foo => 'bar'});
214             $v->required('foo')->size(1, 5);
215             say $v->param('foo');
216              
217             =head1 SEE ALSO
218              
219             L, L, L.
220              
221             =cut