The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Data::CGIForm - Form Data Interface.

DESCRIPTION

Data::CGIForm is yet another way to parse and handle CGI form data. The main motivation behind this module was a simple specification based validator that could handle multiple values.

You probably don't want to use this module. CGI::Validate is a much more feature complete take on getting this sort of work done. You may then ask why this is on the CPAN, I ask that of myself from time to time....

SYNOPSIS

 my %spec = (
     username => qr/^([a-z0-9]+)$/,
     password => {
         regexp => qr/^([a-z0-9+])$/,
         filter => [qw(strip_leading_ws, strip_trailing_ws)],
     },
     email => {
         regexp   => qr/^([a-z0-9@.]+)$/,
         filter   => \&qualify_domain,
         optional => 1,
         errors => {
             empty   => 'You didn\'t enter an email address.',
             invalid => 'Bad [% key %]: "[% value %]"',
         },
         extra_test   => \&check_email_addr,
     },
     email2 => {
        equal_to => email,
        errors   => {
                unequal => 'Both email addresses must be the same.',
        },
     },
 );

 my $r    = $ENV{'MOD_PERL'} ? Apache::Request->instance : CGI->new;
        
 my $form = Data::CGIForm->new(datasource => $r, spec => \%spec);
 

 my @params = $form->params;
 foreach $param (@params) {
     next unless my $error_string = $form->error($param);
                
     print STDERR $error_string;
 }
 
 if ($form->error('username')) {
     handle_error($form->username, $form->error('username'));
 }
 
 my $email    = $form->param('email');
 my $password = $form->password;

Building the Spec

The spec is a hashref describing the format of the data expected, and the rules that that data must match. The keys for this hash are the parameters that you are expecting.

In the most simple use, the value for a key can simply be a regular expression object. For example:

 %spec = (
     key => qr/.../,
 );

For the more complex options, a key should point to a hashref containing the options for that key. The following keys are supported in the hashref:

equal_to

This is simply a bit of syntaxtic sugar. It makes this:

 email2 => {
        equal_to => email,
 }
 

The same as:

 email2 => {
   regexp     => qr/^(.*)$/,
   extra_test => sub { 
     my ($textref, $form) = @_;
                
     return unless my $value = $form->param('email');
                
     if ($$textref eq $value) {
       return 1;
     } else {
       $form->param( email  => '');
       $form->param( email2 => '');
       $self->errorf(email2 => unequal => $$textref);
       $self->error( email => $self->error('email2'));
       return 0;
     }
   },
 }

equal_to does not work properly with multiple values. This is a feature. Also, do not use equal_to with a key more than once. The dragons may come looking for you if you do, and you taste good with ketchup.

regexp

The regular expression that the data must match.

length

The exact length that the input must be.

Note: Length is tested after filtering, but before any extra_test is run.

min_length

The minimum length that the input may be.

max_length

The maximum length that the input may be.

filter

The filter (or filters; to have more than one use an array ref) that the data must be passed though before it is validated. See the 'Filters' section below.

optional

boolean. If true then the parameter is optioinal. Note that if the parameter is given, then it is still validated. It can still be marked as an error if parameter is given.

errors

A hashref to the error strings for this parameter. See the Error Strings section below.

extra_test

A codefef (or arrayref of coderefs) of boolean functions that will be used in the validation process. See the Extra Test section below.

Filters

These functions are used to filter the data before that data is validated. In the spec they can be listed as a single filter, or an arrayref of many filters.

There filters are built in, and can be specified by name:

strip_leading_ws

Removes any leading white space from the data.

strip_trailing_ws

Removes any trailing white space from the data.

strip_ws

Removes any white space from the data.

lc

Converts the data to lowercase.

uc

Converts the data to uppercase.

If you with you use your own filter, then list it as a coderef in the spec.

Filters are passed 1 parameter. $_[0] is a scalar ref to the current data being filtered. For example:

 sub fix_newlines {
     my $textref = shift;
         $$textref   =~ s/[\n\r]*/\n/sg;
 }
 

Error Strings

For each key in the spec, you can specify different error messagses for different situations. For example:

 %spec = (
     field => {
         errors => {
             empty   => "You didn't fill this out!"
             invalid => "That doesn't look right!"
         },
         ...
     },
 ); 
 

Currently, there are three error types. invalid is used when the data does not match the validation specification, while empty is used when no data was given and the field is not optional. unequal is used when an equal_to pair does not match.

Two tags are filled in when the error messages are set:

 [% key %]     == Becomes ==> The current keyname.
 [% value %]   == Becomes ==> The value for the current key.

For example

 errors => {
     invalid => "[% value %] doesn't look like a [% key %]",
 }
 

If a type isn't given, then a default message is used.

Extra Test

Extra tests give the programmer a hook into the validation process.

Extra tests are declared in a similar fasion in the spec to filters, with the exception that everything is a coderef. There are no built in extra tests.

Extra tests functions are passed 3 paramters:

$_[0] is a scalar refernce to the data being tested:

 sub is_right_size {
     return (${$_[0]} > 100 and ${$_[0]} < 1250);
 }

$_[1] is the current Data::CGIForm object. $_[2] is the key name for the data being filtered. For example:

 sub check_email {
     my ($textref, $form, $key) = @_;
     unless (Email::Valid->address($$textref)) {
         $form->error(
             $key => "address failed $Email::Valid::Details check."
         );
         return;
     }
     return 1;
 }

Note that just setting the error string does not clear the parameter. You may want to do this yourself to keep with the built in behavior:

 sub check_email {
     my ($textref, $form, $key) = @_;
     unless (Email::Valid->address($$textref)) {
         $form->param($key => '');
         $form->error(
             $key => "address failed $Email::Valid::Details check."
         );
         return;
     }
     return 1;
 }

METHODS

Data::CGIForm->new()

Creates the Data::CGIForm object.

This should be called in the following matter:

  Data::CGIForm->new(datasource => $r, spec => \%spec, %options)

datasource should be something that has a param() method, like a CGI object, or a Apache::Request object. %spec is explained in the specification docs above.

The following options are supported:

start_param

Specifies that a given parameter acts as a switch for validation. If the value from the datasource for this parameter is true, then validation will be skipped and an empty string set as the value for each parameter in the spec.

$form->params

Returns a list of all the parameters that were in the datasource that are called for in the spec.

$form->param($name => $new_value)

Returns the parameter for a given var. If called in scalar context it returns the first value fetched from the datasource, regardless of the number of values.

$new_value should be a scalar or an array ref.

If $name is not given then this method returns $form->params, just like CGI or Apache::Request.

$form->error($param_name => $new_error)

Returns the error string (if an error occcured) for the a given parameter.

If two arguments are passed, this can be used to set the error string.

If no parameter is passed, than it returns boolean. True if an error occured in validating the data, false if no error occured.

$form->errors

Returns a hash of all the errors in param_name => error_message pairs.

$form->errorf($key, $type, $data)

Sets the error for $key to the format type $type, using $data for the [% value %] tag.

$form->started

Returns boolean based on if the start_param was set. True if the form was started, false otherwise.

$form->ready

Returns boolean; true if the form is started and there are no errors, false other wise.

AUTOLOAD

Data::CGIForm creates uses AUTOLOAD to create methods for the parameters in the spec. These methods just call $form->param($name), but it might prove helpful/elegent.

TODO

Do we want to test new values given to param() against the spec?

Make sure the user hasn't given dangerous equal_to pairs.

AUTHOR

Maintained by: Tim Wilde <twilde@dyndns.com>

Originally by: Chris Reinhardt <cpan@triv.org>

COPYRIGHT

Portions Copyright (c) 2006 Dynamic Network Services, Inc. All rights reserved.

Portions Copyright (c) 2002 Chris Reinhardt. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

SEE ALSO

perl(1), CGI(1).