File Coverage

blib/lib/Data/CGIForm.pm
Criterion Covered Total %
statement 194 213 91.0
branch 110 134 82.0
condition 24 49 48.9
subroutine 16 19 84.2
pod 8 8 100.0
total 352 423 83.2


line stmt bran cond sub pod time code
1             package Data::CGIForm;
2             #
3             # $Id: CGIForm.pm 2 2010-06-25 14:41:40Z twilde $
4             #
5 12     12   339660 use 5.006;
  12         47  
  12         494  
6 12     12   62 use strict;
  12         28  
  12         434  
7 12     12   61 use warnings;
  12         26  
  12         461  
8 12     12   67 use Carp ();
  12         22  
  12         48371  
9              
10             our $VERSION = 0.5;
11              
12             =head1 NAME
13              
14             Data::CGIForm - Form Data Interface.
15              
16             =head1 DESCRIPTION
17              
18             Data::CGIForm is yet another way to parse and handle CGI form data.
19             The main motivation behind this module was a simple specification
20             based validator that could handle multiple values.
21              
22             You probably don't want to use this module. L
23             is a much more feature complete take on getting this sort of work done.
24             You may then ask why this is on the CPAN, I ask that of myself from time to
25             time....
26              
27             =head1 SYNOPSIS
28              
29             my %spec = (
30             username => qr/^([a-z0-9]+)$/,
31             password => {
32             regexp => qr/^([a-z0-9+])$/,
33             filter => [qw(strip_leading_ws, strip_trailing_ws)],
34             },
35             email => {
36             regexp => qr/^([a-z0-9@.]+)$/,
37             filter => \&qualify_domain,
38             optional => 1,
39             errors => {
40             empty => 'You didn\'t enter an email address.',
41             invalid => 'Bad [% key %]: "[% value %]"',
42             },
43             extra_test => \&check_email_addr,
44             },
45             email2 => {
46             equal_to => email,
47             errors => {
48             unequal => 'Both email addresses must be the same.',
49             },
50             },
51             );
52              
53             my $r = $ENV{'MOD_PERL'} ? Apache::Request->instance : CGI->new;
54            
55             my $form = Data::CGIForm->new(datasource => $r, spec => \%spec);
56            
57              
58             my @params = $form->params;
59             foreach $param (@params) {
60             next unless my $error_string = $form->error($param);
61            
62             print STDERR $error_string;
63             }
64            
65             if ($form->error('username')) {
66             handle_error($form->username, $form->error('username'));
67             }
68            
69             my $email = $form->param('email');
70             my $password = $form->password;
71              
72             =head1 Building the Spec
73              
74             The spec is a hashref describing the format of the data expected, and the
75             rules that that data must match. The keys for this hash are the parameters
76             that you are expecting.
77              
78             In the most simple use, the value for a key can simply be a regular expression
79             object. For example:
80              
81             %spec = (
82             key => qr/.../,
83             );
84              
85             For the more complex options, a key should point to a hashref containing the
86             options for that key. The following keys are supported in the hashref:
87              
88             =over 4
89              
90             =item equal_to
91              
92             This is simply a bit of syntaxtic sugar. It makes this:
93              
94             email2 => {
95             equal_to => email,
96             }
97            
98             The same as:
99              
100             email2 => {
101             regexp => qr/^(.*)$/,
102             extra_test => sub {
103             my ($textref, $form) = @_;
104            
105             return unless my $value = $form->param('email');
106            
107             if ($$textref eq $value) {
108             return 1;
109             } else {
110             $form->param( email => '');
111             $form->param( email2 => '');
112             $self->errorf(email2 => unequal => $$textref);
113             $self->error( email => $self->error('email2'));
114             return 0;
115             }
116             },
117             }
118              
119             C does not work properly with multiple values. This is a feature.
120             Also, do not use C with a key more than once. The dragons may
121             come looking for you if you do, and you taste good with ketchup.
122              
123             =item regexp
124              
125             The regular expression that the data must match.
126              
127             =item length
128              
129             The I length that the input must be.
130              
131             B Length is tested after filtering, but before any extra_test is run.
132              
133             =item min_length
134              
135             The minimum length that the input may be.
136              
137             =item max_length
138              
139             The maximum length that the input may be.
140              
141             =item filter
142              
143             The filter (or filters; to have more than one use an array ref) that the data
144             must be passed though before it is validated. See the 'Filters' section
145             below.
146              
147             =item optional
148              
149             boolean. If true then the parameter is optioinal. Note that if the parameter
150             is given, then it is still validated. It can still be marked as an error if
151             parameter is given.
152              
153             =item errors
154              
155             A hashref to the error strings for this parameter. See the Error Strings
156             section below.
157              
158             =item extra_test
159              
160             A codefef (or arrayref of coderefs) of boolean functions that will be used
161             in the validation process. See the Extra Test section below.
162              
163             =back
164              
165             =head2 Filters
166              
167             These functions are used to filter the data before that data is validated. In
168             the spec they can be listed as a single filter, or an arrayref of many filters.
169              
170             There filters are built in, and can be specified by name:
171              
172             =over 4
173              
174             =item strip_leading_ws
175              
176             Removes any leading white space from the data.
177              
178             =item strip_trailing_ws
179              
180             Removes any trailing white space from the data.
181              
182             =item strip_ws
183              
184             Removes any white space from the data.
185              
186             =item lc
187              
188             Converts the data to lowercase.
189              
190             =item uc
191              
192             Converts the data to uppercase.
193              
194             =back
195              
196             If you with you use your own filter, then list it as a coderef in the spec.
197              
198             Filters are passed 1 parameter. $_[0] is a scalar ref to the current data
199             being filtered. For example:
200              
201             sub fix_newlines {
202             my $textref = shift;
203             $$textref =~ s/[\n\r]*/\n/sg;
204             }
205            
206             =cut
207              
208             our %Filters = (
209             strip_leading_ws => sub { ${$_[0]} =~ s/^\s*// },
210             strip_trailing_ws => sub { ${$_[0]} =~ s/\s*$// },
211             strip_ws => sub { ${$_[0]} =~ s/\s*//g },
212             lc => sub { ${$_[0]} = lc ${$_[0]} },
213             uc => sub { ${$_[0]} = uc ${$_[0]} },
214             );
215              
216             =head2 Error Strings
217              
218             For each key in the spec, you can specify different error messagses for
219             different situations. For example:
220              
221             %spec = (
222             field => {
223             errors => {
224             empty => "You didn't fill this out!"
225             invalid => "That doesn't look right!"
226             },
227             ...
228             },
229             );
230            
231             Currently, there are four error types. C is used when
232             the data does not match the validation specification, while
233             C is used when no data was given and the field is not optional.
234             C is used when an equal_to pair does not match. C is used
235             when a length, min_length, or max_length parameter is violated.
236              
237             Two tags are filled in when the error messages are set:
238              
239             [% key %] == Becomes ==> The current keyname.
240             [% value %] == Becomes ==> The value for the current key.
241              
242             For example
243              
244             errors => {
245             invalid => "[% value %] doesn't look like a [% key %]",
246             }
247            
248             If a type isn't given, then a default message is used.
249              
250             =cut
251              
252             our %DefaultErrors = (
253             invalid => 'The input for [% key %] ("[% value %]") is invalid.',
254             empty => '"[% key %]" not given.',
255             unequal => 'The two fields must match.',
256             length => 'The input for [% key %} ("[% value %]") does not meet length constraints.',
257             );
258              
259             our @ValidErrorFields = qw(invalid empty unequal length);
260              
261             =head2 Extra Test
262              
263             Extra tests give the programmer a hook into the validation process.
264              
265             Extra tests are declared in a similar fasion in the spec to filters,
266             with the exception that everything is a coderef. There are no built
267             in extra tests.
268              
269             Extra tests functions are passed 3 paramters:
270              
271             $_[0] is a scalar refernce to the data being tested:
272              
273             sub is_right_size {
274             return (${$_[0]} > 100 and ${$_[0]} < 1250);
275             }
276              
277             $_[1] is the current Data::CGIForm object. $_[2] is the key name for the
278             data being filtered. For example:
279              
280             sub check_email {
281             my ($textref, $form, $key) = @_;
282             unless (Email::Valid->address($$textref)) {
283             $form->error(
284             $key => "address failed $Email::Valid::Details check."
285             );
286             return;
287             }
288             return 1;
289             }
290              
291             Note that just setting the error string does not clear the parameter. You
292             may want to do this yourself to keep with the built in behavior:
293              
294             sub check_email {
295             my ($textref, $form, $key) = @_;
296             unless (Email::Valid->address($$textref)) {
297             $form->param($key => '');
298             $form->error(
299             $key => "address failed $Email::Valid::Details check."
300             );
301             return;
302             }
303             return 1;
304             }
305              
306             =head1 METHODS
307              
308             =head2 Data::CGIForm->new()
309              
310             Creates the Data::CGIForm object.
311              
312             This should be called in the following matter:
313              
314             Data::CGIForm->new(datasource => $r, spec => \%spec, %options)
315              
316             C should be something that has a C method, like a L
317             object, or a L object. C<%spec> is explained in the specification
318             docs above.
319              
320             The following options are supported:
321              
322             =over 4
323              
324             =item start_param
325              
326             Specifies that a given parameter acts as a switch for validation. If the value from
327             the datasource for this parameter is true, then validation will be skipped and an empty
328             string set as the value for each parameter in the spec.
329              
330             =back
331              
332             =cut
333              
334             sub new {
335 23     23 1 6176 my $class = shift;
336            
337 23 50       108 Carp::croak("${class}->new(): Odd number of parameters given.") unless @_ % 2 == 0;
338            
339 23         110 my %params = @_;
340            
341 23         72 for (qw(datasource spec)) {
342 46 50       227 Carp::croak("${class}->new(): $_ not given.") unless $params{$_};
343             }
344            
345 23 50 33     388 unless (ref $params{'datasource'} and $params{'datasource'}->can('param')) {
346 0         0 Carp::croak("${class}->new(): 'datasource' must be an object with a param() method.");
347             }
348            
349 23 50 33     195 unless (ref $params{'spec'} and ref $params{'spec'} eq 'HASH') {
350 0         0 Carp::croak("${class}->new(): 'spec' must be a hashref.");
351             }
352            
353 23         104 my $self = {
354             spec => {},
355             data => {},
356             errors => {},
357             };
358            
359 23 100       77 if ($params{'start_param'}) {
360 3 100       12 unless ($params{'spec'}->{$params{'start_param'}}) {
361 1         215 Carp::croak(qq(${class}->new(): 'start_param' ("$params{'start_param'}") not listed in the spec.));
362             }
363            
364 2         5 $self->{'start_param'} = $params{'start_param'};
365             }
366            
367            
368 22         65 bless($self, $class);
369            
370             # Scan the user spec, and normalize it
371 22         93 $self->_scan_spec($params{'spec'});
372            
373             # pull the data from the datasource
374 22         691 $self->_populate_vars($params{'datasource'});
375            
376             # run the validation spec
377 22 100       109 $self->_validate_params unless $self->{'in_unstarted_mode'};
378            
379 22         192 return $self;
380             }
381              
382             #
383             # $form->_scan_spec($spec)
384             #
385             # Runs though the given spec, and normalizes it.
386             #
387             sub _scan_spec {
388 22     22   51 my ($self, $s) = @_;
389            
390 22         74 foreach my $param (keys %$s) {
391 70         128 my $value = $s->{$param};
392            
393 70 50       169 Carp::croak("new(): spec error: $param is not a ref") unless ref $value;
394            
395 70 100       188 if (ref $value eq 'HASH') {
    50          
396 42         105 $self->_insert_spec($param => $value);
397             } elsif (ref $value eq 'Regexp') {
398 28         105 $self->_insert_spec($param => { regexp => $value});
399             } else {
400 0         0 Carp::croak("new(): spec error: $param is not a hashref or regexp");
401             }
402             }
403            
404 22 100       1476 $self->_insert_delayed_specs if $self->{'delayed_specs'};
405             }
406              
407             #
408             # $form->_insert_spec($key => $spec)
409             #
410             # Does most of the heavy lifting for _scan_spec
411             #
412             sub _insert_spec {
413 72     72   123 my ($self, $key, $old_spec) = @_;
414            
415             #
416             # Make a copy just to be safe.
417             #
418 72         240 my $s = { %$old_spec };
419              
420 72 100       204 if ($s->{'equal_to'}) {
421             # equal_to rules must be inserted last, so
422             # they can see all the other data that has been inserted.
423 2         30 $self->{'delayed_specs'}->{$key} = $s;
424 2         8 return;
425             }
426            
427            
428            
429 70         401 my $regexp = delete $s->{'regexp'};
430            
431 70 50       168 Carp::croak("new(): spec error: no regexp given for '$key'.")
432             unless $regexp;
433            
434 70 50 33     346 Carp::croak("new(): spec error: regexp for '$key' not a regexp.")
435             unless ref $regexp and ref $regexp eq 'Regexp';
436            
437 70 100       181 my $optional = delete $s->{'optional'} ? 1 : 0;
438 70         100 my $errors = delete $s->{'errors'};
439            
440 70         108 my $filter = delete $s->{'filter'};
441 70         99 my $extra_test = delete $s->{'extra_test'};
442            
443 70         99 my $length = delete $s->{'length'};
444 70         88 my $min_length = delete $s->{'min_length'};
445 70         103 my $max_length = delete $s->{'max_length'};
446            
447 70 50       81 if (%{$s}) {
  70         170  
448 0         0 Carp::croak("new(): spec error: invalid options for $key: @{[ keys %{$s} ]}");
  0         0  
  0         0  
449             }
450            
451 70         213 my %spec = (
452             optional => $optional,
453             regexp => $regexp,
454             );
455            
456 70 100       139 $spec{'length'} = $length if $length;
457 70 100       150 $spec{'min_length'} = $min_length if $min_length;
458 70 100       137 $spec{'max_length'} = $max_length if $max_length;
459            
460 70 100       311 if ($filter) {
461 14 100 100     83 my @filters = (ref $filter and ref $filter eq 'ARRAY') ? @{$filter} : ($filter);
  4         612  
462            
463 14         576 foreach my $f (@filters) {
464 17 100 33     74 if ($Filters{$f}) {
    50          
465 11         12 push(@{$spec{'filter'}}, $Filters{$f});
  11         54  
466             } elsif (ref $f and ref $f eq 'CODE') {
467 6         9 push(@{$spec{'filter'}}, $f);
  6         23  
468             } else {
469 0         0 Carp::croak("new(): spec error: No such built in filter: $f");
470             }
471             }
472             }
473            
474 70 100       224 if ($extra_test) {
475 7 100 66     44 my @tests = (ref $extra_test and ref $extra_test eq 'ARRAY') ? @{$extra_test} : ($extra_test);
  1         3  
476            
477 7         580 foreach my $t (@tests) {
478 8 50 33     43 if (ref $t and ref $t eq 'CODE') {
479 8         24 push(@{$spec{'extra_test'}}, $t);
  8         41  
480             } else {
481 0         0 Carp::croak('new(): spec error: extra tests must be a code reference.');
482             }
483             }
484             }
485            
486 70 100       755 if ($errors) {
487             #
488             # Make a copy just to be safe. (we use delete here too)
489             #
490 14         48 $errors = { %$errors };
491            
492 14 50 33     78 unless (ref $errors and ref $errors eq 'HASH') {
493 0         0 Carp::croak('new(): spec error: errors not a hashref');
494             }
495            
496 14         94 my %errors = ();
497            
498 14         34 foreach my $type (@ValidErrorFields) {
499 56   100     1312 my $msg = delete $errors->{$type} || next;
500 25         50 $errors{$type} = $msg;
501             }
502            
503 14 50       16 if (%{$errors}) {
  14         46  
504 0         0 Carp::croak("new(): spec error: invalid error message types: @{[ keys %{$errors} ]}");
  0         0  
  0         0  
505             }
506            
507 14         35 $spec{'errors'} = \%errors;
508             }
509            
510 70         1015 $self->{'spec'}->{$key} = \%spec;
511             }
512              
513              
514             sub _insert_delayed_specs {
515 2     2   5 my ($self) = @_;
516              
517 2         3 while (my ($key, $s) = each %{$self->{'delayed_specs'}}) {
  4         19  
518 2   33     9 my $equal_to = delete $s->{'equal_to'} || Carp::confess("How did we get a delayed spec with no equal_to?!");
519            
520 2 50       8 unless ($self->{'spec'}->{$equal_to}) {
521 0         0 Carp::croak("new(): spec error: equal_to set to unknown parameter: $equal_to.");
522             }
523            
524 2         10 $s->{'regexp'} = qr/^(.*)$/;
525             $s->{'extra_test'} = sub {
526 2     2   4 my ($textref, $form) = @_;
527            
528 2 50       6 return unless my $value = $form->param($equal_to);
529            
530 2 100       7 if ($$textref eq $value) {
531 1         4 return 1;
532             } else {
533 1         3 $form->param( $equal_to => '');
534 1         2 $form->param( $key => '');
535            
536 1         4 $self->errorf($key => unequal => $$textref);
537 1         3 $self->error( $equal_to => $self->error($key));
538            
539 1         3 return 0;
540             }
541 2         27 };
542            
543 2         5 $self->_insert_spec($key, $s);
544             }
545             }
546              
547             #
548             # $form->_populate_vars($datasource)
549             #
550             # Goes though the spec, grabbing data from the datasource for each var.
551             #
552             sub _populate_vars {
553 22     22   41 my ($self, $data) = @_;
554            
555 22 100 100     85 $self->{'in_unstarted_mode'} = 1 if $self->{'start_param'}
556             and !$data->param($self->{'start_param'});
557            
558 22 100       78 if ($self->{'in_unstarted_mode'}) {
559 1         2 foreach my $key (keys %{$self->{'spec'}}) {
  1         4  
560 4         12 $self->{'data'}->{$key} = [''];
561             }
562             } else {
563 21         39 foreach my $key (keys %{$self->{'spec'}}) {
  21         78  
564 66         193 @{$self->{'data'}->{$key}} = $data->param($key);
  66         586  
565             }
566             }
567             }
568              
569              
570             #
571             # $form->_validate_params
572             #
573             # Runs though the spec, validating the data we got from the datastore.
574             # If the data is bad, we drop it to the floor, and set an error message.
575             #
576             sub _validate_params {
577 21     21   37 my ($self) = @_;
578            
579 21         37 KEY: while (my ($key, $spec) = each %{$self->{'spec'}}) {
  87         310  
580              
581 66         73 my @new_data;
582            
583 66 100       69 unless (@{$self->{'data'}->{$key}}) {
  66         176  
584 16 100 66     46 $self->errorf($key => 'empty', $_) unless $self->error($key) || $spec->{'optional'};
585 16         37 next KEY;
586             }
587            
588            
589 50         68 MEMBER: for (@{$self->{'data'}->{$key}}) {
  50         112  
590 76 100 66     423 next MEMBER if defined $_ and length $_;
591            
592 1 50 33     4 $self->errorf($key => 'empty', $_) unless $self->error($key) || $spec->{'optional'};
593 1         2 next KEY;
594             }
595            
596 49         72 DATA: foreach my $data (@{$self->{'data'}->{$key}}) {
  49         110  
597            
598 75 50       134 next DATA unless defined $data;
599            
600 75 100       155 if ($spec->{'filter'}) {
601 19         16 $_->(\$data) for @{$spec->{'filter'}};
  19         51  
602             }
603            
604 75 100       463 unless ($data =~ $spec->{'regexp'}) {
605 10         26 $self->errorf($key => 'invalid' => $data);
606             } else {
607 65         147 $data = $1;
608            
609 65 100       145 if (exists $spec->{'length'}) {
610 3 50       8 $self->errorf($key => 'length', $data), next DATA
611             unless length($data) == $spec->{'length'};
612             }
613            
614 65 100       165 if (exists $spec->{'max_length'}) {
615 3 100       15 $self->errorf($key => 'length', $data), next DATA
616             unless length($data) <= $spec->{'max_length'};
617             }
618            
619 63 100       122 if (exists $spec->{'min_length'}) {
620 3 100       11 $self->errorf($key => 'length', $data), next DATA
621             unless length($data) >= $spec->{'min_length'};
622             }
623            
624 61 100       122 if ($spec->{'extra_test'}) {
625 7         9 foreach my $t (@{$spec->{'extra_test'}}) {
  7         14  
626 8 100       33 unless ($t->(\$data, $self, $key)) {
627             # Don't overide any error message that the test
628             # function set.
629 2 100       34 $self->errorf($key => 'invalid', $data)
630             unless $self->{'errors'}->{$key};
631 2         8 next DATA;
632             }
633             }
634             }
635            
636 59         173 push(@new_data, $data);
637             }
638             }
639            
640 49 100       109 if (@new_data) {
641 38         180 $self->{'data'}->{$key} = [ @new_data ];
642             } else {
643 11         38 delete $self->{'data'}->{$key};
644             }
645            
646            
647            
648             }
649            
650             #
651             # clear out the spec of the cruft we don't need anymore...
652             #
653             # XXX -- this is temp to make things work with storable.
654             #
655 21         35 foreach my $param (keys %{$self->{'spec'}}) {
  21         63  
656 66         104 delete $self->{'spec'}->{$param}->{'extra_test'};
657 66         131 delete $self->{'spec'}->{$param}->{'filter'};
658             }
659             }
660              
661            
662              
663              
664             =head2 $form->params
665              
666             Returns a list of all the parameters that were in the datasource that
667             are called for in the spec.
668              
669             =cut
670              
671             sub params {
672 3     3 1 717 my ($self) = @_;
673            
674             # Store it in an tmp array to force this into list context.
675             # (sort returns undef in non-list context.)
676 3         6 my @params = sort keys %{$self->{'data'}};
  3         28  
677            
678 3         17 return @params;
679             }
680              
681             =head2 $form->param($name => $new_value)
682              
683             Returns the parameter for a given var. If called in scalar context it returns
684             the first value fetched from the datasource, regardless of the number of values.
685              
686             C<$new_value> should be a scalar or an array ref.
687              
688             If C<$name> is not given then this method returns C<$form-Eparams>, just like
689             CGI or Apache::Request.
690              
691             =cut
692              
693             sub param {
694 71     71 1 8473 my ($self, $name, $new_value) = @_;
695            
696 71 100       172 return $self->params unless $name;
697            
698 69 100       176 if (defined $new_value) {
699 8 100       16 if (ref $new_value) {
700 3 100       9 if (ref $new_value eq 'ARRAY') {
701 2         7 $self->{'data'}->{$name} = $new_value;
702             } else {
703 1         180 Carp::croak("param(): new value is not data or an array reference.");
704             }
705             } else {
706 5         14 $self->{'data'}->{$name} = [ $new_value ];
707             }
708             }
709            
710 68 100       209 return unless my $data = $self->{'data'}->{$name};
711            
712 61 100       281 return wantarray ? @{$data} : $data->[0];
  18         143  
713             }
714            
715              
716             =head2 $form->error($param_name => $new_error)
717              
718             Returns the error string (if an error occcured) for the a given parameter.
719              
720             If two arguments are passed, this can be used to set the error string.
721              
722             If no parameter is passed, than it returns boolean. True if an error occured
723             in validating the data, false if no error occured.
724              
725             =cut
726              
727             sub error {
728 96     96 1 11174 my ($self, $name, $new_error) = @_;
729            
730 96 100       188 if ($name) {
731 82 100       195 $self->{'errors'}->{$name} = $new_error if $new_error;
732            
733 82         436 return $self->{'errors'}->{$name};
734             } else {
735 14 100       19 return %{$self->{'errors'}} ? 1 : 0;
  14         92  
736             }
737             }
738              
739             =head2 $form->errors
740              
741             Returns a hash of all the errors in C error_message> pairs.
742              
743             =cut
744              
745 0     0 1 0 sub errors { return %{$_[0]->{'errors'}}; }
  0         0  
746              
747              
748              
749             =head2 $form->errorf($key, $type, $data)
750              
751             Sets the error for C<$key> to the format type C<$type>, using C<$data>
752             for the C<[% value %]> tag.
753              
754             =cut
755              
756             sub errorf {
757 25     25 1 50 my ($self, $key, $type, $data) = @_;
758            
759 25         28 my $format;
760              
761 25 50       74 unless ($self->{'spec'}->{$key}) {
762 0         0 Carp::croak("errorf(): Invalid key: $key");
763             }
764              
765 25 100       61 if ($self->{'spec'}->{$key}->{'errors'}) {
766 7   33     25 $format = $self->{'spec'}->{$key}->{'errors'}->{$type} || $DefaultErrors{$type};
767             } else {
768 18         40 $format = $DefaultErrors{$type};
769             }
770              
771 25 50       53 Carp::croak("errorf(): Invalid error type: $type") unless $format;
772            
773 25         89 my %map = (
774             key => $key,
775             value => $data,
776             );
777              
778 25 50       157 $format =~ s{\[%\s*(\w+)\s*%\]}{ $map{$1} || '' }egs;
  29         144  
779            
780 25         68 return $self->error($key => $format);
781             }
782              
783             =head2 $form->started
784              
785             Returns boolean based on if the start_param was set. True if the form was started,
786             false otherwise.
787              
788             =cut
789              
790             sub started {
791 0     0 1 0 my ($self) = @_;
792            
793 0 0       0 return $self->{'in_unstarted_mode'} ? 0 : 1;
794             }
795              
796             =head2 $form->ready
797              
798             Returns boolean; true if the form is started and there are no errors, false
799             other wise.
800              
801             =cut
802              
803             sub ready {
804 0   0 0 1 0 return ($_[0]->started and not $_[0]->error);
805             }
806              
807              
808             =head1 AUTOLOAD
809              
810             Data::CGIForm creates uses AUTOLOAD to create methods for the parameters
811             in the spec. These methods just call C<$form-Eparam($name)>, but it might prove
812             helpful/elegent.
813              
814             =cut
815              
816             sub AUTOLOAD {
817 28     28   1132 my $self = shift;
818              
819 28         45 our $AUTOLOAD;
820            
821 28 50       93 return if $AUTOLOAD =~ m/DESTROY/;
822 28         116 $AUTOLOAD =~ m/^.*:(.*)$/;
823            
824 28   50     104 my $name = $1 || return;
825              
826 28 100       120 if ($self->{'spec'}->{$name}) {
827 27         79 return $self->param($name, @_);
828             } else {
829 1         209 Carp::croak("Unknown method: $name");
830             }
831             }
832              
833             =head1 TODO
834              
835             Do we want to test new values given to param() against the spec?
836              
837             Make sure the user hasn't given dangerous equal_to pairs.
838              
839             =head1 AUTHOR
840              
841             Maintained by: Tim Wilde Etwilde@cymru.comE
842              
843             Originally by: Chris Reinhardt Ecpan@triv.orgE
844              
845             =head1 COPYRIGHT
846              
847             Portions Copyright (c) 2007 Tim Wilde. All rights reserved.
848              
849             Portions Copyright (c) 2006 Dynamic Network Services, Inc. All rights
850             reserved.
851              
852             Portions Copyright (c) 2002 Chris Reinhardt. All rights reserved. This
853             program is free software; you can redistribute it and/or modify it under the
854             same terms as Perl itself.
855              
856             =head1 SEE ALSO
857              
858             L, L.
859              
860             =cut
861              
862              
863             1;
864             __END__