Skip Menu |

This queue is for tickets about the Data-FormValidator CPAN distribution.

Maintainer(s)' notes

This is the bug queue for Data::FormValidator.

Report information
The Basics
Id: 73235
Status: resolved
Priority: 0/
Queue: Data-FormValidator

People
Owner: MARKSTOS [...] cpan.org
Requestors: LCARMICH [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: 4.70
Fixed in: (no value)



Subject: msgs lookup doesn't work for built in closures
Hello, I've run into an issue with msgs not working for built in constraint closures. Basically, when using 'use Data::FormValidator::Constraints qw( email );' then defining a msgs contraints message for parameter using with name '$results->msgs->{name}' will return default string. It appears that the constraint name is being set to the stringification of the code reference instead of using 'name'. I've attached a test case and patch for this issue. I had trouble finding the root of why this was being set. My patch is a work around for when the closures are setup. It seems that root cause is in the 'Data::FormValidator::Results::_constraint_hash_build' sub but my few attempts at fixing it seem to not have worked and the code is probably best updated by someone that is more familiar w/ all of the logic. My current workaround is to replicate the constraint closure in my local code. Thanks, Lee
Subject: Constraints.pm.diff
*** lib/Data/FormValidator/Constraints.pm 2011-12-13 09:27:41.000000000 -0600 --- ../orig.Data-FormValidator-4.70/lib/Data/FormValidator/Constraints.pm 2011-11-11 21:10:29.000000000 -0600 *************** *** 60,67 **** die "first arg to $func was not an object. Must be called as a constraint_method." unless ( Scalar::Util::blessed(\$dfv) && \$dfv->can('name_this') ); ! \$dfv->name_this('$func') unless \$dfv->get_current_constraint_name() ! && \$dfv->get_current_constraint_name() \!~ m\/^CODE\\(\\w+\\)\$\/; no strict 'refs'; return &{"match_$func"}(\@_); } --- 60,66 ---- die "first arg to $func was not an object. Must be called as a constraint_method." unless ( Scalar::Util::blessed(\$dfv) && \$dfv->can('name_this') ); ! \$dfv->name_this('$func') unless \$dfv->get_current_constraint_name(); no strict 'refs'; return &{"match_$func"}(\@_); }
Subject: closure_msgs.t
use Test::More qw/no_plan/; use strict; use Data::FormValidator; use Data::FormValidator::Constraints qw( email ); my $cm_profile = { required => [qw( admin prefork )], constraint_methods => { admin => email(), prefork => my_email() }, msgs => { missing => 'Test-Missing', invalid => 'Test-Invalid', invalid_seperator => ' ## ', constraints => { admin => 'Invalid Email Address', email => 'Invalid Email Address' }, format => 'ERROR: %s', prefix => 'error_', } }; my $validator = new Data::FormValidator( { cm => $cm_profile } ); my $input_hashref = { admin => 'invalidemail', prefork => 9, sleep => 11, rounds => 8 }; my $results; TODO: { local $TODO = 'need to test for msgs() called before validate'; # msgs() should return emit a warning and return undef if the hash # structure it points to is undefined. However, if it points to an # empty hash, then maybe there are just no messages. } # testing simple msg definition, $self->msgs should be returned as a hash ref my $msgs; # check constraint msg when using 'email' closure eval { $results = $validator->check( $input_hashref, 'cm' ); }; is $@, '', 'survived eval'; $msgs = $results->msgs; like $msgs->{error_admin}, qr/Invalid Email Address/, 'custom message (built in closure)'; like $msgs->{error_prefork}, qr/Invalid Email Address/, 'custom message (local closure)'; exit; # provide locally defined closure constraint method sub my_email { return sub { my $dfv = shift; # Name it to refer to in the 'msgs' system. $dfv->name_this('email'); # value of 'prospective_date' parameter my $in_email = $dfv->get_current_constraint_value(); # get other data to refer to my $data = $dfv->get_filtered_data; require Email::Valid; my $valid_email; # The extra check that the result matches the input prevents # an address like this from being considered valid: Joe Smith <joe@smith.com> if ( ( $valid_email = Email::Valid->address($in_email) ) and ( $valid_email eq $in_email ) ) { return $valid_email; } else { return undef; } } }
Thanks for the report. I agree I'd like to look into this further to understand why the name was being set to a code reference in the first place. Mark
I confirmed this issue today after being bitten by it, and am looking into it now. Thanks again for the bug report, and patch.
A fix for this has been released with 4.71.