File Coverage

blib/lib/CGI/EZForm.pm
Criterion Covered Total %
statement 134 188 71.2
branch 45 80 56.2
condition 29 77 37.6
subroutine 19 26 73.0
pod 15 15 100.0
total 242 386 62.6


\n";
line stmt bran cond sub pod time code
1             package CGI::EZForm;
2              
3             # Pod-style documentation is at the end of this file.
4              
5 1     1   559 use Carp qw(carp croak);
  1         2  
  1         68  
6              
7 1     1   4 use Exporter();
  1         1  
  1         2528  
8             @ISA = Exporter;
9              
10             $CGI::EZForm::VERSION = "2002.0403";
11 0     0 1 0 sub Version { $VERSION; }
12              
13             %default = (
14              
15             # field receive defaults
16             multivalue_sep => ';', # separator for multiple values of a field
17              
18             # table formatting defaults
19             table => 1, # draw fields within a table
20             table_border => 0, # table border is invisible
21             table_width => '80%', # table is 80% of window wide
22             table_align => 'center', # table is centered
23             cellspacing => 0,
24             cellpadding => 10,
25             label_width => '20%', # label column is 20% of table width
26             label_align => 'right', # label alignment
27             td_valign => 'top', # table cell vertical alignment
28              
29             # field defaults
30             type => 'text', # default field type is text
31             size => 30, # default text/textarea width is 30 chars
32             checkbox => 'Y', # default value for checkbox
33             rows => 3, # default textarea rows
34              
35             # form header defaults
36             method => 'POST',
37             enctype => 'application/x-www-form-urlencoded'
38             );
39              
40             sub default {
41             # change default value(s) to those specified
42 0     0 1 0 my ($form) = shift;
43 0         0 my %params = @_;
44 0         0 foreach my $key (keys %params) {
45 0         0 $default{$key} = $params{$key};
46             }
47             }
48              
49 1     1 1 13 sub new { return bless {}; }
50              
51             sub set {
52             # set one or more form values
53 1     1 1 13 my $form = shift;
54 1         7 my %params = @_;
55 1         5 foreach my $key (keys %params) {
56 2         8 $form->{$key} = $params{$key};
57             }
58             }
59              
60             sub clear {
61             # clear (delete) all form fields, or just those named in parameters
62 0     0 1 0 my $form = shift;
63 0         0 my @keys;
64             my $key;
65 0 0       0 if (@_ == 0) { # no params -- clear all
66 0         0 @keys = keys(%$form);
67             } else {
68 0         0 @keys = @_;
69             }
70 0         0 foreach $key (@keys) {
71 0         0 delete $form->{$key};
72             }
73             }
74              
75             sub get {
76 0     0 1 0 my $form = shift;
77 0         0 my $key = shift;
78 0 0       0 return ($form->{$key} ? $form->{$key} : undef);
79             }
80              
81             sub receive {
82 1     1 1 24 my $form = shift;
83              
84 1 50 33     8 if (defined $ENV{'CONTENT_TYPE'}
85             and $ENV{'CONTENT_TYPE'} =~ m#multipart/form-data#) {
86 0         0 &_parse_multipart($form, &_receive());
87             } else {
88 1         5 &_parse_regular($form, &_receive());
89             }
90             }
91              
92             sub _receive {
93 1     1   3 my ($incoming);
94              
95             # get the form data ...
96              
97 1 50 33     10 if (defined $ENV{'REQUEST_METHOD'} and $ENV{'REQUEST_METHOD'} eq "POST") {
    50 33        
98 0         0 read(STDIN, $incoming, $ENV{'CONTENT_LENGTH'});
99             }
100             elsif (defined $ENV{'REQUEST_METHOD'} and $ENV{'REQUEST_METHOD'} eq "GET") {
101 0         0 $incoming = $ENV{'QUERY_STRING'};
102             }
103             else { # for testing, allow input from command line
104 1         4 $incoming = join('&',@ARGV);
105             }
106              
107 1         5 return $incoming;
108             }
109              
110             sub _parse_regular {
111 1     1   2 my ($form, $incoming) = @_;
112              
113             # ... and decode it into %FORM
114              
115 1         4 my @pairs = split(/&/, $incoming);
116              
117 1         6 foreach (@pairs) {
118 0         0 my ($name, $value) = split(/=/, $_);
119              
120             # un-escape any characters 'escaped' for http
121 0         0 $name =~ tr/+/ /;
122 0         0 $value =~ tr/+/ /;
123 0         0 $name =~ s/%([A-F0-9][A-F0-9])/chr(hex($1))/gie;
  0         0  
124 0         0 $value =~ s/%([A-F0-9][A-F0-9])/chr(hex($1))/gie;
  0         0  
125              
126             # Skip blank text entry fields
127 0 0       0 next if ($value eq "");
128              
129             # Check for "assign-dynamic" field names
130             # Mainly for on-the-fly input names, especially checkboxes
131 0 0       0 if ($name =~ /^assign-dynamic/) {
132 0         0 $name = $value;
133 0         0 $value = "on";
134             }
135              
136             # Allow for multiple values of a single name
137 0 0       0 if (defined $form->{$name}) {
138 0         0 $form->{$name} .= $default{multivalue_sep};
139 0         0 $form->{$name} .= $value;
140             } else {
141 0         0 $form->{$name} = $value;
142             }
143             }
144             }
145              
146             sub _parse_multipart {
147 0     0   0 croak 'Sorry, cannot deal with multipart forms yet.';
148             }
149              
150             sub dump {
151 1     1 1 7 my $form = shift;
152 1         2 my @keys;
153             my $key;
154 1 50       5 if (@_ == 0) {
155 1         8 @keys = sort keys(%$form);
156             } else {
157 0         0 @keys = @_;
158             }
159 1         3 foreach $key (@keys) {
160 3         8 print $key, '=', $form->{$key}, "\n";
161             }
162             }
163              
164             sub use_table {
165 0     0 1 0 my $form = shift; # actually ignored for this function
166 0         0 my $thing = shift;
167 0         0 $default{table} = $thing;
168             }
169              
170             sub draw {
171             # draws a form input field or button
172 8     8 1 10 my $form = shift;
173 8         32 my %params = @_;
174 8         24 my @keys = keys %params;
175 8         11 my $key;
176 8         9 my $html = '';
177              
178             # make sure anything required exists
179 8 100       18 unless (defined $params{type}) {$params{type} = $default{type};}
  1         2  
180 8 100       14 unless (defined $params{label}) {$params{label} = ' ';}
  3         9  
181              
182             # name is optional, but if not specified will assign the value as
183             # a name when the data is received.
184 8 100       22 unless (defined $params{name}) {$params{name} = 'assign-dynamic';}
  1         2  
185              
186             # provide for a label;
187             # if we're doing table formatting, this means putting it into
188             # column one
189 8 100       17 unless ($params{type} eq 'hidden') {
190 7 50       16 if ($default{table}) {
191 7         14 $html .= _tr_start($params{label});
192             } else {
193 0         0 $html .= $params{label};
194             }
195             }
196              
197             TYPE_CASE: {
198 8 100       10 if ($params{type} eq 'select') {
  8         17  
199 1         2 $html .= qq|
200 1 50       4 $html .= qq| name="$params{name}"| if $params{name};
201 1 50       5 $html .= qq| multiple| if $params{multiple};
202 1         14 $html .= &_add_extras(\%params,
203             grep !/^(type|label|name|multiple|options|values|selected)$/,
204             (keys %params));
205 1         2 $html .= qq|>\n|;
206 1   50     7 $html .= &_select(
207             $params{options},
208             $params{'values'},
209             ($params{selected} or [($form->{$params{name}} or '')])
210             );
211 1         3 $html .= qq|\n|;
212 1         2 last;
213             }
214              
215 7 100       28 if ($params{type} =~ /submit|reset|image/) {
216 2         6 $html .= "
217 2         15 $html .= &_add_extras(\%params,
218             grep !/^(type|label)$/, (keys %params));
219 2         3 $html .= ">\n";
220 2         4 last;
221             }
222              
223 5 100       12 if ($params{type} eq 'radio') {
224 1   50     11 $html .= &_radio(
      50        
225             $params{name},
226             ($form->{$params{name}} or ''),
227             ($params{vertical} or 0),
228             $params{captions}, $params{'values'});
229 1         3 last;
230             }
231              
232 4 100       9 if ($params{type} eq 'checkbox') {
233             # checkbox gotta have value
234 1 50       4 unless (exists $params{value}) {
235 1 50       3 if (defined $form->{$params{name}}) {
236 0         0 $params{value} = $form->{$params{name}};
237             } else {
238 1         3 $params{value} = $default{checkbox};
239             }
240             }
241 1         3 $html .= sprintf qq|
242             $params{name},
243             $params{value};
244 1 50 33     6 if (defined $form->{$params{name}}
245             and ($params{value} eq $form->{$params{name}}) ) {
246 0         0 $html .= ' checked';
247             }
248 1         9 $html .= &_add_extras(\%params,
249             grep !/^(type|label|name|value|caption)$/, (keys %params));
250 1         3 $html .= ">\n";
251 1   50     4 $html .= ($params{caption} or '');
252 1         1 last;
253             }
254              
255 3 50       9 if ($params{type} eq 'textarea') {
256 0   0     0 $html .= sprintf
      0        
      0        
257             qq|\n|,
268             ($params{value} or $form->{$params{name}} or '');
269 0         0 last;
270             }
271              
272 3 100       6 if ($params{type} eq 'hidden') {
273 1   33     8 $html .= sprintf qq|\n|,
274             $params{name},
275             ($params{value} || $form->{$params{name}});
276 1         2 last;
277             }
278              
279             # default case is an input field (text or password)
280 2   33     32 $html .= sprintf qq|
      66        
      100        
281             ($params{type} or $default{type}),
282             $params{name},
283             ($params{size} || $default{size}),
284             ($params{value} or $form->{$params{name}} or '');
285 2 50       6 $html .= ' readonly' if $params{readonly};
286 2 50       5 $html .= ' disabled' if $params{disabled};
287 2         16 $html .= &_add_extras(\%params,
288             grep !/^(type|label|name|size|value|readonly|disabled)$/,
289             (keys %params));
290 2         6 $html .= ">\n";
291             }
292 8 100       22 unless ($params{type} eq 'hidden') {
293 7 50       15 if ($default{table}) {
294 7         11 $html .= &_tr_end;
295             }
296             }
297 8         42 return $html;
298             }
299              
300             sub _select {
301 1     1   3 my ($options, $values, $selected) = @_;
302 1         1 my ($i, $count);
303              
304 1         9 my $html = '';
305              
306 1         2 $count = @$options;
307 1         4 for ($i = 0; $i < $count; $i++) {
308 3 50       12 $html .= &_option($$options[$i],
309             (defined $values ? $$values[$i] : ''),
310             @$selected);
311             }
312              
313 1         3 return $html;
314             }
315              
316             sub _option {
317 3     3   6 my ($option, $value, @selected) = @_;
318 3         5 my $html = '';
319 3         5 $html .= qq|
320 3 50       10 $html .= qq| value="$value"| if defined $value;
321             # the option should be selected if it matches a list of options to
322             # be selected
323 3 100 66     89 if ( (defined $value and (grep /$value/, @selected))
      33        
      66        
324             or (defined $option and (grep /$option/, @selected)) ) {
325 2         10 $html .= qq| selected|
326             }
327 3         15 $html .= qq|>$option\n|;
328             }
329              
330             sub _radio {
331 1     1   9 my ($name, $selected, $vertical, $captions, $values) = @_;
332 1         7 my ($i, $count);
333              
334 1         2 my $html = '';
335              
336 1         2 $count = @$captions;
337 1         5 for ($i = 0; $i < $count; $i++) {
338 2         5 $html .= qq|
339 2 50       8 $html .= qq| value="$$values[$i]"| if defined $values;
340 2 100 66     9 $html .= qq| checked|
341             if (defined $selected and ($selected eq $$values[$i]));
342 2         4 $html .= qq|>$$captions[$i]|;
343 2 50       5 if ($vertical) {
344 0         0 $html .= "
\n"; } else { $html .= " \n"; }
  2         5  
345             }
346              
347 1         3 return $html;
348             }
349              
350             sub _add_extras {
351             # add attributes from a list of param keys
352             # this usefully allows you to include any attributes you like,
353             # such as javascript.
354             # Less usefully, you can include attributes which are not valid,
355             # so be careful.
356 7     7   14 $params = shift; # hash ref.
357 7         13 my $html = '';
358 7         12 foreach my $key (@_) {
359 3         11 $html .= qq| $key="$$params{$key}"|;
360             }
361 7         25 return $html;
362             }
363              
364             sub hidden {
365 0     0 1 0 my $form = shift;
366 0         0 my @names = @_;
367 0         0 my $html = '';
368 0         0 foreach my $name (@names) {
369 0         0 $html .= sprintf qq|\n|,
370             $name,
371             $form->{$name};
372             }
373 0         0 return $html;
374             }
375              
376             sub form_start {
377 1     1 1 7 my $form = shift;
378 1         4 my %params = @_;
379              
380 1   33     21 my $html =
      33        
      33        
381             sprintf qq|
382             ($params{action} || $ENV{SCRIPT_NAME}),
383             ($params{method} || $default{method}),
384             ($params{enctype} || $default{enctype});
385 1         17 $html .= &_add_extras(\%params,
386             grep !/^(action|method|enctype)$/, (keys %params));
387 1         4 $html .= ">\n";
388 1 50       5 if ($default{table}) {
389 1         5 $html .= &table_start();
390             }
391             }
392              
393              
394             sub form_end {
395 1     1 1 2 my $html = '';
396 1 50       4 if ($default{table}) {
397 1         11 $html .= &table_end();
398             }
399 1         5 $html .= "\n";
400             }
401              
402             sub table_start {
403 1     1 1 2 my $form = shift;
404 1         2 my %params = @_;
405 1         3 $default{table} = 1;
406 1   33     43 return sprintf
      33        
      33        
      33        
      33        
407             qq|\n|,
408             ($params{border} || $default{table_border}),
409             ($params{width} || $default{table_width}),
410             ($params{cellspacing} || $default{cellspacing}),
411             ($params{cellpadding} || $default{cellpadding}),
412             ($params{table_align} || $default{table_align});
413             }
414              
415             sub table_end {
416 1     1 1 3 $default{table} = 0;
417 1         2 return "
\n";
418             }
419              
420              
421             sub _tr_start {
422 7     7   31 my ($label) = @_;
423 7 50       12 $label = '' unless $label;
424 7         42 return sprintf
425             qq|
%s\n|,
426             $default{td_valign},
427             $default{label_align},
428             $default{label_width},
429             $label,
430             $default{td_valign};
431             }
432              
433              
434             sub _tr_end {
435             # prints closing tags for a table row.
436 7     7   20 return "
437             }
438              
439             1;
440              
441             __END__