Subversion Repositories Applications.papyrus

Rev

Rev 1087 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
320 jpm 1
<?php
2
/* vim: set expandtab tabstop=4 shiftwidth=4: */
3
// +----------------------------------------------------------------------+
4
// | PHP version 4.0                                                      |
5
// +----------------------------------------------------------------------+
6
// | Copyright (c) 1997-2003 The PHP Group                                |
7
// +----------------------------------------------------------------------+
8
// | This source file is subject to version 2.0 of the PHP license,       |
9
// | that is bundled with this package in the file LICENSE, and is        |
10
// | available at through the world-wide-web at                           |
11
// | http://www.php.net/license/2_02.txt.                                 |
12
// | If you did not receive a copy of the PHP license and are unable to   |
13
// | obtain it through the world-wide-web, please send a note to          |
14
// | license@php.net so we can mail you a copy immediately.               |
15
// +----------------------------------------------------------------------+
16
// | Author: Bertrand Mansion <bmansion@mamasam.com>                      |
17
// +----------------------------------------------------------------------+
18
//
443 ddelon 19
// $Id: ITStatic.php,v 1.2 2005-09-20 17:01:22 ddelon Exp $
320 jpm 20
 
21
require_once('HTML/QuickForm/Renderer.php');
22
 
23
/**
24
 * A static renderer for HTML_QuickForm compatible
25
 * with HTML_Template_IT and HTML_Template_Sigma.
26
 *
27
 * As opposed to the dynamic renderer, this renderer needs
28
 * every elements and labels in the form to be specified by
29
 * placeholders at the position you want them to be displayed.
30
 *
31
 * @author Bertrand Mansion <bmansion@mamasam.com>
32
 * @access public
33
 */
34
class HTML_QuickForm_Renderer_ITStatic extends HTML_QuickForm_Renderer
35
{
36
   /**
37
    * An HTML_Template_IT or some other API compatible Template instance
38
    * @var object
39
    */
40
    var $_tpl = null;
41
 
42
   /**
43
    * Rendered form name
44
    * @var string
45
    */
46
    var $_formName = 'form';
47
 
48
   /**
49
    * The errors that were not shown near concrete fields go here
50
    * @var array
51
    */
52
    var $_errors = array();
53
 
54
   /**
55
    * Show the block with required note?
56
    * @var bool
57
    */
58
    var $_showRequired = false;
59
 
60
   /**
61
    * Which group are we currently parsing ?
62
    * @var string
63
    */
64
    var $_inGroup;
65
 
66
   /**
67
    * Index of the element in its group
68
    * @var int
69
    */
70
    var $_elementIndex = 0;
71
 
72
   /**
73
    * If elements have been added with the same name
74
    * @var array
75
    */
76
    var $_duplicateElements = array();
77
 
78
   /**
79
    * How to handle the required tag for required fields
80
    * @var string
81
    */
82
    var $_required = '{label}<font size="1" color="red">*</font>';
83
 
84
   /**
85
    * How to handle error messages in form validation
86
    * @var string
87
    */
88
    var $_error = '<font color="red">{error}</font><br />{html}';
89
 
90
   /**
91
    * Collected HTML for hidden elements, if needed
92
    * @var string
93
    */
94
    var $_hidden = '';
95
 
96
   /**
97
    * Constructor
98
    *
99
    * @param object     An HTML_Template_IT or other compatible Template object to use
100
    */
101
    function HTML_QuickForm_Renderer_ITStatic(&$tpl)
102
    {
103
        $this->HTML_QuickForm_Renderer();
104
        $this->_tpl =& $tpl;
105
    } // end constructor
106
 
107
   /**
108
    * Called when visiting a form, before processing any form elements
109
    *
110
    * @param    object      An HTML_QuickForm object being visited
111
    * @access   public
112
    * @return   void
113
    */
114
    function startForm(&$form)
115
    {
116
        $this->_formName = $form->getAttribute('id');
117
 
118
        if (count($form->_duplicateIndex) > 0) {
119
            // Take care of duplicate elements
120
            foreach ($form->_duplicateIndex as $elementName => $indexes) {
121
                $this->_duplicateElements[$elementName] = 0;
122
            }
123
        }
124
    } // end func startForm
125
 
126
   /**
127
    * Called when visiting a form, after processing all form elements
128
    *
129
    * @param    object     An HTML_QuickForm object being visited
130
    * @access   public
131
    * @return   void
132
    */
133
    function finishForm(&$form)
134
    {
135
        // display errors above form
136
        if (!empty($this->_errors) && $this->_tpl->blockExists($this->_formName.'_error_loop')) {
137
            foreach ($this->_errors as $error) {
138
                $this->_tpl->setVariable($this->_formName.'_error', $error);
139
                $this->_tpl->parse($this->_formName.'_error_loop');
140
            }
141
        }
142
        // show required note
143
        if ($this->_showRequired) {
144
            $this->_tpl->setVariable($this->_formName.'_required_note', $form->getRequiredNote());
145
        }
146
        // add hidden elements, if collected
147
        if (!empty($this->_hidden)) {
148
            $this->_tpl->setVariable($this->_formName . '_hidden', $this->_hidden);
149
        }
150
        // assign form attributes
151
        $this->_tpl->setVariable($this->_formName.'_attributes', $form->getAttributes(true));
152
        // assign javascript validation rules
153
        $this->_tpl->setVariable($this->_formName.'_javascript', $form->getValidationScript());
154
    } // end func finishForm
155
 
156
   /**
157
    * Called when visiting a header element
158
    *
159
    * @param    object     An HTML_QuickForm_header element being visited
160
    * @access   public
161
    * @return   void
162
    */
163
    function renderHeader(&$header)
164
    {
165
        $name = $header->getName();
166
        $varName = $this->_formName.'_header';
167
 
168
        // Find placeHolder
169
        if (!empty($name) && $this->_tpl->placeHolderExists($this->_formName.'_header_'.$name)) {
170
            $varName = $this->_formName.'_header_'.$name;
171
        }
172
        $this->_tpl->setVariable($varName, $header->toHtml());
173
    } // end func renderHeader
174
 
175
   /**
176
    * Called when visiting an element
177
    *
178
    * @param    object     An HTML_QuickForm_element object being visited
179
    * @param    bool       Whether an element is required
180
    * @param    string     An error message associated with an element
181
    * @access   public
182
    * @return   void
183
    */
184
    function renderElement(&$element, $required, $error)
185
    {
186
        $name = $element->getName();
187
 
188
        // are we inside a group?
189
        if (!empty($this->_inGroup)) {
190
            $varName = $this->_formName.'_'.str_replace(array('[', ']'), '_', $name);
191
            if (substr($varName, -2) == '__') {
192
                // element name is of type : group[]
193
                $varName = $this->_inGroup.'_'.$this->_elementIndex.'_';
194
                $this->_elementIndex++;
195
            }
196
            if ($varName != $this->_inGroup) {
197
                $varName .= '_' == substr($varName, -1)? '': '_';
198
                // element name is of type : group[name]
199
                $label = $element->getLabel();
200
                $html = $element->toHtml();
201
 
202
                if ($required && !$element->isFrozen()) {
203
                    $this->_renderRequired($label, $html);
204
                    $this->_showRequired = true;
205
                }
206
                if (!empty($label)) {
207
                    if (is_array($label)) {
208
                        foreach ($label as $key => $value) {
209
                            $this->_tpl->setVariable($varName.'label_'.$key, $value);
210
                        }
211
                    } else {
212
                        $this->_tpl->setVariable($varName.'label', $label);
213
                    }
214
                }
215
                $this->_tpl->setVariable($varName.'html', $html);
216
            }
217
 
218
        } else {
219
 
220
            $name = str_replace(array('[', ']'), array('_', ''), $name);
221
 
222
            if (isset($this->_duplicateElements[$name])) {
223
                // Element is a duplicate
224
                $varName = $this->_formName.'_'.$name.'_'.$this->_duplicateElements[$name];
225
                $this->_duplicateElements[$name]++;
226
            } else {
227
                $varName = $this->_formName.'_'.$name;
228
            }
229
 
230
            $label = $element->getLabel();
231
            $html = $element->toHtml();
232
 
233
            if ($required) {
234
                $this->_showRequired = true;
235
                $this->_renderRequired($label, $html);
236
            }
237
            if (!empty($error)) {
238
                $this->_renderError($label, $html, $error);
239
            }
240
            if (is_array($label)) {
241
                foreach ($label as $key => $value) {
242
                    $this->_tpl->setVariable($varName.'_label_'.$key, $value);
243
                }
244
            } else {
245
                $this->_tpl->setVariable($varName.'_label', $label);
246
            }
247
            $this->_tpl->setVariable($varName.'_html', $html);
248
        }
249
    } // end func renderElement
250
 
251
   /**
252
    * Called when visiting a hidden element
253
    *
254
    * @param    object     An HTML_QuickForm_hidden object being visited
255
    * @access   public
256
    * @return   void
257
    */
258
    function renderHidden(&$element)
259
    {
260
        if ($this->_tpl->placeholderExists($this->_formName . '_hidden')) {
261
            $this->_hidden .= $element->toHtml();
262
        } else {
263
            $name = $element->getName();
264
            $name = str_replace(array('[', ']'), array('_', ''), $name);
265
            $this->_tpl->setVariable($this->_formName.'_'.$name.'_html', $element->toHtml());
266
        }
267
    } // end func renderHidden
268
 
269
   /**
270
    * Called when visiting a group, before processing any group elements
271
    *
272
    * @param    object     An HTML_QuickForm_group object being visited
273
    * @param    bool       Whether a group is required
274
    * @param    string     An error message associated with a group
275
    * @access   public
276
    * @return   void
277
    */
278
    function startGroup(&$group, $required, $error)
279
    {
280
        $name = $group->getName();
281
        $varName = $this->_formName.'_'.$name;
282
 
283
        $this->_elementIndex = 0;
284
 
285
        $html = $this->_tpl->placeholderExists($varName.'_html') ? $group->toHtml() : '';
286
        $label = $group->getLabel();
287
 
288
        if ($required) {
289
            $this->_renderRequired($label, $html);
290
        }
291
        if (!empty($error)) {
292
            $this->_renderError($label, $html, $error);
293
        }
294
        if (!empty($html)) {
295
            $this->_tpl->setVariable($varName.'_html', $html);
296
        } else {
297
            // Uses error blocks to set the special groups layout error
298
            // <!-- BEGIN form_group_error -->{form_group_error}<!-- END form_group_error -->
299
            if (!empty($error)) {
300
                if ($this->_tpl->placeholderExists($varName.'_error')) {
301
                    if ($this->_tpl->blockExists($this->_formName . '_error_block')) {
302
                        $this->_tpl->setVariable($this->_formName . '_error', $error);
303
                        $error = $this->_getTplBlock($this->_formName . '_error_block');
304
                    } elseif (strpos($this->_error, '{html}') !== false || strpos($this->_error, '{label}') !== false) {
305
                        $error = str_replace('{error}', $error, $this->_error);
306
                    }
307
                }
308
                $this->_tpl->setVariable($varName . '_error', $error);
309
                array_pop($this->_errors);
310
            }
311
        }
312
        if (is_array($label)) {
313
            foreach ($label as $key => $value) {
314
                $this->_tpl->setVariable($varName.'_label_'.$key, $value);
315
            }
316
        } else {
317
            $this->_tpl->setVariable($varName.'_label', $label);
318
        }
319
        $this->_inGroup = $varName;
320
    } // end func startGroup
321
 
322
   /**
323
    * Called when visiting a group, after processing all group elements
324
    *
325
    * @param    object     An HTML_QuickForm_group object being visited
326
    * @access   public
327
    * @return   void
328
    */
329
    function finishGroup(&$group)
330
    {
331
        $this->_inGroup = '';
332
    } // end func finishGroup
333
 
334
   /**
335
    * Sets the way required elements are rendered
336
    *
337
    * You can use {label} or {html} placeholders to let the renderer know where
338
    * where the element label or the element html are positionned according to the
339
    * required tag. They will be replaced accordingly with the right value.
340
    * For example:
341
    * <font color="red">*</font>{label}
342
    * will put a red star in front of the label if the element is required.
343
    *
344
    * @param    string      The required element template
345
    * @access   public
346
    * @return   void
347
    */
348
    function setRequiredTemplate($template)
349
    {
350
        $this->_required = $template;
351
    } // end func setRequiredTemplate
352
 
353
   /**
354
    * Sets the way elements with validation errors are rendered
355
    *
356
    * You can use {label} or {html} placeholders to let the renderer know where
357
    * where the element label or the element html are positionned according to the
358
    * error message. They will be replaced accordingly with the right value.
359
    * The error message will replace the {error} place holder.
360
    * For example:
361
    * <font color="red">{error}</font><br />{html}
362
    * will put the error message in red on top of the element html.
363
    *
364
    * If you want all error messages to be output in the main error block, do not specify
365
    * {html} nor {label}.
366
    *
367
    * Groups can have special layouts. With this kind of groups, the renderer will need
368
    * to know where to place the error message. In this case, use error blocks like:
369
    * <!-- BEGIN form_group_error -->{form_group_error}<!-- END form_group_error -->
370
    * where you want the error message to appear in the form.
371
    *
372
    * @param    string      The element error template
373
    * @access   public
374
    * @return   void
375
    */
376
    function setErrorTemplate($template)
377
    {
378
        $this->_error = $template;
379
    } // end func setErrorTemplate
380
 
381
   /**
382
    * Called when an element is required
383
    *
384
    * This method will add the required tag to the element label and/or the element html
385
    * such as defined with the method setRequiredTemplate
386
    *
387
    * @param    string      The element label
388
    * @param    string      The element html rendering
389
    * @see      setRequiredTemplate()
390
    * @access   private
391
    * @return   void
392
    */
393
    function _renderRequired(&$label, &$html)
394
    {
395
        if ($this->_tpl->blockExists($tplBlock = $this->_formName . '_required_block')) {
396
            if (!empty($label) && $this->_tpl->placeholderExists($this->_formName . '_label', $tplBlock)) {
397
                $this->_tpl->setVariable($this->_formName . '_label', is_array($label)? $label[0]: $label);
398
                if (is_array($label)) {
399
                    $label[0] = $this->_getTplBlock($tplBlock);
400
                } else {
401
                    $label    = $this->_getTplBlock($tplBlock);
402
                }
403
            }
404
            if (!empty($html) && $this->_tpl->placeholderExists($this->_formName . '_html', $tplBlock)) {
405
                $this->_tpl->setVariable($this->_formName . '_html', $html);
406
                $html = $this->_getTplBlock($tplBlock);
407
            }
408
        } else {
409
            if (!empty($label) && strpos($this->_required, '{label}') !== false) {
410
                if (is_array($label)) {
411
                    $label[0] = str_replace('{label}', $label[0], $this->_required);
412
                } else {
413
                    $label = str_replace('{label}', $label, $this->_required);
414
                }
415
            }
416
            if (!empty($html) && strpos($this->_required, '{html}') !== false) {
417
                $html = str_replace('{html}', $html, $this->_required);
418
            }
419
        }
420
    } // end func _renderRequired
421
 
422
   /**
423
    * Called when an element has a validation error
424
    *
425
    * This method will add the error message to the element label or the element html
426
    * such as defined with the method setErrorTemplate. If the error placeholder is not found
427
    * in the template, the error will be displayed in the form error block.
428
    *
429
    * @param    string      The element label
430
    * @param    string      The element html rendering
431
    * @param    string      The element error
432
    * @see      setErrorTemplate()
433
    * @access   private
434
    * @return   void
435
    */
436
    function _renderError(&$label, &$html, $error)
437
    {
438
        if ($this->_tpl->blockExists($tplBlock = $this->_formName . '_error_block')) {
439
            $this->_tpl->setVariable($this->_formName . '_error', $error);
440
            if (!empty($label) && $this->_tpl->placeholderExists($this->_formName . '_label', $tplBlock)) {
441
                $this->_tpl->setVariable($this->_formName . '_label', is_array($label)? $label[0]: $label);
442
                if (is_array($label)) {
443
                    $label[0] = $this->_getTplBlock($tplBlock);
444
                } else {
445
                    $label    = $this->_getTplBlock($tplBlock);
446
                }
447
            } elseif (!empty($html) && $this->_tpl->placeholderExists($this->_formName . '_html', $tplBlock)) {
448
                $this->_tpl->setVariable($this->_formName . '_html', $html);
449
                $html = $this->_getTplBlock($tplBlock);
450
            }
451
            // clean up after ourselves
452
            $this->_tpl->setVariable($this->_formName . '_error', null);
453
        } elseif (!empty($label) && strpos($this->_error, '{label}') !== false) {
454
            if (is_array($label)) {
455
                $label[0] = str_replace(array('{label}', '{error}'), array($label[0], $error), $this->_error);
456
            } else {
457
                $label = str_replace(array('{label}', '{error}'), array($label, $error), $this->_error);
458
            }
459
        } elseif (!empty($html) && strpos($this->_error, '{html}') !== false) {
460
            $html = str_replace(array('{html}', '{error}'), array($html, $error), $this->_error);
461
        } else {
462
            $this->_errors[] = $error;
463
        }
464
    }// end func _renderError
465
 
466
 
467
   /**
468
    * Returns the block's contents
469
    *
470
    * The method is needed because ITX and Sigma implement clearing
471
    * the block contents on get() a bit differently
472
    *
473
    * @param    string  Block name
474
    * @return   string  Block contents
475
    */
476
    function _getTplBlock($block)
477
    {
478
        $this->_tpl->parse($block);
479
        if (is_a($this->_tpl, 'html_template_sigma')) {
480
            $ret = $this->_tpl->get($block, true);
481
        } else {
482
            $oldClear = $this->_tpl->clearCache;
483
            $this->_tpl->clearCache = true;
484
            $ret = $this->_tpl->get($block);
485
            $this->_tpl->clearCache = $oldClear;
486
        }
487
        return $ret;
488
    }
489
} // end class HTML_QuickForm_Renderer_ITStatic
490
?>