root/branches/gettext/patForms.php

Revision 399, 76.2 kB (checked in by gerd, 4 weeks ago)

removed empty line at the end of file :-(

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