2 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
 
   5  * A concrete renderer for HTML_QuickForm, based on QuickForm 2.x built-in one
 
   9  * LICENSE: This source file is subject to version 3.01 of the PHP license
 
  10  * that is available through the world-wide-web at the following URI:
 
  11  * http://www.php.net/license/3_01.txt If you did not receive a copy of
 
  12  * the PHP License and are unable to obtain it through the web, please
 
  13  * send a note to license@php.net so we can mail you a copy immediately.
 
  16  * @package     HTML_QuickForm
 
  17  * @author      Alexey Borzov <avb@php.net>
 
  18  * @author      Adam Daniel <adaniel1@eesus.jnj.com>
 
  19  * @author      Bertrand Mansion <bmansion@mamasam.com>
 
  20  * @copyright   2001-2011 The PHP Group
 
  21  * @license     http://www.php.net/license/3_01.txt PHP License 3.01
 
  23  * @link        http://pear.php.net/package/HTML_QuickForm
 
  27  * An abstract base class for QuickForm renderers
 
  29 require_once 'HTML/QuickForm/Renderer.php';
 
  32  * A concrete renderer for HTML_QuickForm, based on QuickForm 2.x built-in one
 
  35  * @package     HTML_QuickForm
 
  36  * @author      Alexey Borzov <avb@php.net>
 
  37  * @author      Adam Daniel <adaniel1@eesus.jnj.com>
 
  38  * @author      Bertrand Mansion <bmansion@mamasam.com>
 
  39  * @version     Release: 3.2.16
 
  42 class HTML_QuickForm_Renderer_Default extends HTML_QuickForm_Renderer
 
  45     * The HTML of the form  
 
  52     * Header Template string
 
  56     var $_headerTemplate = 
 
  57         "\n\t<tr>\n\t\t<td style=\"white-space: nowrap; background-color: #CCCCCC;\" align=\"left\" valign=\"top\" colspan=\"2\"><b>{header}</b></td>\n\t</tr>";
 
  60     * Element template string
 
  64     var $_elementTemplate = 
 
  65         "\n\t<tr>\n\t\t<td align=\"right\" valign=\"top\"><!-- BEGIN required --><span style=\"color: #ff0000\">*</span><!-- END required --><b>{label}</b></td>\n\t\t<td valign=\"top\" align=\"left\"><!-- BEGIN error --><span style=\"color: #ff0000\">{error}</span><br /><!-- END error -->\t{element}</td>\n\t</tr>";
 
  68     * Form template string
 
  73         "\n<form{attributes}>\n<div>\n{hidden}<table border=\"0\">\n{content}\n</table>\n</div>\n</form>";
 
  76     * Required Note template string
 
  80     var $_requiredNoteTemplate = 
 
  81         "\n\t<tr>\n\t\t<td></td>\n\t<td align=\"left\" valign=\"top\">{requiredNote}</td>\n\t</tr>";
 
  84     * Array containing the templates for customised elements
 
  88     var $_templates = array();
 
  91     * Array containing the templates for group wraps.
 
  93     * These templates are wrapped around group elements and groups' own
 
  94     * templates wrap around them. This is set by setGroupTemplate().
 
  99     var $_groupWraps = array();
 
 102     * Array containing the templates for elements within groups
 
 106     var $_groupTemplates = array();
 
 109     * True if we are inside a group 
 
 113     var $_inGroup = false;
 
 116     * Array with HTML generated for group elements
 
 120     var $_groupElements = array();
 
 123     * Template for an element inside a group
 
 127     var $_groupElementTemplate = '';
 
 130     * HTML that wraps around the group elements
 
 134     var $_groupWrap = '';
 
 137     * HTML for the current group
 
 141     var $_groupTemplate = '';
 
 144     * Collected HTML of the hidden fields
 
 148     var $_hiddenHtml = '';
 
 155     function HTML_QuickForm_Renderer_Default()
 
 157         $this->HTML_QuickForm_Renderer();
 
 161     * returns the HTML generated for the form
 
 168         // _hiddenHtml is cleared in finishForm(), so this only matters when
 
 169         // finishForm() was not called (e.g. group::toHtml(), bug #3511)
 
 170         return $this->_hiddenHtml . $this->_html;
 
 174     * Called when visiting a form, before processing any form elements
 
 176     * @param    HTML_QuickForm  form object being visited
 
 180     function startForm(&$form)
 
 183         $this->_hiddenHtml = '';
 
 184     } // end func startForm
 
 187     * Called when visiting a form, after processing all form elements
 
 188     * Adds required note, form attributes, validation javascript and form content.
 
 190     * @param    HTML_QuickForm  form object being visited
 
 194     function finishForm(&$form)
 
 196         // add a required note, if one is needed
 
 197         if (!empty($form->_required) && !$form->_freezeAll) {
 
 198             $this->_html .= str_replace('{requiredNote}', $form->getRequiredNote(), $this->_requiredNoteTemplate);
 
 200         // add form attributes and content
 
 201         $html = str_replace('{attributes}', $form->getAttributes(true), $this->_formTemplate);
 
 202         if (strpos($this->_formTemplate, '{hidden}')) {
 
 203             $html = str_replace('{hidden}', $this->_hiddenHtml, $html);
 
 205             $this->_html .= $this->_hiddenHtml;
 
 207         $this->_hiddenHtml = '';
 
 208         $this->_html = str_replace('{content}', $this->_html, $html);
 
 209         // add a validation script
 
 210         if ('' != ($script = $form->getValidationScript())) {
 
 211             $this->_html = $script . "\n" . $this->_html;
 
 213     } // end func finishForm
 
 216     * Called when visiting a header element
 
 218     * @param    HTML_QuickForm_header   header element being visited
 
 222     function renderHeader(&$header)
 
 224         $name = $header->getName();
 
 225         if (!empty($name) && isset($this->_templates[$name])) {
 
 226             $this->_html .= str_replace('{header}', $header->toHtml(), $this->_templates[$name]);
 
 228             $this->_html .= str_replace('{header}', $header->toHtml(), $this->_headerTemplate);
 
 230     } // end func renderHeader
 
 233     * Helper method for renderElement
 
 235     * @param    string      Element name
 
 236     * @param    mixed       Element label (if using an array of labels, you should set the appropriate template)
 
 237     * @param    bool        Whether an element is required
 
 238     * @param    string      Error message associated with the element
 
 240     * @see      renderElement()
 
 241     * @return   string      Html for element
 
 243     function _prepareTemplate($name, $label, $required, $error)
 
 245         if (is_array($label)) {
 
 246             $nameLabel = array_shift($label);
 
 250         if (isset($this->_templates[$name])) {
 
 251             $html = str_replace('{label}', $nameLabel, $this->_templates[$name]);
 
 253             $html = str_replace('{label}', $nameLabel, $this->_elementTemplate);
 
 256             $html = str_replace('<!-- BEGIN required -->', '', $html);
 
 257             $html = str_replace('<!-- END required -->', '', $html);
 
 259             $html = preg_replace("/([ \t\n\r]*)?<!-- BEGIN required -->.*<!-- END required -->([ \t\n\r]*)?/isU", '', $html);
 
 262             $html = str_replace('{error}', $error, $html);
 
 263             $html = str_replace('<!-- BEGIN error -->', '', $html);
 
 264             $html = str_replace('<!-- END error -->', '', $html);
 
 266             $html = preg_replace("/([ \t\n\r]*)?<!-- BEGIN error -->.*<!-- END error -->([ \t\n\r]*)?/isU", '', $html);
 
 268         if (is_array($label)) {
 
 269             foreach($label as $key => $text) {
 
 270                 $key  = is_int($key)? $key + 2: $key;
 
 271                 $html = str_replace("{label_{$key}}", $text, $html);
 
 272                 $html = str_replace("<!-- BEGIN label_{$key} -->", '', $html);
 
 273                 $html = str_replace("<!-- END label_{$key} -->", '', $html);
 
 276         if (strpos($html, '{label_')) {
 
 277             $html = preg_replace('/\s*<!-- BEGIN label_(\S+) -->.*<!-- END label_\1 -->\s*/is', '', $html);
 
 280     } // end func _prepareTemplate
 
 283     * Renders an element Html
 
 284     * Called when visiting an element
 
 286     * @param HTML_QuickForm_element form element being visited
 
 287     * @param bool                   Whether an element is required
 
 288     * @param string                 An error message associated with an element
 
 292     function renderElement(&$element, $required, $error)
 
 294         if (!$this->_inGroup) {
 
 295             $html = $this->_prepareTemplate($element->getName(), $element->getLabel(), $required, $error);
 
 296             $this->_html .= str_replace('{element}', $element->toHtml(), $html);
 
 298         } elseif (!empty($this->_groupElementTemplate)) {
 
 299             $html = str_replace('{label}', $element->getLabel(), $this->_groupElementTemplate);
 
 301                 $html = str_replace('<!-- BEGIN required -->', '', $html);
 
 302                 $html = str_replace('<!-- END required -->', '', $html);
 
 304                 $html = preg_replace("/([ \t\n\r]*)?<!-- BEGIN required -->.*<!-- END required -->([ \t\n\r]*)?/isU", '', $html);
 
 306             $this->_groupElements[] = str_replace('{element}', $element->toHtml(), $html);
 
 309             $this->_groupElements[] = $element->toHtml();
 
 311     } // end func renderElement
 
 314     * Renders an hidden element
 
 315     * Called when visiting a hidden element
 
 317     * @param HTML_QuickForm_element     form element being visited
 
 321     function renderHidden(&$element)
 
 323         $this->_hiddenHtml .= $element->toHtml() . "\n";
 
 324     } // end func renderHidden
 
 327     * Called when visiting a raw HTML/text pseudo-element
 
 329     * @param  HTML_QuickForm_html   element being visited
 
 333     function renderHtml(&$data)
 
 335         $this->_html .= $data->toHtml();
 
 336     } // end func renderHtml
 
 339     * Called when visiting a group, before processing any group elements
 
 341     * @param HTML_QuickForm_group   group being visited
 
 342     * @param bool       Whether a group is required
 
 343     * @param string     An error message associated with a group
 
 347     function startGroup(&$group, $required, $error)
 
 349         $name = $group->getName();
 
 350         $this->_groupTemplate        = $this->_prepareTemplate($name, $group->getLabel(), $required, $error);
 
 351         $this->_groupElementTemplate = empty($this->_groupTemplates[$name])? '': $this->_groupTemplates[$name];
 
 352         $this->_groupWrap            = empty($this->_groupWraps[$name])? '': $this->_groupWraps[$name];
 
 353         $this->_groupElements        = array();
 
 354         $this->_inGroup              = true;
 
 355     } // end func startGroup
 
 358     * Called when visiting a group, after processing all group elements
 
 360     * @param    HTML_QuickForm_group    group being visited
 
 364     function finishGroup(&$group)
 
 366         $separator = $group->_separator;
 
 367         if (is_array($separator)) {
 
 368             $count = count($separator);
 
 370             for ($i = 0; $i < count($this->_groupElements); $i++) {
 
 371                 $html .= (0 == $i? '': $separator[($i - 1) % $count]) . $this->_groupElements[$i];
 
 374             if (is_null($separator)) {
 
 375                 $separator = ' ';
 
 377             $html = implode((string)$separator, $this->_groupElements);
 
 379         if (!empty($this->_groupWrap)) {
 
 380             $html = str_replace('{content}', $html, $this->_groupWrap);
 
 382         $this->_html   .= str_replace('{element}', $html, $this->_groupTemplate);
 
 383         $this->_inGroup = false;
 
 384     } // end func finishGroup
 
 387      * Sets element template 
 
 389      * @param       string      The HTML surrounding an element 
 
 390      * @param       string      (optional) Name of the element to apply template for
 
 394     function setElementTemplate($html, $element = null)
 
 396         if (is_null($element)) {
 
 397             $this->_elementTemplate = $html;
 
 399             $this->_templates[$element] = $html;
 
 401     } // end func setElementTemplate
 
 405      * Sets template for a group wrapper 
 
 407      * This template is contained within a group-as-element template 
 
 408      * set via setTemplate() and contains group's element templates, set
 
 409      * via setGroupElementTemplate()
 
 411      * @param       string      The HTML surrounding group elements
 
 412      * @param       string      Name of the group to apply template for
 
 416     function setGroupTemplate($html, $group)
 
 418         $this->_groupWraps[$group] = $html;
 
 419     } // end func setGroupTemplate
 
 422      * Sets element template for elements within a group
 
 424      * @param       string      The HTML surrounding an element 
 
 425      * @param       string      Name of the group to apply template for
 
 429     function setGroupElementTemplate($html, $group)
 
 431         $this->_groupTemplates[$group] = $html;
 
 432     } // end func setGroupElementTemplate
 
 435      * Sets header template
 
 437      * @param       string      The HTML surrounding the header 
 
 441     function setHeaderTemplate($html)
 
 443         $this->_headerTemplate = $html;
 
 444     } // end func setHeaderTemplate
 
 449      * @param     string    The HTML surrounding the form tags 
 
 453     function setFormTemplate($html)
 
 455         $this->_formTemplate = $html;
 
 456     } // end func setFormTemplate
 
 459      * Sets the note indicating required fields template
 
 461      * @param       string      The HTML surrounding the required note 
 
 465     function setRequiredNoteTemplate($html)
 
 467         $this->_requiredNoteTemplate = $html;
 
 468     } // end func setRequiredNoteTemplate
 
 471      * Clears all the HTML out of the templates that surround notes, elements, etc.
 
 472      * Useful when you want to use addData() to create a completely custom form look
 
 477     function clearAllTemplates()
 
 479         $this->setElementTemplate('{element}');
 
 480         $this->setFormTemplate("\n\t<form{attributes}>{content}\n\t</form>\n");
 
 481         $this->setRequiredNoteTemplate('');
 
 482         $this->_templates = array();
 
 483     } // end func clearAllTemplates
 
 484 } // end class HTML_QuickForm_Renderer_Default