root/trunk/patForms.php

Revision 392, 79.0 kB (checked in by argh, 1 year ago)

Fixed a bug when using an autoload() function in combination with external modules.

  • 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     'moduleDirs'        =>  array( '__all' => array() )
211 );
212
213 /**
214  * patForms form manager class - serialize form elements into any given output format
215  * using element classes, and build the output via renderer classes.
216  *
217  * @package        patForms
218  * @author        Sebastian Mordziol <argh@php-tools.net>
219  * @author        gERD Schaufelberger <gerd@php-tools.net>
220  * @author        Stephan Schmidt <schst@php-tools.net>
221  * @copyright    2003-2004 PHP Application Tools
222  * @license        LGPL
223  * @link        http://www.php-tools.net
224  * @version        0.9.0a2
225  */
226 class patForms
227 {
228    /**
229     * javascript that will displayed only once
230     *
231     * @access    private
232     * @var        array
233     */
234     var $globalJavascript    =    array();
235
236    /**
237     * javascript that will be displayed once per instance
238     *
239     * @access    private
240     * @var        array
241     */
242     var $instanceJavascript    =    array();
243
244    /**
245     * stores the mode for the form. It defaults to 'default', and is only overwritten if
246     * set specifically. It is passed on to any elements you create.
247     *
248     * @access    private
249     * @see        setMode()
250     */
251     var $mode    =    'default';
252
253    /**
254     * XML entities
255     *
256     * @access    private
257     * @see        toXML()
258     */
259     var $xmlEntities = array(
260         "<"    =>    "&lt;",
261         ">"    =>    "&gt;",
262         "&"    =>    "&amp;",
263         "'"    =>    "&apos;",
264         '"'    =>    "&quot;"
265     );
266
267    /**
268     * stores the format for the element. It defaults to 'html', and is only overwritten if
269     * set specifically. It is passed on to any elements you create.
270     *
271     * @access    private
272     * @see        setFormat()
273     */
274     var $format    =    'html';
275
276    /**
277     * stores the flag telling the form whether it has been submitted - this is passed on to any
278     * elements you create.
279     *
280     * @access    private
281     * @see        setSubmitted()
282     */
283     var $submitted    =    false;
284
285    /**
286     * stores the element objects of this form.
287     * @access    private
288     * @see        addElement()
289     */
290     var $elements    =    array();
291
292    /**
293     * stores a renderer
294     * @access    private
295     * @see        setRenderer(), renderForm()
296     */
297     var $renderer        =    null;
298
299    /**
300     * stores the locale to use when adding validation errors for the whole form.
301     *
302     * @access    private
303     * @var        string    $locale
304     * @see        setLocale()
305     */
306     var    $locale        =    'C';
307
308    /**
309     * stores custom locale
310     *
311     * @access    private
312     * @var        array
313     * @see        setLocale()
314     */
315     var    $customLocales = array();
316
317    /**
318     * stores the element name
319     * @access    private
320     * @see        getElementName()
321     */
322     var $elementName = 'Form';
323
324    /**
325     * flag to indicate, whether form should be validated automatically
326     * by renderForm()
327     *
328     * @access    private
329     * @var        boolean
330     * @see        setAutoValidate(), renderForm()
331     */
332     var    $autoValidate = false;
333
334    /**
335     * flag to indicate, whether autovalidation has been
336     * already called
337     *
338     * @access    private
339     * @var        boolean
340     */
341     var    $autoValidateUsed = false;
342
343    /**
344     * name of the variable that indicates, whether the form has
345     * been submitted.
346     *
347     * @access    private
348     * @var        string
349     * @see        setAutoValidate()
350     */
351     var    $submitVar    =    null;
352
353    /**
354     * event handlers
355     *
356     * @access    private
357     * @var        array
358     * @see        registerEventHandler()
359     * @see        registerEvent()
360     */
361     var    $_eventHandler    =    array();
362
363    /**
364     * events that can be triggered
365     *
366     * @access    private
367     * @var        array
368     * @see        registerEventHandler()
369     * @see        triggerEvent()
370     * @see        registerEvent()
371     */
372     var    $_validEvents = array('onInit', 'onValidate', 'onSubmit', 'onError', 'onSuccess', 'onRender');
373
374    /**
375     * Stores whether the current form has been validated
376     *
377     * @access    private
378     */
379     var $validated    =    false;
380
381    /**
382     * Stores whether the current form is valid or not (after the
383     * validation process)
384     *
385     * @access    private
386     */
387     var $valid    =    null;
388
389    /**
390     * Stores the names of all static properties that patForms will use as defaults
391     * for the properties with the same name on startup.
392     *
393     * @access    private
394     */
395     var $staticProperties    =    array(
396         'format'        =>    'setFormat',
397         'autoFinalize'    =>    'setAutoFinalize',
398         'locale'        =>    'setLocale',
399     );
400
401    /**
402     * Stores the flag for the autoFinalize feature
403     *
404     * @access    private
405     */
406     var $autoFinalize    =    true;
407
408    /**
409     * custom validation rules
410     *
411     * @access    private
412     * @var        array
413     */
414     var $_rules            =    array();
415
416    /**
417     * define error codes an messages for the form
418     *
419     * Will be set by validation rules that have been
420     * added to the form.
421     *
422     * @access private
423     * @var    array    $validatorErrorCodes
424     */
425     var    $validatorErrorCodes  =   array();
426
427    /**
428     * stores any validation errors that can occurr during the
429     * form's validation process.
430     *
431     * @access    private
432     * @var        array    $validationErrors
433     */
434     var    $validationErrors  =   array();
435
436    /**
437     * next error offset for rules
438     * @access    private
439     * @var        integer
440     */
441     var $nextErrorOffset    =    1000;
442
443    /**
444     * Attributes of the form - needed to generate the form tag
445     *
446     * @access    private
447     * @var        array    $attributes
448     * @see        setAttribute()
449     */
450     var    $attributes    =    array();
451
452    /**
453     * Attribute definition for the form - defines which attribute the form
454     * itself supports.
455     *
456     * @access    public
457     */
458     var    $attributeDefinition    =    array(
459
460         'class' =>    array(
461             'required'        =>    false,
462             'format'        =>    'string',
463             'outputFormats'    =>    array( 'html' ),
464         ),
465
466         'id' =>    array(
467             'required'        =>    false,
468             'format'        =>    'string',
469             'outputFormats'    =>    array( 'html' ),
470         ),
471
472         'name' => array(
473             'required'        =>    true,
474             'format'        =>    'string',
475             'outputFormats'    =>    array( 'html' ),
476         ),
477
478         'method' => array(
479             'required'        =>    true,
480             'format'        =>    'string',
481             'default'        =>    'post',
482             'outputFormats'    =>    array( 'html' ),
483         ),
484
485         'action' => array(
486             'required'        =>    true,
487             'format'        =>    'string',
488             'outputFormats'    =>    array( 'html' ),
489         ),
490
491         'accept' => array(
492             'required'        =>    false,
493             'format'        =>    'string',
494             'outputFormats'    =>    array( 'html' ),
495         ),
496
497         'accept-charset' => array(
498             'required'        =>    false,
499             'format'        =>    'string',
500             'outputFormats'    =>    array( 'html' ),
501         ),
502
503         'enctype' => array(
504             'required'        =>    false,
505             'format'        =>    'string',
506             'outputFormats'    =>    array( 'html' ),
507         ),
508
509         'onreset' => array(
510             'required'        =>    false,
511             'format'        =>    'string',
512             'outputFormats'    =>    array( 'html' ),
513         ),
514
515         'onsubmit' => array(
516             'required'        =>    false,
517             'format'        =>    'string',
518             'outputFormats'    =>    array( 'html' ),
519         ),
520
521         'target' => array(
522             'required'        =>    false,
523             'format'        =>    'string',
524             'outputFormats'    =>    array( 'html' ),
525         ),
526     );
527
528    /**
529     * Stores all available patForms options - these are inherited by all elements
530     * and their dependencies, like rules.
531     *
532     * Short option overview:
533     *
534     * - scripts: enable client script integration
535     *
536     * @access    public
537     */
538     var $options    =    array(
539
540         'scripts' => array(
541             'enabled' => false,
542             'params' =>    array(
543                 'folder' => PATFORMS_SCRIPT_PATH,
544                 'jsInclude' => false
545             ),
546         ),
547     );
548
549    /**
550     * the form's namespace
551     *
552     * @access    private
553     * @var        string
554     */
555     var    $namespace = '';
556
557    /**
558     * observers of the form
559     *
560     * @access    private
561     * @var        array
562     */
563     var    $observers = array();
564
565    /**
566     * add a directory where patForms should search for
567     * modules.
568     *
569     * You may either pass a string or an array of directories.
570     *
571     * patTemplate will be searching for a module in the same
572     * order you added them. If the module cannot be found in
573     * the custom folders, it will look in
574     * patForms/$moduleType.
575     *
576     * @static
577     * @access   public
578     * @param    string          module type or NULL for any
579     * @param    string|array    directory or directories to search.
580     */
581     function addModuleDir($moduleType, $dir)
582     {
583         $dirs   =&  patForms::getStaticProperty( 'moduleDirs' );
584
585         if (!is_array($dir)) {
586             $dir    =   array($dir);
587         }
588
589         if ($moduleType === null) {
590             $dirs['__all']  =   array_merge($dirs['__all'], $dir);
591             return true;
592         }
593
594         if (!isset($dirs[$moduleType])) {
595             $dirs[$moduleType]    =   array();
596         }
597
598         $dirs[$moduleType]    =   array_merge($dirs[$moduleType], $dir);
599         return true;
600     }
601
602    /**
603     * add a base directory where patForms should search for
604     * modules.
605     *
606     * You may either pass a string or an array of directories.
607     *
608     * patForms will be searching for a module in the same
609     * order you added them. It will first look in module specific
610     * directory (added with addModuleDir()), afterwards in module
611     * base dirs. If the module cannot be found in the custom
612     * folders, it will look in patForms/$moduleType.
613     *
614     * @static
615     * @access   public
616     * @param    string|array    directory or directories to search.
617     * @see addModuleDir()
618     */
619     function addModuleBaseDir($dir)
620     {
621         return patForms::addModuleDir(null, $dir);
622     }
623
624    /**
625     * Sets the default attributes that will be inherited by any elements you add to the form.
626     *
627     * <b>Note:</b> You have to call this method statically before creating a new form if you use
628     * patForm's automatic element creation feature via the {@link createForm()} method, as the
629     * default attributes cannot be set after an element has been created.
630     *
631     * @static
632     * @access    public
633     * @param    array    $attributes    The list of attributes to set with key => value pairs.
634     */
635     function setDefaultAttributes( $attributes )
636     {
637         patForms::setStaticProperty( 'defaultAttributes', $attributes );
638     }
639
640    /**
641     * Sets the default-encoding of the form / the site the form is displayed on.
642     *
643     * This affects the encoding/decoding of html-entities in the form's element-value
644     * and attributes.
645     *
646     * @static
647     * @access   public
648     * @param    string  $encoding   the ISO code for the desired encoding (UTF-8, ISO-8859-1, ...)
649     */
650     function setDefaultEncoding( $encoding )
651     {
652         patForms::setStaticProperty( 'defaultEncoding', $encoding );
653     }
654
655
656    /**
657     * sets the locale (language) to use for the validation error messages of all elements
658     * in the form.
659     *
660     * @access    public
661     * @param    string        language code
662     * @param    string        optional language file
663     * @return    bool        True on success
664     */
665     function setLocale( $locale, $languageFile = null )
666     {
667         if (!is_null($languageFile)) {
668             $languageData = patForms::parseLocaleFile($languageFile);
669             if (patErrorManager::isError($languageData)) {
670                 return $languageData;
671             }
672             $customLocales = patForms::getStaticProperty('customLocales');
673             $customLocales[$locale] = $languageData;
674             patForms::setStaticProperty('customLocales', $customLocales);
675         }
676
677         if (isset($this) && is_a($this, 'patForms')) {
678             $this->locale = $locale;
679
680             if (!empty($this->elements)) {
681                 $cnt = count($this->elements);
682                 for ($i=0; $i < $cnt; $i++) {
683                     $this->elements[$i]->setLocale($locale);
684                 }
685             }
686         } else {
687             patForms::setStaticProperty('locale', $locale);
688         }
689         return true;
690     }
691
692    /**
693     * checks, whether a locale is a custom locale
694     *
695     * @static
696     * @access    public
697     * @param    string        locale name
698     * @return    boolean
699     */
700     function isCustomLocale($locale)
701     {
702         $customLocales = patForms::getStaticProperty('customLocales');
703         if (isset($customLocales[$locale])) {
704             return true;
705         }
706         return false;
707     }
708
709    /**
710     * get the form's namespace
711     *
712     * @static
713     * @access    public
714     * @param    string        namespace
715     * @return    string
716     */
717     function getNamespace()
718     {
719         return $this->namespace;
720     }
721
722    /**
723     * set the form's namespace
724     *
725     * @static
726     * @access    public
727     * @param    string        namespace
728     * @return    null
729     */