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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.5 - (show annotations)
Thu Aug 11 14:09:26 2005 UTC (18 years, 11 months ago) by jonen
Branch: MAIN
CVS Tags: HEAD
Changes since 1.4: +86 -70 lines
+ updated to version 2.5.3

1 <?php
2 /**
3 * This file contains the FormProcessor class.
4 *
5 * $Id: FormProcessor.inc,v 1.47.2.3 2005/05/12 01:24:02 hemna Exp $
6 *
7 * @author Walter A. Boring IV <waboring@newsblob.com>
8 * @author Suren Markossian <suren@cbestwhat?>
9 * @package phpHtmlLib
10 * @subpackage FormProcessing
11 *
12 * @copyright LGPL - See LICENCE
13 *
14 */
15
16 define("FORM_ACTION", "_form_action");
17 define("FORM_VISITED", "_form_visited");
18 define("FORM_CONFIRM", "_form_confirm");
19
20 /**
21 * This is the main engine for the processing
22 * of Forms. It builds the form tag, and calls
23 * the appropriate FormContent methods to build
24 * the FormElement's and validation, as well as
25 * backend processing to do the action after the
26 * data has been validated.
27 *
28 * @package phpHtmlLib
29 * @subpackage FormProcessing
30 */
31 class FormProcessor extends Container {
32
33
34 /**
35 * This array holds the FORMtag
36 * attributes for this form
37 *
38 */
39 var $_form_attributes = array("method" => "post",
40 "action" => "",
41 "name" => "myform",
42 "target" => "",
43 "onsubmit" => "",
44 "style" => "margin: 0px 0px 0px 0px;");
45
46 /**
47 * This holds the FormContent Object
48 * that knows how to render the
49 * form.
50 */
51 var $_form_content = NULL;
52
53
54 /**
55 * This flag lets us know there
56 * were errors during processing or
57 * validating the form.
58 */
59 var $_has_errors = FALSE;
60
61 /**
62 * Flag to let us know the form
63 * has been confirmed.
64 */
65 var $_confirmed = FALSE;
66
67 /**
68 * Flag to let us know if we should
69 * render the form after it was
70 * successfully processed
71 */
72 var $_form_success_render = TRUE;
73
74 /**
75 * This is the FormValidation object
76 * used to validate the form elements
77 */
78 var $_FormValidation = NULL;
79
80 /**
81 * The action that was taken
82 * for the form
83 */
84 var $_form_submit_action = NULL;
85
86 /**
87 * The form was processed and passed
88 * the confirmation if any, and
89 * it was successfull ?
90 */
91 var $_confirmed_successfull = FALSE;
92
93 /**
94 * This tells us to show or not to
95 * show the form errors autmatically.
96 * The user of the FormProcessor
97 * may want to deal with errors manually
98 */
99 var $_auto_show_errors = TRUE;
100
101
102 /**
103 * The constructor for the FormProcessor
104 *
105 * @param FormContent object
106 * @param string the form name
107 */
108 function FormProcessor(&$form_content, $form_name="myform",
109 $form_action=NULL) {
110
111 $this->_form_content = &$form_content;
112 $this->set_form_name( $form_name );
113 $this->_form_content->set_form_name($form_name);
114
115 if ($form_action != NULL) {
116 $this->set_form_action( $form_action );
117 } else {
118 $this->set_form_action( $_SERVER["PHP_SELF"] );
119 }
120
121 //Set up the Validation object
122 //and the FormErrors object to
123 //be used by this form.
124 $this->setup_validation();
125
126 //now process the form
127 $this->_process_form();
128 }
129
130 /**
131 * This function is used to setup
132 * the validation object and the
133 * form errors object that is to be
134 * used by this form.
135 *
136 * You can override this method to
137 * use a different FormErrors object
138 * for localization.
139 */
140 function setup_validation() {
141 $this->_FormValidation =& FormValidation::singleton();
142 $this->_form_content->_set_validation_object($this->_FormValidation);
143 }
144
145 /**
146 * This method does the logic of
147 * doing the form processing
148 */
149 function _process_form() {
150 $this->_init_form_content();
151
152 //we only need to process the form
153 //if it has been visited. Otherwise
154 //it just gets rendered.
155 if (!empty($_REQUEST[$this->_form_attributes['name'].FORM_VISITED]) &&
156 $_REQUEST[$this->_form_attributes['name'].FORM_VISITED] == 1) {
157 $this->_set_action();
158
159 //let see if this was a confirmation page.
160 if ( !empty($_REQUEST[FORM_CONFIRM]) ) {
161 if ($_REQUEST[FORM_CONFIRM] == 1) {
162 //looks like this was a submit on a
163 //confirmation page. we don't need
164 //to do form field validation.
165 $this->_confirmed = TRUE;
166 } else {
167 //looks like the confirmation was aborted.
168 xxx("aborted");
169 }
170 }
171
172 if ($this->_form_content->has_confirm()) {
173 //the form content has a confirmation
174 //we need to process
175 $this->_has_errors = !$this->_pre_confirm();
176 }
177
178 //we haven't been confirmed, so we
179 //need to validate the form.
180 if ($this->can_validate()) {
181 //looks like we should do validation
182 $this->do_validation();
183 }
184 if (!$this->_has_errors) {
185 //no errors were found
186 //make sure we don't have any backend errors
187 $this->_has_errors = !$this->_form_content->form_backend_validation();
188 if (!$this->_has_errors && (($this->_form_content->has_confirm()
189 && $this->_confirmed) || !$this->_form_content->has_confirm())) {
190 // process action only at the final stage
191 $this->_has_errors = !$this->_process_action();
192
193 if (!$this->_has_errors) {
194 $this->_set_confirmed_success(TRUE);
195 }
196 }
197 }
198 }
199 }
200
201
202 /**
203 * This function is responsible for
204 * processing the form action
205 * after validation, and form confirmation
206 * happens.
207 *
208 */
209 function _process_action() {
210 //There were no validation errors.
211 return $this->_form_content->form_action();
212 }
213
214 /**
215 * This method calls the FormContent
216 * to let it do any data munging before the
217 * confirmation page is rendered
218 */
219 function _pre_confirm() {
220
221 if ($this->_form_content->_has_file_element) {
222 //we need to allow any/all of the file elements
223 //save the temp files during a confirmation.
224 //if we don't, then the web server may delete
225 //them before confirmation has been accepted.
226 $this->_form_content->_pre_confirm();
227 }
228
229 //call the user defineable FormContent pre_confirm.
230 return $this->_form_content->pre_confirm();
231 }
232
233
234 /**
235 * This method walks the FormContent's visible elements
236 * and calls the validation function for the element
237 *
238 */
239 function do_validation() {
240 $keys = array_keys( $this->_form_content->_elements );
241 foreach( $keys as $key ) {
242 if (!$this->_form_content->_elements[$key]->is_disabled()) {
243 $valid = $this->_form_content->_elements[$key]->_do_validation($this->_FormValidation);
244 if (!$valid) {
245 $this->_has_errors = TRUE;
246 }
247 } else {
248 //detect disabled field hack attempts
249 if ($this->_form_content->_elements[$key]->has_error()) {
250 $this->_has_errors = TRUE;
251 }
252 }
253 }
254 }
255
256
257 /**
258 * This method is called to render the form's html
259 *
260 */
261 function render($indent_level=0, $output_debug=0) {
262 if ($this->_has_errors) {
263 //we need to render the form errors
264 //and then the form
265 return $this->render_error($indent_level, $output_debug);
266 } else {
267 //there are no errors!
268 if (@$_REQUEST[$this->_form_attributes['name'] . FORM_VISITED] == 1) {
269 //looks like the form has been processed?
270 if ($this->_form_content->has_confirm() && !$this->_confirmed) {
271 return $this->render_confirm($indent_level, $output_debug);
272 } else {
273 //Looks like the action worked
274 $success = $this->_form_content->form_success();
275
276 if ($this->_form_success_render) {
277 return $this->render_form($indent_level, $output_debug,
278 $success);
279 } else {
280 if (method_exists($success,"render")) {
281 //looks like this is an object.
282 //we'll assume it has a render function.
283 return $success->render($indent_level, $output_debug);
284 } else {
285 //since its not an object,
286 //lets just display it.
287 return $success;
288 }
289 }
290 }
291 } else {
292 return $this->render_form($indent_level, $output_debug);
293 }
294 }
295 }
296
297
298 /**
299 * This renders the form
300 *
301 * @param the FormContent->form() object
302 * @param int - $indent_level
303 * @param int - $output_debug
304 * @param object - the form errors object.
305 * @return raw html
306 */
307 function render_form( $indent_level, $output_debug, $obj=NULL ) {
308
309 //build the $this->_form object.
310 $this->_build_form_tag();
311
312 //check to see if the form_content
313 //has any js, or any of the form elements
314 //have js.
315 $form_js = $this->_build_javascript();
316 if (strlen($form_js) > 0) {
317 $script = html_script();
318 $script->add( $form_js );
319 //$this->_form->add( $script );
320 }
321
322 if ($obj) {
323 $this->_form->add_reference( $obj );
324 }
325
326 $this->_form->add_reference( $this->_form_content->form() );
327
328 //add the FormContent's hidden declared
329 //hidden form fields.
330 $this->_add_hidden_fields();
331
332 //Ok lets add our hidden vars
333 $this->__hidden_fields();
334
335 if (isset($script)) {
336 $c = container( $script, $this->_form );
337 return $c->render($indent_level, $output_debug);
338 } else {
339 return $this->_form->render($indent_level, $output_debug);
340 }
341
342 }
343
344 /**
345 * This function renders the confirmation
346 * page. This page sits in between the
347 * front end form, and the action handler.
348 * This only gets called after a form
349 * and its data has been successfully
350 * validated.
351 *
352 * @param int - $indent_level
353 * @param int - $output_debug
354 *
355 * @return string - the raw html
356 */
357 function render_confirm( $indent_level, $output_debug ) {
358 //build the $this->_form object.
359 $this->_build_form_tag();
360
361 //add the confirm object/html
362 $confirm = &$this->_form_content->form_confirm( );
363 $this->_form->add_reference( $confirm );
364
365 //ok add all of the submitted data as hidden form fields
366 $this->_add_confirm_data();
367
368 //Ok lets add our hidden vars
369 $this->__hidden_fields();
370
371 return $this->_form->render($indent_level, $output_debug);
372 }
373
374
375 /**
376 * This renders the error table
377 * and then the form with the fields
378 *
379 * @param array - the form field vlues.
380 * @param array - array of errors.
381 * @param int - $indent_level
382 * @param int - $output_debug
383 *
384 * @return raw html
385 */
386 function render_error( $indent_level, $output_debug) {
387
388 if ($this->_auto_show_errors) {
389 //Ok first lets build the error table
390 $wrapper = new DIVtag;
391 $errors = &$this->_form_content->form_errors();
392 if ($errors != NULL) $wrapper->add( $errors, html_br() );
393 } else {
394 $wrapper = NULL;
395 }
396
397
398 return $this->render_form( $indent_level, $output_debug, $wrapper);
399 }
400
401
402
403
404 //***********************************************//
405 //* utility functions for this class *//
406 //***********************************************//
407
408
409 /**
410 * This method lets us turn on/off the
411 * ability to do validation for the form
412 *
413 * @return BOOLEAN
414 */
415 function can_validate() {
416 return TRUE;
417 }
418
419
420 /**
421 * This function turns on the ability to
422 * render the form after the success
423 * of the action. Normally this feature
424 * is off
425 *
426 */
427 function set_render_form_after_success($flag=TRUE) {
428 $this->_form_success_render = $flag;
429 }
430
431 /**
432 * This is used to test to see if the form action
433 * was processed succesfully.
434 * This is usefull for external entities to determine
435 * if the form was processed, and it was successfull.
436 *
437 * @return boolean
438 */
439 function is_action_successfull() {
440 return $this->_confirmed_successfull;
441 }
442
443 /**
444 * This flag sets the flag that tells
445 * if we successfully confirmed the form,
446 * and processed the action
447 *
448 * @param boolean
449 */
450 function _set_confirmed_success($flag=TRUE) {
451 $this->_confirmed_successfull = $flag;
452 }
453
454 /**
455 * This sets the flag that tells this class
456 * to automatically call the form contents
457 * form errors and display it or not
458 *
459 * @param boolean - show errors?
460 */
461 function set_auto_error_display($flag=TRUE) {
462 $this->_auto_show_errors = $flag;
463 }
464
465 /**
466 * This gets the current value of the flag
467 * that tells us to show form errors automatically
468 * or not.
469 *
470 * @return boolean
471 */
472 function get_auto_error_display() {
473 return $this->_auto_show_errors;
474 }
475
476
477 /**
478 * This method allows us to get access to the
479 * errors display object that is generated by
480 * the form content. This is the display
481 * object that is meant to be rendered directly.
482 * If there are no errors. we will return NULL
483 *
484 * @return object
485 */
486 function &get_error_display_object() {
487 if ($this->_has_errors) {
488 return $this->_form_content->form_errors();
489 } else {
490 return NULL;
491 }
492 }
493
494
495 /**
496 * This method returns an array of errors that
497 * happened in the form.
498 *
499 * @return array
500 */
501 function get_error_array() {
502 return $this->_form_content->get_error_array();
503 }
504
505 /**
506 * This returns the flag that tells us that
507 * the form has errors during processing
508 *
509 * @return boolean
510 */
511 function has_errors() {
512 return $this->_has_errors;
513 }
514
515
516
517
518 //************************************************//
519 //* FORMtag Attributes for this class *//
520 //************************************************//
521
522 /**
523 * This function is used to set the
524 * form name
525 *
526 * @param string
527 */
528 function set_form_name($name) {
529 $this->_form_attributes["name"] = $name;
530 }
531
532 /**
533 * This function is used to get
534 * the form name
535 *
536 * @return string
537 */
538 function get_form_name() {
539 return $this->_form_attributes["name"];
540 }
541
542 /**
543 * This function is used to set the
544 * form target
545 *
546 * @param string
547 */
548 function set_form_target($target) {
549 $this->_form_attributes["target"] = $target;
550 }
551
552 /**
553 * This function is used to get
554 * the form target
555 *
556 * @return string
557 */
558 function get_form_target() {
559 return $this->_form_attributes["target"];
560 }
561
562 /**
563 * This function is used to set the
564 * form method
565 *
566 * @param string (POST or GET)
567 */
568 function set_form_method($method) {
569 if ( strcasecmp($method,"GET") !=0 && strcasecmp($method,"POST") !=0 ) {
570 user_error("FormProcessor::set_form_method() - INVALID Form method ".$method);
571 } else {
572 $this->_form_attributes["method"] = $method;
573 }
574 }
575
576 /**
577 * This function is used to get
578 * the form method
579 *
580 * @return string (POST or GET)
581 */
582 function get_form_method() {
583 return $this->_form_attributes["method"];
584 }
585
586 /**
587 * Sets the form action
588 *
589 * @param string
590 */
591 function set_form_action($action) {
592 $this->_form_attributes["action"] = $action;
593 }
594
595 /**
596 * This function is used to get
597 * the form action
598 *
599 * @return string (POST or GET)
600 */
601 function get_form_action() {
602 return $this->_form_attributes["action"];
603 }
604
605 /**
606 * Sets the form enctype
607 *
608 * @param string
609 */
610 function set_form_enctype($enctype) {
611 $this->_form_attributes["enctype"] = $enctype;
612 }
613
614 /**
615 * This function is used to get
616 * the form enctype value
617 *
618 * @return string
619 */
620 function get_form_enctype() {
621 return $this->_form_attributes["enctype"];
622 }
623
624
625 /**
626 * This is used to set the action
627 * submitted by the user
628 *
629 */
630 function _set_action() {
631 $this->_form_submit_action = $_REQUEST[FORM_ACTION];
632 $this->_form_content->set_action($this->_form_submit_action);
633 }
634
635 /**
636 * This is used to get the action that was
637 * processed by the form
638 *
639 * @return string
640 */
641 function get_action() {
642 return $this->_form_submit_action;
643 }
644
645
646 /**
647 * Set the onsubmit attribute to the form
648 * NOTE: The FormContent child can automatically
649 * set this value depending on the FormElement
650 * children it contains.
651 *
652 * @param string
653 * @return none
654 */
655 function set_onsubmit($js) {
656 $this->_form_attributes["onsubmit"] = $js;
657 }
658
659 /**
660 * Gets the current value of the form tag's
661 * onsubmit value
662 *
663 * @return string
664 */
665 function get_onsubmit() {
666 return $this->_form_attributes["onsubmit"];
667 }
668
669 /**
670 * Set a random attribute on the form tag.
671 * You should know what you are doing as this
672 * might invalidate the output html with the
673 * W3C validator.
674 *
675 * @param string the key
676 * @param string the value
677 */
678 function set_form_attribute($key, $value) {
679 $this->_form_attributes[$key] = $value;
680 }
681
682
683 //************************************//
684 //* Some Private methods *//
685 //************************************//
686
687 /**
688 * This method initializes the FormContent
689 * during processing.
690 *
691 * @return none
692 */
693 function _init_form_content() {
694 //let the form build the FormElement objects
695 //that will be used by the form
696 $this->_form_content->form_init_elements();
697
698 //first we need to
699 if (!@$_REQUEST[$this->_form_attributes['name'] . FORM_VISITED]) {
700 $this->_form_content->form_init_data();
701 }
702
703 //see if the form content has a child of the
704 //FEFile element, so we can automatically
705 //add the enctype to the form tag attribute
706 if ($this->_form_content->_has_file_element) {
707 $this->set_form_enctype("multipart/form-data");
708 }
709 }
710
711
712 /**
713 * this function builds the FORMtag object
714 * and its attributes.
715 *
716 * @return FORMtag object.
717 */
718 function _build_form_tag() {
719 //see if we need to add the onsubmit attribute to the form
720 //this only needs to happen on the non-confirmation
721 //portion of the forms.
722 if (!isset($_REQUEST[$this->_form_attributes['name'] . FORM_VISITED])) {
723 if (strlen($this->_form_content->_form_on_submit) > 0) {
724 $set = TRUE;
725 $this->set_onsubmit( $this->get_onsubmit().$this->_form_content->_form_on_submit.$this->_form_content->_form_action_elements_on_submit );
726 }
727 } else {
728 //re-rendering the form and it has errors.
729 //we need the onsubmit if they have it.
730 if (isset($_REQUEST[$this->_form_attributes['name'] . FORM_VISITED]) && $this->_has_errors) {
731 if (strlen($this->_form_content->_form_on_submit) > 0) {
732 $set = TRUE;
733 $this->set_onsubmit($this->get_onsubmit().$this->_form_content->_form_on_submit.$this->_form_content->_form_action_elements_on_submit );
734 }
735 } else if (isset($_REQUEST[FORM_CONFIRM]) && $_REQUEST[FORM_CONFIRM] == 1) {
736 //form has been confirmed lets add it
737 //in case we are showing the form again
738 if (strlen($this->_form_content->_form_on_submit) > 0) {
739 $set = TRUE;
740 $this->set_onsubmit( $this->get_onsubmit().$this->_form_content->_form_on_submit.$this->_form_content->_form_action_elements_on_submit );
741 }
742 } else {
743 $this->set_onsubmit($this->_form_content->_form_action_elements_on_submit);
744 }
745 }
746
747 $form_attrs = array();
748 foreach( $this->_form_attributes as $name => $value) {
749 if ($value) {
750 $form_attrs[$name] = $value;
751 }
752 }
753 $this->_form = new FORMtag( $form_attrs );
754 }
755
756 /**
757 * This adds all of the submitted data as
758 * hidden form fields
759 *
760 */
761 function _add_confirm_data() {
762 $keys = array_keys( $this->_form_content->_elements );
763 foreach( $keys as $key ) {
764 //make sure the element isn't disabled.
765 if (!$this->_form_content->_elements[$key]->is_disabled()) {
766 $this->_form->add($this->_form_content->_elements[$key]->get_confirm_element());
767 }
768 }
769
770 $keys = array_keys( $this->_form_content->_hidden_elements );
771 foreach( $keys as $key ) {
772 $this->_form->add( $this->_form_content->_hidden_elements[$key]->get_confirm_element() );
773 }
774 }
775
776
777 /**
778 * This function adds the form content's
779 * hidden form fields to the
780 * form automatically
781 *
782 */
783 function _add_hidden_fields() {
784 //Lets add the form's hidden vars it wants
785 foreach ($this->_form_content->_hidden_elements as $element) {
786 $this->_form->add( $element->get_element() );
787 }
788 }
789
790
791 /**
792 * This method adds the processor specific
793 * hidden fields.
794 *
795 */
796 function __hidden_fields() {
797 $this->_form->add( form_hidden(FORM_ACTION),
798 form_hidden($this->_form_attributes['name'] . FORM_VISITED,1) );
799
800 if ($this->_form_content->has_confirm() && !$this->_confirmed) {
801 if (@!$_REQUEST[$this->_form_attributes['name'] . FORM_VISITED] || $this->_has_errors) {
802 $this->_form->add( form_hidden(FORM_CONFIRM, 0 ) );
803 } else {
804 $this->_form->add( form_hidden(FORM_CONFIRM, 1 ) );
805 }
806 } else if ($this->_form_content->has_confirm() && !$this->_confirmed) {
807 //reset this so they can submit again
808 $this->_form->add( form_hidden(FORM_CONFIRM, 0 ) );
809 }
810 }
811
812 /**
813 * This method is used to build any Javascript
814 * that is used by the form and/or the form elements
815 * used in the form.
816 *
817 * @return string
818 */
819 function _build_javascript() {
820 $form_js = $this->_form_content->javascript();
821
822 //now walk each form element and try to get any js
823 foreach( $this->_form_content->_elements as $element ) {
824 $form_js .= $element->javascript();
825 }
826
827 return $form_js;
828 }
829 }
830 ?>

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