diff options
author | Yorhel <git@yorhel.nl> | 2008-10-23 20:37:15 +0200 |
---|---|---|
committer | Yorhel <git@yorhel.nl> | 2008-10-23 20:37:15 +0200 |
commit | 4276f0c419350bf7209bbef9692fdc2d561fae21 (patch) | |
tree | 26816af658148a7d9bde70d46b8024cc8dcd073e /lib | |
parent | e4480ac65bb2d58bb0d4f10d3669bd9c3cb61149 (diff) |
Wrote a form validator
This is basically a rewrite of VNDB::Util::Tools::FormCheck(), only
way more readable, with better documentation, added functionality,
and most likely less error-prone.
I haven't actually tested the function yet, though, but I do know it
compiles.
Also, commenting code is very unlike me, what the hell is wrong with
me!?
Diffstat (limited to 'lib')
-rw-r--r-- | lib/YAWF/Misc.pm | 99 |
1 files changed, 97 insertions, 2 deletions
diff --git a/lib/YAWF/Misc.pm b/lib/YAWF/Misc.pm index c32f75c..89a0e04 100644 --- a/lib/YAWF/Misc.pm +++ b/lib/YAWF/Misc.pm @@ -1,10 +1,105 @@ package YAWF::Misc; +# Yeah, just put all miscellaneous functions in one module! +# Geez, talk about being sloppy... - +use strict; +use warnings; use Exporter 'import'; -our @EXPORT = ('mail'); + +our @EXPORT = ('mail', 'formValidate'); + + +# Some pre-defined templates. It's possible to add templates at any time +# and from any file by executing something like: +# $YAWF::Misc::templates{templatename} = qr/regex/; +our %templates = ( + mail => qr/^[^@<>]+@[^@.<>]+(?:\.[^@.<>]+)+$/, + url => qr/^(http|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:\/~\+#]*[\w\-\@?^=%&\/~\+#])?$/, + asciiprint => qr/^[\x20-\x7E]*$/, + int => qr/^-?\d+$/, + pname => qr/^[a-z][a-z0-9-]*$/, +); + + +# Arguments: list of hashes representing a form item with validation rules +# { +# name => name of the form +# multi => 0/1, multiple form fields with the same name (see below) +# default => value to return if the field is left empty +# required => 0/1, whether this field is required, defaults to 1 +# maxlength => maximum length of the field +# minlength => minimum required length +# enum => [ value must be present in a set list ] +# template => one of the templates as defined in %templates +# regex => [ qr/ regex /, "message for the user" ] +# func => [ sub { external subroutine }, "message for the user" ] +# } +# +# Returns a hash with form names as keys and their value as argument, and +# a special key called '_err' in case there were errors. The value of this +# hash item is an array of failed test cases, each represented as an array +# with a list of: name of the field that failed validation and the rule on +# which the validation failed (the key-value pair specified as argument) +# +# If the multi rule is specified, the returned value will be an arrayref +# with the values of each item. If no fields were found with that name, the +# arrayref will be empty. The validator will stop checking the other values +# after one has failed. +sub formValidate { + my($self, @fields) = @_; + + my @err; + my %ret; + + for my $f (@fields) { + my @values = $f->{multi} ? $self->reqParam($f->{name}) : ( scalar $self->reqParam($f->{name}) ); + $values[0] = '' if !@values; + for (@values) { + my $valid = _validate($_, $f); + if(!ref $valid) { + $_ = $valid; + next; + } + push @err, [ $f->{name}, $$valid, $f->{$$valid} ]; + last; + } + $ret{$f->{name}} = $f->{multi} ? \@values : $values[0]; + } + + $ret{_err} = \@err if @err; + return \%ret; +} + + +# Internal function used by formValidate, checks one value on the validation +# rules, returns scalarref containing the failed rule on error, new value +# otherwise +sub _validate { # value, { rules } + my($v, $r) = @_; + + # empty + if(!$v && length $v < 1 && $v ne '0') { + return \'required' if $r->{required}; + return exists $r->{default} ? $r->{default} : undef; + } + + # length + return \'minlength' if $r->{minlength} && length $v < $r->{minlength}; + return \'maxlength' if $r->{maxlength} && length $v > $r->{maxlength}; + # enum + return \'enum' if $r->{enum} && !grep $_ eq $v, @{$r->{enum}}; + # template + return \'template' if $r->{template} && $v !~ /$templates{$r->{template}}/; + # regex + return \'regex' if $r->{regex} && $v !~ /$r->{regex}[0]/; + # function + return \'func' if $r->{func} && !$r->{func}[0]->($v); + # passed validation + return $v; +} + # A simple mail function, body and headers as arguments. Usage: |