Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.10.x will end 8 November 2021 (12 months).
  • Bug fixes for security issues in 3.10.x will end 9 May 2022 (18 months).
  • PHP version: minimum PHP 7.2.0 Note: minimum PHP version has increased since Moodle 3.8. PHP 7.3.x and 7.4.x are supported too.

Differences Between: [Versions 310 and 402] [Versions 310 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  // | Author: Ron McClain <ron@humaniq.com>                                |
  17  // +----------------------------------------------------------------------+
  18  //
  19  // $Id$
  20  
  21  require_once('HTML/QuickForm/Renderer.php');
  22  
  23  /**
  24   * A concrete renderer for HTML_QuickForm, makes an object from form contents
  25   *
  26   * Based on HTML_Quickform_Renderer_Array code
  27   *
  28   * @access public
  29   */
  30  class HTML_QuickForm_Renderer_Object extends HTML_QuickForm_Renderer
  31  {
  32      /**
  33       * The object being generated
  34       * @var object $_obj
  35       */
  36      var $_obj= null;
  37  
  38      /**
  39       * Number of sections in the form (i.e. number of headers in it)
  40       * @var integer $_sectionCount
  41       */
  42      var $_sectionCount;
  43  
  44      /**
  45      * Current section number
  46      * @var integer $_currentSection
  47      */
  48      var $_currentSection;
  49  
  50      /**
  51      * Object representing current group
  52      * @var object $_currentGroup
  53      */
  54      var $_currentGroup = null;
  55  
  56      /**
  57       * Class of Element Objects
  58       * @var object $_elementType
  59       */
  60      var $_elementType = 'QuickFormElement';
  61  
  62      /**
  63      * Additional style information for different elements  
  64      * @var array $_elementStyles
  65      */
  66      var $_elementStyles = array();
  67  
  68      /**
  69      * true: collect all hidden elements into string; false: process them as usual form elements
  70      * @var bool $_collectHidden
  71      */
  72      var $_collectHidden = false;
  73  
  74  
  75      /**
  76       * Constructor
  77       *
  78       * @param collecthidden bool    true: collect all hidden elements
  79       * @access public
  80       */
  81      public function __construct($collecthidden = false) {
  82          parent::__construct();
  83          $this->_collectHidden = $collecthidden;
  84          $this->_obj = new QuickformForm;
  85      }
  86  
  87      /**
  88       * Old syntax of class constructor. Deprecated in PHP7.
  89       *
  90       * @deprecated since Moodle 3.1
  91       */
  92      public function HTML_QuickForm_Renderer_Object($collecthidden = false) {
  93          debugging('Use of class name as constructor is deprecated', DEBUG_DEVELOPER);
  94          self::__construct($collecthidden);
  95      }
  96  
  97      /**
  98       * Return the rendered Object
  99       * @access public
 100       */
 101      function toObject() 
 102      {
 103          return $this->_obj;
 104      }
 105  
 106      /**
 107       * Set the class of the form elements.  Defaults to QuickformElement.
 108       * @param type string   Name of element class
 109       * @access public
 110       */
 111      function setElementType($type)
 112      {
 113          $this->_elementType = $type;
 114      }
 115  
 116      function startForm(&$form) 
 117      {
 118          $this->_obj->frozen = $form->isFrozen();
 119          $this->_obj->javascript = $form->getValidationScript();
 120          $this->_obj->attributes = $form->getAttributes(true);
 121          $this->_obj->requirednote = $form->getRequiredNote();
 122          $this->_obj->errors = new StdClass;
 123  
 124          if($this->_collectHidden) {
 125              $this->_obj->hidden = '';
 126          }
 127          $this->_elementIdx = 1;
 128          $this->_currentSection = null;
 129          $this->_sectionCount = 0;
 130      } // end func startForm
 131  
 132      function renderHeader(&$header) 
 133      {
 134          $hobj = new StdClass;
 135          $hobj->header = $header->toHtml();
 136          $this->_obj->sections[$this->_sectionCount] = $hobj;
 137          $this->_currentSection = $this->_sectionCount++;
 138      }
 139  
 140      function renderElement(&$element, $required, $error) 
 141      {
 142          $elObj = $this->_elementToObject($element, $required, $error);
 143          if(!empty($error)) {
 144              $name = $elObj->name;
 145              $this->_obj->errors->$name = $error;
 146          }
 147          $this->_storeObject($elObj);
 148      } // end func renderElement
 149  
 150      function renderHidden(&$element)
 151      {
 152          if($this->_collectHidden) {
 153              $this->_obj->hidden .= $element->toHtml() . "\n";
 154          } else {
 155              $this->renderElement($element, false, null);
 156          }
 157      } //end func renderHidden
 158  
 159      function startGroup(&$group, $required, $error) 
 160      {
 161          $this->_currentGroup = $this->_elementToObject($group, $required, $error);
 162          if(!empty($error)) {
 163              $name = $this->_currentGroup->name;
 164              $this->_obj->errors->$name = $error;
 165          }
 166      } // end func startGroup
 167  
 168      function finishGroup(&$group) 
 169      {
 170          $this->_storeObject($this->_currentGroup);
 171          $this->_currentGroup = null;
 172      } // end func finishGroup
 173  
 174      /**
 175       * Creates an object representing an element
 176       *
 177       * @access private
 178       * @param element object    An HTML_QuickForm_element object
 179       * @param required bool         Whether an element is required
 180       * @param error string    Error associated with the element
 181       * @return object
 182       */
 183      function _elementToObject(&$element, $required, $error) 
 184      {
 185          if($this->_elementType) {
 186              $ret = new $this->_elementType;
 187          }
 188          $ret->name = $element->getName();
 189          $ret->value = $element->getValue();
 190          $ret->type = $element->getType();
 191          $ret->frozen = $element->isFrozen();
 192          $labels = $element->getLabel();
 193          if (is_array($labels)) {
 194              $ret->label = array_shift($labels);
 195              foreach ($labels as $key => $label) {
 196                  $key = is_int($key)? $key + 2: $key;
 197                  $ret->{'label_' . $key} = $label;
 198              }
 199          } else {
 200              $ret->label = $labels;
 201          }
 202          $ret->required = $required;
 203          $ret->error = $error;
 204  
 205          if(isset($this->_elementStyles[$ret->name])) {
 206              $ret->style = $this->_elementStyles[$ret->name];
 207              $ret->styleTemplate = "styles/". $ret->style .".html";
 208          }
 209          if($ret->type == 'group') {
 210              $ret->separator = $element->_separator;
 211              $ret->elements = array();
 212          } else {
 213              $ret->html = $element->toHtml();
 214          }
 215          return $ret;
 216      }
 217  
 218      /** 
 219       * Stores an object representation of an element in the form array
 220       *
 221       * @access private
 222       * @param elObj object     Object representation of an element
 223       * @return void
 224       */
 225      function _storeObject($elObj) 
 226      {
 227          $name = $elObj->name;
 228          if(is_object($this->_currentGroup) && $elObj->type != 'group') {
 229              $this->_currentGroup->elements[] = $elObj;
 230          } elseif (isset($this->_currentSection)) {
 231              $this->_obj->sections[$this->_currentSection]->elements[] = $elObj;
 232          } else {
 233              $this->_obj->elements[] = $elObj;
 234          }
 235      }
 236  
 237      function setElementStyle($elementName, $styleName = null)
 238      {
 239          if(is_array($elementName)) {
 240              $this->_elementStyles = array_merge($this->_elementStyles, $elementName);
 241          } else {
 242              $this->_elementStyles[$elementName] = $styleName;
 243          }
 244      }
 245  
 246  } // end class HTML_QuickForm_Renderer_Object
 247  
 248  
 249  
 250  /**
 251   * Convenience class for the form object passed to outputObject()
 252   * 
 253   * Eg.  
 254   * {form.outputJavaScript():h}
 255   * {form.outputHeader():h}
 256   *   <table>
 257   *     <tr>
 258   *       <td>{form.name.label:h}</td><td>{form.name.html:h}</td>
 259   *     </tr>
 260   *   </table>
 261   * </form>
 262   */
 263  class QuickformForm
 264  {
 265     /**
 266      * Whether the form has been frozen
 267      * @var boolean $frozen
 268      */
 269      var $frozen;
 270  
 271     /**
 272      * Javascript for client-side validation
 273      * @var string $javascript
 274      */
 275      var $javascript;
 276  
 277     /**
 278      * Attributes for form tag
 279      * @var string $attributes
 280      */
 281      var $attributes;
 282  
 283     /**
 284      * Note about required elements
 285      * @var string $requirednote
 286      */
 287      var $requirednote;
 288  
 289     /**
 290      * Collected html of all hidden variables
 291      * @var string $hidden
 292      */
 293      var $hidden;
 294  
 295     /**
 296      * Set if there were validation errors.  
 297      * StdClass object with element names for keys and their
 298      * error messages as values
 299      * @var object $errors
 300      */
 301      var $errors;
 302  
 303     /**
 304      * Array of QuickformElementObject elements.  If there are headers in the form
 305      * this will be empty and the elements will be in the 
 306      * separate sections
 307      * @var array $elements
 308      */
 309      var $elements;
 310  
 311     /**
 312      * Array of sections contained in the document
 313      * @var array $sections
 314      */
 315      var $sections;
 316  
 317     /**
 318      * Output &lt;form&gt; header
 319      * {form.outputHeader():h} 
 320      * @return string    &lt;form attributes&gt;
 321      */
 322      function outputHeader()
 323      {
 324          return "<form " . $this->attributes . ">\n";
 325      }
 326  
 327     /**
 328      * Output form javascript
 329      * {form.outputJavaScript():h}
 330      * @return string    Javascript
 331      */
 332      function outputJavaScript()
 333      {
 334          return $this->javascript;
 335      }
 336  } // end class QuickformForm
 337  
 338  
 339  /**
 340   * Convenience class describing a form element.
 341   * The properties defined here will be available from 
 342   * your flexy templates by referencing
 343   * {form.zip.label:h}, {form.zip.html:h}, etc.
 344   */
 345  class QuickformElement
 346  {
 347      /**
 348       * Element name
 349       * @var string $name
 350       */
 351      var $name;
 352  
 353      /**
 354       * Element value
 355       * @var mixed $value
 356       */
 357      var $value;
 358  
 359      /**
 360       * Type of element
 361       * @var string $type
 362       */
 363      var $type;
 364  
 365      /**
 366       * Whether the element is frozen
 367       * @var boolean $frozen
 368       */
 369      var $frozen;
 370  
 371      /**
 372       * Label for the element
 373       * @var string $label
 374       */
 375      var $label;
 376  
 377      /**
 378       * Whether element is required
 379       * @var boolean $required
 380       */
 381      var $required;
 382  
 383      /**
 384       * Error associated with the element
 385       * @var string $error
 386       */
 387      var $error;
 388  
 389      /**
 390       * Some information about element style
 391       * @var string $style
 392       */
 393      var $style;
 394  
 395      /**
 396       * HTML for the element
 397       * @var string $html
 398       */
 399      var $html;
 400  
 401      /**
 402       * If element is a group, the group separator
 403       * @var mixed $separator
 404       */
 405      var $separator;
 406  
 407      /**
 408       * If element is a group, an array of subelements
 409       * @var array $elements
 410       */
 411      var $elements;
 412  
 413      function isType($type)
 414      {
 415          return ($this->type == $type);
 416      }
 417  
 418      function notFrozen()
 419      {
 420          return !$this->frozen;
 421      }
 422  
 423      function isButton()
 424      {
 425          return ($this->type == "submit" || $this->type == "reset");
 426      }
 427  
 428  
 429     /**
 430      * XXX: why does it use Flexy when all other stuff here does not depend on it?
 431      */
 432      function outputStyle()
 433      {
 434          ob_start();
 435          HTML_Template_Flexy::staticQuickTemplate('styles/' . $this->style . '.html', $this);
 436          $ret = ob_get_contents();
 437          ob_end_clean();
 438          return $ret;
 439      }
 440  } // end class QuickformElement
 441  ?>