File Coverage

blib/lib/CGI/Ex.pm
Criterion Covered Total %
statement 161 317 50.7
branch 76 190 40.0
condition 34 110 30.9
subroutine 24 40 60.0
pod 18 31 58.0
total 313 688 45.4


line stmt bran cond sub pod time code
1             package CGI::Ex;
2              
3             =head1 NAME
4              
5             CGI::Ex - CGI utility suite - makes powerful application writing fun and easy
6              
7             =head1 VERSION
8              
9             version 2.53
10              
11             =for markdown [![master](https://travis-ci.org/ljepson/CGI-Ex.svg?branch=master)](https://travis-ci.org/ljepson/CGI-Ex)
12              
13             =for HTML
14              
15             =cut
16              
17             ###----------------------------------------------------------------###
18             # Copyright - Paul Seamons #
19             # Distributed under the Perl Artistic License without warranty #
20             ###----------------------------------------------------------------###
21              
22             ### See perldoc at bottom
23              
24 6     6   848 use 5.006;
  6         17  
25 6     6   26 use strict;
  6         11  
  6         445  
26             our $VERSION = '2.53'; # VERSION
27              
28             our ($PREFERRED_CGI_MODULE,
29             $PREFERRED_CGI_REQUIRED,
30             $AUTOLOAD,
31             $DEBUG_LOCATION_BOUNCE,
32             @EXPORT, @EXPORT_OK
33             );
34 6     6   35 use Exporter qw(import);
  6         10  
  6         2070  
35              
36 0         0 BEGIN {
37 6   50 6   62 $PREFERRED_CGI_MODULE ||= 'CGI';
38 6         8 @EXPORT = ();
39 6         21 @EXPORT_OK = qw(get_form
40             get_cookies
41             print_content_type
42             content_type
43             content_typed
44             set_cookie
45             location_bounce
46             );
47              
48             ### cache mod_perl version (light if or if not mod_perl)
49             my $v = (! $ENV{'MOD_PERL'}) ? 0
50             # mod_perl/1.27 or mod_perl/1.99_16 or mod_perl/2.0.1
51             # if MOD_PERL is set - don't die if regex fails - just assume 1.0
52 6 0       32 : ($ENV{'MOD_PERL'} =~ m{ ^ mod_perl / (\d+\.[\d_]+) (?: \.\d+)? $ }x) ? $1
    50          
53             : '1.0_0';
54 0     0   0 sub _mod_perl_version () { $v }
55 6 50   6   64 sub _is_mod_perl_1 () { $v < 1.98 && $v > 0 }
56 6     6   23 sub _is_mod_perl_2 () { $v >= 1.98 }
57              
58             ### cache apache request getter (light if or if not mod_perl)
59 6         8 my $sub;
60 6 50       11 if (_is_mod_perl_1) { # old mod_perl
    50          
61 0         0 require Apache;
62 0         0 $sub = sub { Apache->request };
  0         0  
63             } elsif (_is_mod_perl_2) {
64 0 0       0 if (eval { require Apache2::RequestRec }) { # debian style
  0         0  
65 0         0 require Apache2::RequestUtil;
66 0         0 $sub = sub { Apache2::RequestUtil->request };
  0         0  
67             } else { # fedora and mandrake style
68 0         0 require Apache::RequestUtil;
69 0         0 $sub = sub { Apache->request };
  0         0  
70             }
71             } else {
72 6         22111 $sub = sub {};
73             }
74 13     13 0 17 sub apache_request_sub () { $sub }
75             }
76              
77             ###----------------------------------------------------------------###
78              
79             # my $cgix = CGI::Ex->new;
80             sub new {
81 16   50 16 0 534 my $class = shift || die "Missing class name";
82 16 100       45 my $self = ref($_[0]) ? shift : {@_};
83 16         73 return bless $self, $class;
84             }
85              
86             ###----------------------------------------------------------------###
87              
88             ### allow for holding another classed CGI style object
89             # my $query = $cgix->object;
90             # $cgix->object(CGI->new);
91             sub object {
92 6   50 6 1 19 my $self = shift || die 'Usage: my $query = $cgix_obj->object';
93 6 50       54 $self->{'object'} = shift if $#_ != -1;
94              
95 6 100       25 if (! defined $self->{'object'}) {
96 3   33     13 $PREFERRED_CGI_REQUIRED ||= do {
97 3   33     13 my $file = $self->{'cgi_module'} || $PREFERRED_CGI_MODULE;
98 3         7 $file .= ".pm";
99 3         23 $file =~ s|::|/|g;
100 3         6 eval { require $file };
  3         1565  
101 3 50       54309 die "Couldn't require $PREFERRED_CGI_MODULE: $@" if $@;
102 3         17 1; # return of do
103             };
104 3         61 $self->{'object'} = $PREFERRED_CGI_MODULE->new;
105             }
106              
107 6         955 return $self->{'object'};
108             }
109              
110             ### allow for calling CGI MODULE methods
111             sub AUTOLOAD {
112 0     0   0 my $self = shift;
113 0 0       0 my $meth = ($AUTOLOAD =~ /(\w+)$/) ? $1 : die "Invalid method $AUTOLOAD";
114 0         0 return $self->object->$meth(@_);
115             }
116              
117       0     sub DESTROY { }
118              
119             ###----------------------------------------------------------------###
120              
121             ### Form getter that will act like CGI->new->Vars only it will return arrayrefs
122             ### for values that are arrays
123             # my $hash = $cgix->get_form;
124             # my $hash = $cgix->get_form(CGI->new);
125             # my $hash = get_form();
126             # my $hash = get_form(CGI->new);
127             sub get_form {
128 6   33 6 1 16 my $self = shift || __PACKAGE__->new;
129 6 50       33 if (! $self->isa(__PACKAGE__)) { # get_form(CGI->new) syntax
130 0         0 my $obj = $self;
131 0         0 $self = __PACKAGE__->new;
132 0         0 $self->object($obj);
133             }
134 6 100       24 return $self->{'form'} if $self->{'form'};
135              
136             ### get the info out of the object
137 4   66     11 my $obj = shift || $self->object;
138 4         6 my %hash = ();
139             ### this particular use of $cgi->param in list context is safe
140 4         15 local $CGI::LIST_CONTEXT_WARN = 0;
141 4 50       21 my $mp = $obj->can('multi_param') ? 1 : 0;
142 4         13 foreach my $key ($obj->param) {
143 5 50       70 my @val = $mp ? $obj->multi_param($key) : $obj->param($key);
144 5 100       111 $hash{$key} = ($#val <= 0) ? $val[0] : \@val;
145             }
146 4         30 return $self->{'form'} = \%hash;
147             }
148              
149             ### allow for a setter
150             ### $cgix->set_form(\%form);
151             sub set_form {
152 1   50 1 1 4 my $self = shift || die 'Usage: $cgix_obj->set_form(\%form)';
153 1   50     7 return $self->{'form'} = shift || {};
154             }
155              
156             ### Combined get and set form
157             # my $hash = $cgix->form;
158             # $cgix->form(\%form);
159             sub form {
160 3     3 1 28624 my $self = shift;
161 3 100       11 return $self->set_form(shift) if @_ == 1;
162 2         8 return $self->get_form;
163             }
164              
165             ### allow for creating a url encoded key value sequence
166             # my $str = $cgix->make_form(\%form);
167             # my $str = $cgix->make_form(\%form, \@keys_to_include);
168             sub make_form {
169 2   50 2 1 730 my $self = shift || die 'Usage: $cgix_obj->make_form(\%form)';
170 2   33     6 my $form = shift || $self->get_form;
171 2 100       10 my $keys = ref($_[0]) ? shift : [sort keys %$form];
172 2         4 my $str = '';
173 2         5 foreach (@$keys) {
174 3         4 my $key = $_; # make a copy
175 3         5 my $val = $form->{$key};
176 3         6 $key =~ s/([^\w.\-\ ])/sprintf('%%%02X', ord $1)/eg;
  0         0  
177 3         8 $key =~ y/ /+/;
178 3 100       24 foreach (ref($val) eq 'ARRAY' ? @$val : $val) {
179 5         8 my $_val = $_; # make a copy
180 5         7 $_val =~ s/([^\w.\-\ ])/sprintf('%%%02X', ord $1)/eg;
  0         0  
181 5         6 $_val =~ y/ /+/;
182 5         11 $str .= "$key=$_val&"; # intentionally not using join
183             }
184             }
185 2         5 chop $str;
186 2         7 return $str;
187             }
188              
189             ###----------------------------------------------------------------###
190              
191             ### like get_form - but a hashref of cookies
192             ### cookies are parsed depending upon the functionality of ->cookie
193             # my $hash = $cgix->get_cookies;
194             # my $hash = $cgix->get_cookies(CGI->new);
195             # my $hash = get_cookies();
196             # my $hash = get_cookies(CGI->new);
197             sub get_cookies {
198 3   33 3 1 8 my $self = shift || __PACKAGE__->new;
199 3 50       16 if (! $self->isa(__PACKAGE__)) { # get_cookies(CGI->new) syntax
200 0         0 my $obj = $self;
201 0         0 $self = __PACKAGE__->new;
202 0         0 $self->object($obj);
203             }
204 3 100       12 return $self->{'cookies'} if $self->{'cookies'};
205              
206 2   33     40 my $obj = shift || $self->object;
207 2         8 my %hash = ();
208 2         9 foreach my $key ($obj->cookie) {
209 2         3106 my @val = $obj->cookie($key);
210 2 50       896 $hash{$key} = ($#val == -1) ? "" : ($#val == 0) ? $val[0] : \@val;
    50          
211             }
212 2         2775 return $self->{'cookies'} = \%hash;
213             }
214              
215             ### Allow for a setter
216             ### $cgix->set_cookies(\%cookies);
217             sub set_cookies {
218 1   50 1 1 4 my $self = shift || die 'Usage: $cgix_obj->set_cookies(\%cookies)';
219 1   50     6 return $self->{'cookies'} = shift || {};
220             }
221              
222             ### Combined get and set cookies
223             # my $hash = $cgix->cookies;
224             # $cgix->cookies(\%cookies);
225             sub cookies {
226 3     3 0 1988 my $self = shift;
227 3 100       10 return $self->set_cookies(shift) if @_ == 1;
228 2         7 return $self->get_cookies;
229             }
230              
231             ###----------------------------------------------------------------###
232              
233             ### Allow for shared apache request object
234             # my $r = $cgix->apache_request
235             # $cgix->apache_request($r);
236             sub apache_request {
237 13   50 13 0 24 my $self = shift || die 'Usage: $cgix_obj->apache_request';
238 13 50       21 $self->{'apache_request'} = shift if $#_ != -1;
239              
240 13   33     40 return $self->{'apache_request'} ||= apache_request_sub()->();
241             }
242              
243             ### Get the version of mod_perl running (0 if not mod_perl)
244             # my $version = $cgix->mod_perl_version;
245 0     0 0 0 sub mod_perl_version { _mod_perl_version }
246 0     0 0 0 sub is_mod_perl_1 { _is_mod_perl_1 }
247 0     0 0 0 sub is_mod_perl_2 { _is_mod_perl_2 }
248              
249             ### Allow for a setter
250             # $cgix->set_apache_request($r)
251 0     0 0 0 sub set_apache_request { shift->apache_request(shift) }
252              
253             ###----------------------------------------------------------------###
254              
255             ### same signature as print_content_type
256 0     0 1 0 sub content_type { &print_content_type }
257              
258             ### will send the Content-type header
259             # $cgix->print_content_type;
260             # $cgix->print_content_type('text/plain');
261             # print_content_type();
262             # print_content_type('text/plain);
263             sub print_content_type {
264 10 100 100 10 0 2949 my ($self, $type, $charset) = (@_ && ref $_[0]) ? @_ : (undef, @_);
265 10 100       32 $self = __PACKAGE__->new if ! $self;
266              
267 10 100       15 if ($type) {
268 8 50       41 die "Invalid type: $type" if $type !~ m|^[\w\-\.]+/[\w\-\.\+]+$|; # image/vid.x-foo
269             } else {
270 2         3 $type = 'text/html';
271             }
272 10 100 66     26 $type .= "; charset=$charset" if $charset && $charset =~ m|^[\w\-\.\:\+]+$|;
273              
274 10 50       20 if (my $r = $self->apache_request) {
275 0 0       0 return if $r->bytes_sent;
276 0         0 $r->content_type($type);
277 0 0       0 $r->send_http_header if $self->is_mod_perl_1;
278             } else {
279 10 50       22 if (! $ENV{'CONTENT_TYPED'}) {
280 10         30 print "Content-Type: $type\r\n\r\n";
281 10         56 $ENV{'CONTENT_TYPED'} = '';
282             }
283 10         72 $ENV{'CONTENT_TYPED'} .= sprintf("%s, %d\n", (caller)[1,2]);
284             }
285             }
286              
287             ### Boolean check if content has been typed
288             # $cgix->content_typed;
289             # content_typed();
290             sub content_typed {
291 2   33 2 0 6 my $self = shift || __PACKAGE__->new;
292              
293 2 50       5 if (my $r = $self->apache_request) {
294 0         0 return $r->bytes_sent;
295             } else {
296 2 100       8 return $ENV{'CONTENT_TYPED'} ? 1 : undef;
297             }
298             }
299              
300             ###----------------------------------------------------------------###
301              
302             ### location bounce nicely - even if we have already sent content
303             ### may be called as function or a method
304             # $cgix->location_bounce($url);
305             # location_bounce($url);
306             sub location_bounce {
307 0 0   0 1 0 my ($self, $loc) = ($#_ == 1) ? (@_) : (undef, shift);
308 0 0       0 $self = __PACKAGE__->new if ! $self;
309 0 0       0 $loc =~ s{(\s)}{sprintf("%%%02X", ord $1)}xge if $loc;
  0         0  
310 0         0 my $html_loc = $loc;
311 0 0       0 if ($html_loc) {
312 0         0 $html_loc =~ s/&/&/g;
313 0         0 $html_loc =~ s/
314 0         0 $html_loc =~ s/>/>/g;
315 0         0 $html_loc =~ s/\"/"/g;
316             }
317              
318 0 0       0 if ($self->content_typed) {
    0          
319 0 0       0 if ($DEBUG_LOCATION_BOUNCE) {
320 0         0 print "Location: $html_loc
\n";
321             } else {
322 0         0 print "\n";
323             }
324              
325             } elsif (my $r = $self->apache_request) {
326 0         0 $r->status(302);
327 0 0       0 if ($self->is_mod_perl_1) {
328 0         0 $r->header_out("Location", $loc);
329 0         0 $r->content_type('text/html');
330 0         0 $r->send_http_header;
331 0         0 $r->print("Bounced to $html_loc\n");
332             } else {
333 0         0 $r->headers_out->add("Location", $loc);
334 0         0 $r->custom_response(302, "Bounced to $html_loc\n");
335             }
336              
337             } else {
338 0         0 print "Location: $loc\r\n",
339             "Status: 302 Bounce\r\n",
340             "Content-Type: text/html\r\n\r\n",
341             "Bounced to $html_loc\r\n";
342             }
343             }
344              
345             ### set a cookie nicely - even if we have already sent content
346             ### may be called as function or a method - fancy algo to allow for first argument of args hash
347             # $cgix->set_cookie({name => $name, ...});
348             # $cgix->set_cookie( name => $name, ... );
349             # set_cookie({name => $name, ...});
350             # set_cookie( name => $name, ... );
351             sub set_cookie {
352 2 50   2 1 3037 my $self = UNIVERSAL::isa($_[0], __PACKAGE__) ? shift : __PACKAGE__->new;
353              
354 2 50       9 my $args = ref($_[0]) ? shift : {@_};
355 2         8 foreach (keys %$args) {
356 4 50       10 next if /^-/;
357 4         12 $args->{"-$_"} = delete $args->{$_};
358             }
359              
360             ### default path to / and allow for 1hour instead of 1h
361 2   50     10 $args->{-path} ||= '/';
362 2 50       5 $args->{-expires} = time_calc($args->{-expires}) if $args->{-expires};
363              
364 2         5 my $obj = $self->object;
365 2         10 my $cookie = "" . $obj->cookie(%$args);
366              
367 2 100       725 if ($self->content_typed) {
368 1         5 print "\n";
369             } else {
370 1 50       2 if (my $r = $self->apache_request) {
371 0 0       0 if ($self->is_mod_perl_1) {
372 0         0 $r->header_out("Set-cookie", $cookie);
373             } else {
374 0         0 $r->headers_out->add("Set-Cookie", $cookie);
375             }
376             } else {
377 1         8 print "Set-Cookie: $cookie\r\n";
378             }
379             }
380             }
381              
382             ### print the last modified time
383             ### takes a time or filename and an optional keyname
384             # $cgix->last_modified; # now
385             # $cgix->last_modified((stat $file)[9]); # file's time
386             # $cgix->last_modified(time, 'Expires'); # different header
387             sub last_modified {
388 0   0 0 1 0 my $self = shift || die 'Usage: $cgix_obj->last_modified($time)'; # may be called as function or method
389 0   0     0 my $time = shift || time;
390 0   0     0 my $key = shift || 'Last-Modified';
391              
392             ### get a time string - looks like:
393             ### Mon Dec 9 18:03:21 2002
394             ### valid RFC (although not prefered)
395 0         0 $time = scalar gmtime time_calc($time);
396              
397 0 0       0 if ($self->content_typed) {
    0          
398 0         0 print "\n";
399             } elsif (my $r = $self->apache_request) {
400 0 0       0 if ($self->is_mod_perl_1) {
401 0         0 $r->header_out($key, $time);
402             } else {
403 0         0 $r->headers_out->add($key, $time);
404             }
405             } else {
406 0         0 print "$key: $time\r\n";
407             }
408             }
409              
410             ### add expires header
411             sub expires {
412 0 0   0 1 0 my $self = ref($_[0]) ? shift : __PACKAGE__->new; # may be called as a function or method
413 0   0     0 my $time = shift || time;
414 0         0 return $self->last_modified($time, 'Expires');
415             }
416              
417             ### similar to expires_calc from CGI::Util
418             ### allows for lenient calling, hour instead of just h, etc
419             ### takes time or 0 or now or filename or types of -23minutes
420             sub time_calc {
421 7     7 0 3335 my $time = shift; # may only be called as a function
422 7 100 66     64 if (! $time || lc($time) eq 'now') {
    100          
    100          
423 1         6 return time;
424             } elsif ($time =~ m/^\d+$/) {
425 1         7 return $time;
426             } elsif ($time =~ m/^([+-]?)\s*(\d+|\d*\.\d+)\s*([a-z])[a-z]*$/i) {
427 4         22 my $m = {
428             's' => 1,
429             'm' => 60,
430             'h' => 60 * 60,
431             'd' => 60 * 60 * 24,
432             'w' => 60 * 60 * 24 * 7,
433             'M' => 60 * 60 * 24 * 30,
434             'y' => 60 * 60 * 24 * 365,
435             };
436 4   50     44 return time + ($m->{lc($3)} || 1) * "$1$2";
437             } else {
438 1         35 my @stat = stat $time;
439 1 50       5 die "Could not find file \"$time\" for time_calc. You should pass one of \"now\", time(), \"[+-] \\d+ [smhdwMy]\" or a filename." if $#stat == -1;
440 1         7 return $stat[9];
441             }
442             }
443              
444              
445             ### allow for generic status send
446             sub send_status {
447 0   0 0 1 0 my $self = shift || die 'Usage: $cgix_obj->send_status(302 => "Bounced")';
448 0   0     0 my $code = shift || die "Missing status";
449 0         0 my $mesg = shift;
450 0 0       0 if (! defined $mesg) {
451 0         0 $mesg = "HTTP Status of $code received\n";
452             }
453 0 0       0 if ($self->content_typed) {
454 0         0 die "Cannot send a status ($code - $mesg) after content has been sent";
455             }
456 0 0       0 if (my $r = $self->apache_request) {
457 0         0 $r->status($code);
458 0 0       0 if ($self->is_mod_perl_1) {
459 0         0 $r->content_type('text/html');
460 0         0 $r->send_http_header;
461 0         0 $r->print($mesg);
462             } else {
463 0         0 $r->content_type('text/html');
464 0         0 $r->print($mesg);
465 0         0 $r->rflush;
466             }
467             } else {
468 0         0 print "Status: $code\r\n";
469 0         0 $self->print_content_type;
470 0         0 print $mesg;
471             }
472             }
473              
474             ### allow for sending a simple header
475             sub send_header {
476 0   0 0 1 0 my $self = shift || die 'Usage: $cgix_obj->send_header';
477 0         0 my $key = shift;
478 0         0 my $val = shift;
479 0 0       0 if ($self->content_typed) {
480 0         0 die "Cannot send a header ($key - $val) after content has been sent";
481             }
482 0 0       0 if (my $r = $self->apache_request) {
483 0 0       0 if ($self->is_mod_perl_1) {
484 0         0 $r->header_out($key, $val);
485             } else {
486 0         0 $r->headers_out->add($key, $val);
487             }
488             } else {
489 0         0 print "$key: $val\r\n";
490             }
491             }
492              
493             ###----------------------------------------------------------------###
494              
495             ### allow for printing out a static javascript file
496             ### for example $self->print_js("CGI::Ex::validate.js");
497             sub print_js {
498 0   0 0 1 0 my $self = shift || die 'Usage: $cgix_obj->print_js($js_file)';
499 0   0     0 my $js_file = shift || '';
500 0 0       0 $self = $self->new if ! ref $self;
501              
502             ### fix up the file - force .js on the end
503 0 0 0     0 $js_file .= '.js' if $js_file && $js_file !~ /\.js$/i;
504 0         0 $js_file =~ s|::|/|g;
505              
506             ### get file info
507 0         0 my $stat;
508 0 0 0     0 if ($js_file && $js_file =~ m|^/*(\w+(?:/+\w+)*\.js)$|i) {
509 0         0 foreach my $path (@INC) {
510 0         0 my $_file = "$path/$1";
511 0 0       0 next if ! -f $_file;
512 0         0 $js_file = $_file;
513 0         0 $stat = [stat _];
514 0         0 last;
515             }
516             }
517              
518             ### no file = 404
519 0 0       0 if (! $stat) {
520 0 0       0 if (! $self->content_typed) {
521 0         0 $self->send_status(404, "JS File not found for print_js\n");
522             } else {
523 0         0 print "

JS File not found for print_js

\n";
524             }
525 0         0 return;
526             }
527              
528             ### do headers
529 0 0       0 if (! $self->content_typed) {
530 0         0 $self->last_modified($stat->[9]);
531 0         0 $self->expires('+ 1 year');
532 0         0 $self->print_content_type('application/x-javascript');
533             }
534              
535 0 0 0     0 return if $ENV{'REQUEST_METHOD'} && $ENV{'REQUEST_METHOD'} eq 'HEAD';
536              
537             ### send the contents
538 0         0 local *FH;
539 0 0       0 open(FH, "<$js_file") || die "Couldn't open file $js_file: $!";
540 0         0 local $/ = undef;
541 0         0 print ;
542 0         0 close FH;
543             }
544              
545             ###----------------------------------------------------------------###
546              
547             ### form filler that will use either HTML::FillInForm, CGI::Ex::Fill
548             ### or another specified filler. Argument style is similar to
549             ### HTML::FillInForm. May be called as a method or a function.
550             sub fill {
551 10     10 1 2855 my $self = shift;
552 10         22 my $args = shift;
553 10 50       20 if (ref($args)) {
554 0 0       0 if (! UNIVERSAL::isa($args, 'HASH')) {
555 0         0 $args = {text => $args};
556 0         0 @$args{'form','target','fill_password','ignore_fields'} = @_;
557             }
558             } else {
559 10         26 $args = {$args, @_};
560             }
561              
562 10   50     36 my $module = $self->{'fill_module'} || 'CGI::Ex::Fill';
563              
564             ### allow for using the standard HTML::FillInForm
565             ### too bad it won't modify our file in place for us
566 10 50       19 if ($module eq 'HTML::FillInForm') {
567 0         0 eval { require HTML::FillInForm };
  0         0  
568 0 0       0 if ($@) {
569 0         0 die "Couldn't require HTML::FillInForm: $@";
570             }
571 0 0       0 $args->{scalarref} = $args->{text} if $args->{text};
572 0 0       0 $args->{fdat} = $args->{form} if $args->{form};
573 0         0 my $filled = HTML::FillInForm->new->fill(%$args);
574 0 0       0 if ($args->{text}) {
575 0         0 my $ref = $args->{text};
576 0         0 $$ref = $filled;
577 0         0 return 1;
578             }
579 0         0 return $filled;
580              
581             } else {
582 10         712 require CGI::Ex::Fill;
583              
584             ### get the text to work on
585 10         15 my $ref;
586 10 100       27 if ($args->{text}) { # preferred method - gets modified in place
    100          
    50          
    0          
587 1         2 $ref = $args->{text};
588             } elsif ($args->{scalarref}) { # copy to mimic HTML::FillInForm
589 8         10 my $str = ${ $args->{scalarref} };
  8         11  
590 8         35 $ref = \$str;
591             } elsif ($args->{arrayref}) { # joined together (copy)
592 1         2 my $str = join "", @{ $args->{arrayref} };
  1         3  
593 1         3 $ref = \$str;
594             } elsif ($args->{file}) { # read it in
595 0 0       0 open (IN, $args->{file}) || die "Couldn't open $args->{file}: $!";
596 0         0 my $str = '';
597 0 0       0 read(IN, $str, -s _) || die "Couldn't read $args->{file}: $!";
598 0         0 close IN;
599 0         0 $ref = \$str;
600             } else {
601 0         0 die "No suitable text found for fill.";
602             }
603              
604             ### allow for data to be passed many ways
605             my $form = $args->{form} || $args->{fobject}
606 10   0     31 || $args->{fdat} || $self->object;
607              
608             CGI::Ex::Fill::form_fill($ref,
609             $form,
610             $args->{target},
611             $args->{fill_password},
612             $args->{ignore_fields},
613 10         40 );
614 10 100       63 return ! $args->{text} ? $$ref : 1;
615             }
616              
617             }
618              
619             ###----------------------------------------------------------------###
620              
621             sub validate {
622 2   50 2 1 894 my $self = shift || die 'Usage: my $er = $cgix_obj->validate($form, $val_hash_or_file)';
623 2 50       9 my ($form, $file) = (@_ == 2) ? (shift, shift) : ($self->object, shift);
624              
625 2         712 require CGI::Ex::Validate;
626              
627 2         5 my $args = {};
628 2 50       9 $args->{raise_error} = 1 if $self->{raise_error};
629 2         12 return CGI::Ex::Validate->new($args)->validate($form, $file);
630             }
631              
632             ###----------------------------------------------------------------###
633              
634             sub conf_obj {
635 0   0 0 0 0 my $self = shift || die 'Usage: my $ob = $cgix_obj->conf_obj($args)';
636 0   0     0 return $self->{conf_obj} ||= do {
637 0         0 require CGI::Ex::Conf;
638 0         0 CGI::Ex::Conf->new(@_);
639             };
640             }
641              
642             sub conf_read {
643 0   0 0 0 0 my $self = shift || die 'Usage: my $conf = $cgix_obj->conf_read($file)';
644 0         0 return $self->conf_obj->read(@_);
645             }
646              
647             ###----------------------------------------------------------------###
648              
649             sub swap_template {
650 2   50 2 1 1078 my $self = shift || die 'Usage: my $out = $cgix_obj->swap_template($file, \%vars, $template_args)';
651 2         4 my $str = shift;
652 2         3 my $form = shift;
653 2   50     5 my $args = shift || {};
654 2 50 33     6 $form = $self if ! $form && ref($self);
655 2 50       7 $form = $self->get_form if UNIVERSAL::isa($form, __PACKAGE__);
656              
657 2 100       8 my ($ref, $return) = ref($str) ? ($str, 0) : (\$str, 1);
658              
659             ### look up the module
660 2   50     10 my $module = $self->{'template_module'} || 'CGI::Ex::Template';
661 2         5 my $pkg = "$module.pm";
662 2         16 $pkg =~ s|::|/|g;
663 2         616 require $pkg;
664              
665             ### swap it
666 2         6 my $out = '';
667 2         12 $module->new($args)->process($ref, $form, \$out);
668              
669 2 100       26349 if (! $return) {
670 1         4 $$ref = $out;
671 1         4 return 1;
672             } else {
673 1         5 return $out;
674             }
675             }
676              
677             ###----------------------------------------------------------------###
678              
679             1;
680              
681             __END__