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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.4 - (hide annotations)
Thu May 6 16:27:22 2004 UTC (20 years, 3 months ago) by jonen
Branch: MAIN
Changes since 1.3: +105 -26 lines
 updated all to v2.4.1 - Apr 01, 2004

1 jonen 1.1 <?php
2     /**
3     * This file contains the FormProcessor class.
4     *
5 jonen 1.4 * $Id: FormProcessor.inc,v 1.36 2004/03/25 00:44:17 hemna Exp $
6 jonen 1.1 *
7     * @author Walter A. Boring IV <waboring@buildabetterweb.com>
8     * @author Suren Markossian <suren@cbestwhat?>
9     * @package phpHtmlLib
10     * @subpackage FormProcessing
11     *
12     * @copyright LGPL - See LICENCE
13     *
14     */
15    
16 jonen 1.3 define("FORM_ACTION", "_form_action");
17     define("FORM_VISITED", "_form_visited");
18     define("FORM_CONFIRM", "_form_confirm");
19 jonen 1.1
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 jonen 1.3 * This array holds the FORMtag
36     * attributes for this form
37 jonen 1.1 *
38     */
39 jonen 1.3 var $_form_attributes = array("method" => "post",
40     "action" => "",
41     "name" => "myform",
42     "target" => "",
43     "onsubmit" => "",
44     "style" => "margin: 0px 0px 0px 0px;");
45 jonen 1.1
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 jonen 1.3 /**
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 jonen 1.1
102     /**
103     * The constructor for the FormProcessor
104     *
105     * @param FormContent object
106     * @param string the form name
107     */
108 jonen 1.3 function FormProcessor(&$form_content, $form_name="myform",
109 jonen 1.1 $form_action=NULL) {
110    
111     $this->_form_content = &$form_content;
112 jonen 1.3 $this->set_form_name( $form_name );
113 jonen 1.1 $this->_form_content->set_form_name($form_name);
114    
115     if ($form_action != NULL) {
116 jonen 1.3 $this->set_form_action( $form_action );
117 jonen 1.1 } else {
118 jonen 1.3 $this->set_form_action( $_SERVER["PHP_SELF"] );
119 jonen 1.1 }
120    
121 jonen 1.3 //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 jonen 1.1 }
129    
130     /**
131 jonen 1.3 * 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 = new FormValidation( new FormErrors );
142     }
143    
144     /**
145 jonen 1.1 * This method does the logic of
146     * doing the form processing
147     */
148     function _process_form() {
149 jonen 1.4 $this->_init_form_content();
150 jonen 1.1
151     //we only need to process the form
152     //if it has been visited. Otherwise
153     //it just gets rendered.
154 jonen 1.3 if (!empty($_REQUEST[FORM_VISITED]) && $_REQUEST[FORM_VISITED] == 1) {
155     $this->_set_action();
156 jonen 1.1
157     //let see if this was a confirmation page.
158 jonen 1.4 if ( !empty($_REQUEST[FORM_CONFIRM]) ) {
159     if ($_REQUEST[FORM_CONFIRM] == 1) {
160     //looks like this was a submit on a
161     //confirmation page. we don't need
162     //to do form field validation.
163     $this->_confirmed = TRUE;
164     } else {
165     //looks like the confirmation was aborted.
166     xxx("aborted");
167     }
168 jonen 1.1 }
169    
170     //now do the validation
171     if (!$this->_confirmed) {
172     //we haven't been confirmed, so we
173     //need to validate the form.
174     if ($this->can_validate()) {
175     //looks like we should do validation
176     $this->do_validation();
177     }
178     if (!$this->_has_errors) {
179     //no errors were found
180     if ($this->_form_content->has_confirm()) {
181     //the form content has a confirmation
182     //we need to process
183     $this->_has_errors = !$this->_pre_confirm();
184     } else {
185     //make sure we don't have any backend errors
186     $this->_has_errors = !$this->_form_content->form_backend_validation();
187     if (!$this->_has_errors) {
188     $this->_has_errors = !$this->_process_action();
189 jonen 1.3 if (!$this->_has_errors) {
190     $this->_set_confirmed_success(TRUE);
191     }
192 jonen 1.1 }
193     }
194     }
195     } else {
196     //make sure we don't have any backend errors
197     $this->_has_errors = !$this->_form_content->form_backend_validation();
198     if (!$this->_has_errors) {
199     $this->_has_errors = !$this->_process_action();
200 jonen 1.3 if (!$this->_has_errors) {
201     $this->_set_confirmed_success(TRUE);
202     }
203 jonen 1.1 }
204     }
205     }
206     }
207    
208    
209     /**
210     * This function is responsible for
211     * processing the form action
212     * after validation, and form confirmation
213     * happens.
214     *
215     */
216     function _process_action() {
217     //There were no validation errors.
218     return $this->_form_content->form_action();
219     }
220    
221     /**
222     * This method calls the FormContent
223     * to let it do any data munging before the
224     * confirmation page is rendered
225     */
226     function _pre_confirm() {
227 jonen 1.4
228     if ($this->_form_content->_has_file_element) {
229     //we need to allow any/all of the file elements
230     //save the temp files during a confirmation.
231     //if we don't, then the web server may delete
232     //them before confirmation has been accepted.
233     $this->_form_content->_pre_confirm();
234     }
235    
236     //call the user defineable FormContent pre_confirm.
237 jonen 1.1 return $this->_form_content->pre_confirm();
238     }
239    
240    
241     /**
242     * This method walks the FormContent's visible elements
243     * and calls the validation function for the element
244     *
245     */
246     function do_validation() {
247     $keys = array_keys( $this->_form_content->_elements );
248     foreach( $keys as $key ) {
249 jonen 1.3 $valid = $this->_form_content->_elements[$key]->_do_validation($this->_FormValidation);
250 jonen 1.1 if (!$valid) {
251     $this->_has_errors = TRUE;
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 jonen 1.3 if (@$_REQUEST[FORM_VISITED] == 1) {
269 jonen 1.1 //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 jonen 1.3 $success = $this->_form_content->form_success();
275 jonen 1.1
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 jonen 1.3 //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 jonen 1.1 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 jonen 1.3 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 jonen 1.1 }
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 jonen 1.3 $confirm = &$this->_form_content->form_confirm( );
363 jonen 1.1 $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 jonen 1.3
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 jonen 1.1
398 jonen 1.3 return $this->render_form( $indent_level, $output_debug, $wrapper);
399 jonen 1.1 }
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 jonen 1.3 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 jonen 1.1 }
644    
645    
646     /**
647 jonen 1.4 * 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     //************************************//
671     //* Some Private methods *//
672     //************************************//
673    
674     /**
675     * This method initializes the FormContent
676     * during processing.
677     *
678     * @return none
679     */
680     function _init_form_content() {
681     //let the form build the FormElement objects
682     //that will be used by the form
683     $this->_form_content->form_init_elements();
684    
685     //first we need to
686     if (!@$_REQUEST[FORM_VISITED]) {
687     $this->_form_content->form_init_data();
688     }
689    
690     //see if the form content has a child of the
691     //FEFile element, so we can automatically
692     //add the enctype to the form tag attribute
693     if ($this->_form_content->_has_file_element) {
694     $this->set_form_enctype("multipart/form-data");
695     }
696     }
697    
698    
699     /**
700 jonen 1.1 * this function builds the FORMtag object
701     * and its attributes.
702     *
703     * @return FORMtag object.
704     */
705     function _build_form_tag() {
706 jonen 1.4 //see if we need to add the onsubmit attribute to the form
707     //this only needs to happen on the non-confirmation
708     //portion of the forms.
709     if (!isset($_REQUEST[FORM_VISITED])) {
710     if (strlen($this->_form_content->_form_on_submit) > 0) {
711     $set = TRUE;
712     $this->set_onsubmit( $this->get_onsubmit().$this->_form_content->_form_on_submit );
713     }
714     } else {
715     //re-rendering the form and it has errors.
716     //we need the onsubmit if they have it.
717     if ($_REQUEST[FORM_VISITED] && $this->_has_errors) {
718     if (strlen($this->_form_content->_form_on_submit) > 0) {
719     $set = TRUE;
720     $this->set_onsubmit( $this->get_onsubmit().$this->_form_content->_form_on_submit );
721     }
722     }
723    
724     //form has been confirmed lets add it
725     //in case we are showing the form again
726     if (isset($_REQUEST[FORM_CONFIRM]) && $_REQUEST[FORM_CONFIRM] == 1) {
727     if (strlen($this->_form_content->_form_on_submit) > 0) {
728     $set = TRUE;
729     $this->set_onsubmit( $this->get_onsubmit().$this->_form_content->_form_on_submit );
730     }
731     }
732     }
733    
734 jonen 1.3 $form_attrs = array();
735     foreach( $this->_form_attributes as $name => $value) {
736     if ($value) {
737     $form_attrs[$name] = $value;
738     }
739     }
740 jonen 1.1 $this->_form = new FORMtag( $form_attrs );
741     }
742    
743     /**
744     * This adds all of the submitted data as
745     * hidden form fields
746     *
747     */
748     function _add_confirm_data() {
749     $keys = array_keys( $this->_form_content->_elements );
750     foreach( $keys as $key ) {
751 jonen 1.4 $this->_form->add($this->_form_content->_elements[$key]->get_confirm_element());
752 jonen 1.1 }
753    
754     $keys = array_keys( $this->_form_content->_hidden_elements );
755     foreach( $keys as $key ) {
756 jonen 1.4 $this->_form->add( $this->_form_content->_hidden_elements[$key]->get_confirm_element() );
757 jonen 1.1 }
758     }
759    
760    
761     /**
762     * This function adds the form content's
763     * hidden form fields to the
764     * form automatically
765     *
766     */
767     function _add_hidden_fields() {
768     //Lets add the form's hidden vars it wants
769     foreach ($this->_form_content->_hidden_elements as $element) {
770     $this->_form->add( $element->get_element() );
771     }
772     }
773    
774    
775     /**
776     * This method adds the processor specific
777     * hidden fields.
778     *
779     */
780     function __hidden_fields() {
781     $this->_form->add( form_hidden(FORM_ACTION),
782     form_hidden(FORM_VISITED,1) );
783    
784     if ($this->_form_content->has_confirm() && !$this->_confirmed) {
785 jonen 1.3 if (@!$_REQUEST[FORM_VISITED] || $this->_has_errors) {
786 jonen 1.1 $this->_form->add( form_hidden(FORM_CONFIRM, 0 ) );
787     } else {
788     $this->_form->add( form_hidden(FORM_CONFIRM, 1 ) );
789     }
790     } else if ($this->_form_content->has_confirm() && !$this->_confirmed) {
791     //reset this so they can submit again
792     $this->_form->add( form_hidden(FORM_CONFIRM, 0 ) );
793     }
794 jonen 1.3 }
795    
796     /**
797     * This method is used to build any Javascript
798     * that is used by the form and/or the form elements
799     * used in the form.
800     *
801     * @return string
802     */
803     function _build_javascript() {
804     $form_js = $this->_form_content->javascript();
805    
806     //now walk each form element and try to get any js
807     foreach( $this->_form_content->_elements as $element ) {
808     $form_js .= $element->javascript();
809     }
810    
811     return $form_js;
812 jonen 1.1 }
813     }
814     ?>

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