/[cvs]/nfo/php/libs/com.newsblob.phphtmllib/form/FormWizard.inc
ViewVC logotype

Annotation of /nfo/php/libs/com.newsblob.phphtmllib/form/FormWizard.inc

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (hide annotations)
Sat Sep 20 00:18:43 2003 UTC (20 years, 11 months ago) by jonen
Branch: MAIN
+ updated whole phphtmllib to v2.3.0

1 jonen 1.1 <?php
2     /**
3     * This file contains the FormWizard class.
4     *
5     * $Id: FormWizard.inc,v 1.2 2003/07/31 21:51:20 hemna Exp $
6     *
7     * @author Walter A. Boring IV <waboring@buildabetterweb.com>
8     * @package phpHtmlLib
9     * @subpackage FormProcessing
10     *
11     * @copyright LGPL - See LICENCE
12     *
13     */
14    
15     define("WIZARD_VISITED", "_wizard_visited");
16     define("WIZARD_STEP", "_wizard_step");
17     define("WIZARD_TO_STEP", "_wizard_to_step");
18     define("WIZARD_ID", "_wizard_id");
19     define("WIZARD_ACTION", "_wizard_action");
20    
21     define("WIZARD_NEXT", "NEXT");
22     define("WIZARD_PREV", "PREV");
23     define("WIZARD_JUMP", "JUMP");
24     define("WIZARD_FINAL", "FINAL");
25    
26     class FormWizard extends FormProcessor {
27    
28     /**
29     * This holds the array of
30     * step objects for the
31     * wizard
32     */
33     var $_steps = array();
34    
35    
36     /**
37     * Holds a bunch of state
38     * variables
39     */
40     var $_vars = array("to_step" => 0,
41     "num_steps" => 0,
42     "on_confirm" => FALSE,
43     WIZARD_ID => NULL );
44    
45     /**
46     * The constructor
47     *
48     */
49     function FormWizard() {
50     user_error(__CLASS__."::".__FUNCTION." - this class isn't done yet.");
51     $this->_session_test();
52     $this->set_form_name( "form_wizard" );
53     $this->set_form_action( $_SERVER["PHP_SELF"] );
54    
55     //let the child class add the steps
56     $this->user_setup();
57    
58     //init our vars
59     $this->_init();
60    
61     //Set up the Validation object
62     //and the FormErrors object to
63     //be used by this form.
64     $this->setup_validation();
65    
66     //set the current step
67     $this->_set_step();
68    
69     //now process the form
70     $this->_process_form();
71    
72     //now we need to process the current step.
73     }
74    
75    
76     /**
77     * This function renders the
78     * FormWizard
79     *
80     */
81     function render($indent_level=0, $output_debug=0) {
82     $container = container();
83    
84     //add the JS
85     $container->add( $this->_build_js() );
86    
87     $container->add( $this->_build_toolbar(),
88     html_br(2) );
89    
90     if ($this->_has_errors) {
91     //we need to render the form errors
92     //and then the form
93     $container->add( $this->render_error($indent_level, $output_debug) );
94     } else {
95     //there are no errors!
96     ddd( "have we visited?" );
97     //ddd( $_REQUEST );
98     if (@$_REQUEST[FORM_VISITED] == 1) {
99     //looks like the form has been processed?
100     ddd( "confirmed = ".$this->_confirmed );
101     ddd( "curr step = ".$this->_current_step() );
102     if (!$this->_confirmed && $this->_vars["on_confirm"]) {
103     ddd("FINAL DUDE!");
104     $container->add( $this->render_confirm($indent_level, $output_debug) );
105     } else {
106     //Looks like the action worked
107     $success = $this->_form_content->form_success();
108    
109     if ($this->_form_success_render) {
110     $container->add( $this->render_form($indent_level, $output_debug, $success) );
111     } else {
112     if (method_exists($success,"render")) {
113     //looks like this is an object.
114     //we'll assume it has a render function.
115     $container->add( $success->render($indent_level, $output_debug) );
116     } else {
117     //since its not an object,
118     //lets just display it.
119     $container->add( $success );
120     }
121     }
122     }
123     } else {
124     $container->add( $this->render_form($indent_level, $output_debug) );
125     }
126     }
127    
128     return $container->render($indent_level, $output_debug);
129     }
130    
131    
132     /**
133     * This method does the logic of
134     * doing the form processing
135     */
136     function _process_form() {
137     //Has this step been visited yet?
138    
139     if (!$this->_is_step_visited($this->_current_step()) &&
140     $this->_current_step() <= $this->_vars["num_steps"]) {
141     $this->_form_content->form_init_data();
142     }
143    
144     //we only need to process the form
145     //if it has been visited. Otherwise
146     //it just gets rendered.
147     if (@$_REQUEST[FORM_VISITED] == 1) {
148     ddd("PROCESS STEP ".$this->_current_step());
149     $this->_form_content->set_action($_REQUEST[FORM_ACTION]);
150    
151     //let see if this was a confirmation page.
152     if ( @$_REQUEST[WIZARD_ACTION] == WIZARD_FINAL ) {
153     //looks like this was a submit on a
154     //confirmation page. we don't need
155     //to do form field validation.
156     $this->_confirmed = TRUE;
157     for ($i=0; $i<=$this->_vars["num_steps"]-1; $i++) {
158     $this->_has_errors = !$this->_steps[$i]["form"]->form_action();
159     }
160     } else {
161     //we haven't been confirmed, so we
162     //need to validate the form.
163     if ($this->can_validate()) {
164     //looks like we should do validation
165     $this->do_validation();
166     }
167     if (!$this->_has_errors) {
168     //no errors were found
169     //make sure we don't have any backend errors
170     $this->_has_errors = !$this->_form_content->form_backend_validation();
171     if (!$this->_has_errors) {
172     //ok this step validated. lets display the next.
173     //mark this step as visited
174     $current_step = $this->_current_step();
175     $this->_step_visited( $current_step );
176     ddd( "CURRENT STEP ".$current_step);
177    
178     switch ($_REQUEST[WIZARD_ACTION]) {
179     case WIZARD_NEXT:
180     ddd("NEXT");
181     if ($current_step == $this->_vars["num_steps"]) {
182     //we need to show the confirmation
183     //don't process
184     $this->_vars["on_confirm"] = TRUE;
185     ddd("ASS");
186     } else {
187     $this->_set_current_step($current_step+1);
188     unset($_REQUEST[FORM_VISITED]);
189     $this->_form_content = &$this->_steps[$this->_current_step()-1]["form"];
190     $this->_process_form();
191     }
192     break;
193    
194     case WIZARD_PREV:
195     $this->_set_current_step($current_step-1);
196     unset($_REQUEST[FORM_VISITED]);
197     $this->_form_content = &$this->_steps[$this->_current_step()-1]["form"];
198     ddd("PREV");
199     $this->_process_form();
200     break;
201     }
202     }
203     }
204     }
205     }
206     ddd("bail");
207     }
208    
209    
210     /**
211     * This function renders the confirmation
212     * page. This page sits in between the
213     * front end form, and the action handler.
214     * This only gets called after a form
215     * and its data has been successfully
216     * validated.
217     *
218     * @param int - $indent_level
219     * @param int - $output_debug
220     *
221     * @return string - the raw html
222     */
223     function render_confirm( $indent_level, $output_debug ) {
224     ddd("BUILD CONFIRM");
225     //build the $this->_form object.
226     $this->_build_form_tag();
227    
228     //add the confirm object/html
229     for($i=0; $i<=$this->_vars["num_steps"]-1; $i++) {
230     $title = "Step ".($i+1)." : ".$this->_steps[$i]["title"];
231     $this->_form->add( $this->_steps[$i]["form"]->form_confirm($title, FALSE),
232     html_br(2));
233     }
234     //$confirm = &$this->_form_content->form_confirm( $this->data );
235     //$this->_form->add_reference( $confirm );
236    
237     //ok add all of the submitted data as hidden form fields
238     $this->_add_confirm_data();
239    
240     //Ok lets add our hidden vars
241     $this->__hidden_fields();
242    
243     return $this->_form->render($indent_level, $output_debug);
244     }
245    
246     /**
247     * A subclass can override this function
248     * to setup the class variables after
249     * the constructor. The constructor
250     * automatically calls this function.
251     *
252     */
253     function user_setup() {
254     trigger_error("FormWizard::user_setup() - ".
255     "child class must override this method ".
256     "to add the wizard steps");
257     }
258    
259    
260     /**
261     * This adds a step to the wizard
262     *
263     * @param string - the title for the step
264     * @param string - the description for the step
265     * @param string - the help url for the step (if any)
266     * @param FormContent - the form content object
267     * that is the step.
268     */
269     function add_step( $title, $desc, $help, &$step ) {
270     $this->_steps[] = array("title" => $title,
271     "desc" => $desc,
272     "help" => $help,
273     "form" => &$step);
274     $this->_vars["num_steps"]++;
275     }
276    
277    
278     /**
279     * This function initializes all of the fields we
280     * need to keep track of for the internal state
281     * of the wizard. It also walks each of the
282     * step FormContent objects and initializes them.
283     *
284     * We save some of the state of the wizard in
285     * the session.
286     */
287     function _init() {
288     if (!isset($_REQUEST[WIZARD_VISITED])) {
289    
290     $this->_vars[WIZARD_ID] = uniqid("wizard_");
291     ddd( $this->_vars );
292    
293     $this->_init_session();
294     $this->_vars["to_step"] = 2;
295     } else {
296     $this->_vars[WIZARD_ID] = $_REQUEST[WIZARD_ID];
297     $current_step = $this->_current_step();
298     $this->_vars["to_step"] = $current_step++;
299    
300     //if ($this->_vars["current_step"] == count($this->_steps)) {
301     // $this->_vars["to_step"] = WIZARD_FINAL;
302     //} else {
303     // $this->_vars["to_step"] = WIZARD_NEXT;
304     //}
305     }
306     //ddd( $_SESSION );
307    
308     //initialize all of the Forms
309     //so they retain their data.
310     for ($i=0; $i<=$this->_vars["num_steps"]-1; $i++) {
311     $this->_steps[$i]["form"]->form_init_elements();
312     }
313    
314     }
315    
316     /**
317     * This function sets the _form_content
318     * object for the current step we are operating on.
319     * The parent FormProcessor needs this object set
320     * in order to process the step correctly.
321     *
322     */
323     function _set_step() {
324     $this->_form_content = &$this->_steps[$this->_current_step()-1]["form"];
325     }
326    
327     function __hidden_fields() {
328    
329     //add all of the other steps fields
330     //we need to add all the previous visted steps
331     //fields so we save em.
332     $step_count = 1;
333     foreach( $this->_steps as $step ) {
334     if ($step_count != $this->_current_step()) {
335     $this->_form_content = &$step["form"];
336     $this->_add_confirm_data();
337     }
338     $step_count++;
339     }
340    
341     if (isset($_REQUEST[WIZARD_ACTION]) &&
342     $_REQUEST[WIZARD_ACTION] == WIZARD_FINAL) {
343     $this->_set_step();
344     }
345    
346     parent::__hidden_fields();
347    
348     //$this->_form->add( form_hidden(WIZARD_STEP, $this->_vars["current_step"]) );
349     $this->_form->add( form_hidden(WIZARD_TO_STEP, $this->_vars["to_step"]) );
350     $this->_form->add( form_hidden(WIZARD_ID, $this->_vars[WIZARD_ID]) );
351     $this->_form->add( form_hidden(WIZARD_ACTION, WIZARD_NEXT) );
352     $this->_form->add( form_hidden(WIZARD_VISITED, 1) );
353     }
354    
355    
356     /**
357     * This builds the javascript needed for the
358     * navigation of the wizard
359     *
360     * @return string
361     */
362     function _build_js() {
363     $name = $this->_form_attributes["name"];
364     $js = "
365     function wizard_cancel_confirm(butname, txt) {
366     if (confirm(txt)){
367     document.$name.".WIZARD_ACTION.".value = butname;
368     document.$name.submit();
369     }
370     }
371     function wizard_submit(txt) {
372     document.$name.".WIZARD_ACTION.".value = txt;
373     document.$name.submit();
374     }
375     function wizard_submit2(txt, step) {
376     document.$name.".WIZARD_ACTION.".value = txt;
377     document.$name.".WIZARD_TO_STEP.".value = step;
378     document.$name.submit();
379     }";
380    
381     $script = html_script();
382     $script->add( $js );
383     return $script;
384     }
385    
386    
387    
388     /**
389     * This renders the toolbar/step table
390     * for the navigation of the wizard
391     */
392     function _build_toolbar() {
393     $current_step = $this->_current_step();
394     if ($this->_vars["on_confirm"]) {
395     $current_step++;
396     $step_title = "Confirmation";
397     } else {
398     $step_title = $this->_steps[$current_step - 1]["title"];
399     }
400    
401     $title = "Step ".$current_step." : ". $step_title;
402     $table = new InfoTable($title, 500);
403    
404     //build the table of steps.
405     $c = container();
406     $step_num = 1;
407     foreach( $this->_steps as $step ) {
408     $c->add( $this->_build_step_image( $step_num, $step["title"] ) );
409    
410     if ($step_num != $this->_vars["num_steps"]) {
411     $arrow = html_img("/phphtmllib/images/wizard/arrow.png");
412     $arrow->set_style("vertical-align:super");
413     $c->add( $arrow );
414     }
415    
416     $step_num++;
417     }
418    
419     //add the confirmation step
420     $c->add( $arrow );
421     $c->add( $this->_build_step_image( $step_num, "Confirmation" ) );
422    
423    
424     $tr = html_tr("", $c );
425     $tr->set_style("text-align: center");
426     $table->add_row( $tr );
427    
428     //now show the description
429     if ($this->_vars["on_confirm"] == true) {
430     $desc = "Confirmation";
431     } else {
432     $desc = $this->_steps[$current_step - 1]["desc"];
433     }
434     $tr = html_tr("", $desc );
435     $tr->set_style("text-align: center");
436     $table->add_row( $tr );
437    
438     //now add the controls
439     $c = html_div();
440     $c->set_style("padding-top: 5px;");
441    
442     if ($current_step != 1) {
443     $link = html_a("javascript:wizard_submit2('".WIZARD_PREV."',".($current_step-1).");",
444     html_img("/phphtmllib/images/wizard/previous_step.png"));
445     $c->add( $link );
446     }
447    
448     if ($current_step != $this->_vars["num_steps"]) {
449     $link = html_a("javascript:wizard_submit2('".WIZARD_NEXT."',".($current_step+1).");",
450     html_img("/phphtmllib/images/wizard/next_step.png") );
451     $c->add( $link );
452     } else {
453     $link = html_a("javascript:wizard_submit2('".WIZARD_FINAL."',".($current_step).");",
454     html_img("/phphtmllib/images/wizard/finish_steps.png") );
455    
456     $c->add( _HTML_SPACE, _HTML_SPACE, $link);
457     }
458    
459    
460     $tr = html_tr("", $c );
461     $tr->set_style("text-align: center;");
462     $table->add_row( $tr );
463    
464     return $table;
465     }
466    
467    
468     /**
469     * This function builds an image for a step #
470     *
471     * @param string - the step # to build
472     * @return Atag object
473     */
474     function &_build_step_image( $step_num, $step_title ) {
475     $title = "Step ".$step_num." ";
476    
477     $current_step = $this->_current_step();
478     if ($this->_vars["on_confirm"]) {
479     $current_step++;
480     }
481    
482     if ($step_num == $current_step) {
483     $title .= " (Current) : ".$step_title;
484     $img = html_img("/phphtmllib/images/wizard/".$step_num."_red.png", 30, 30, 0,
485     $title, NULL, $title);
486    
487     } else if ($this->_is_step_visited($step_num)) {
488     $title .= " (Completed) : ".$step_title;
489     $img = html_img("/phphtmllib/images/wizard/".$step_num."_black.png", 30, 30 ,0,
490     $title, NULL, $title);
491    
492     } else {
493     $title .= " (Not Completed) : ".$step_title;
494     $img = html_img("/phphtmllib/images/wizard/".$step_num."_gray.png", 30,30,0,
495     $title, NULL, $title);
496     }
497    
498     return $img;
499     }
500    
501    
502    
503     /*****************************************/
504     /* SESSION RELATED METHODS */
505     /*****************************************/
506    
507     /**
508     * This method initializes the session
509     * variable that we use
510     *
511     */
512     function _init_session() {
513     //create a unique id for this wizard
514     //so we can have multple wizards
515     //running per session.
516     $_SESSION[$this->_vars[WIZARD_ID]] = array();
517     $_SESSION[$this->_vars[WIZARD_ID]];
518     $this->_set_current_step(1);
519    
520     //mark all steps as NOT visited
521     for ($i=0; $i<=$this->_vars["num_steps"]-1; $i++) {
522     $this->_step_visited($i, FALSE);
523     }
524     }
525    
526     /**
527     * This returns the current step id
528     * from the session
529     *
530     */
531     function _current_step() {
532     return $_SESSION[$this->_vars[WIZARD_ID]]["current_step"];
533     }
534    
535     /**
536     * This sets the current step id
537     *
538     * @param int - the new step #
539     */
540     function _set_current_step($step) {
541     ddd( "SET STEP ".$step);
542     $_SESSION[$this->_vars[WIZARD_ID]]["current_step"] = $step;
543     }
544    
545    
546     /**
547     * This sets the state variable for the
548     * step to let us know it has been visited or not
549     *
550     * @param int - the step to mark
551     * @param boolean - TRUE = visited
552     */
553     function _step_visited($step_num, $visited=TRUE) {
554     $_SESSION[$this->_vars[WIZARD_ID]]["visited_steps"][$step_num] = $visited;
555     }
556    
557     /**
558     * This tests to see if the step has been visited or not.
559     *
560     * @param int - the step to mark
561     * @return boolean - TRUE = visited
562     */
563     function _is_step_visited($step_num) {
564     if (isset($_SESSION[$this->_vars[WIZARD_ID]]["visited_steps"][$step_num])) {
565     return $_SESSION[$this->_vars[WIZARD_ID]]["visited_steps"][$step_num];
566     } else {
567     return FALSE;
568     }
569     }
570    
571     /**
572     * This function cleans up the saved Session state
573     * for the wizard. This gets called when we have
574     * completed the wizard w/o errors.
575     *
576     */
577     function _clean() {
578     unset($_SESSION[$this->_vars[WIZARD_ID]]);
579     }
580    
581     /**
582     * This ensures that we have sessions started
583     *
584     */
585     function _session_test() {
586     if (!session_id()) {
587     //we have to have sessions started.
588     session_start();
589     }
590     }
591     }
592     ?>

MailToCvsAdmin">MailToCvsAdmin
ViewVC Help
Powered by ViewVC 1.1.26 RSS 2.0 feed