Configure the dmca form site on ridley
[chef.git] / cookbooks / dmca / files / default / html / HTML / QuickForm / Renderer / Tableless.php
1 <?php
2 /**
3  * Replacement for the default renderer of HTML_QuickForm that uses only XHTML
4  * and CSS but no table tags, and generates fully valid XHTML output
5  *
6  * PHP versions 4 and 5
7  *
8  * LICENSE:
9  *
10  * Copyright (c) 2005-2007, Mark Wiesemann <wiesemann@php.net>
11  * All rights reserved.
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions
15  * are met:
16  *
17  *    * Redistributions of source code must retain the above copyright
18  *      notice, this list of conditions and the following disclaimer.
19  *    * Redistributions in binary form must reproduce the above copyright
20  *      notice, this list of conditions and the following disclaimer in the
21  *      documentation and/or other materials provided with the distribution.
22  *    * The names of the authors may not be used to endorse or promote products
23  *      derived from this software without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
26  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
27  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
29  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
33  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36  *
37  * @category   HTML
38  * @package    HTML_QuickForm_Renderer_Tableless
39  * @author     Alexey Borzov <borz_off@cs.msu.su>
40  * @author     Adam Daniel <adaniel1@eesus.jnj.com>
41  * @author     Bertrand Mansion <bmansion@mamasam.com>
42  * @author     Mark Wiesemann <wiesemann@php.net>
43  * @license    http://www.opensource.org/licenses/bsd-license.php New BSD License
44  * @version    CVS: $Id: Tableless.php 271939 2008-12-26 20:22:30Z wiesemann $
45  * @link       http://pear.php.net/package/HTML_QuickForm_Renderer_Tableless
46  */
47
48 require_once 'HTML/QuickForm/Renderer/Default.php';
49
50 /**
51  * Replacement for the default renderer of HTML_QuickForm that uses only XHTML
52  * and CSS but no table tags, and generates fully valid XHTML output
53  *
54  * You need to specify a stylesheet like the one that you find in
55  * data/stylesheet.css to make this work.
56  *
57  * @category   HTML
58  * @package    HTML_QuickForm_Renderer_Tableless
59  * @author     Alexey Borzov <borz_off@cs.msu.su>
60  * @author     Adam Daniel <adaniel1@eesus.jnj.com>
61  * @author     Bertrand Mansion <bmansion@mamasam.com>
62  * @author     Mark Wiesemann <wiesemann@php.net>
63  * @license    http://www.opensource.org/licenses/bsd-license.php New BSD License
64  * @version    Release: 0.6.2
65  * @link       http://pear.php.net/package/HTML_QuickForm_Renderer_Tableless
66  */
67 class HTML_QuickForm_Renderer_Tableless extends HTML_QuickForm_Renderer_Default
68 {
69    /**
70     * Header Template string
71     * @var      string
72     * @access   private
73     */
74     var $_headerTemplate = "\n\t\t<legend>{header}</legend>\n\t\t<ol>";
75
76    /**
77     * Element template string
78     * @var      string
79     * @access   private
80     */
81     var $_elementTemplate =
82         "\n\t\t\t<li><label class=\"element\"><!-- BEGIN required --><span class=\"required\">*</span><!-- END required -->{label}</label><div class=\"element<!-- BEGIN error --> error<!-- END error -->\"><!-- BEGIN error --><span class=\"error\">{error}</span><br /><!-- END error -->{element}</div></li>";
83
84    /**
85     * Form template string
86     * @var      string
87     * @access   private
88     */
89     var $_formTemplate =
90         "\n<form{attributes}>\n\t<div style=\"display: none;\">\n{hidden}\t</div>\n{content}\n</form>";
91
92    /**
93     * Template used when opening a fieldset
94     * @var      string
95     * @access   private
96     */
97     var $_openFieldsetTemplate = "\n\t<fieldset{id}{attributes}>";
98
99    /**
100     * Template used when opening a hidden fieldset
101     * (i.e. a fieldset that is opened when there is no header element)
102     * @var      string
103     * @access   private
104     */
105     var $_openHiddenFieldsetTemplate = "\n\t<fieldset class=\"hidden{class}\">\n\t\t<ol>";
106
107    /**
108     * Template used when closing a fieldset
109     * @var      string
110     * @access   private
111     */
112     var $_closeFieldsetTemplate = "\n\t\t</ol>\n\t</fieldset>";
113
114    /**
115     * Required Note template string
116     * @var      string
117     * @access   private
118     */
119     var $_requiredNoteTemplate =
120         "\n\t\t\t<li class=\"reqnote\"><label class=\"element\">&nbsp;</label>{requiredNote}</li>";
121
122    /**
123     * How many fieldsets are open
124     * @var      integer
125     * @access   private
126     */
127    var $_fieldsetsOpen = 0;
128
129    /**
130     * Array of element names that indicate the end of a fieldset
131     * (a new one will be opened when the next header element occurs)
132     * @var      array
133     * @access   private
134     */
135     var $_stopFieldsetElements = array();
136
137    /**
138     * Name of the currently active group
139     * @var      string
140     * @access   private
141     */
142     var $_currentGroupName = '';
143
144    /**
145     * Constructor
146     *
147     * @access public
148     */
149     function HTML_QuickForm_Renderer_Tableless()
150     {
151         $this->HTML_QuickForm_Renderer_Default();
152     } // end constructor
153
154    /**
155     * Called when visiting a header element
156     *
157     * @param    object     An HTML_QuickForm_header element being visited
158     * @access   public
159     * @return   void
160     */
161     function renderHeader(&$header)
162     {
163         $name = $header->getName();
164         $id = empty($name) ? '' : ' id="' . $name . '"';
165         if (!empty($name) && isset($this->_templates[$name])) {
166             $header_html = str_replace('{header}', $header->toHtml(), $this->_templates[$name]);
167         } else {
168             $header_html = str_replace('{header}', $header->toHtml(), $this->_headerTemplate);
169         }
170         $attributes = $header->getAttributes();
171         $strAttr = '';
172         if (is_array($attributes)) {
173             $charset = HTML_Common::charset();
174             foreach ($attributes as $key => $value) {
175                 if ($key == 'name') {
176                     continue;
177                 }
178                 $strAttr .= ' ' . $key . '="' . htmlspecialchars($value, ENT_COMPAT, $charset) . '"';
179             }
180         }
181         if ($this->_fieldsetsOpen > 0) {
182             $this->_html .= $this->_closeFieldsetTemplate;
183             $this->_fieldsetsOpen--;
184         }
185         $openFieldsetTemplate = str_replace('{id}', $id, $this->_openFieldsetTemplate);
186         $openFieldsetTemplate = str_replace('{attributes}',
187                                             $strAttr,
188                                             $openFieldsetTemplate);
189         $this->_html .= $openFieldsetTemplate . $header_html;
190         $this->_fieldsetsOpen++;
191     } // end func renderHeader
192
193    /**
194     * Renders an element Html
195     * Called when visiting an element
196     *
197     * @param object     An HTML_QuickForm_element object being visited
198     * @param bool       Whether an element is required
199     * @param string     An error message associated with an element
200     * @access public
201     * @return void
202     */
203     function renderElement(&$element, $required, $error)
204     {
205         $this->_handleStopFieldsetElements($element->getName());
206         if (!$this->_inGroup) {
207             $html = $this->_prepareTemplate($element->getName(), $element->getLabel(), $required, $error);
208             // the following lines (until the "elseif") were changed / added
209             // compared to the default renderer
210             $element_html = $element->toHtml();
211             if (!is_null($element->getAttribute('id'))) {
212                 $id = $element->getAttribute('id');
213             } else {
214                 $id = $element->getName();
215             }
216             if ($element->getType() != 'static' && !empty($id)) {
217                 $html = str_replace('<label', '<label for="' . $id . '"', $html);
218                 $element_html = preg_replace(preg_quote('#name="' . $id . '#'),
219                                              'id="' . $id . '" name="' . $id,
220                                              $element_html,
221                                              1);
222             }
223             $this->_html .= str_replace('{element}', $element_html, $html);
224         } elseif (!empty($this->_groupElementTemplate)) {
225             $html = str_replace('{label}', $element->getLabel(), $this->_groupElementTemplate);
226             if ($required) {
227                 $html = str_replace('<!-- BEGIN required -->', '', $html);
228                 $html = str_replace('<!-- END required -->', '', $html);
229             } else {
230                 $html = preg_replace("/([ \t\n\r]*)?<!-- BEGIN required -->(\s|\S)*<!-- END required -->([ \t\n\r]*)?/i", '', $html);
231             }
232             $this->_groupElements[] = str_replace('{element}', $element->toHtml(), $html);
233
234         } else {
235             $element_html = $element->toHtml();
236             // add "id" attribute to first element of the group
237             if (count($this->_groupElements) === 0) {
238                 if (!is_null($element->getAttribute('id'))) {
239                     $id = $element->getAttribute('id');
240                 } else {
241                     $id = $element->getName();
242                 }
243                 $groupId = $this->_currentGroupName;
244                 if ($element->getType() != 'static' && !empty($id)) {
245                     $element_html = preg_replace(preg_quote('#name="' . $id . '#'),
246                                                  'id="' . $groupId . '" name="' . $id,
247                                                  $element_html,
248                                                  1);
249                 }
250             }
251             $this->_groupElements[] = $element_html;
252         }
253     } // end func renderElement
254
255    /**
256     * Renders an hidden element
257     * Called when visiting a hidden element
258     *
259     * @param object     An HTML_QuickForm_hidden object being visited
260     * @access public
261     * @return void
262     */
263     function renderHidden(&$element)
264     {
265         if (!is_null($element->getAttribute('id'))) {
266             $id = $element->getAttribute('id');
267         } else {
268             $id = $element->getName();
269         }
270         $html = $element->toHtml();
271         if (!empty($id)) {
272             $html = str_replace('name="' . $id,
273                                 'id="' . $id . '" name="' . $id,
274                                 $html);
275         }
276         $this->_hiddenHtml .= $html . "\n";
277     } // end func renderHidden
278
279    /**
280     * Called when visiting a group, before processing any group elements
281     *
282     * @param object     An HTML_QuickForm_group object being visited
283     * @param bool       Whether a group is required
284     * @param string     An error message associated with a group
285     * @access public
286     * @return void
287     */
288     function startGroup(&$group, $required, $error)
289     {
290         $this->_handleStopFieldsetElements($group->getName());
291         $name = $group->getName();
292         $this->_groupTemplate        = $this->_prepareTemplate($name, $group->getLabel(), $required, $error);
293         $this->_groupTemplate        = str_replace('<label', '<label for="' . $name . '"', $this->_groupTemplate);
294         $this->_groupElementTemplate = empty($this->_groupTemplates[$name])? '': $this->_groupTemplates[$name];
295         $this->_groupWrap            = empty($this->_groupWraps[$name])? '': $this->_groupWraps[$name];
296         $this->_groupElements        = array();
297         $this->_inGroup              = true;
298         $this->_currentGroupName     = $name;
299     } // end func startGroup
300
301     /**
302     * Called when visiting a group, after processing all group elements
303     *
304     * @param    object      An HTML_QuickForm_group object being visited
305     * @access   public
306     * @return   void
307     */
308     function finishGroup(&$group)
309     {
310         $separator = $group->_separator;
311         if (is_array($separator)) {
312             $count = count($separator);
313             $html  = '';
314             for ($i = 0; $i < count($this->_groupElements); $i++) {
315                 $html .= (0 == $i? '': $separator[($i - 1) % $count]) . $this->_groupElements[$i];
316             }
317         } else {
318             if (is_null($separator)) {
319                 $separator = '&nbsp;';
320             }
321             $html = implode((string)$separator, $this->_groupElements);
322         }
323         if (!empty($this->_groupWrap)) {
324             $html = str_replace('{content}', $html, $this->_groupWrap);
325         }
326         if (!is_null($group->getAttribute('id'))) {
327             $id = $group->getAttribute('id');
328         } else {
329             $id = $group->getName();
330         }
331         $groupTemplate = $this->_groupTemplate;
332
333         $this->_html   .= str_replace('{element}', $html, $groupTemplate);
334         $this->_inGroup = false;
335     } // end func finishGroup
336
337     /**
338     * Called when visiting a form, before processing any form elements
339     *
340     * @param    object      An HTML_QuickForm object being visited
341     * @access   public
342     * @return   void
343     */
344     function startForm(&$form)
345     {
346         $this->_fieldsetsOpen = 0;
347         parent::startForm($form);
348     } // end func startForm
349
350    /**
351     * Called when visiting a form, after processing all form elements
352     * Adds required note, form attributes, validation javascript and form content.
353     *
354     * @param    object      An HTML_QuickForm object being visited
355     * @access   public
356     * @return   void
357     */
358     function finishForm(&$form)
359     {
360         // add a required note, if one is needed
361         if (!empty($form->_required) && !$form->_freezeAll) {
362             $requiredNote = $form->getRequiredNote();
363             // replace default required note by DOM/XHTML optimized note
364             if ($requiredNote == '<span style="font-size:80%; color:#ff0000;">*</span><span style="font-size:80%;"> denotes required field</span>') {
365                 $requiredNote = '<span class="required">*</span> denotes required field';
366             }
367             $this->_html .= str_replace('{requiredNote}', $requiredNote, $this->_requiredNoteTemplate);
368         }
369         // close the open fieldset
370         if ($this->_fieldsetsOpen > 0) {
371             $this->_html .= $this->_closeFieldsetTemplate;
372             $this->_fieldsetsOpen--;
373         }
374         // add form attributes and content
375         $html = str_replace('{attributes}', $form->getAttributes(true), $this->_formTemplate);
376         if (strpos($this->_formTemplate, '{hidden}')) {
377             $html = str_replace('{hidden}', $this->_hiddenHtml, $html);
378         } else {
379             $this->_html .= $this->_hiddenHtml;
380         }
381         $this->_hiddenHtml = '';
382         $this->_html = str_replace('{content}', $this->_html, $html);
383         $this->_html = str_replace('></label>', '>&nbsp;</label>', $this->_html);
384         // add a validation script
385         if ('' != ($script = $form->getValidationScript())) {
386             $this->_html = $script . "\n" . $this->_html;
387         }
388     } // end func finishForm
389
390     /**
391      * Sets the template used when opening a fieldset
392      *
393      * @param       string      The HTML used when opening a fieldset
394      * @access      public
395      * @return      void
396      */
397     function setOpenFieldsetTemplate($html)
398     {
399         $this->_openFieldsetTemplate = $html;
400     } // end func setOpenFieldsetTemplate
401
402     /**
403      * Sets the template used when opening a hidden fieldset
404      * (i.e. a fieldset that is opened when there is no header element)
405      *
406      * @param       string      The HTML used when opening a hidden fieldset
407      * @access      public
408      * @return      void
409      */
410     function setOpenHiddenFieldsetTemplate($html)
411     {
412         $this->_openHiddenFieldsetTemplate = $html;
413     } // end func setOpenHiddenFieldsetTemplate
414
415     /**
416      * Sets the template used when closing a fieldset
417      *
418      * @param       string      The HTML used when closing a fieldset
419      * @access      public
420      * @return      void
421      */
422     function setCloseFieldsetTemplate($html)
423     {
424         $this->_closeFieldsetTemplate = $html;
425     } // end func setCloseFieldsetTemplate
426
427     /**
428      * Adds one or more element names that indicate the end of a fieldset
429      * (a new one will be opened when a the next header element occurs)
430      *
431      * @param       mixed      Element name(s) (as array or string)
432      * @param       string     (optional) Class name for the fieldset(s)
433      * @access      public
434      * @return      void
435      */
436     function addStopFieldsetElements($element, $class = '')
437     {
438         if (is_array($element)) {
439             $elements = array();
440             foreach ($element as $name) {
441                 $elements[$name] = $class;
442             }
443             $this->_stopFieldsetElements = array_merge($this->_stopFieldsetElements,
444                                                        $elements);
445         } else {
446             $this->_stopFieldsetElements[$element] = $class;
447         }
448     } // end func addStopFieldsetElements
449
450     /**
451      * Handle element/group names that indicate the end of a group
452      *
453      * @param string     The name of the element or group
454      * @access private
455      * @return void
456      */
457     function _handleStopFieldsetElements($element)
458     {
459         // if the element/group name indicates the end of a fieldset, close
460         // the fieldset
461         if (   array_key_exists($element, $this->_stopFieldsetElements)
462             && $this->_fieldsetsOpen > 0
463            ) {
464             $this->_html .= $this->_closeFieldsetTemplate;
465             $this->_fieldsetsOpen--;
466         }
467         // if no fieldset was opened, we need to open a hidden one here to get
468         // XHTML validity
469         if ($this->_fieldsetsOpen === 0) {
470             $replace = '';
471             if (   array_key_exists($element, $this->_stopFieldsetElements)
472                 && $this->_stopFieldsetElements[$element] != ''
473                ) {
474                 $replace = ' ' . $this->_stopFieldsetElements[$element];
475             }
476             $this->_html .= str_replace('{class}', $replace,
477                                         $this->_openHiddenFieldsetTemplate);
478             $this->_fieldsetsOpen++;
479         }
480     } // end func _handleStopFieldsetElements
481
482     /**
483      * Sets element template
484      *
485      * @param   string    The HTML surrounding an element
486      * @param   mixed     (optional) Name(s) of the element to apply template
487      *                    for (either single element name as string or multiple
488      *                    element names as an array)
489      * @access  public
490      * @return  void
491      */
492     function setElementTemplate($html, $element = null)
493     {
494         if (is_null($element)) {
495             $this->_elementTemplate = $html;
496         } elseif (is_array($element)) {
497             foreach ($element as $name) {
498                 $this->_templates[$name] = $html;
499             }
500         } else {
501             $this->_templates[$element] = $html;
502         }
503     } // end func setElementTemplate
504
505 } // end class HTML_QuickForm_Renderer_Default
506 ?>