Re: Data validation
[prev]
[thread]
[next]
[Date index for 2004/11/10]
On Tue, 9 Nov 2004 17:40:40 -0800, Dan Sully <daniel@xxxxxxxxxxxx.xxx> wrote:
> * Drew Taylor <taylor.andrew.j@xxxxx.xxx> shaped the electrons to say...
>
> >I also follow the MVC pattern in my applications. I do form validation
> >in my CGI::Application-based applications with DFV, but the paranoid
> >part of me wants validation at the model level too - mostly to check
> >for required fields, etc.
>
> Is anyone using DFV with mod_perl + Template Toolkit? I'd love to see some examples.
This probably isn't anything special but here's how I'm currently
doing it. This uses a combination of CGI::App::Plugin::TT and DFV.
First my form display and processing code is in separate methods. The
display methods can be named anything (set via run_modes() in
setup()), and the processing methods are name "process_$rm" where $rm
is the current runmode. So in prerun I check to see if the form has
been submitted (I just use a hidden element). If not, then continue
running the display method.
If it was submitted, check to see if a DFV profile has been defined. I
have this in another method called "profile_$rm" where $rm is the
current runmode and just returns a data structure suitable for use
with DFV. If no profile was defined, go ahead and run the processing
code assuming that it does whatever validation it needs. If uses the
prerun_mode() method to change the runmode. Remember that you are
changing the runmode if any code/templates need this. It's as simple
as $rm =~ s/^process_//;
If a DFV profile was defined, then run DFV using that profile. If
there are any errors, store them for later inclusion into the template
params and DON'T run the processing code. If everything passes, change
the runmode via prerun_mode() and run the processing method. This
assumes that the processing will either return a redirect (what I
typically do to avoid form resubmission problems), or output
something.
I'm sure someone will say "That's rather complicated. Why not just go
ahead and define a procesing runmode and have the form submit to that
runmode directly?" This is really a matter of my personal preference.
I don't want the processing code to be directly accessible via a
runmode. In my scheme, it's added on the fly via run_modes() as
needed. All my processing method redirect back to a display runmode
after doing their thing, so I only want them run when the
circumstances are right.
For me, this makes it very easy to write new runmodes: I write a
display method, a processing method, and a validation method. The
decision about when to call each is done automatically, and I get data
validation for minimal effort. The only big thing left on my todo list
is a way to get the templates (TT of course) to automatically include
the error messages - "[% err_element_name %] beside the form elements.
The code below was written by me, for me, and anyone is free to resuse
as much as you like.
Comments welcome!
Drew
sub cgiapp_prerun {
my $self = shift;
my $rm = $self->get_current_runmode;
# check for form submission
if (!$self->is_form_submitted) {
return;
}
# check for method defining DFV profile - not required
my $profile_method = "_profile_$rm";
unless ($self->can($profile_method)) {
$self->_set_processing_mode($rm);
return;
}
# get the profile data structure - required at this point
my $profile;
eval {
$profile = $self->$profile_method();
};
$self->prerun_mode('error', $@) if $@ || !$profile;
# check the profile and save any errors
my $dfv = Data::FormValidator->new({}, $self->dfv_defaults);
my $results = $dfv->check($self->query, $profile);
if ($results->has_missing || $results->has_invalid) {
$self->param('dfv_results', $results);
my $msgs = $results->msgs;
$self->param('dfv_msgs', $msgs);
$self->status("Error processing the form");
return;
}
$self->_set_processing_mode($rm);
}
sub _set_processing_mode {
my ($self, $rm) = @_;
# run the processor method
$rm = "process_$rm";
$self->run_modes($rm => $rm);
$self->prerun_mode($rm);
}
--
----------------------------------------------------------------
Drew Taylor * Web development & consulting
Email: drew@xxxxxxxxxx.xxx * Site implementation & hosting
Web : www.drewtaylor.com * perl/mod_perl/DBI/mysql/postgres
----------------------------------------------------------------
|
(message missing)
|