NAME
Data::FormValidator::Multi - Check multidimensional data structures with Data::FormValidator
SYNOPSIS
use Data::FormValidator::Multi;
# a hash that has hashes and arrays as some of its values
my $data = { ... };
# a Data::FormValidator profile
my $main_profile = { ... };
# Data::FormValidator profiles for hashes and arrays in $data
my $meta_profile = { ... };
my $timezones_profile = { ... };
# create the validator
my $dfv = Data::FormValidator::Multi->new({
profile => $main_profile,
subprofiles => {
meta => $meta_profile,
timezones => $timezones_profile,
}
});
# run the check on the data
my $results = $dfv->check( $data );
# call ->to_json on the results object to get a data structure of errors
use Data::Dumper;
print Data::Dumper->Dump([$results->to_json], ['results_as_json']);
DESCRIPTION
Data::FormValidator feels like the sanest data validator to me other than now that I use angular a lot I'm POSTing complex data structures now instead of CGI key=value pairs.
This module provides the ability to validate complex data structures and keep the same DFV if ( $results->success ) { ... }
pattern during validation.
DFVM can validate arbitrarily nested hash and array data structures. For arrays the specified profile is applied to each element in the array.
After a data structure is check()
ed, success()
will return false if a single bit of data in the data structure is invalid. From there to_json()
can be called on the $result
to get a data structure that has invalid fields as keys and the errors for that field as its value. What I do with this return value is pass it back to an angular controller so that, with of the magic of two way binding, error messages and indicators magically light up.
EXAMPLE
Here is a complete example of validating a hash that has a hash and an array as some of its values. See the t/lib/Test/Data/FormValidator/Multi/Nested.pm test for an example of validating an arbitrarily deep data structure.
use warnings;
use strict;
use Data::FormValidator::Multi;
# the data we are validating. Note the negative $data->{dashboard} and
# $data->{timezones}[1]{id} fields, and the commented out hash entries.
# These are the invalid / missing fields that DFVM will report on
my $data = {
dashboard => -23,
name => 'FooBar',
meta => {
foo => 'Foo',
# bar => 'Bar',
bazz => 'Bazz',
},
timezones => [
{
id => 999,
name => 'Home',
zone => 'America/New_York',
date => '01/01',
time => '23:59'
},
{
id => -111,
name => 'L. A.',
zone => 'America/Los_Angeles',
# date => '01/01',
time => '20:59'
}
]
};
# profile for the fields in the top level of the input data
my $main_profile = {
required => [qw(name dashboard timezones )],
optional => [qw(meta)],
constraint_methods => {
dashboard => [
{
name => 'not_positive',
constraint_method => sub {
my ($dfv, $val) = @_;
return $val =~ /\A\d+\z/;
}
}
]
},
msgs => {
format => '%s',
invalid => 'FIELD IS INVALID',
missing => 'FIELD IS REQUIRED',
constraints => {
not_positive => 'MUST BE POSITIVE'
}
}
};
# profile for the data in the $data->{meta} hash
my $meta_profile = {
required => [qw( foo bar bazz )],
msgs => {
format => '%s',
invalid => 'FIELD IS INVALID',
missing => 'FIELD IS REQUIRED',
}
};
# profile for the data in the $data->{timezones} array
my $timezones_profile = {
required => [ qw( id zone name date time ) ],
constraint_methods => {
id => [
{
name => 'not_positive',
constraint_method => sub {
my ($dfv, $val) = @_;
return $val =~ /\A\d+\z/;
}
}
]
},
msgs => {
format => '%s',
invalid => 'FIELD IS INVALID',
missing => 'FIELD IS REQUIRED',
constraints => {
not_positive => 'MUST BE POSITIVE'
}
}
};
# create a profile, passing the top level profile under the 'profile' key, and
# the profiles for the $data->{meta} hash and $data->{timezones} array as a
# hash under the 'subprofiles' key.
my $dfv = Data::FormValidator::Multi->new({
profile => $main_profile,
subprofiles => {
meta => $meta_profile,
timezones => $timezones_profile,
}
});
# run the check on the data
my $results = $dfv->check( $data );
use Data::Dumper;
print Data::Dumper->Dump([$results->to_json], ['results_as_json']);
outputs:
$results_as_json = {
'meta' => {
'bar' => 'FIELD IS REQUIRED'
},
'timezones' => [
undef,
{
'id' => 'MUST BE POSITIVE',
'date' => 'FIELD IS REQUIRED'
}
],
'dashboard' => 'MUST BE POSITIVE'
};
METHODS
check
If given an array, loop over them, do a DFVM check on each element, and return an array blessed as a DFV::Multi::Results object.
Otherwise, call in to parent check method (plain Data::FormValidator) for validation of the data and return the DFV::Multi::Results object.
check_nested
check_nested_for
has_nested_profiles
no_nested_profiles
handle_hash_input
handle_array_input
move_from_valid_to_objects
SEE ALSO
AUTHOR
Todd Wade <waveright@gmail.com>
COPYRIGHT AND LICENSE
This software is copyright (c) 2016 by Todd Wade.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.