Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.

Differences Between: [Versions 310 and 401] [Versions 39 and 401]

   1  <?php
   2  
   3  /**
   4   * XHTML 1.1 Forms module, defines all form-related elements found in HTML 4.
   5   */
   6  class HTMLPurifier_HTMLModule_Forms extends HTMLPurifier_HTMLModule
   7  {
   8      /**
   9       * @type string
  10       */
  11      public $name = 'Forms';
  12  
  13      /**
  14       * @type bool
  15       */
  16      public $safe = false;
  17  
  18      /**
  19       * @type array
  20       */
  21      public $content_sets = array(
  22          'Block' => 'Form',
  23          'Inline' => 'Formctrl',
  24      );
  25  
  26      /**
  27       * @param HTMLPurifier_Config $config
  28       */
  29      public function setup($config)
  30      {
  31          if ($config->get('HTML.Forms')) {
  32              $this->safe = true;
  33          }
  34  
  35          $form = $this->addElement(
  36              'form',
  37              'Form',
  38              'Required: Heading | List | Block | fieldset',
  39              'Common',
  40              array(
  41                  'accept' => 'ContentTypes',
  42                  'accept-charset' => 'Charsets',
  43                  'action*' => 'URI',
  44                  'method' => 'Enum#get,post',
  45                  // really ContentType, but these two are the only ones used today
  46                  'enctype' => 'Enum#application/x-www-form-urlencoded,multipart/form-data',
  47              )
  48          );
  49          $form->excludes = array('form' => true);
  50  
  51          $input = $this->addElement(
  52              'input',
  53              'Formctrl',
  54              'Empty',
  55              'Common',
  56              array(
  57                  'accept' => 'ContentTypes',
  58                  'accesskey' => 'Character',
  59                  'alt' => 'Text',
  60                  'checked' => 'Bool#checked',
  61                  'disabled' => 'Bool#disabled',
  62                  'maxlength' => 'Number',
  63                  'name' => 'CDATA',
  64                  'readonly' => 'Bool#readonly',
  65                  'size' => 'Number',
  66                  'src' => 'URI#embedded',
  67                  'tabindex' => 'Number',
  68                  'type' => 'Enum#text,password,checkbox,button,radio,submit,reset,file,hidden,image',
  69                  'value' => 'CDATA',
  70              )
  71          );
  72          $input->attr_transform_post[] = new HTMLPurifier_AttrTransform_Input();
  73  
  74          $this->addElement(
  75              'select',
  76              'Formctrl',
  77              'Required: optgroup | option',
  78              'Common',
  79              array(
  80                  'disabled' => 'Bool#disabled',
  81                  'multiple' => 'Bool#multiple',
  82                  'name' => 'CDATA',
  83                  'size' => 'Number',
  84                  'tabindex' => 'Number',
  85              )
  86          );
  87  
  88          $this->addElement(
  89              'option',
  90              false,
  91              'Optional: #PCDATA',
  92              'Common',
  93              array(
  94                  'disabled' => 'Bool#disabled',
  95                  'label' => 'Text',
  96                  'selected' => 'Bool#selected',
  97                  'value' => 'CDATA',
  98              )
  99          );
 100          // It's illegal for there to be more than one selected, but not
 101          // be multiple. Also, no selected means undefined behavior. This might
 102          // be difficult to implement; perhaps an injector, or a context variable.
 103  
 104          $textarea = $this->addElement(
 105              'textarea',
 106              'Formctrl',
 107              'Optional: #PCDATA',
 108              'Common',
 109              array(
 110                  'accesskey' => 'Character',
 111                  'cols*' => 'Number',
 112                  'disabled' => 'Bool#disabled',
 113                  'name' => 'CDATA',
 114                  'readonly' => 'Bool#readonly',
 115                  'rows*' => 'Number',
 116                  'tabindex' => 'Number',
 117              )
 118          );
 119          $textarea->attr_transform_pre[] = new HTMLPurifier_AttrTransform_Textarea();
 120  
 121          $button = $this->addElement(
 122              'button',
 123              'Formctrl',
 124              'Optional: #PCDATA | Heading | List | Block | Inline',
 125              'Common',
 126              array(
 127                  'accesskey' => 'Character',
 128                  'disabled' => 'Bool#disabled',
 129                  'name' => 'CDATA',
 130                  'tabindex' => 'Number',
 131                  'type' => 'Enum#button,submit,reset',
 132                  'value' => 'CDATA',
 133              )
 134          );
 135  
 136          // For exclusions, ideally we'd specify content sets, not literal elements
 137          $button->excludes = $this->makeLookup(
 138              'form',
 139              'fieldset', // Form
 140              'input',
 141              'select',
 142              'textarea',
 143              'label',
 144              'button', // Formctrl
 145              'a', // as per HTML 4.01 spec, this is omitted by modularization
 146              'isindex',
 147              'iframe' // legacy items
 148          );
 149  
 150          // Extra exclusion: img usemap="" is not permitted within this element.
 151          // We'll omit this for now, since we don't have any good way of
 152          // indicating it yet.
 153  
 154          // This is HIGHLY user-unfriendly; we need a custom child-def for this
 155          $this->addElement('fieldset', 'Form', 'Custom: (#WS?,legend,(Flow|#PCDATA)*)', 'Common');
 156  
 157          $label = $this->addElement(
 158              'label',
 159              'Formctrl',
 160              'Optional: #PCDATA | Inline',
 161              'Common',
 162              array(
 163                  'accesskey' => 'Character',
 164                  // 'for' => 'IDREF', // IDREF not implemented, cannot allow
 165              )
 166          );
 167          $label->excludes = array('label' => true);
 168  
 169          $this->addElement(
 170              'legend',
 171              false,
 172              'Optional: #PCDATA | Inline',
 173              'Common',
 174              array(
 175                  'accesskey' => 'Character',
 176              )
 177          );
 178  
 179          $this->addElement(
 180              'optgroup',
 181              false,
 182              'Required: option',
 183              'Common',
 184              array(
 185                  'disabled' => 'Bool#disabled',
 186                  'label*' => 'Text',
 187              )
 188          );
 189          // Don't forget an injector for <isindex>. This one's a little complex
 190          // because it maps to multiple elements.
 191      }
 192  }
 193  
 194  // vim: et sw=4 sts=4