package LIMS::Controller::Roles::FormData; use Moose::Role; use Data::Dumper; has results_data_validation => ( is => 'ro', lazy_build => 1 ); sub _build_results_data_validation { $_[0]->get_yaml_file('results_data_validation'); } has test_name_map => ( is => 'ro', lazy_build => 1 ); # don't use name 'lab_tests_map' sub _build_test_name_map { my $aref = $_[0]->model('LabTest')->get_lab_tests; # warn Dumper $aref; my %h = map { $_->id => $_->test_name } @$aref; # warn Dumper \%h; return \%h; } has results_input_errors => ( is => 'ro', isa => 'ArrayRef[Str]', traits => ['Array'], default => sub { [] }, handles => { all_results_errors => 'elements', have_results_errors => 'count', add_results_error => 'push', }, ); use Data::FormValidator; use LIMS::Local::Config; sub get_data_from_dfv { my $self = shift; my $profile = shift || return $self->error('no profile passed to get_data_from_dfv()'); my $validator = $self->_get_validator(); # warn Dumper $validator; my $dfv = $validator->check($self->query, $profile); my $data = $dfv->valid(); # $self->debug($data); return $data; } sub validate_form_params { my $self = shift; my $profile = shift || return $self->error('no profile passed to get_data_from_dfv()'); my $params = shift || $self->query(); # optional - uses CGI if not passed my $validator = $self->_get_validator(); # warn Dumper $validator; my $results = $validator->check($params, $profile); # warn Dumper $results; return $results; } sub validate_results_data_entry { my ($self, $ref) = @_; # warn Dumper $ref; my $test_label = $ref->{test_label}; my $data_type = $ref->{data_type}; my $test_id = $ref->{test_id}; my $result = $ref->{result}; # form param test name for results passed as lab_test_id_: my $form_param_name = 'lab_test_id_' . $test_id; my $test_result_pair = sprintf '%s [%s]', $test_label, $result; # generic validation for data type: my $profile_name = 'data_entry_' . $data_type; # not all data types need or have validators: if ( LIMS::Validate->can($profile_name) ) { # get validation method & error msg for profile name: my $validator = $self->validate($profile_name); # warn Dumper $validator; my $error_msg = join ': ', $test_result_pair, $validator->{err_msg}; my $validation_method = $validator->{method}; my $validation_profile = { required => [ $form_param_name ], # or param is ignored constraint_methods => { $form_param_name => $validation_method, }, }; # warn Dumper $validation_profile; my $dfv = $self->validate_form_params($validation_profile); # warn Dumper $dfv; # add failure msg & return if invalid: if ( $dfv->has_invalid ) { $self->add_results_error($error_msg); return { validation_failed => 1 }; } } if ( my $cfg = $self->results_data_validation ) { # warn Dumper $cfg; my $test_name = $self->test_name_map->{$test_id}; # warn $test_name; my $messages = $self->messages('dfv_msgs'); if ( my $regex = $cfg->{$test_name} ) { # warn $regex; warn $result; # warn $result =~ /^$regex$/ ? 'match' : 'no match'; if ( $result !~ /^$regex$/ ) { my $err = $test_result_pair .': '. $messages->{invalid_format}; $self->add_results_error($err); return { validation_failed => 1 }; } } } # OK, validation didn't fail: return { validation_failed => 0 } } # loads dfv_defaults from LIMS config: sub _get_validator { my $self = shift; my $cfg = LIMS::Local::Config->instance; my $dfv = Data::FormValidator->new({}, $cfg->{dfv_defaults}); return $dfv; } 1;