File Coverage

blib/lib/CGI/Path.pm
Criterion Covered Total %
statement 9 785 1.1
branch 0 274 0.0
condition 0 237 0.0
subroutine 3 89 3.3
pod 0 85 0.0
total 12 1470 0.8


line stmt bran cond sub pod time code
1             #!/usr/bin/perl -w
2              
3             package CGI::Path;
4              
5 1     1   21376 use strict;
  1         2  
  1         45  
6 1     1   5 use vars qw($VERSION);
  1         1  
  1         78  
7              
8             $VERSION = "1.12";
9              
10 1     1   1852211 use CGI;
  1         16390  
  1         7  
11              
12             sub new {
13 0     0 0   my $type = shift;
14 0   0       my %DEFAULT_ARGS = (
15             ### turn on keeping history, $self->form->{$self->{history_key}} also needs to be true
16             allow_history => 0,
17             ### history_key is the key from the form to turn on history
18             history_key => 'history',
19              
20             ### turn on magic fill
21             allow_magic_fill => 0,
22             ### turn on micro seconds, which requires Time::HiRes
23             allow_magic_micro => 0,
24             ### full path to the magic_fill file
25             magic_fill_filename => '',
26              
27             ### if a given page doesn't exist, create it using create_page method
28             create_page => 0,
29              
30             ### form_name is used for javascript
31             form_name => 'MYFORM',
32             form_keyname => 'form',
33              
34             ### extension for htm files
35             htm_extension => 'htm',
36             ### extension for validation files
37             val_extension => 'val',
38              
39             ### if the user submits an empty form, keep the session
40             keep_no_form_session => 0,
41              
42             my_form => {},
43             my_path => {},
44              
45             ### 'fake keys', stuff that gets skipped from the session
46             not_a_real_key => [qw(_begin_time _http_referer _printed_pages _session_id _submit _validated)],
47              
48             ### sort of a linked list of the path
49             path_hash => {
50             # simple example
51             # initial_step => 'page1',
52             # page1 => 'page2',
53             # page2 => 'page3',
54             # page3 => '',
55             },
56              
57             ### used for requiring in files
58             perl5lib => $ENV{PERL5LIB} || '',
59              
60             ### only get these values from the session
61             session_only => ['_validated'],
62             ### if these values are in the session and form, the session wins
63             session_wins => [],
64             ### sometimes you might not want to use a session
65             use_session => 1,
66              
67             ### what got validated on this request
68             validated_fresh => {},
69              
70             ### a history of bless'ings
71             WASA => [],
72             );
73 0           my $self = bless \%DEFAULT_ARGS, $type;
74              
75 0   0       $self->{my_module} ||= ref $self;
76 0           $self->merge_in_args(@_);
77              
78 0 0         if($self->{use_session}) {
79 0           $self->session;
80             }
81              
82             ### don't always want to do all the extra stuff
83 0 0         unless($self->{no_new_helper}) {
84 0           $self->new_helper;
85             }
86              
87 0           return $self;
88             }
89              
90             sub session_dir {
91 0     0 0   return '/tmp/path/session';
92             }
93              
94             sub session_lock_dir {
95 0     0 0   return '/tmp/path/session/lock';
96             }
97              
98             sub cookies {
99 0     0 0   my $self = shift;
100 0 0         unless($self->{cookies}) {
101 0           $self->{cookies} = {};
102 0           my $query = CGI->new;
103 0           foreach my $key ($query->cookie()) {
104 0           $self->{cookies}{$key} = $query->cookie($key);
105             }
106             }
107 0           return $self->{cookies};
108             }
109              
110             sub DESTROY {
111 0     0     my $self = shift;
112             }
113              
114             sub new_session {
115 0     0 0   my $self = shift;
116 0           my ($sid, $session_dir, $session_lock_dir) = @_;
117 0           require Apache::Session::File;
118 0           $self->{session} = {};
119 0           tie %{$self->{session}}, 'Apache::Session::File', $sid, {
  0            
120             Directory => $session_dir,
121             LockDirectory => $session_lock_dir,
122             };
123 0           $self->set_sid($self->{session}{_session_id});
124             }
125              
126             sub session {
127 0     0 0   my $self = shift;
128 0           my $opt = shift;
129 0 0         unless($self->{session}) {
130 0           eval {
131 0           $self->new_session($self->sid, $self->session_dir, $self->session_lock_dir);
132             };
133 0 0         if($@) {
134 0 0         if($@ =~ /Object does not exist/i) {
135 0           eval {
136 0           $self->new_session('', $self->session_dir, $self->session_lock_dir);
137             };
138             }
139             }
140 0 0         die $@ if($@);
141             }
142 0 0         if($opt) {
143 0           my $opt_ref = ref $opt;
144 0 0         if($opt_ref) {
145 0 0         if($opt_ref eq 'HASH') {
146 0           foreach(keys %{$opt}) {
  0            
147 0           $self->{session}{$_} = $opt->{$_};
148             }
149             }
150             } else {
151 0           die "I got not a ref on session opt";
152             }
153             }
154 0           return $self->{session};
155             }
156              
157             sub sid_cookie_name {
158 0     0 0   my $self = shift;
159 0           return $self->my_content . "_sid";
160             }
161              
162             sub set_cookie {
163 0     0 0   my $self = shift;
164 0           my ($cookie_name, $cookie_value) = @_;
165 0           my $new_cookie = CGI::cookie
166             (-name => $cookie_name,
167             -value => $cookie_value,
168             );
169 0 0         if (exists $ENV{CONTENT_TYPED}) {
170 0           print qq{\n};
171             } else {
172 0           print "Set-Cookie: $new_cookie\n";
173             }
174 0           return;
175             }
176              
177             sub set_sid {
178 0     0 0   my $self = shift;
179 0           my $sid = shift;
180 0           $self->set_cookie($self->sid_cookie_name, $sid);
181             }
182              
183             sub sid {
184 0     0 0   my $self = shift;
185 0   0       return $self->cookies->{$self->sid_cookie_name} || '';
186             }
187              
188             sub merge_in_args {
189 0     0 0   my $self = shift;
190 0 0         my %PASSED_ARGS = (ref $_[0] eq 'HASH') ? %{$_[0]} : @_;
  0            
191 0           foreach my $passed_arg (keys %PASSED_ARGS) {
192 0 0 0       if(ref $PASSED_ARGS{$passed_arg} && ref $PASSED_ARGS{$passed_arg} eq 'HASH') {
193 0           foreach my $key (keys %{$PASSED_ARGS{$passed_arg}}) {
  0            
194 0           $self->{$passed_arg}{$key} = $PASSED_ARGS{$passed_arg}{$key};
195             }
196             } else {
197 0           $self->{$passed_arg} = $PASSED_ARGS{$passed_arg}
198             }
199             }
200             }
201              
202             ### morph methods
203              
204             sub morph_path {
205 0     0 0   my $self = shift;
206 0   0       my $my_module = shift || $self->my_module;
207              
208             # morph to my_module
209 0 0         if($my_module) {
210 0           $self->morph($my_module, 1);
211             }
212              
213             }
214              
215             sub morph_step {
216 0     0 0   my $self = shift;
217              
218 0           my $step = shift;
219             # going to morph based on my_module
220              
221 0           my $full_step = $self->my_module . "::$step";
222              
223             # morph to something like CGI::Path::Skel::page_one
224             # the 1 turns on the -e check
225 0           $self->morph($full_step, 1);
226            
227             }
228              
229             sub morph {
230 0     0 0   my $self = shift;
231              
232 0           my $starting_ref = ref $self;
233              
234 0           my $package = shift;
235 0           my $do_dash_e_check = shift;
236              
237 0           my $tmp_package = $package;
238 0           $tmp_package =~ s@::@/@g;
239              
240 0           my $path = "$tmp_package.pm";
241              
242 0           my $exists = 1;
243              
244             # if they don't want to force the require, I will check -e before morphing
245 0 0         if($do_dash_e_check) {
246 0           my $full_path = "$self->{perl5lib}/$path";
247 0           $exists = -e $full_path;
248             }
249              
250 0 0         if($exists) {
251             ### polymorph
252 0           eval {
253 0           require $path;
254             };
255 0 0         if( $@ ){
256 0           $self->{errstr} = "bad stuff on require of $tmp_package.pm: $@";
257 0           die $@;
258             }
259 0           bless $self, $package;
260             }
261              
262 0           my $ending_ref = ref $self;
263              
264 0           my $sub_ref = $self->can('add_WASA');
265 0 0         if($sub_ref) {
266 0           &$sub_ref($self, $starting_ref);
267 0           &$sub_ref($self, $ending_ref);
268             }
269 0           return $self;
270             }
271              
272             sub add_WASA {
273 0     0 0   my $self = shift;
274 0           my $ref = shift;
275 0 0         push @{$self->{WASA}}, $ref unless(grep { $_ eq $ref } @{$self->{WASA}});
  0            
  0            
  0            
276             }
277              
278              
279             sub my_module {
280 0     0 0   my $self = shift;
281 0           return $self->{my_module};
282             }
283              
284             sub base_include_path {
285 0     0 0   my $self = shift;
286 0           die "please write your own base_include_path method";
287             }
288              
289             sub include_path {
290 0     0 0   my $self = shift;
291 0           return [$self->base_include_path . "/default"];
292             }
293              
294             sub my_content {
295 0     0 0   my $self = shift;
296 0   0       return $self->{my_content} ||= do {
297 0           my $my_content = lc($self->my_module);
298 0           my $this_package = __PACKAGE__;
299 0           $my_content =~ s/^${this_package}:://i;
300 0           $my_content =~ s@::@/@g;
301 0           $my_content; # return of the do
302             };
303             }
304              
305              
306              
307              
308             sub new_helper {
309 0     0 0   my $self = shift;
310              
311 0 0 0       if(!$self->{keep_no_form_session} && !scalar keys %{$self->this_form} &&
  0   0        
312             scalar keys %{$self->session}) {
313             #warn "User posted an empty form with a non empty session.\n";
314 0           $self->session_wipe;
315             }
316              
317 0           $self->generate_form;
318 0           $self->morph_path;
319 0           $self->get_path_array;
320              
321 0 0         unless($self->session->{_begin_time}) {
322 0           $self->session({
323             _begin_time => time,
324             });
325             }
326 0 0 0       if($ENV{HTTP_REFERER} && $ENV{SCRIPT_NAME}
      0        
327             && $ENV{HTTP_REFERER} !~ $ENV{SCRIPT_NAME}) {
328 0           $self->session({
329             _http_referer => $ENV{HTTP_REFERER},
330             });
331             }
332             }
333              
334             sub delete_session {
335 0     0 0   my $self = shift;
336 0           delete $self->{session};
337             }
338              
339             sub session_wipe {
340 0     0 0   my $self = shift;
341 0           $self->delete_cookie($self->sid_cookie_name);
342 0           $self->delete_session;
343 0 0         if(keys %{$self->this_form}) {
  0            
344 0           die "need to get session_wipe to work generally";
345             }
346             }
347              
348             sub delete_cookie {
349 0     0 0   my $self = shift;
350 0   0       my $cookie_name = shift || die "need a cookie_name for delete_cookie";
351              
352 0 0         if($self->cookies->{$cookie_name}) {
353 0           delete $self->cookies->{$cookie_name};
354 0           $self->set_cookie($cookie_name, '');
355             }
356             }
357              
358             sub get_path_array {
359 0     0 0   my $self = shift;
360              
361 0           my $path_hash = $self->path_hash;
362              
363 0           $self->{path_array} = [];
364 0   0       my $next_step = $self->initial_step || die "need an initial_step";
365 0           while($next_step) {
366 0 0         die "infinite loop on $next_step" if(grep {$next_step eq $_ } @{$self->{path_array}});
  0            
  0            
367 0           push @{$self->{path_array}}, $next_step;
  0            
368              
369 0           $next_step = $path_hash->{$next_step};
370             }
371 0           return $self->{path_array};
372             }
373              
374             sub session_form {
375 0     0 0   return {};
376             }
377              
378             sub generate_form {
379             # generate_form takes two hashes
380             # $self->this_form - the results of CGI get form
381             # $self->session - the stuff from the session file
382             # and merges them into
383             # $self->{form} - the place to use
384 0     0 0   my $self = shift;
385 0           my $form = {};
386              
387 0           my $this_form = $self->this_form;
388             # some things we want to just get from the session
389 0           foreach(@{$self->{session_only}}) {
  0            
390 0           delete $this_form->{$_};
391 0 0         $form->{$_} = $self->session->{$_} if(exists $self->session->{$_});
392             }
393              
394             # there might be some stuff we want to give session precedence to
395 0           foreach(@{$self->{session_wins}}) {
  0            
396 0 0         $form->{$_} = $self->session->{$_} if(exists $self->session->{$_});
397             }
398              
399             # lay the hashes on top of each other in reverse order of precedence
400 0           $self->form({%{$self->session}, %{$this_form}, %{$form}});
  0            
  0            
  0            
401 0 0         if($self->form->{session_wipe}) {
402 0           $self->session_wipe;
403 0           $self->clear_value('session_wipe');
404             }
405             }
406              
407             sub this_form {
408 0     0 0   my $self = shift;
409 0   0       return $self->{this_form} ||= do {
410 0           my $cgi = CGI->new;
411 0           my %form = $cgi->Vars;
412 0           foreach(keys %form) {
413 0 0         next unless($form{$_} =~ /\0/);
414 0           $form{$_} = [split /\0/, $form{$_}];
415             }
416 0           \%form;
417             }
418             }
419              
420             sub empty_form {
421 0     0 0   my $self = shift;
422 0           my $form = $self->form;
423 0           my $empty_form = 1;
424 0           foreach my $key (keys %{$form}) {
  0            
425 0 0         next if(grep { $_ eq $key } @{$self->{not_a_real_key}});
  0            
  0            
426 0           $empty_form = 0;
427 0           last;
428             }
429 0           return $empty_form;
430             }
431              
432             sub form {
433 0     0 0   my $self = shift;
434 0 0         $self->{$self->{form_keyname}} = shift if($#_ != -1);
435 0   0       return $self->{$self->{form_keyname}} ||= {};
436             }
437              
438             ### history methods
439              
440             sub allow_history {
441 0     0 0   my $self = shift;
442 0           my $return = 0;
443 0 0 0       if($self->{allow_history} && $self->form->{$self->{history_key}}) {
444 0 0         unless($self->session->{$self->{history_key}}) {
445 0           $self->session({
446             $self->{history_key} => $self->form->{$self->{history_key}},
447             });
448             }
449 0           $return = 1;
450             }
451 0           return $return;
452             }
453              
454             sub history_window_name {
455 0     0 0   my $self = shift;
456 0           return $self->my_content . "_window";
457             }
458              
459             sub show_history {
460 0     0 0   my $self = shift;
461 0 0         return unless($self->allow_history);
462 0           $self->my_content_type;
463 0           my $window_name = $self->history_window_name;
464 0           $window_name =~ s/\W//g;
465 0           my $out = $self->out('history.tt', {
466             history => $self->{history}
467             });
468 0           $$out =~ s@\n@\\n@g;
469 0           $$out =~ s@()@$1" + "$2@ig;
470 0           print <
471            
479             SCRIPT
480             }
481              
482             sub history_init {
483 0     0 0   my $self = shift;
484 0 0         if($self->allow_history) {
485 0           $self->{history} = [];
486             }
487             }
488              
489             sub hook_history_init {
490 0     0 0   my $self = shift;
491 0 0         if($self->allow_history) {
492 0   0       $self->{_history} ||= {};
493 0           $self->{_history}{hook} = [];
494             }
495             }
496              
497             sub add_history_step {
498 0     0 0   my $self = shift;
499 0 0         if($self->allow_history) {
500 0   0       my $step = shift || die "need a step";
501 0           $self->{_history}{hash} = {};
502 0           $self->{_history}{hash}{step} = $step;
503             }
504             }
505              
506             sub history_push {
507 0     0 0   my $self = shift;
508 0 0         if($self->allow_history) {
509 0           push @{$self->{history}}, $self->{_history}{hash};
  0            
510 0           delete $self->{_history};
511             }
512             }
513              
514             sub hook_history_add {
515 0     0 0   my $self = shift;
516 0 0         if($self->allow_history) {
517 0   0       my $hash = shift || die "need a hook history hash";
518 0           push @{$self->{_history}{hash}{hook}}, $hash;
  0            
519             }
520             }
521              
522             ### where lots of the magic happens
523              
524             sub navigate {
525 0     0 0   my $self = shift;
526              
527 0           my $form = $self->form;
528 0           my $path = $self->get_path_array;
529              
530 0           $self->history_init;
531              
532 0           $self->handle_jump_around;
533              
534 0 0 0       my $previous_step = $form->{_printed_pages} && $form->{_printed_pages}[-1] ? $form->{_printed_pages}[-1] : '';
535              
536             ### sub_ref is where I put references to subroutines that can returned
537 0           my $sub_ref;
538              
539 0 0         &$sub_ref($self) if($sub_ref = $self->can('pre_navigate_walk'));
540            
541             ### foreach path, run the gamut of routines
542 0           my $return_val = undef;
543 0           foreach my $step (@$path){
544            
545 0           $self->add_history_step($step);
546              
547 0 0         return 1 if($self->{stop_navigate});
548 0           $self->morph_step($step);
549              
550 0           $self->{this_step} = {
551             this_step => $step,
552             previous_step => $previous_step,
553             validate_ref => $self->get_validate_ref($step),
554             };
555            
556 0           my $method_pre = "${step}_hook_pre";
557 0           my $method_fill = "${step}_hash_fill";
558 0           my $method_form = "${step}_hash_form";
559 0           my $method_err = "${step}_hash_errors";
560 0           my $method_step = "${step}_step";
561 0           my $method_post = "${step}_hook_post";
562              
563             # my $method_val = "${step}_validate";
564             # method_val gets called in $self->validate
565              
566             ### a hook beforehand
567 0 0         if($sub_ref = $self->can($method_pre)){
568 0           $return_val = &$sub_ref($self);
569 0           $self->hook_history_add({
570             hook => $method_pre,
571             could => 'Y',
572             return => $return_val,
573             });
574 0 0         unless($return_val) {
575 0           $self->hook_history_add({
576             hook => $method_pre,
577             could => 'Y',
578             return => $return_val,
579             });
580 0           $self->history_push;
581              
582 0           next;
583             }
584             } else {
585 0           $self->hook_history_add({
586             hook => $method_pre,
587             could => 'N',
588             return => undef,
589             });
590             }
591              
592 0           my $validated = 1;
593 0           my $info_exists;
594              
595 0 0         if($self->info_exists($step)) {
596 0           $info_exists = 1;
597              
598 0           $self->hook_history_add({
599             hook => 'info_exists',
600             could => 'Y',
601 0           return => join(", ", @{$self->{_extant_info}}),
602             });
603              
604 0           $validated = $self->validate($step);
605              
606 0           $self->hook_history_add({
607             hook => 'validate',
608             could => 'Y',
609             return => $validated,
610             });
611              
612             } else {
613 0           $info_exists = 0;
614              
615 0           $self->hook_history_add({
616             hook => 'info_exists',
617             could => 'Y',
618             return => $info_exists,
619             });
620              
621             }
622              
623             ### see if information is complete for this step
624 0 0 0       if( ! $info_exists || ! $validated) {
625              
626 0 0         if($sub_ref = $self->can($method_fill)) {
627 0           my $fill_return = $self->add_to_fill(&$sub_ref($self));
628              
629 0           $self->hook_history_add({
630             hook => $method_fill,
631             could => 'Y',
632             return => $fill_return,
633             });
634              
635             } else {
636              
637 0           $self->hook_history_add({
638             hook => $method_fill,
639             could => 'N',
640             return => undef,
641             });
642              
643             }
644              
645 0           $self->add_to_fill($self->form, 'smart_merge');
646 0           $self->hook_history_add({
647             hook => 'add_to_fill',
648             could => 'Y',
649             return => $self->form,
650             });
651              
652 0 0 0       if(!$info_exists || $self->{magic_fill_regardless}) {
653              
654 0 0         if($self->allow_magic_fill) {
655 0           my $magic_fill_ref = $self->magic_fill_ref;
656 0 0         if(scalar keys %{$magic_fill_ref}) {
  0            
657 0           $self->add_to_fill($magic_fill_ref, 'smart_merge');
658             }
659              
660             $self->hook_history_add({
661 0           hook => 'magic_fill',
662             could => 'Y',
663             return => undef,
664             });
665              
666             }
667              
668             }
669              
670 0           my $hash_form;
671 0 0         if($sub_ref = $self->can($method_form)) {
672 0           $hash_form = &$sub_ref($self);
673              
674 0           $self->hook_history_add({
675             hook => $method_form,
676             could => 'Y',
677             return => $hash_form,
678             });
679              
680             } else {
681 0           $hash_form = {};
682              
683 0           $self->hook_history_add({
684             hook => $method_form,
685             could => 'N',
686             return => undef,
687             });
688              
689             }
690              
691 0           my $hash_err;
692 0 0         if($sub_ref = $self->can($method_err)) {
693 0           $hash_err = &$sub_ref($self);
694              
695 0           $self->hook_history_add({
696             hook => $method_err,
697             could => 'Y',
698             return => $hash_err,
699             });
700              
701             } else {
702 0           $hash_err = {};
703              
704 0           $self->hook_history_add({
705             hook => $method_err,
706             could => 'N',
707             return => undef,
708             });
709              
710             }
711              
712 0           my $page_to_print;
713 0 0         if($sub_ref = $self->can($method_step)) {
714 0           my $potential_page_to_print = &$sub_ref($self);
715              
716             # want to make this the page_to_print only if it a real page
717 0 0 0       if($potential_page_to_print && !ref $potential_page_to_print && $potential_page_to_print !~ /^\d+$/) {
      0        
718 0           $page_to_print = $potential_page_to_print
719             }
720              
721             $self->hook_history_add({
722 0           hook => $method_step,
723             could => 'Y',
724             return => "$page_to_print ($potential_page_to_print)",
725             });
726              
727              
728             } else {
729              
730 0           $self->hook_history_add({
731             hook => $method_step,
732             could => 'N',
733             return => undef,
734             });
735              
736             }
737              
738 0   0       $page_to_print ||= $self->my_content . "/$step";
739              
740 0           my $val_ref = $self->{this_step}{validate_ref};
741 0   0       $self->{my_form}{js_validation} ||= $self->generate_js_validation($val_ref);
742              
743 0           $self->hook_history_add({
744             hook => 'print',
745             could => 'Y',
746             return => "printing $page_to_print",
747             });
748 0           $self->history_push;
749              
750 0           $self->print($page_to_print,
751             $hash_form,
752             $hash_err,
753             );
754 0           return;
755             }
756              
757 0           $self->history_push;
758              
759             ### a hook after
760 0 0         if($sub_ref = $self->can($method_post)) {
761 0           $return_val = &$sub_ref($self);
762 0 0         if($return_val) {
763 0           next;
764             }
765             }
766              
767             }
768 0 0         return if $return_val;
769              
770 0           return $self->print($self->my_content . "/" . $self->initial_step ,$form);
771             }
772              
773             sub generate_js_validation {
774 0     0 0   my $self = shift;
775              
776 0   0       my $val_ref = shift || die "need a val_ref";
777 0   0       my $form_name = $self->{form_name} || die "need a form name";
778              
779 0           require CGI::Ex::Validate;
780 0           my $val = CGI::Ex::Validate->new($self->validate_new_hash($val_ref));
781            
782             ### yes, sort of dumb, but gets rid of variable only used once warning
783 0           $CGI::Ex::Validate::JS_URI_PATH_VALIDATE = $CGI::Ex::Validate::JS_URI_PATH_VALIDATE = "/validate.js";
784 0           $CGI::Ex::Validate::JS_URI_PATH_YAML = $CGI::Ex::Validate::JS_URI_PATH_YAML = "/yaml_load.js";
785              
786 0           return $val->generate_js($val_ref, $form_name);
787             }
788              
789             ### handle_jump_around aims to help keep things nice when a user goes back and resubmits a page
790             sub handle_jump_around {
791 0     0 0   my $self = shift;
792              
793 0           my $path = $self->get_path_array;
794              
795 0           foreach my $step (reverse @{$path}) {
  0            
796 0 0         if($self->fresh_form_info_exists($step)) {
797 0           my $save_validated = delete $self->form->{_validated}{$step};
798              
799 0           foreach my $page_to_check ($step, @{$self->pages_after_page($step)}) {
  0            
800              
801 0 0         if($self->page_has_displayed($page_to_check)) {
802 0           my $cleared = 0;
803 0           my $val_hash = $self->get_validate_ref($page_to_check);
804              
805 0           foreach my $val_key (keys %{$val_hash}) {
  0            
806 0 0 0       next unless($val_hash->{$val_key} && ref $val_hash->{$val_key} && ref $val_hash->{$val_key} eq 'HASH');
      0        
807 0 0 0       if($val_hash->{$val_key}{WipeOnBack} && (! exists $self->this_form->{$val_key}) && exists $self->form->{$val_key}) {
      0        
808 0           $self->clear_value($val_key);
809 0           $cleared = 1;
810             }
811             }
812              
813 0 0         if($cleared) {
814 0           $save_validated .= delete $self->form->{_validated}{$page_to_check};
815             ### need to make it look like these pages never got printed
816 0           for(my $i=(scalar @{$self->form->{_printed_pages}}) - 1;$i>=0;$i--) {
  0            
817 0 0         if($self->form->{_printed_pages}[$i] eq $page_to_check) {
818 0           splice @{$self->form->{_printed_pages}}, $i, 1;
  0            
819             }
820             }
821 0           $self->session({
822             _printed_pages => $self->form->{_printed_pages},
823             });
824             }
825             }
826             }
827 0 0         if($save_validated) {
828 0           $self->save_value('_validated');
829             }
830             }
831             }
832             }
833              
834             sub pages_after_page {
835 0     0 0   my $self = shift;
836 0           my $step = shift;
837 0           my $return = [];
838 0           my $after = 0;
839 0           foreach my $path_step (@{$self->get_path_array}) {
  0            
840 0 0         push @{$return}, $path_step if($after);
  0            
841 0 0         if($path_step eq $step) {
842 0           $after = 1;
843             }
844             }
845 0           return $return;
846             }
847              
848             sub get_real_keys {
849 0     0 0   my $self = shift;
850 0   0       my $real_keys = {%{$self->form}} || {};
851 0           foreach(@{$self->{not_a_real_key}}) {
  0            
852 0           delete $real_keys->{$_};
853             }
854 0           return $real_keys;
855             }
856              
857             sub handle_unvalidated_keys {
858 0     0 0   my $self = shift;
859 0           my $path = $self->get_path_array;
860              
861 0           my $form = $self->form;
862              
863 0   0       my $validated = $form->{_validated} || {};
864 0           my $mini_validated = {%$validated};
865 0           my $unvalidated_keys = $self->get_real_keys;
866              
867 0           foreach my $step (@$path){
868 0 0         last unless(keys %{$unvalidated_keys});
  0            
869 0           my $val_hash = $self->get_validate_ref($step);
870 0 0         if($mini_validated->{$step}) {
871 0           foreach (keys %{$val_hash}) {
  0            
872 0           delete $unvalidated_keys->{$_};
873             }
874 0           next;
875             }
876              
877 0           my $to_save = {};
878 0           foreach(keys %{$unvalidated_keys}) {
  0            
879 0 0 0       if($val_hash->{$_} && $unvalidated_keys->{$_} && $form->{$_} && !$val_hash->{$_ . "_error"}) {
      0        
      0        
880 0           $to_save->{$_} = $form->{$_};
881 0           delete $unvalidated_keys->{$_};
882             }
883             }
884 0 0         if(keys %$to_save) {
885 0           $self->session($to_save);
886             }
887             }
888             }
889              
890             sub initial_step {
891 0     0 0   my $self = shift;
892 0           return $self->path_hash->{initial_step};
893             }
894              
895             sub path_hash {
896 0     0 0   my $self = shift;
897 0   0       return $self->{path_hash} || die "need a hash ref for \$self->{path_hash}";
898             }
899              
900             sub my_path {
901 0     0 0   my $self = shift;
902 0   0       $self->{my_path}{$self->my_content} ||= {};
903 0           return $self->{my_path}{$self->my_content};
904             }
905              
906             sub my_path_step {
907 0     0 0   my $self = shift;
908 0           my $step = shift;
909 0   0       $self->my_path->{$step} ||= {};
910 0           return $self->my_path->{$step};
911             }
912              
913             sub get_validate_ref {
914 0     0 0   my $self = shift;
915              
916 0           my $step = shift;
917 0           my $return;
918 0           my $step_hash = $self->my_path_step($step);
919 0 0 0       if($step_hash && $step_hash->{validate_ref}) {
    0          
920 0           $return = $step_hash->{validate_ref};
921             } elsif($self->{validate_refs}) {
922              
923             ### can break out validate refs by content chunk
924 0 0 0       if($self->{validate_refs}{$self->my_content} && $self->{validate_refs}{$self->my_content}{$step}) {
    0          
925 0           $return = $self->{validate_refs}{$self->my_content}{$step};
926              
927             ### or just by step
928             } elsif($self->{validate_refs}{$step}) {
929 0           $return = $self->{validate_refs}{$step};
930             }
931             }
932 0 0         unless($return) {
933 0           $return = $self->include_validate_ref($self->my_content . "/$step");
934             }
935 0           $step_hash->{validate_ref} = $return;
936 0           return $return;
937             }
938              
939             sub include_validate_ref {
940 0     0 0   my $self = shift;
941              
942             # step is the full step like path/skel/enter_info
943 0           my $step = shift;
944              
945 0           my $val_filename = $self->get_full_path($self->step_with_extension($step, 'val'));
946 0 0         return -e $val_filename ? $self->conf_read($val_filename) : {};
947             }
948              
949             sub conf_read {
950 0     0 0   my $self = shift;
951 0           my $filename = shift;
952 0           require YAML;
953 0           my $ref;
954 0           eval {
955 0           $ref = YAML::LoadFile($filename);
956             };
957 0 0         if($@) {
958 0           die "YAML error: $@";
959             }
960 0           return $ref;
961             }
962              
963             sub page_name_helper {
964 0     0 0   my $self = shift;
965 0   0       my $base_page = shift || die "need a \$base_page for page_name_helper";
966 0 0         $base_page = "content/$base_page" unless($base_page =~ m@^(conf|content|images|template)/@);
967 0 0         $base_page .= ".$self->{htm_extension}" unless($base_page =~ /\.\w+$/);
968 0           return $base_page;
969             }
970              
971             sub get_full_path {
972 0     0 0   my $self = shift;
973 0           my $relative_path = shift;
974 0           $relative_path = $self->page_name_helper($relative_path);
975 0   0       my $dirs = shift || $self->include_path;
976 0           my $full_path = '';
977 0           foreach my $dir (GET_VALUES($dirs)) {
978 0           my $this_path = "$dir/$relative_path";
979 0 0         if(-e $this_path) {
980 0           $full_path = $this_path;
981 0           last;
982             }
983             }
984 0           return $full_path;
985             }
986              
987             sub fresh_form_info_exists {
988 0     0 0   my $self = shift;
989 0           my $step = shift;
990 0           my $return = 0;
991 0 0 0       if($self->non_empty_val_ref($step) && $self->info_exists($step, $self->this_form)) {
992 0           $return = 1;
993             }
994 0           return $return;
995             }
996              
997             sub non_empty_val_ref {
998 0     0 0   my $self = shift;
999 0           my $step = shift;
1000            
1001 0           my $val_hash = $self->get_validate_ref($step);
1002 0           return $self->non_empty_ref($val_hash);
1003             }
1004              
1005             sub non_empty_ref {
1006 0     0 0   my $self = shift;
1007 0           my $ref = shift;
1008 0           my $non_empty = 0;
1009 0 0         if($ref) {
1010 0           my $ref_ref = ref $ref;
1011 0 0         if($ref_ref) {
1012 0 0         if($ref_ref eq 'HASH') {
    0          
1013 0 0         $non_empty = (scalar keys %{$ref}) ? 1 : 0;
  0            
1014             } elsif($ref_ref eq 'ARRAY') {
1015 0 0         $non_empty = (@{$ref}) ? 1 : 0;
  0            
1016             }
1017             }
1018             }
1019 0           return $non_empty;
1020             }
1021              
1022             sub info_exists {
1023 0     0 0   my $self = shift;
1024 0           my $step = shift;
1025 0   0       my $form = shift || $self->form;
1026            
1027 0           my $val_ref = $self->get_validate_ref($step);
1028              
1029 0           my $return = 0;
1030             ### default to info exists on an empty val_ref
1031 0 0         unless($self->non_empty_ref($val_ref)) {
1032 0           $return = 1;
1033             }
1034            
1035 0           $self->{_extant_info} = [];
1036 0           my $validating_keys = $self->get_validating_keys($val_ref);
1037             #if there exists one key in the form that matches
1038             #one key in the validate_ref return true
1039 0           foreach(@{$validating_keys}) {
  0            
1040 0 0         if(exists $form->{$_}) {
1041 0           $return = 1;
1042 0           push @{$self->{_extant_info}}, $_;
  0            
1043             }
1044             }
1045 0           return $return;
1046             }
1047              
1048             sub get_validating_keys {
1049 0     0 0   my $self = shift;
1050 0           my $val_ref = shift;
1051 0           require CGI::Ex::Validate;
1052 0           my $val = CGI::Ex::Validate->new;
1053 0           my $keys = $val->get_validation_keys($val_ref);
1054 0           return [sort keys %{$keys}];
  0            
1055             }
1056              
1057             sub page_has_displayed {
1058 0     0 0   my $self = shift;
1059 0           my $page = shift;
1060 0           return (grep $_ eq $page, @{$self->form->{_printed_pages}});
  0            
1061             }
1062              
1063             sub page_was_just_printed {
1064 0     0 0   my $self = shift;
1065 0           my $page = shift;
1066             return (
1067             # were we passed a page
1068             $page
1069             &&
1070             # we have printed_pages
1071             ($self->form->{_printed_pages})
1072             &&
1073             # we have an array
1074             (ref $self->form->{_printed_pages} eq 'ARRAY')
1075             &&
1076             # we have a non empty array
1077 0   0       ( scalar @{$self->form->{_printed_pages}})
1078             &&
1079             # was $page the last entry
1080             $self->form->{_printed_pages}[-1] eq $page
1081             );
1082             }
1083              
1084             sub validate {
1085 0     0 0   my $self = shift;
1086 0   0       my $validated = $self->form->{_validated} || {};
1087              
1088 0           my $this_step = $self->{this_step}{this_step};
1089 0           my $return = 1;
1090              
1091 0           my $show_errors = 1;
1092 0 0 0       if(!$self->page_was_just_printed($this_step) || !$self->fresh_form_info_exists($this_step)) {
1093 0           $show_errors = 0;
1094             }
1095              
1096 0           my $sub_ref;
1097 0           my $method_pre_val = "$self->{this_step}{this_step}_pre_validate";
1098 0 0         if($sub_ref = $self->can($method_pre_val)) {
1099 0           my $pre_val_return = &$sub_ref($self, $show_errors);
1100 0           $self->hook_history_add({
1101             hook => 'pre_val',
1102             could => 'Y',
1103             return => $pre_val_return,
1104             });
1105 0   0       $return = $pre_val_return && $return;
1106             } else {
1107 0           $self->hook_history_add({
1108             hook => 'pre_val',
1109             could => 'N',
1110             return => '',
1111             });
1112             }
1113              
1114 0 0         if($validated->{$this_step}) {
1115              
1116              
1117             } else {
1118              
1119             ### validate_proper returns the number of errors it found
1120             ### so, 0 means success
1121 0           my $validate_proper_return = $self->validate_proper($self->form, $self->{this_step}{validate_ref}, $show_errors);
1122 0           $self->hook_history_add({
1123             hook => 'validate_proper',
1124             could => 'Y',
1125             return => $validate_proper_return,
1126             });
1127              
1128 0 0         if($validate_proper_return) {
1129              
1130 0           $return = 0;
1131              
1132             } else {
1133 0           $self->{validated_fresh}{$this_step} = 1;
1134 0           $validated->{$this_step} = 1;
1135 0           my $validated_hash = {
1136             _validated => $validated,
1137             };
1138              
1139 0           $self->form->{_validated} = $validated;
1140             # going to save the keys that have been validated to the session
1141 0           foreach my $key (@{$self->get_validating_keys($self->{this_step}{validate_ref})}) {
  0            
1142 0           $validated_hash->{$key} = $self->form->{$key};
1143             }
1144 0           $self->session($validated_hash);
1145             }
1146             }
1147 0 0         if($return) {
1148 0           my $method_post_val = "$self->{this_step}{this_step}_post_validate";
1149 0 0         if($sub_ref = $self->can($method_post_val)) {
1150 0           my $post_val_return = &$sub_ref($self, $show_errors);
1151 0           $self->hook_history_add({
1152             hook => 'post_val',
1153             could => 'Y',
1154             return => $post_val_return,
1155             });
1156 0   0       $return = $post_val_return && $return;
1157             }
1158             }
1159              
1160 0 0         if(!$return) {
1161 0           my $change = '';
1162 0           foreach my $check_page ($this_step, @{$self->pages_after_page($this_step)}) {
  0            
1163 0   0       $change .= (delete $validated->{$check_page}||'');
1164             }
1165 0 0         if($change) {
1166 0           $self->session({
1167             _validated => $validated,
1168             });
1169             }
1170             }
1171 0           return $return;
1172             }
1173              
1174             sub validate_new_hash {
1175 0     0 0   return {};
1176             }
1177              
1178             sub validate_proper {
1179 0     0 0   my $self = shift;
1180 0           my $form = shift;
1181 0           my $val_ref = shift;
1182 0           my $show_errors = shift;
1183              
1184 0           require CGI::Ex::Validate;
1185 0           my $errobj = CGI::Ex::Validate->new($self->validate_new_hash($val_ref))->validate($form, $val_ref);
1186 0           my $return = 0;
1187 0 0         if($errobj) {
1188 0           my $error_hash = $errobj->as_hash;
1189 0 0         if($show_errors) {
1190 0           $return = $self->add_my_error($error_hash);
1191             } else {
1192 0           $return = scalar keys %{$error_hash};
  0            
1193             }
1194             }
1195 0           return $return;
1196             }
1197              
1198             sub save_value {
1199 0     0 0   my $self = shift;
1200 0           my $name = shift;
1201              
1202 0 0         if (!ref $name) {
1203 0           $self->session({
1204             $name => $self->form->{$name}
1205             });
1206             } else {
1207 0           foreach my $key (keys %{$name}) {
  0            
1208 0           $self->form->{$key} = $name->{$key};
1209             }
1210 0           $self->session($name);
1211             }
1212             }
1213              
1214             sub clear_value {
1215 0     0 0   my $self = shift;
1216 0           my $name = shift;
1217              
1218 0           delete $self->form->{$name};
1219 0           delete $self->fill->{$name};
1220 0           delete $self->session->{$name};
1221             }
1222              
1223             sub add_my_error {
1224 0     0 0   my $self = shift;
1225 0           my $errors = shift;
1226              
1227 0 0 0       unless(ref $errors && ref $errors eq 'HASH') {
1228 0           die "need to send a hash ref of errors"
1229             }
1230              
1231 0           my $added = 0;
1232 0   0       $self->{my_form}{errors} ||= {};
1233              
1234 0           foreach my $key (keys %{$errors}) {
  0            
1235 0 0         next unless($errors->{$key});
1236 0           $added++;
1237 0           $self->{my_form}{errors}{$key} = $errors->{$key};
1238             }
1239              
1240             ### returns how many errors were added
1241 0           return $added;
1242             }
1243              
1244             sub fill {
1245 0     0 0   my $self = shift;
1246 0   0       $self->{fill} ||= {};
1247 0           return $self->{fill};
1248             }
1249              
1250             sub add_to_fill {
1251 0     0 0   my $self = shift;
1252              
1253 0           my $fill_to_add = shift;
1254 0           my $smart_merge = shift;
1255            
1256 0           foreach(keys %{$fill_to_add}) {
  0            
1257 0 0 0       next if($smart_merge && exists $self->fill->{$_});
1258 0           $self->fill->{$_} = $fill_to_add->{$_};
1259             }
1260             }
1261              
1262             sub preload {
1263 0     0 0   my $self = shift;
1264 0           foreach my $step (@{$self->{path_array}}) {
  0            
1265 0           my $page = $self->page_name_helper($self->my_content . "/$step");
1266 0           my $ref = $self->get_validate_ref($step);
1267 0           $self->process($page, {});
1268             }
1269             }
1270              
1271             sub out {
1272 0     0 0   my $self = shift;
1273 0   0       my $page = shift || die "need a page to \$self->out";
1274 0   0       my $form = shift || {};
1275              
1276 0           $page = $self->page_name_helper($page);
1277 0           my $out = $self->process($page, $form);
1278 0 0         $out = \$out unless(ref $out);
1279 0           $self->fill_in($out);
1280 0           return $out;
1281             }
1282              
1283             sub print {
1284 0     0 0   my $self = shift;
1285 0           my $step = shift;
1286              
1287 0           $self->handle_unvalidated_keys;
1288              
1289 0           my $out;
1290              
1291 0 0 0       if($self->{htm} && $self->{htm}{$step}) {
    0          
1292 0           my $content = $self->{htm}{$step};
1293 0 0         $self->template->process(\$content, $self->uber_form, \$out) || die $self->template->error;
1294 0           $self->fill_in(\$out);
1295              
1296             } elsif (!-e $self->get_full_path($self->step_with_extension($step, 'htm'))) {
1297 0           $out = $self->create_page($step);
1298 0 0         die "couldn't find content for page: $step" unless($out);
1299 0           $self->fill_in(\$out);
1300             }
1301              
1302 0           $self->record_page_print;
1303 0           $self->my_content_type($step);
1304 0 0         print $out ? $out : ${$self->out($step, $self->uber_form(\@_))};
  0            
1305             }
1306              
1307             sub fill_in {
1308 0     0 0   my $self = shift;
1309 0           my $content = shift;
1310 0 0 0       die "need a scalar ref for \$content" unless($content && ref $content && ref $content eq 'SCALAR');
      0        
1311 0   0       my $hashref = shift || $self->fill;
1312 0 0         if($self->{uber_form}{fill}) {
1313 0           foreach(keys %{$self->{uber_form}{fill}}) {
  0            
1314 0           $hashref->{$_} = $self->{uber_form}{fill}{$_};
1315             }
1316             }
1317 0           require CGI::Ex;
1318 0           my $cgix = CGI::Ex->new;
1319 0           $cgix->fill({text => $content, form => $hashref});
1320             }
1321              
1322             ### magic fill methods
1323              
1324             sub allow_magic_fill {
1325 0     0 0   my $self = shift;
1326 0 0         return $self->{allow_magic_fill} ? 1 : 0;
1327             }
1328              
1329             sub magic_fill_interpolation_hash {
1330 0     0 0   my $self = shift;
1331              
1332 0           my ($script) = $0 =~ m@(?:.+/)?(.+)@;
1333 0           my ($_script) = $script =~ m@.*_(.+)@;
1334 0   0       $_script ||= $script;
1335              
1336 0           my $hash = {
1337             localtime => scalar (localtime),
1338             script => $script,
1339             _script => $_script,
1340             time => time,
1341             %ENV,
1342             };
1343 0 0         if($self->{allow_magic_micro}) {
1344 0           require Time::HiRes;
1345 0           $hash->{micro} = join(".", &Time::HiRes::gettimeofday());
1346 0           $hash->{micro_part} = (&Time::HiRes::gettimeofday())[1];
1347             };
1348 0           return $hash;
1349             }
1350              
1351             sub magic_fill_ref {
1352 0     0 0   my $self = shift;
1353              
1354 0   0       my $filename = shift || $self->{magic_fill_filename};
1355              
1356 0           my $ref = {};
1357              
1358 0 0         if(open(FILE, $filename)) {
1359              
1360 0           my $file = join("", );
1361              
1362 0           my $out = '';
1363 0           $self->process(\$file, $self->magic_fill_interpolation_hash, \$out);
1364              
1365 0           while($out =~ /^(.+)$/mg) {
1366 0           my $line = $1;
1367 0 0         next if($line =~ /^\s*#/);
1368 0           my ($keys, $value) = split /\s+/, $line, 2;
1369 0           foreach my $key (split /,/, $keys) {
1370 0           my $this_value = $value;
1371 0           $this_value =~ s/\$key_name/$key/g;
1372 0           $ref->{$key} = $this_value;
1373             }
1374             }
1375              
1376             }
1377              
1378 0           return $ref;
1379             }
1380              
1381             sub uber_form {
1382 0     0 0   my $self = shift;
1383 0   0       my $others = shift || [];
1384              
1385 0           foreach my $hash (@{$others}) {
  0            
1386 0 0 0       next unless($hash && ref $hash && ref $hash eq 'HASH');
      0        
1387 0           foreach (keys %{$hash}) {
  0            
1388 0 0         next if(/^_/);
1389 0           $self->{uber_form}{$_} = $hash->{$_};
1390             }
1391             }
1392              
1393 0   0       $self->{uber_form} ||= {};
1394 0   0       $self->{uber_form}{fill} ||= {};
1395 0           foreach (keys %{$self->form}) {
  0            
1396 0 0         next if(/^_/);
1397 0           $self->{uber_form}{$_} = $self->form->{$_};
1398             }
1399 0           foreach (keys %{$self->{my_form}}) {
  0            
1400 0           $self->{uber_form}{$_} = $self->{my_form}->{$_};
1401             }
1402 0           foreach (keys %{$self->fill}) {
  0            
1403 0 0         next if(/^_/);
1404 0           $self->{uber_form}{fill}{$_} = $self->fill->{$_};
1405             }
1406 0   0       $self->{uber_form}{script_name} = $ENV{SCRIPT_NAME} || '';
1407 0   0       $self->{uber_form}{path_info} = $ENV{PATH_INFO} || '';
1408 0           return $self->{uber_form};
1409             }
1410              
1411             sub process {
1412 0     0 0   my $self = shift;
1413 0   0       my $step_filename = shift || die "need a \$step_filename to \$self->process";
1414 0   0       my $form = shift || {};
1415 0           my $out = shift;
1416              
1417 0 0         unless(defined $out) {
1418 0           my $scalar = '';
1419 0           $out = \$scalar;
1420             }
1421              
1422 0 0         $self->template->process($step_filename, $form, $out) || die "Template error: " . $self->template->error();
1423             #my $return = '';
1424             #$self->template->process($out, $form, \$return) || die $self->template->error();
1425 0 0         return ref $out ? $out : \$out;
1426             }
1427              
1428             sub step_with_extension {
1429 0     0 0   my $self = shift;
1430 0           my $step = shift;
1431 0           my $extension_type = shift;
1432 0           my $extension = $self->{"${extension_type}_extension"};
1433              
1434 0 0         return ($step =~ /\.\w+$/) ? $step : "$step.$extension";
1435             }
1436              
1437             sub template {
1438 0     0 0   require Template;
1439 0           my $self = shift;
1440 0 0         unless($self->{template}) {
1441 0           $self->{template} = Template->new({
1442             INCLUDE_PATH => $self->include_path,
1443             });
1444             }
1445 0           return $self->{template};
1446             }
1447              
1448             sub record_mail_print {
1449 0     0 0   my $self = shift;
1450 0           my $step = shift;
1451 0   0       my $printed_mail = $self->session->{printed_mail} || [];
1452 0 0 0       unless($step && $printed_mail->[-1] && $step eq $printed_mail->[-1]) {
      0        
1453 0           push @{$printed_mail}, $step;
  0            
1454 0           $self->session({
1455             printed_mail => $printed_mail,
1456             });
1457             }
1458             }
1459              
1460             sub record_page_print {
1461 0     0 0   my $self = shift;
1462 0   0       my $step = shift || $self->{this_step}{this_step};
1463 0   0       my $printed_pages = $self->session->{_printed_pages} || [];
1464 0 0 0       unless($step && $printed_pages->[-1] && $step eq $printed_pages->[-1]) {
      0        
1465 0           push @{$printed_pages}, $step;
  0            
1466 0           $self->session({
1467             _printed_pages => $printed_pages,
1468             });
1469             }
1470             }
1471              
1472             # This subroutine will generate a generic HTML page
1473             # with form fields for the required fields based on the validate file
1474             sub create_page {
1475 0     0 0   my $self = shift;
1476 0           my $step = shift;
1477              
1478 0   0       my $form_name = $self->{form_name} || die "need a form name";
1479              
1480 0   0       $self->{create_page} ||= {};
1481 0           my $interpolate_hash = {
1482             full_step => $self->my_content . "/" . $self->{this_step}{this_step},
1483             form_name => $form_name,
1484             };
1485 0   0       $self->{create_page}{header} ||= <
1486            
1487            
1488            
1489             created step: [% full_step %]
1490            
1491            
1492             HEADER
1493              
1494 0           my $validate_ref = $self->get_validate_ref($self->{this_step}{this_step});
1495 0 0         die "couldn't get validate_ref to create_page with" unless($validate_ref);
1496              
1497 0           $interpolate_hash->{validating_keys} = [];
1498 0           for my $name ( @{$self->get_validating_keys($validate_ref)}) {
  0            
1499 0           my $hash = {
1500             name => $name,
1501             };
1502 0           push @{$interpolate_hash->{validating_keys}}, $hash;
  0            
1503             #$content .= "[form.$name"."_required]";
1504             #$content .= "[|| form.$name"."_error env.blank]";
1505             }
1506              
1507 0   0       $self->{create_page}{js} ||= $self->generate_js_validation($validate_ref);
1508 0   0       $self->{create_page}{table_open} ||= "";
1509 0   0       $ENV{SCRIPT_NAME} ||= '';
1510 0   0       $ENV{PATH_INFO} ||= '';
1511 0   0       $self->{create_page}{form_open} ||= "
";
1512 0   0       $self->{create_page}{form} ||= <
1513             [% FOREACH hash = validating_keys %]
1514            
1515             [% hash.name %]
1516            
1517            
1518             [% END %]
1519            
1520             FORM
1521 0   0       $self->{create_page}{form_close} ||= "";
1522 0   0       $self->{create_page}{table_close} ||= "
";
1523 0   0       $self->{create_page}{footer} ||= <
1524            
1525            
1526             FOOTER
1527              
1528 0           my $content = <
1529             $self->{create_page}{header}
1530             $self->{create_page}{form_open}
1531             $self->{create_page}{table_open}
1532             $self->{create_page}{form}
1533             $self->{create_page}{table_close}
1534             $self->{create_page}{form_close}
1535             $self->{create_page}{footer}
1536             $self->{create_page}{js}
1537             CONTENT
1538              
1539 0           my $return = '';
1540 0           $self->template->process(\$content, $interpolate_hash, \$return);
1541 0           return $return;
1542             }
1543              
1544              
1545             sub GET_VALUES {
1546 0     0 0   my $values=shift;
1547 0 0         return () unless defined $values;
1548 0 0         if (ref $values eq "ARRAY") {
1549 0           return @$values;
1550             }
1551 0           return ($values);
1552             }
1553              
1554             sub URLEncode {
1555 0     0 0   my $arg = shift;
1556 0 0         my ($ref,$return) = ref($arg) ? ($arg,0) : (\$arg,1) ;
1557              
1558 0 0         if (ref($ref) ne 'SCALAR') {
1559 0           die "URLEncode can only modify a SCALAR ref!: ".ref($ref);
1560 0           return undef;
1561             }
1562              
1563 0 0 0       if ( (defined $$ref) && length $$ref) {
1564 0           $$ref =~ s/([^\w\.\-\ \@\/\:])/sprintf("%%%02X",ord($1))/eg;
  0            
1565 0           $$ref =~ y/\ /+/;
1566             }
1567              
1568 0 0         return $return ? $$ref : '';
1569             }
1570              
1571             sub my_content_type {
1572 0     0 0   my $self = shift;
1573 0           my $step = shift;
1574 0 0         unless($ENV{CONTENT_TYPED}) {
1575 0 0 0       if($step && $step =~ /\.xml/) {
1576 0           print "Content-type: text/xml\n\n";
1577             } else {
1578 0           print "Content-type: text/html\n\n";
1579             }
1580 0           $ENV{CONTENT_TYPED} = 1;
1581             }
1582             }
1583              
1584             sub location_bounce {
1585 0     0 0   my $self = shift;
1586 0           my $url = shift;
1587 0           my $referer = shift;
1588 0 0         if (exists $ENV{CONTENT_TYPED}) {
1589 0           print "Location: $url
\n";
1590             } else {
1591 0           print "Status: 302\r\n";
1592 0 0         print "Referer: $referer\r\n" if($referer);
1593 0           print "Location: $url\r\n\r\n";
1594             }
1595 0           return 1;
1596             }
1597              
1598             1;
1599              
1600             __END__