source: main/trunk/greenstone2/perllib/cpan/Mojolicious/Validator/Validation.pm@ 32205

Last change on this file since 32205 was 32205, checked in by ak19, 6 years ago

First set of commits to do with implementing the new 'paged_html' output option of PDFPlugin that uses using xpdftools' new pdftohtml. So far tested only on Linux (64 bit), but things work there so I'm optimistically committing the changes since they work. 2. Committing the pre-built Linux binaries of XPDFtools for both 32 and 64 bit built by the XPDF group. 2. To use the correct bitness variant of xpdftools, setup.bash now exports the BITNESS env var, consulted by gsConvert.pl. 3. All the perl code changes to do with using xpdf tools' pdftohtml to generate paged_html and feed it in the desired form into GS(3): gsConvert.pl, PDFPlugin.pm and its parent ConvertBinaryPFile.pm have been modified to make it all work. xpdftools' pdftohtml generates a folder containing an html file and a screenshot for each page in a PDF (as well as an index.html linking to each page's html). However, we want a single html file that contains each individual 'page' html's content in a div, and need to do some further HTML style, attribute and structure modifications to massage the xpdftool output to what we want for GS. In order to parse and manipulate the HTML 'DOM' to do this, we're using the Mojo::DOM package that Dr Bainbridge found and which he's compiled up. Mojo::DOM is therefore also committed in this revision. Some further changes and some display fixes are required, but need to check with the others about that.

File size: 7.1 KB
Line 
1package Mojolicious::Validator::Validation;
2use Mojo::Base -base;
3
4use Carp ();
5use Scalar::Util ();
6
7has [qw(csrf_token topic validator)];
8has [qw(input output)] => sub { {} };
9
10sub AUTOLOAD {
11 my $self = shift;
12
13 my ($package, $method) = our $AUTOLOAD =~ /^(.+)::(.+)$/;
14 Carp::croak "Undefined subroutine &${package}::$method called"
15 unless Scalar::Util::blessed $self && $self->isa(__PACKAGE__);
16
17 return $self->check($method => @_) if $self->validator->checks->{$method};
18 Carp::croak qq{Can't locate object method "$method" via package "$package"};
19}
20
21sub check {
22 my ($self, $check) = (shift, shift);
23
24 return $self unless $self->is_valid;
25
26 my $cb = $self->validator->checks->{$check};
27 my $name = $self->topic;
28 my $values = $self->output->{$name};
29 for my $value (ref $values eq 'ARRAY' ? @$values : $values) {
30 next unless my $result = $self->$cb($name, $value, @_);
31 return $self->error($name => [$check, $result, @_]);
32 }
33
34 return $self;
35}
36
37sub csrf_protect {
38 my $self = shift;
39 my $token = $self->input->{csrf_token};
40 $self->error(csrf_token => ['csrf_protect'])
41 unless $token && $token eq ($self->csrf_token // '');
42 return $self;
43}
44
45sub error {
46 my ($self, $name) = (shift, shift);
47 return $self->{error}{$name} unless @_;
48 $self->{error}{$name} = shift;
49 delete $self->output->{$name};
50 return $self;
51}
52
53sub every_param {
54 return [] unless defined(my $value = $_[0]->output->{$_[1] // $_[0]->topic});
55 return [ref $value eq 'ARRAY' ? @$value : $value];
56}
57
58sub failed { [sort keys %{shift->{error}}] }
59
60sub has_data { !!keys %{shift->input} }
61
62sub has_error { $_[1] ? exists $_[0]{error}{$_[1]} : !!keys %{$_[0]{error}} }
63
64sub is_valid { exists $_[0]->output->{$_[1] // $_[0]->topic} }
65
66sub optional {
67 my ($self, $name, @filters) = @_;
68
69 return $self->topic($name) unless defined(my $input = $self->input->{$name});
70
71 my @input = ref $input eq 'ARRAY' ? @$input : ($input);
72 for my $cb (map { $self->validator->filters->{$_} } @filters) {
73 @input = map { $self->$cb($name, $_) } @input;
74 }
75 $self->output->{$name} = ref $input eq 'ARRAY' ? \@input : $input[0]
76 if @input && !grep { !length } @input;
77
78 return $self->topic($name);
79}
80
81sub param { shift->every_param(shift)->[-1] }
82
83sub passed { [sort keys %{shift->output}] }
84
85sub required {
86 my ($self, $name) = (shift, shift);
87 return $self if $self->optional($name, @_)->is_valid;
88 return $self->error($name => ['required']);
89}
90
911;
92
93=encoding utf8
94
95=head1 NAME
96
97Mojolicious::Validator::Validation - Perform validations
98
99=head1 SYNOPSIS
100
101 use Mojolicious::Validator;
102 use Mojolicious::Validator::Validation;
103
104 my $validator = Mojolicious::Validator->new;
105 my $v = Mojolicious::Validator::Validation->new(validator => $validator);
106 $v->input({foo => 'bar'});
107 $v->required('foo')->in('bar', 'baz');
108 say $v->param('foo');
109
110=head1 DESCRIPTION
111
112L<Mojolicious::Validator::Validation> performs L<Mojolicious::Validator>
113validation checks.
114
115=head1 ATTRIBUTES
116
117L<Mojolicious::Validator::Validation> implements the following attributes.
118
119=head2 csrf_token
120
121 my $token = $v->csrf_token;
122 $v = $v->csrf_token('fa6a08...');
123
124CSRF token.
125
126=head2 input
127
128 my $input = $v->input;
129 $v = $v->input({foo => 'bar', baz => [123, 'yada']});
130
131Data to be validated.
132
133=head2 output
134
135 my $output = $v->output;
136 $v = $v->output({foo => 'bar', baz => [123, 'yada']});
137
138Validated data.
139
140=head2 topic
141
142 my $topic = $v->topic;
143 $v = $v->topic('foo');
144
145Name of field currently being validated.
146
147=head2 validator
148
149 my $v = $v->validator;
150 $v = $v->validator(Mojolicious::Validator->new);
151
152L<Mojolicious::Validator> object this validation belongs to.
153
154=head1 METHODS
155
156L<Mojolicious::Validator::Validation> inherits all methods from L<Mojo::Base>
157and implements the following new ones.
158
159=head2 check
160
161 $v = $v->check('size', 2, 7);
162
163Perform validation check on all values of the current L</"topic">, no more
164checks will be performed on them after the first one failed. All checks from
165L<Mojolicious::Validator/"CHECKS"> are supported.
166
167=head2 csrf_protect
168
169 $v = $v->csrf_protect;
170
171Validate C<csrf_token> and protect from cross-site request forgery.
172
173=head2 error
174
175 my $err = $v->error('foo');
176 $v = $v->error(foo => ['custom_check']);
177 $v = $v->error(foo => [$check, $result, @args]);
178
179Get or set details for failed validation check, at any given time there can
180only be one per field.
181
182 # Details about failed validation
183 my ($check, $result, @args) = @{$v->error('foo')};
184
185 # Force validation to fail for a field without performing a check
186 $v->error(foo => ['some_made_up_check_name']);
187
188=head2 every_param
189
190 my $values = $v->every_param;
191 my $values = $v->every_param('foo');
192
193Similar to L</"param">, but returns all values sharing the same name as an
194array reference.
195
196 # Get first value
197 my $first = $v->every_param('foo')->[0];
198
199=head2 failed
200
201 my $names = $v->failed;
202
203Return an array reference with all names for values that failed validation.
204
205 # Names of all values that failed
206 say for @{$v->failed};
207
208=head2 has_data
209
210 my $bool = $v->has_data;
211
212Check if L</"input"> is available for validation.
213
214=head2 has_error
215
216 my $bool = $v->has_error;
217 my $bool = $v->has_error('foo');
218
219Check if validation resulted in errors, defaults to checking all fields.
220
221=head2 is_valid
222
223 my $bool = $v->is_valid;
224 my $bool = $v->is_valid('foo');
225
226Check if validation was successful and field has a value, defaults to checking
227the current L</"topic">.
228
229=head2 optional
230
231 $v = $v->optional('foo');
232 $v = $v->optional('foo', 'filter1', 'filter2');
233
234Change validation L</"topic"> and apply filters. All filters from
235L<Mojolicious::Validator/"FILTERS"> are supported.
236
237 # Trim value and check size
238 $v->optional('user', 'trim')->size(1, 15);
239
240=head2 param
241
242 my $value = $v->param;
243 my $value = $v->param('foo');
244
245Access validated values, defaults to the current L</"topic">. If there are
246multiple values sharing the same name, and you want to access more than just the
247last one, you can use L</"every_param">.
248
249 # Get value right away
250 my $user = $v->optional('user')->size(1, 15)->param;
251
252=head2 passed
253
254 my $names = $v->passed;
255
256Return an array reference with all names for values that passed validation.
257
258 # Names of all values that passed
259 say for @{$v->passed};
260
261=head2 required
262
263 $v = $v->required('foo');
264 $v = $v->required('foo', 'filter1', 'filter2');
265
266Change validation L</"topic">, apply filters, and make sure a value is present
267and not an empty string. All filters from L<Mojolicious::Validator/"FILTERS">
268are supported.
269
270 # Trim value and check size
271 $v->required('user', 'trim')->size(1, 15);
272
273=head1 AUTOLOAD
274
275In addition to the L</"ATTRIBUTES"> and L</"METHODS"> above, you can also call
276validation checks provided by L</"validator"> on
277L<Mojolicious::Validator::Validation> objects, similar to L</"check">.
278
279 # Call validation checks
280 $v->required('foo')->size(2, 5)->like(qr/^[A-Z]/);
281 $v->optional('bar')->equal_to('foo');
282 $v->optional('baz')->in('test', '123');
283
284 # Longer version
285 $v->required('foo')->check('size', 2, 5)->check('like', qr/^[A-Z]/);
286
287=head1 SEE ALSO
288
289L<Mojolicious>, L<Mojolicious::Guides>, L<https://mojolicious.org>.
290
291=cut
Note: See TracBrowser for help on using the repository browser.