root/tags/RELEASE_0_9_0B3/patForms.php

Revision 374, 76.0 kB (checked in by schst, 2 years ago)

Removed decorateElement() (should not have been committed)

  • 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         'class' =>    array(
460             'required'        =>    false,
461             'format'        =>    'string',
462             'outputFormats'    =>    array( 'html' ),
463         ),
464
465         'id' =>    array(
466             'required'        =>    false,
467             'format'        =>    'string',
468             'outputFormats'    =>    array( 'html' ),
469         ),
470
471         'name' => array(
472             'required'        =>    true,
473             'format'        =>    'string',
474             'outputFormats'    =>    array( 'html' ),
475         ),
476
477         'method' => array(
478             'required'        =>    true,
479             'format'        =>    'string',
480             'default'        =>    'post',
481             'outputFormats'    =>    array( 'html' ),
482         ),
483
484         'action' => array(
485             'required'        =>    true,
486             'format'        =>    'string',
487             'outputFormats'    =>    array( 'html' ),
488         ),
489
490         'accept' => array(
491             'required'        =>    false,
492             'format'        =>    'string',
493             'outputFormats'    =>    array( 'html' ),
494         ),
495
496         'accept-charset' => array(
497             'required'        =>    false,
498             'format'        =>    'string',
499             'outputFormats'    =>    array( 'html' ),
500         ),
501
502         'enctype' => array(
503             'required'        =>    false,
504             'format'        =>    'string',
505             'outputFormats'    =>    array( 'html' ),
506         ),
507
508         'onreset' => array(
509             'required'        =>    false,
510             'format'        =>    'string',
511             'outputFormats'    =>    array( 'html' ),
512         ),
513
514         'onsubmit' => array(
515             'required'        =>    false,
516             'format'        =>    'string',
517             'outputFormats'    =>    array( 'html' ),
518         ),
519
520         'target' => array(
521             'required'        =>    false,
522             'format'        =>    'string',
523             'outputFormats'    =>    array( 'html' ),
524         ),
525     );
526
527    /**
528     * Stores all available patForms options - these are inherited by all elements
529     * and their dependencies, like rules.
530     *
531     * Short option overview:
532     *
533     * - scripts: enable client script integration
534     *
535     * @access    public
536     */
537     var $options    =    array(
538
539         'scripts' => array(
540             'enabled' => false,
541             'params' =>    array(
542                 'folder' => PATFORMS_SCRIPT_PATH,
543                 'jsInclude' => false
544             ),
545         ),
546     );
547
548    /**
549     * the form's namespace
550     *
551     * @access    private
552     * @var        string
553     */
554     var    $namespace = '';
555
556    /**
557     * observers of the form
558     *
559     * @access    private
560     * @var        array
561     */
562     var    $observers = array();
563
564    /**
565     * Sets the default attributes that will be inherited by any elements you add to the form.
566     *
567     * <b>Note:</b> You have to call this method statically before creating a new form if you use
568     * patForm's automatic element creation feature via the {@link createForm()} method, as the
569     * default attributes cannot be set after an element has been created.
570     *
571     * @static
572     * @access    public
573     * @param    array    $attributes    The list of attributes to set with key => value pairs.
574     */
575     function setDefaultAttributes( $attributes )
576     {
577         patForms::setStaticProperty( 'defaultAttributes', $attributes );
578     }
579
580    /**
581     * Sets the default-encoding of the form / the site the form is displayed on.
582     *
583     * This affects the encoding/decoding of html-entities in the form's element-value
584     * and attributes.
585     *
586     * @static
587     * @access   public
588     * @param    string  $encoding   the ISO code for the desired encoding (UTF-8, ISO-8859-1, ...)
589     */
590     function setDefaultEncoding( $encoding )
591     {
592         patForms::setStaticProperty( 'defaultEncoding', $encoding );
593     }
594
595
596    /**
597     * sets the locale (language) to use for the validation error messages of all elements
598     * in the form.
599     *
600     * @access    public
601     * @param    string        language code
602     * @param    string        optional language file
603     * @return    bool        True on success
604     */
605     function setLocale( $locale, $languageFile = null )
606     {
607         if (!is_null($languageFile)) {
608             $languageData = patForms::parseLocaleFile($languageFile);
609             if (patErrorManager::isError($languageData)) {
610                 return $languageData;
611             }
612             $customLocales = patForms::getStaticProperty('customLocales');
613             $customLocales[$locale] = $languageData;
614             patForms::setStaticProperty('customLocales', $customLocales);
615         }
616
617         if (isset($this) && is_a($this, 'patForms')) {
618             $this->locale = $locale;
619
620             if (!empty($this->elements)) {
621                 $cnt = count($this->elements);
622                 for ($i=0; $i < $cnt; $i++) {
623                     $this->elements[$i]->setLocale($locale);
624                 }
625             }
626         } else {
627             patForms::setStaticProperty('locale', $locale);
628         }
629         return true;
630     }
631
632    /**
633     * checks, whether a locale is a custom locale
634     *
635     * @static
636     * @access    public
637     * @param    string        locale name
638     * @return    boolean
639     */
640     function isCustomLocale($locale)
641     {
642         $customLocales = patForms::getStaticProperty('customLocales');
643         if (isset($customLocales[$locale])) {
644             return true;
645         }
646         return false;
647     }
648
649    /**
650     * get the form's namespace
651     *
652     * @static
653     * @access    public
654     * @param    string        namespace
655     * @return    string
656     */
657     function getNamespace()
658     {
659         return $this->namespace;
660     }
661
662    /**
663     * set the form's namespace
664     *
665     * @static
666     * @access    public
667     * @param    string        namespace
668     * @return    null
669     */
670     function setNamespace($namespace)
671     {
672         $this->namespace = $namespace;
673         for($i=0; $i < count($this->elements); $i++) {
674             $this->elements[$i]->setNamespace($namespace);
675         }
676     }
677
678    /**
679     * get the custom locale for an element or a rule
680     *
681     * @static
682     * @access    public
683     * @param    string        locale
684     * @param    string        key
685     * @return    array
686     */
687     function getCustomLocale($locale, $key)
688     {
689         $customLocales = patForms::getStaticProperty('customLocales');
690         if (!isset($customLocales[$locale])) {
691             return false;
692         }
693         if (!isset($customLocales[$locale][$key])) {
694             return false;
695         }
696         return $customLocales[$locale][$key];
697     }
698
699    /**
700     * parses a locale file
701     *
702     * @access    private
703     * @param    string        filename
704     * @return    array        locale information
705     */
706     function parseLocaleFile($filename)
707     {
708         if (!file_exists($filename) ||
709             !is_file($filename) ||
710             !is_readable($filename)) {
711             return patErrorManager::raiseWarning(PATFORMS_WARNING_LOCALEFILE_NOT_FOUND, 'Could not locale-file ' . $filename . '.');
712         }
713         return parse_ini_file($filename, true);
714     }
715
716    /**
717     * sets the format of the element - this will be passed on to any elements you create. If you
718     * have already added some elements when you call this method, it will be passed on to them too.
719     *
720     * @access    public
721     * @param    string    $format    The name of the format you have implemented in your element(s).