Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.11.x will end 14 Nov 2022 (12 months plus 6 months extension).
  • Bug fixes for security issues in 3.11.x will end 13 Nov 2023 (18 months plus 12 months extension).
  • PHP version: minimum PHP 7.3.0 Note: minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is supported too.

Differences Between: [Versions 311 and 402] [Versions 311 and 403]

   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  // | Authors: Alexey Borzov <borz_off@cs.msu.su>                          |
  17  // |          Adam Daniel <adaniel1@eesus.jnj.com>                        |
  18  // |          Bertrand Mansion <bmansion@mamasam.com>                     |
  19  // |          Thomas Schulz <ths@4bconsult.de>                            |
  20  // +----------------------------------------------------------------------+
  21  //
  22  // $Id$
  23  
  24  require_once 'HTML/QuickForm/Renderer.php';
  25  
  26  /**
  27   * A concrete renderer for HTML_QuickForm, makes an array of form contents
  28   *
  29   * Based on old toArray() code.
  30   *
  31   * The form array structure is the following:
  32   * array(
  33   *   'frozen'           => 'whether the form is frozen',
  34   *   'javascript'       => 'javascript for client-side validation',
  35   *   'attributes'       => 'attributes for <form> tag',
  36   *   'requirednote      => 'note about the required elements',
  37   *   // if we set the option to collect hidden elements
  38   *   'hidden'           => 'collected html of all hidden elements',
  39   *   // if there were some validation errors:
  40   *   'errors' => array(
  41   *     '1st element name' => 'Error for the 1st element',
  42   *     ...
  43   *     'nth element name' => 'Error for the nth element'
  44   *   ),
  45   *   // if there are no headers in the form:
  46   *   'elements' => array(
  47   *     element_1,
  48   *     ...
  49   *     element_N
  50   *   )
  51   *   // if there are headers in the form:
  52   *   'sections' => array(
  53   *     array(
  54   *       'header'   => 'Header text for the first header',
  55   *       'name'     => 'Header name for the first header',
  56   *       'elements' => array(
  57   *          element_1,
  58   *          ...
  59   *          element_K1
  60   *       )
  61   *     ),
  62   *     ...
  63   *     array(
  64   *       'header'   => 'Header text for the Mth header',
  65   *       'name'     => 'Header name for the Mth header',
  66   *       'elements' => array(
  67   *          element_1,
  68   *          ...
  69   *          element_KM
  70   *       )
  71   *     )
  72   *   )
  73   * );
  74   *
  75   * where element_i is an array of the form:
  76   * array(
  77   *   'name'      => 'element name',
  78   *   'value'     => 'element value',
  79   *   'type'      => 'type of the element',
  80   *   'frozen'    => 'whether element is frozen',
  81   *   'label'     => 'label for the element',
  82   *   'required'  => 'whether element is required',
  83   *   'error'     => 'error associated with the element',
  84   *   'style'     => 'some information about element style (e.g. for Smarty)',
  85   *   // if element is not a group
  86   *   'html'      => 'HTML for the element'
  87   *   // if element is a group
  88   *   'separator' => 'separator for group elements',
  89   *   'elements'  => array(
  90   *     element_1,
  91   *     ...
  92   *     element_N
  93   *   )
  94   * );
  95   *
  96   * @access public
  97   */
  98  class HTML_QuickForm_Renderer_Array extends HTML_QuickForm_Renderer
  99  {
 100     /**
 101      * An array being generated
 102      * @var array
 103      */
 104      var $_ary;
 105  
 106     /**
 107      * Number of sections in the form (i.e. number of headers in it)
 108      * @var integer
 109      */
 110      var $_sectionCount;
 111  
 112     /**
 113      * Current section number
 114      * @var integer
 115      */
 116      var $_currentSection;
 117  
 118     /**
 119      * Array representing current group
 120      * @var array
 121      */
 122      var $_currentGroup = null;
 123  
 124     /**
 125      * Additional style information for different elements
 126      * @var array
 127      */
 128      var $_elementStyles = array();
 129  
 130     /**
 131      * true: collect all hidden elements into string; false: process them as usual form elements
 132      * @var bool
 133      */
 134      var $_collectHidden = false;
 135  
 136     /**
 137      * true:  render an array of labels to many labels, $key 0 named 'label', the rest "label_$key"
 138      * false: leave labels as defined
 139      * @var bool
 140      */
 141      var $staticLabels = false;
 142  
 143     /**
 144      * Constructor
 145      *
 146      * @param  bool    true: collect all hidden elements into string; false: process them as usual form elements
 147      * @param  bool    true: render an array of labels to many labels, $key 0 to 'label' and the oterh to "label_$key"
 148      * @access public
 149      */
 150      public function __construct($collectHidden = false, $staticLabels = false) {
 151          parent::__construct();
 152          $this->_collectHidden = $collectHidden;
 153          $this->_staticLabels  = $staticLabels;
 154      } // end constructor
 155  
 156      /**
 157       * Old syntax of class constructor. Deprecated in PHP7.
 158       *
 159       * @deprecated since Moodle 3.1
 160       */
 161      public function HTML_QuickForm_Renderer_Array($collectHidden = false, $staticLabels = false) {
 162          debugging('Use of class name as constructor is deprecated', DEBUG_DEVELOPER);
 163          self::__construct($collectHidden, $staticLabels);
 164      }
 165  
 166     /**
 167      * Returns the resultant array
 168      *
 169      * @access public
 170      * @return array
 171      */
 172      function toArray()
 173      {
 174          return $this->_ary;
 175      }
 176  
 177  
 178      function startForm(&$form)
 179      {
 180          $this->_ary = array(
 181              'frozen'            => $form->isFrozen(),
 182              'javascript'        => $form->getValidationScript(),
 183              'attributes'        => $form->getAttributes(true),
 184              'requirednote'      => $form->getRequiredNote(),
 185              'errors'            => array()
 186          );
 187          if ($this->_collectHidden) {
 188              $this->_ary['hidden'] = '';
 189          }
 190          $this->_elementIdx     = 1;
 191          $this->_currentSection = null;
 192          $this->_sectionCount   = 0;
 193      } // end func startForm
 194  
 195  
 196      function renderHeader(&$header)
 197      {
 198          $this->_ary['sections'][$this->_sectionCount] = array(
 199              'header' => $header->toHtml(),
 200              'name'   => $header->getName()
 201          );
 202          $this->_currentSection = $this->_sectionCount++;
 203      } // end func renderHeader
 204  
 205  
 206      function renderElement(&$element, $required, $error)
 207      {
 208          $elAry = $this->_elementToArray($element, $required, $error);
 209          if (!empty($error)) {
 210              $this->_ary['errors'][$elAry['name']] = $error;
 211          }
 212          $this->_storeArray($elAry);
 213      } // end func renderElement
 214  
 215  
 216      function renderHidden(&$element)
 217      {
 218          if ($this->_collectHidden) {
 219              $this->_ary['hidden'] .= $element->toHtml() . "\n";
 220          } else {
 221              $this->renderElement($element, false, null);
 222          }
 223      } // end func renderHidden
 224  
 225  
 226      function startGroup(&$group, $required, $error)
 227      {
 228          $this->_currentGroup = $this->_elementToArray($group, $required, $error);
 229          if (!empty($error)) {
 230              $this->_ary['errors'][$this->_currentGroup['name']] = $error;
 231          }
 232      } // end func startGroup
 233  
 234  
 235      function finishGroup(&$group)
 236      {
 237          $this->_storeArray($this->_currentGroup);
 238          $this->_currentGroup = null;
 239      } // end func finishGroup
 240  
 241  
 242     /**
 243      * Creates an array representing an element
 244      *
 245      * @access private
 246      * @param  object    An HTML_QuickForm_element object
 247      * @param  bool      Whether an element is required
 248      * @param  string    Error associated with the element
 249      * @return array
 250      */
 251      function _elementToArray(&$element, $required, $error)
 252      {
 253          $ret = array(
 254              'name'      => $element->getName(),
 255              'value'     => $element->getValue(),
 256              'type'      => $element->getType(),
 257              'frozen'    => $element->isFrozen(),
 258              'required'  => $required,
 259              'error'     => $error
 260          );
 261          // render label(s)
 262          $labels = $element->getLabel();
 263          if (is_array($labels) && $this->_staticLabels) {
 264              foreach($labels as $key => $label) {
 265                  $key = is_int($key)? $key + 1: $key;
 266                  if (1 === $key) {
 267                      $ret['label'] = $label;
 268                  } else {
 269                      $ret['label_' . $key] = $label;
 270                  }
 271              }
 272          } else {
 273              $ret['label'] = $labels;
 274          }
 275  
 276          // set the style for the element
 277          if (isset($this->_elementStyles[$ret['name']])) {
 278              $ret['style'] = $this->_elementStyles[$ret['name']];
 279          }
 280          if ('group' == $ret['type']) {
 281              $ret['separator'] = $element->_separator;
 282              $ret['elements']  = array();
 283          } else {
 284              $ret['html']      = $element->toHtml();
 285          }
 286          return $ret;
 287      }
 288  
 289  
 290     /**
 291      * Stores an array representation of an element in the form array
 292      *
 293      * @access private
 294      * @param array  Array representation of an element
 295      * @return void
 296      */
 297      function _storeArray($elAry)
 298      {
 299          // where should we put this element...
 300          if (is_array($this->_currentGroup) && ('group' != $elAry['type'])) {
 301              $this->_currentGroup['elements'][] = $elAry;
 302          } elseif (isset($this->_currentSection)) {
 303              $this->_ary['sections'][$this->_currentSection]['elements'][] = $elAry;
 304          } else {
 305              $this->_ary['elements'][] = $elAry;
 306          }
 307      }
 308  
 309  
 310     /**
 311      * Sets a style to use for element rendering
 312      *
 313      * @param mixed      element name or array ('element name' => 'style name')
 314      * @param string     style name if $elementName is not an array
 315      * @access public
 316      * @return void
 317      */
 318      function setElementStyle($elementName, $styleName = null)
 319      {
 320          if (is_array($elementName)) {
 321              $this->_elementStyles = array_merge($this->_elementStyles, $elementName);
 322          } else {
 323              $this->_elementStyles[$elementName] = $styleName;
 324          }
 325      }
 326  }
 327  ?>