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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (show 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 <?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