Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.3.x will end 7 October 2024 (12 months).
  • Bug fixes for security issues in 4.3.x will end 21 April 2025 (18 months).
  • PHP version: minimum PHP 8.0.0 Note: minimum PHP version has increased since Moodle 4.1. PHP 8.2.x is supported too.

Differences Between: [Versions 310 and 403] [Versions 311 and 403] [Versions 39 and 403] [Versions 400 and 403] [Versions 401 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->_currentSection = null;
 128          $this->_sectionCount = 0;
 129      } // end func startForm
 130  
 131      function renderHeader(&$header) 
 132      {
 133          $hobj = new StdClass;
 134          $hobj->header = $header->toHtml();
 135          $this->_obj->sections[$this->_sectionCount] = $hobj;
 136          $this->_currentSection = $this->_sectionCount++;
 137      }
 138  
 139      function renderElement(&$element, $required, $error) 
 140      {
 141          $elObj = $this->_elementToObject($element, $required, $error);
 142          if(!empty($error)) {
 143              $name = $elObj->name;
 144              $this->_obj->errors->$name = $error;
 145          }
 146          $this->_storeObject($elObj);
 147      } // end func renderElement
 148  
 149      function renderHidden(&$element)
 150      {
 151          if($this->_collectHidden) {
 152              $this->_obj->hidden .= $element->toHtml() . "\n";
 153          } else {
 154              $this->renderElement($element, false, null);
 155          }
 156      } //end func renderHidden
 157  
 158      function startGroup(&$group, $required, $error) 
 159      {
 160          $this->_currentGroup = $this->_elementToObject($group, $required, $error);
 161          if(!empty($error)) {
 162              $name = $this->_currentGroup->name;
 163              $this->_obj->errors->$name = $error;
 164          }
 165      } // end func startGroup
 166  
 167      function finishGroup(&$group) 
 168      {
 169          $this->_storeObject($this->_currentGroup);
 170          $this->_currentGroup = null;
 171      } // end func finishGroup
 172  
 173      /**
 174       * Creates an object representing an element
 175       *
 176       * @access private
 177       * @param element object    An HTML_QuickForm_element object
 178       * @param required bool         Whether an element is required
 179       * @param error string    Error associated with the element
 180       * @return object
 181       */
 182      function _elementToObject(&$element, $required, $error) 
 183      {
 184          if($this->_elementType) {
 185              $ret = new $this->_elementType;
 186          }
 187          $ret->name = $element->getName();
 188          $ret->value = $element->getValue();
 189          $ret->type = $element->getType();
 190          $ret->frozen = $element->isFrozen();
 191          $labels = $element->getLabel();
 192          if (is_array($labels)) {
 193              $ret->label = array_shift($labels);
 194              foreach ($labels as $key => $label) {
 195                  $key = is_int($key)? $key + 2: $key;
 196                  $ret->{'label_' . $key} = $label;
 197              }
 198          } else {
 199              $ret->label = $labels;
 200          }
 201          $ret->required = $required;
 202          $ret->error = $error;
 203  
 204          if(isset($this->_elementStyles[$ret->name])) {
 205              $ret->style = $this->_elementStyles[$ret->name];
 206              $ret->styleTemplate = "styles/". $ret->style .".html";
 207          }
 208          if($ret->type == 'group') {
 209              $ret->separator = $element->_separator;
 210              $ret->elements = array();
 211          } else {
 212              $ret->html = $element->toHtml();
 213          }
 214          return $ret;
 215      }
 216  
 217      /** 
 218       * Stores an object representation of an element in the form array
 219       *
 220       * @access private
 221       * @param elObj object     Object representation of an element
 222       * @return void
 223       */
 224      function _storeObject($elObj) 
 225      {
 226          $name = $elObj->name;
 227          if(is_object($this->_currentGroup) && $elObj->type != 'group') {
 228              $this->_currentGroup->elements[] = $elObj;
 229          } elseif (isset($this->_currentSection)) {
 230              $this->_obj->sections[$this->_currentSection]->elements[] = $elObj;
 231          } else {
 232              $this->_obj->elements[] = $elObj;
 233          }
 234      }
 235  
 236      function setElementStyle($elementName, $styleName = null)
 237      {
 238          if(is_array($elementName)) {
 239              $this->_elementStyles = array_merge($this->_elementStyles, $elementName);
 240          } else {
 241              $this->_elementStyles[$elementName] = $styleName;
 242          }
 243      }
 244  
 245  } // end class HTML_QuickForm_Renderer_Object
 246  
 247  
 248  
 249  /**
 250   * Convenience class for the form object passed to outputObject()
 251   * 
 252   * Eg.  
 253   * {form.outputJavaScript():h}
 254   * {form.outputHeader():h}
 255   *   <table>
 256   *     <tr>
 257   *       <td>{form.name.label:h}</td><td>{form.name.html:h}</td>
 258   *     </tr>
 259   *   </table>
 260   * </form>
 261   */
 262  class QuickformForm
 263  {
 264     /**
 265      * Whether the form has been frozen
 266      * @var boolean $frozen
 267      */
 268      var $frozen;
 269  
 270     /**
 271      * Javascript for client-side validation
 272      * @var string $javascript
 273      */
 274      var $javascript;
 275  
 276     /**
 277      * Attributes for form tag
 278      * @var string $attributes
 279      */
 280      var $attributes;
 281  
 282     /**
 283      * Note about required elements
 284      * @var string $requirednote
 285      */
 286      var $requirednote;
 287  
 288     /**
 289      * Collected html of all hidden variables
 290      * @var string $hidden
 291      */
 292      var $hidden;
 293  
 294     /**
 295      * Set if there were validation errors.  
 296      * StdClass object with element names for keys and their
 297      * error messages as values
 298      * @var object $errors
 299      */
 300      var $errors;
 301  
 302     /**
 303      * Array of QuickformElementObject elements.  If there are headers in the form
 304      * this will be empty and the elements will be in the 
 305      * separate sections
 306      * @var array $elements
 307      */
 308      var $elements;
 309  
 310     /**
 311      * Array of sections contained in the document
 312      * @var array $sections
 313      */
 314      var $sections;
 315  
 316     /**
 317      * Output &lt;form&gt; header
 318      * {form.outputHeader():h} 
 319      * @return string    &lt;form attributes&gt;
 320      */
 321      function outputHeader()
 322      {
 323          return "<form " . $this->attributes . ">\n";
 324      }
 325  
 326     /**
 327      * Output form javascript
 328      * {form.outputJavaScript():h}
 329      * @return string    Javascript
 330      */
 331      function outputJavaScript()
 332      {
 333          return $this->javascript;
 334      }
 335  } // end class QuickformForm
 336  
 337  
 338  /**
 339   * Convenience class describing a form element.
 340   * The properties defined here will be available from 
 341   * your flexy templates by referencing
 342   * {form.zip.label:h}, {form.zip.html:h}, etc.
 343   */
 344  class QuickformElement
 345  {
 346      /**
 347       * Element name
 348       * @var string $name
 349       */
 350      var $name;
 351  
 352      /**
 353       * Element value
 354       * @var mixed $value
 355       */
 356      var $value;
 357  
 358      /**
 359       * Type of element
 360       * @var string $type
 361       */
 362      var $type;
 363  
 364      /**
 365       * Whether the element is frozen
 366       * @var boolean $frozen
 367       */
 368      var $frozen;
 369  
 370      /**
 371       * Label for the element
 372       * @var string $label
 373       */
 374      var $label;
 375  
 376      /**
 377       * Whether element is required
 378       * @var boolean $required
 379       */
 380      var $required;
 381  
 382      /**
 383       * Error associated with the element
 384       * @var string $error
 385       */
 386      var $error;
 387  
 388      /**
 389       * Some information about element style
 390       * @var string $style
 391       */
 392      var $style;
 393  
 394      /**
 395       * HTML for the element
 396       * @var string $html
 397       */
 398      var $html;
 399  
 400      /**
 401       * If element is a group, the group separator
 402       * @var mixed $separator
 403       */
 404      var $separator;
 405  
 406      /**
 407       * If element is a group, an array of subelements
 408       * @var array $elements
 409       */
 410      var $elements;
 411  
 412      function isType($type)
 413      {
 414          return ($this->type == $type);
 415      }
 416  
 417      function notFrozen()
 418      {
 419          return !$this->frozen;
 420      }
 421  
 422      function isButton()
 423      {
 424          return ($this->type == "submit" || $this->type == "reset");
 425      }
 426  
 427  
 428     /**
 429      * XXX: why does it use Flexy when all other stuff here does not depend on it?
 430      */
 431      function outputStyle()
 432      {
 433          ob_start();
 434          HTML_Template_Flexy::staticQuickTemplate('styles/' . $this->style . '.html', $this);
 435          $ret = ob_get_contents();
 436          ob_end_clean();
 437          return $ret;
 438      }
 439  } // end class QuickformElement
 440  ?>