root/tags/RELEASE_0_9_0B1/patForms.php

Revision 318, 72.8 kB (checked in by schst, 3 years ago)

Added validateForm() and finalizeForm() to the Collection

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 <?php
2 /**
3  * patForms form manager class - serialize form elements into any given output format
4  * using element classes, and build the output via renderer classes.
5  *
6  * $Id$
7  *
8  * @package        patForms
9  * @author        Sebastian Mordziol <argh@php-tools.net>
10  * @author        gERD Schaufelberger <gerd@php-tools.net>
11  * @author        Stephan Schmidt <schst@php-tools.net>
12  * @copyright    2003-2004 PHP Application Tools
13  * @license        LGPL
14  * @link        http://www.php-tools.net
15  */
16
17 /**
18  * set the include path
19  */
20 if( !defined( 'PATFORMS_INCLUDE_PATH' ) ) {
21     define( 'PATFORMS_INCLUDE_PATH', dirname( __FILE__ ). '/patForms' );
22 }
23
24 /**
25  * location of global javascripts
26  */
27 define('PATFORMS_SCRIPT_PATH', PATFORMS_INCLUDE_PATH . '/Scripts');
28
29 /**
30  * needs helper methods of patForms_Element
31  */
32 include_once PATFORMS_INCLUDE_PATH . "/Element.php";
33
34 /**
35  * error definition: renderer base class file (renderers/_base.php) could not
36  * be found.
37  *
38  * @see    patForms::_createModule()
39  */
40 define( "PATFORMS_ERROR_NO_MODULE_BASE_FILE", 1001 );
41
42 /**
43  * error definition: the specified renderer could not be found.
44  *
45  * @see    patForms::_createModule()
46  */
47 define( "PATFORMS_ERROR_MODULE_NOT_FOUND", 1002 );
48
49 /**
50  * error definition: the element added via the {@link patForms::addElement()}
51  * is not an object. Use the {@link patForms::createElement()} method to
52  * create an element object.
53  *
54  * @see    patForms::addElement()
55  * @see    patForms::createElement()
56  */
57 define( "PATFORMS_ERROR_ELEMENT_IS_NO_OBJECT", 1003 );
58
59 /**
60  * error definition: generic unexpected error.
61  */
62 define( "PATFORMS_ERROR_UNEXPECTED_ERROR", 1004 );
63
64 /**
65  * element does not exist
66  */
67 define( "PATFORMS_ERROR_ELEMENT_NOT_FOUND", 1012 );
68
69 /**
70  * renderer object has not been set - if you want to render the form, you have to
71  * set a renderer object via the {@link patForms::setRenderer()} method. To create
72  * a renderer, use the {@link patForms::createRenderer()} method.
73  *
74  * @see    patForms::setRenderer()
75  * @see    patForms::createRenderer()
76  */
77 define( "PATFORMS_ERROR_NO_RENDERER_SET", 1013 );
78
79 /**
80  * invalid renderer
81  *
82  * @see    createRenderer()
83  */
84 define( "PATFORMS_ERROR_INVALID_RENDERER", 1014 );
85
86 /**
87  * invalid method
88  *
89  * @see    setMethod()
90  */
91 define( "PATFORMS_ERROR_INVALID_METHOD", 1015 );
92
93 /**
94  * Given parameter is not a boolean value
95  */
96 define( "PATFORMS_ERROR_PARAMETER_NO_BOOL", 1016 );
97
98 /**
99  * Given Static property does not exist
100  */
101 define( "PATFORMS_ERROR_NO_STATIC_PROPERTY", 1017 );
102
103 /**
104  * Unknown event
105  */
106 define( "PATFORMS_ERROR_UNKNOWN_EVENT", 1018 );
107
108 /**
109  * Invalid event handler
110  */
111 define( "PATFORMS_ERROR_INVALID_HANDLER", 1019 );
112
113 /**
114  * Event exists
115  */
116 define( 'PATFORMS_NOTICE_EVENT_ALREADY_REGISTERED', 1020 );
117
118 /**
119  * Invalid storage container
120  */
121 define( 'PATFORMS_ERROR_INVALID_STORAGE', 1021 );
122
123 define( 'PATFORMS_NOTICE_ARRAY_EXPECTED', 1022 );
124
125 define( 'PATFORMS_NOTICE_ATTRIBUTE_NOT_SUPPORTED', 1023 );
126
127 define( 'PATFORMS_NOTICE_INVALID_OPTION', 1024 );
128
129 define( 'PATFORMS_ERROR_ATTRIBUTE_REQUIRED', 1025 );
130
131 define( 'PATFORMS_ERROR_CAN_NOT_VERIFY_FORMAT', 1026 );
132
133 define( 'PATFORMS_ERROR_METHOD_FOR_MODE_NOT_AVAILABLE', 1027 );
134
135
136 /**
137  * errors apply on translating errors matching current locale settings
138  */
139 define( 'PATFORMS_NOTICE_VALIDATOR_ERROR_LOCALE_UNDEFINED', 1028 );
140 define( 'PATFORMS_WARNING_VALIDATOR_ERROR_UNDEFINED', 1029 );
141
142 /**
143  * Script file could not be loaded
144  */
145 define( 'PATFORMS_WARNING_SCRIPTFILE_NOT_FOUND', 1040 );
146
147 /**
148  * locale file not found
149  */
150 define('PATFORMS_WARNING_LOCALEFILE_NOT_FOUND', 1050);
151
152 /**
153  * apply the rule before the built-in validation
154  */
155 define( 'PATFORMS_RULE_BEFORE_VALIDATION', 1 );
156
157 /**
158  * apply the rule after the built-in validation
159  */
160 define( 'PATFORMS_RULE_AFTER_VALIDATION', 2 );
161
162 /**
163  * apply the rule before AND after the built-in validation
164  */
165 define( 'PATFORMS_RULE_BOTH', 3 );
166
167 /**
168  * attach the observer to the elements
169  */
170 define( 'PATFORMS_OBSERVER_ATTACH_TO_ELEMENTS', 1 );
171
172 /**
173  * attach the observer to the form
174  */
175 define( 'PATFORMS_OBSERVER_ATTACH_TO_FORM', 2 );
176
177 /**
178  * attach the observer to the form and the elements
179  */
180 define( 'PATFORMS_OBSERVER_ATTACH_TO_BOTH', 3 );
181
182 /**
183  * group values should stay nested
184  */
185 define('PATFORMS_VALUES_NESTED', 0);
186
187 /**
188  * group values should be flattened
189  */
190 define('PATFORMS_VALUES_FLATTENED', 1);
191
192 /**
193  * group values should be prefixed
194  */
195 define('PATFORMS_VALUES_PREFIXED', 2);
196
197 /**
198  * Static patForms properties - used to emulate pre-PHP5 static properties.
199  *
200  * @see    setStaticProperty()
201  * @see    getStaticProperty()
202  */
203 $GLOBALS['_patForms']    =    array(
204     'format'            =>    'html',
205     'locale'            =>    'C',
206     'customLocales'        =>    array(),
207     'autoFinalize'        =>    true,
208     'defaultAttributes'    =>    array(),
209     'elementCounter'    =>    0,
210 );
211
212 /**
213  * patForms form manager class - serialize form elements into any given output format
214  * using element classes, and build the output via renderer classes.
215  *
216  * @package        patForms
217  * @author        Sebastian Mordziol <argh@php-tools.net>
218  * @author        gERD Schaufelberger <gerd@php-tools.net>
219  * @author        Stephan Schmidt <schst@php-tools.net>
220  * @copyright    2003-2004 PHP Application Tools
221  * @license        LGPL
222  * @link        http://www.php-tools.net
223  * @version        0.9.0a2
224  */
225 class patForms
226 {
227    /**
228     * javascript that will displayed only once
229     *
230     * @access    private
231     * @var        array
232     */
233     var $globalJavascript    =    array();
234
235    /**
236     * javascript that will be displayed once per instance
237     *
238     * @access    private
239     * @var        array
240     */
241     var $instanceJavascript    =    array();
242
243    /**
244     * stores the mode for the form. It defaults to 'default', and is only overwritten if
245     * set specifically. It is passed on to any elements you create.
246     *
247     * @access    private
248     * @see        setMode()
249     */
250     var $mode    =    'default';
251
252    /**
253     * XML entities
254     *
255     * @access    private
256     * @see        toXML()
257     */
258     var $xmlEntities = array(
259         "<"    =>    "&lt;",
260         ">"    =>    "&gt;",
261         "&"    =>    "&amp;",
262         "'"    =>    "&apos;",
263         '"'    =>    "&quot;"
264     );
265
266    /**
267     * stores the format for the element. It defaults to 'html', and is only overwritten if
268     * set specifically. It is passed on to any elements you create.
269     *
270     * @access    private
271     * @see        setFormat()
272     */
273     var $format    =    'html';
274
275    /**
276     * stores the flag telling the form whether it has been submitted - this is passed on to any
277     * elements you create.
278     *
279     * @access    private
280     * @see        setSubmitted()
281     */
282     var $submitted    =    false;
283
284    /**
285     * stores the element objects of this form.
286     * @access    private
287     * @see        addElement()
288     */
289     var $elements    =    array();
290
291    /**
292     * stores a renderer
293     * @access    private
294     * @see        setRenderer(), renderForm()
295     */
296     var $renderer        =    null;
297
298    /**
299     * stores the locale to use when adding validation errors for the whole form.
300     *
301     * @access    private
302     * @var        string    $locale
303     * @see        setLocale()
304     */
305     var    $locale        =    'C';
306
307    /**
308     * stores custom locale
309     *
310     * @access    private
311     * @var        array
312     * @see        setLocale()
313     */
314     var    $customLocales = array();
315
316    /**
317     * stores the element name
318     * @access    private
319     * @see        getElementName()
320     */
321     var $elementName = 'Form';
322
323    /**
324     * flag to indicate, whether form should be validated automatically
325     * by renderForm()
326     *
327     * @access    private
328     * @var        boolean
329     * @see        setAutoValidate(), renderForm()
330     */
331     var    $autoValidate = false;
332
333    /**
334     * flag to indicate, whether autovalidation has been
335     * already called
336     *
337     * @access    private
338     * @var        boolean
339     */
340     var    $autoValidateUsed = false;
341     
342    /**
343     * name of the variable that indicates, whether the form has
344     * been submitted.
345     *
346     * @access    private
347     * @var        string
348     * @see        setAutoValidate()
349     */
350     var    $submitVar    =    null;
351
352    /**
353     * event handlers
354     *
355     * @access    private
356     * @var        array
357     * @see        registerEventHandler()
358     * @see        registerEvent()
359     */
360     var    $_eventHandler    =    array();
361
362    /**
363     * events that can be triggered
364     *
365     * @access    private
366     * @var        array
367     * @see        registerEventHandler()
368     * @see        triggerEvent()
369     * @see        registerEvent()
370     */
371     var    $_validEvents = array('onInit', 'onValidate', 'onSubmit', 'onError', 'onSuccess', 'onRender');
372
373    /**
374     * Stores whether the current form has been validated
375     *
376     * @access    private
377     */
378     var $validated    =    false;
379
380    /**
381     * Stores whether the current form is valid or not (after the
382     * validation process)
383     *
384     * @access    private
385     */
386     var $valid    =    null;
387
388    /**
389     * Stores the names of all static properties that patForms will use as defaults
390     * for the properties with the same name on startup.
391     *
392     * @access    private
393     */
394     var $staticProperties    =    array(
395         'format'        =>    'setFormat',
396         'autoFinalize'    =>    'setAutoFinalize',
397         'locale'        =>    'setLocale',
398     );
399
400    /**
401     * Stores the flag for the autoFinalize feature
402     *
403     * @access    private
404     */
405     var $autoFinalize    =    true;
406
407    /**
408     * custom validation rules
409     *
410     * @access    private
411     * @var        array
412     */
413     var $_rules            =    array();
414
415    /**
416     * define error codes an messages for the form
417     *
418     * Will be set by validation rules that have been
419     * added to the form.
420     *
421     * @access private
422     * @var    array    $validatorErrorCodes
423     */
424     var    $validatorErrorCodes  =   array();
425
426    /**
427     * stores any validation errors that can occurr during the
428     * form's validation process.
429     *
430     * @access    private
431     * @var        array    $validationErrors
432     */
433     var    $validationErrors  =   array();
434
435    /**
436     * next error offset for rules
437     * @access    private
438     * @var        integer
439     */
440     var $nextErrorOffset    =    1000;
441
442    /**
443     * Attributes of the form - needed to generate the form tag
444     *
445     * @access    private
446     * @var        array    $attributes
447     * @see        setAttribute()
448     */
449     var    $attributes    =    array();
450
451    /**
452     * Attribute definition for the form - defines which attribute the form
453     * itself supports.
454     *
455     * @access    public
456     */
457     var    $attributeDefinition    =    array(
458
459         'id' =>    array(
460             'required'        =>    false,
461             'format'        =>    'string',
462             'outputFormats'    =>    array( 'html' ),
463         ),
464
465         'name' => array(
466             'required'        =>    true,
467             'format'        =>    'string',
468             'outputFormats'    =>    array( 'html' ),
469         ),
470
471         'method' => array(
472             'required'        =>    true,
473             'format'        =>    'string',
474             'default'        =>    'post',
475             'outputFormats'    =>    array( 'html' ),
476         ),
477
478         'action' => array(
479             'required'        =>    true,
480             'format'        =>    'string',
481             'outputFormats'    =>    array( 'html' ),
482         ),
483
484         'accept' => array(
485             'required'        =>    false,
486             'format'        =>    'string',
487             'outputFormats'    =>    array( 'html' ),
488         ),
489
490         'accept-charset' => array(
491             'required'        =>    false,
492             'format'        =>    'string',
493             'outputFormats'    =>    array( 'html' ),
494         ),
495
496         'enctype' => array(
497             'required'        =>    false,
498             'format'        =>    'string',
499             'outputFormats'    =>    array( 'html' ),
500         ),
501
502         'onreset' => array(
503             'required'        =>    false,
504             'format'        =>    'string',
505             'outputFormats'    =>    array( 'html' ),
506         ),
507
508         'onsubmit' => array(
509             'required'        =>    false,
510             'format'        =>    'string',
511             'outputFormats'    =>    array( 'html' ),
512         ),
513
514         'target' => array(
515             'required'        =>    false,
516             'format'        =>    'string',
517             'outputFormats'    =>    array( 'html' ),
518         ),
519     );
520
521    /**
522     * Stores all available patForms options - these are inherited by all elements
523     * and their dependencies, like rules.
524     *
525     * Short option overview:
526     *
527     * - scripts: enable client script integration
528     *
529     * @access    public
530     */
531     var $options    =    array(
532
533         'scripts' => array(
534             'enabled' => false,
535             'params' =>    array(
536                 'folder' => PATFORMS_SCRIPT_PATH,
537                 'jsInclude' => false
538             ),
539         ),
540     );
541
542    /**
543     * the form's namespace
544     *
545     * @access    private
546     * @var        string
547     */
548     var    $namespace = '';
549
550    /**
551     * observers of the form
552     *
553     * @access    private
554     * @var        array
555     */
556     var    $observers = array();
557
558    /**
559     * Sets the default attributes that will be inherited by any elements you add to the form.
560     *
561     * <b>Note:</b> You have to call this method statically before creating a new form if you use
562     * patForm's automatic element creation feature via the {@link createForm()} method, as the
563     * default attributes cannot be set after an element has been created.
564     *
565     * @static
566     * @access    public
567     * @param    array    $attributes    The list of attributes to set with key => value pairs.
568     */
569     function setDefaultAttributes( $attributes )
570     {
571         patForms::setStaticProperty( 'defaultAttributes', $attributes );
572     }
573     
574    /**
575     * Sets the default-encoding of the form / the site the form is displayed on.
576     *
577     * This affects the encoding/decoding of html-entities in the form's element-value
578     * and attributes.
579     *
580     * @static
581     * @access   public
582     * @param    string  $encoding   the ISO code for the desired encoding (UTF-8, ISO-8859-1, ...)
583     */
584     function setDefaultEncoding( $encoding )
585     {
586         patForms::setStaticProperty( 'defaultEncoding', $encoding );
587     }
588   
589
590    /**
591     * sets the locale (language) to use for the validation error messages of all elements
592     * in the form.
593     *
594     * @access    public
595     * @param    string        language code
596     * @param    string        optional language file
597     * @return    bool        True on success
598     */
599     function setLocale( $locale, $languageFile = null )
600     {
601         if (!is_null($languageFile)) {
602             $languageData = patForms::parseLocaleFile($languageFile);
603             if (patErrorManager::isError($languageData)) {
604                 return $languageData;
605             }
606             $customLocales = patForms::getStaticProperty('customLocales');
607             $customLocales[$locale] = $languageData;
608             patForms::setStaticProperty('customLocales', $customLocales);
609         }
610
611         if (isset($this) && is_a($this, 'patForms')) {
612             $this->locale = $locale;
613
614             if (!empty($this->elements)) {
615                 $cnt = count($this->elements);
616                 for ($i=0; $i < $cnt; $i++) {
617                     $this->elements[$i]->setLocale($locale);
618                 }
619             }
620         } else {
621             patForms::setStaticProperty('locale', $locale);
622         }
623         return true;
624     }
625
626    /**
627     * checks, whether a locale is a custom locale
628     *
629     * @static
630     * @access    public
631     * @param    string        locale name
632     * @return    boolean
633     */
634     function isCustomLocale($locale)
635     {
636         $customLocales = patForms::getStaticProperty('customLocales');
637         if (isset($customLocales[$locale])) {
638             return true;
639         }
640         return false;
641     }
642
643    /**
644     * get the form's namespace
645     *
646     * @static
647     * @access    public
648     * @param    string        namespace
649     * @return    string
650     */
651     function getNamespace()
652     {
653         return $this->namespace;
654     }
655
656    /**
657     * set the form's namespace
658     *
659     * @static
660     * @access    public
661     * @param    string        namespace
662     * @return    null
663     */
664     function setNamespace($namespace)
665     {
666         $this->namespace = $namespace;
667         for($i=0; $i < count($this->elements); $i++) {
668             $this->elements[$i]->setNamespace($namespace);
669         }
670     }
671
672    /**
673     * get the custom locale for an element or a rule
674     *
675     * @static
676     * @access    public
677     * @param    string        locale
678     * @param    string        key
679     * @return    array
680     */
681     function getCustomLocale($locale, $key)
682     {
683         $customLocales = patForms::getStaticProperty('customLocales');
684         if (!isset($customLocales[$locale])) {
685             return false;
686         }
687         if (!isset($customLocales[$locale][$key])) {
688             return false;
689         }
690         return $customLocales[$locale][$key];
691     }
692
693    /**
694     * parses a locale file
695     *
696     * @access    private
697     * @param    string        filename
698     * @return    array        locale information
699     */
700     function parseLocaleFile($filename)
701     {
702         if (!file_exists($filename) ||
703             !is_file($filename) ||
704             !is_readable($filename)) {
705             return patErrorManager::raiseWarning(PATFORMS_WARNING_LOCALEFILE_NOT_FOUND, 'Could not locale-file ' . $filename . '.');
706         }
707         return parse_ini_file($filename, true);
708     }
709
710    /**
711     * sets the format of the element - this will be passed on to any elements you create. If you
712     * have already added some elements when you call this method, it will be passed on to them too.
713     *
714     * @access    public
715     * @param    string    $format    The name of the format you have implemented in your element(s).
716     * @return    bool    $result    True on success
717     * @see        setMode()
718     * @see        format
719     * @see        serialize()
720     */
721     function setFormat( $format )
722     {
723         if( isset( $this ) && is_a