[ Index ]

PHP Cross Reference of DokuWiki

title

Body

[close]

/inc/ -> form.php (source)

   1  <?php
   2  /**
   3   * DokuWiki XHTML Form
   4   *
   5   * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
   6   * @author     Tom N Harris <tnharris@whoopdedo.org>
   7   */
   8  
   9  if(!defined('DOKU_INC')) define('DOKU_INC',fullpath(dirname(__FILE__).'/../').'/');
  10  if(!defined('NL')) define('NL',"\n");
  11  require_once (DOKU_INC.'inc/html.php');
  12  
  13  /**
  14   * Class for creating simple HTML forms.
  15   *
  16   * The forms is built from a list of pseudo-tags (arrays with expected keys).
  17   * Every pseudo-tag must have the key '_elem' set to the name of the element.
  18   * When printed, the form class calls functions named 'form_$type' for each
  19   * element it contains.
  20   *
  21   * Standard practice is for non-attribute keys in a pseudo-element to start
  22   * with '_'. Other keys are HTML attributes that will be included in the element
  23   * tag. That way, the element output functions can pass the pseudo-element
  24   * directly to buildAttributes.
  25   *
  26   * See the form_make* functions later in this file.
  27   *
  28   * @author Tom N Harris <tnharris@whoopdedo.org>
  29   */
  30  class Doku_Form {
  31  
  32    // Usually either DOKU_SCRIPT or wl($ID)
  33    var $action = '';
  34  
  35    // Most likely no need to change this
  36    var $method = 'post';
  37  
  38    // Change for special forms only
  39    var $enctype = '';
  40  
  41    // Form id attribute
  42    var $id = '';
  43  
  44    // Draw a border around form fields.
  45    // Adds <fieldset></fieldset> around the elements
  46    var $_infieldset = false;
  47  
  48    // Hidden form fields.
  49    var $_hidden = array();
  50  
  51    // Array of pseudo-tags
  52    var $_content = array();
  53  
  54    /**
  55     * Constructor
  56     *
  57     * Autoadds a security token
  58     *
  59     * @param   string  $id     ID attribute of the form.
  60     * @param   string  $action (optional) submit URL, defaults to DOKU_SCRIPT
  61     * @param   string  $method (optional) 'POST' or 'GET', default is post
  62     * @author  Tom N Harris <tnharris@whoopdedo.org>
  63     */
  64    function Doku_Form($id, $action=false, $method=false, $enctype=false) {
  65      $this->id = $id;
  66      $this->action = ($action) ? $action : script();
  67      if ($method) $this->method = $method;
  68      if ($enctype) $this->enctype = $enctype;
  69  
  70      $this->addHidden('sectok', getSecurityToken());
  71    }
  72  
  73    /**
  74     * startFieldset
  75     *
  76     * Add <fieldset></fieldset> tags around fields.
  77     * Usually results in a border drawn around the form.
  78     *
  79     * @param   string  $legend Label that will be printed with the border.
  80     * @author  Tom N Harris <tnharris@whoopdedo.org>
  81     */
  82    function startFieldset($legend) {
  83      if ($this->_infieldset) {
  84        $this->addElement(array('_elem'=>'closefieldset'));
  85      }
  86      $this->addElement(array('_elem'=>'openfieldset', '_legend'=>$legend));
  87      $this->_infieldset = true;
  88    }
  89  
  90    /**
  91     * endFieldset
  92     *
  93     * @author  Tom N Harris <tnharris@whoopdedo.org>
  94     */
  95    function endFieldset() {
  96      if ($this->_infieldset) {
  97        $this->addElement(array('_elem'=>'closefieldset'));
  98      }
  99      $this->_infieldset = false;
 100    }
 101  
 102    /**
 103     * addHidden
 104     *
 105     * Adds a name/value pair as a hidden field.
 106     * The value of the field (but not the name) will be passed to
 107     * formText() before printing.
 108     *
 109     * @param   string  $name   Field name.
 110     * @param   string  $value  Field value. If null, remove a previously added field.
 111     * @author  Tom N Harris <tnharris@whoopdedo.org>
 112     */
 113    function addHidden($name, $value) {
 114      if (is_null($value))
 115        unset($this->_hidden[$name]);
 116      else
 117        $this->_hidden[$name] = $value;
 118    }
 119  
 120    /**
 121     * addElement
 122     *
 123     * Appends a content element to the form.
 124     * The element can be either a pseudo-tag or string.
 125     * If string, it is printed without escaping special chars.   *
 126     *
 127     * @param   string  $elem   Pseudo-tag or string to add to the form.
 128     * @author  Tom N Harris <tnharris@whoopdedo.org>
 129     */
 130    function addElement($elem) {
 131      $this->_content[] = $elem;
 132    }
 133  
 134    /**
 135     * insertElement
 136     *
 137     * Inserts a content element at a position.
 138     *
 139     * @param   string  $pos    0-based index where the element will be inserted.
 140     * @param   string  $elem   Pseudo-tag or string to add to the form.
 141     * @author  Tom N Harris <tnharris@whoopdedo.org>
 142     */
 143    function insertElement($pos, $elem) {
 144      array_splice($this->_content, $pos, 0, array($elem));
 145    }
 146  
 147    /**
 148     * replaceElement
 149     *
 150     * Replace with NULL to remove an element.
 151     *
 152     * @param   int     $pos    0-based index the element will be placed at.
 153     * @param   string  $elem   Pseudo-tag or string to add to the form.
 154     * @author  Tom N Harris <tnharris@whoopdedo.org>
 155     */
 156    function replaceElement($pos, $elem) {
 157      $rep = array();
 158      if (!is_null($elem)) $rep[] = $elem;
 159      array_splice($this->_content, $pos, 1, $rep);
 160    }
 161  
 162    /**
 163     * findElementByType
 164     *
 165     * Gets the position of the first of a type of element.
 166     *
 167     * @param   string  $type   Element type to look for.
 168     * @return  array   pseudo-element if found, false otherwise
 169     * @author  Tom N Harris <tnharris@whoopdedo.org>
 170     */
 171    function findElementByType($type) {
 172      foreach ($this->_content as $pos=>$elem) {
 173        if (is_array($elem) && $elem['_elem'] == $type)
 174          return $pos;
 175      }
 176      return false;
 177    }
 178  
 179    /**
 180     * findElementById
 181     *
 182     * Gets the position of the element with an ID attribute.
 183     *
 184     * @param   string  $id     ID of the element to find.
 185     * @return  array   pseudo-element if found, false otherwise
 186     * @author  Tom N Harris <tnharris@whoopdedo.org>
 187     */
 188    function findElementById($id) {
 189      foreach ($this->_content as $pos=>$elem) {
 190        if (is_array($elem) && isset($elem['id']) && $elem['id'] == $id)
 191          return $pos;
 192      }
 193      return false;
 194    }
 195  
 196    /**
 197     * findElementByAttribute
 198     *
 199     * Gets the position of the first element with a matching attribute value.
 200     *
 201     * @param   string  $name   Attribute name.
 202     * @param   string  $value  Attribute value.
 203     * @return  array   pseudo-element if found, false otherwise
 204     * @author  Tom N Harris <tnharris@whoopdedo.org>
 205     */
 206    function findElementByAttribute($name, $value) {
 207      foreach ($this->_content as $pos=>$elem) {
 208        if (is_array($elem) && isset($elem[$name]) && $elem[$name] == $value)
 209          return $pos;
 210      }
 211      return false;
 212    }
 213  
 214    /**
 215     * getElementAt
 216     *
 217     * Returns a reference to the element at a position.
 218     * A position out-of-bounds will return either the
 219     * first (underflow) or last (overflow) element.
 220     *
 221     * @param   int     $pos    0-based index
 222     * @return  arrayreference  pseudo-element
 223     * @author  Tom N Harris <tnharris@whoopdedo.org>
 224     */
 225    function &getElementAt($pos) {
 226      if ($pos < 0) $pos = count($this->_content) + $pos;
 227      if ($pos < 0) $pos = 0;
 228      if ($pos >= count($this->_content)) $pos = count($this->_content) - 1;
 229      return $this->_content[$pos];
 230    }
 231  
 232    /**
 233     * printForm
 234     *
 235     * Output the form.
 236     * Each element in the form will be passed to a function named
 237     * 'form_$type'. The function should return the HTML to be printed.
 238     *
 239     * @author  Tom N Harris <tnharris@whoopdedo.org>
 240     */
 241    function printForm() {
 242      global $lang;
 243      print '<form action="'.$this->action.'" method="'.$this->method.'" accept-charset="'.$lang['encoding'].'"';
 244      if (!empty($this->id)) print ' id="'.$this->id.'"';
 245      if (!empty($this->enctype)) print ' enctype="'.$this->enctype.'"';
 246      print '>'.NL;
 247      if (!empty($this->_hidden)) {
 248        print '<div class="no">';
 249        foreach ($this->_hidden as $name=>$value)
 250          print form_hidden(array('name'=>$name, 'value'=>$value));
 251        print '</div>'.NL;
 252      }
 253      foreach ($this->_content as $element) {
 254        if (is_array($element)) {
 255          $elem_type = $element['_elem'];
 256          if (function_exists('form_'.$elem_type)) {
 257            print call_user_func('form_'.$elem_type, $element).NL;
 258          }
 259        } else {
 260          print $element;
 261        }
 262      }
 263      if ($this->_infieldset) print form_closefieldset().NL;
 264      print '</form>'.NL;
 265    }
 266  
 267  }
 268  
 269  /**
 270   * form_makeTag
 271   *
 272   * Create a form element for a non-specific empty tag.
 273   *
 274   * @param   string  $tag    Tag name.
 275   * @param   array   $attrs  Optional attributes.
 276   * @return  array   pseudo-tag
 277   * @author  Tom N Harris <tnharris@whoopdedo.org>
 278   */
 279  function form_makeTag($tag, $attrs=array()) {
 280    $elem = array('_elem'=>'tag', '_tag'=>$tag);
 281    return array_merge($elem, $attrs);
 282  }
 283  
 284  /**
 285   * form_makeOpenTag
 286   *
 287   * Create a form element for a non-specific opening tag.
 288   * Remember to put a matching close tag after this as well.
 289   *
 290   * @param   string  $tag    Tag name.
 291   * @param   array   $attrs  Optional attributes.
 292   * @return  array   pseudo-tag
 293   * @author  Tom N Harris <tnharris@whoopdedo.org>
 294   */
 295  function form_makeOpenTag($tag, $attrs=array()) {
 296    $elem = array('_elem'=>'opentag', '_tag'=>$tag);
 297    return array_merge($elem, $attrs);
 298  }
 299  
 300  /**
 301   * form_makeCloseTag
 302   *
 303   * Create a form element for a non-specific closing tag.
 304   * Careless use of this will result in invalid XHTML.
 305   *
 306   * @param   string  $tag    Tag name.
 307   * @return  array   pseudo-tag
 308   * @author  Tom N Harris <tnharris@whoopdedo.org>
 309   */
 310  function form_makeCloseTag($tag) {
 311    return array('_elem'=>'closetag', '_tag'=>$tag);
 312  }
 313  
 314  /**
 315   * form_makeWikiText
 316   *
 317   * Create a form element for a textarea containing wiki text.
 318   * Only one wikitext element is allowed on a page. It will have
 319   * a name of 'wikitext' and id 'wiki__text'. The text will
 320   * be passed to formText() before printing.
 321   *
 322   * @param   string  $text   Text to fill the field with.
 323   * @param   array   $attrs  Optional attributes.
 324   * @return  array   pseudo-tag
 325   * @author  Tom N Harris <tnharris@whoopdedo.org>
 326   */
 327  function form_makeWikiText($text, $attrs=array()) {
 328    $elem = array('_elem'=>'wikitext', '_text'=>$text,
 329                  'class'=>'edit', 'cols'=>'80', 'rows'=>'10');
 330    return array_merge($elem, $attrs);
 331  }
 332  
 333  /**
 334   * form_makeButton
 335   *
 336   * Create a form element for an action button.
 337   * A title will automatically be generated using the value and
 338   * accesskey attributes, unless you provide one.
 339   *
 340   * @param   string  $type   Type attribute. 'submit' or 'cancel'
 341   * @param   string  $act    Wiki action of the button, will be used as the do= parameter
 342   * @param   string  $value  (optional) Displayed label. Uses $act if not provided.
 343   * @param   array   $attrs  Optional attributes.
 344   * @return  array   pseudo-tag
 345   * @author  Tom N Harris <tnharris@whoopdedo.org>
 346   */
 347  function form_makeButton($type, $act, $value='', $attrs=array()) {
 348    if ($value == '') $value = $act;
 349    //$name = (!empty($act)) ? 'do[$act]' : null;
 350    $elem = array('_elem'=>'button', 'type'=>$type, '_action'=>$act, 
 351                  'value'=>$value, 'class'=>'button');
 352    if (!empty($attrs['accesskey']) && empty($attrs['title'])) {
 353      $attrs['title'] = $value . ' ['.strtoupper($attrs['accesskey']).']';
 354    }
 355    return array_merge($elem, $attrs);
 356  }
 357  
 358  /**
 359   * form_makeField
 360   *
 361   * Create a form element for a labelled input element.
 362   * The label text will be printed before the input.
 363   *
 364   * @param   string  $type   Type attribute of input.
 365   * @param   string  $name   Name attribute of the input.
 366   * @param   string  $value  (optional) Default value.
 367   * @param   string  $class  Class attribute of the label. If this is 'block',
 368   *                          then a line break will be added after the field.
 369   * @param   string  $label  Label that will be printed before the input.
 370   * @param   string  $id     ID attribute of the input. If set, the label will
 371   *                          reference it with a 'for' attribute.
 372   * @param   array   $attrs  Optional attributes.
 373   * @return  array   pseudo-tag
 374   * @author  Tom N Harris <tnharris@whoopdedo.org>
 375   */
 376  function form_makeField($type, $name, $value='', $label=null, $id='', $class='', $attrs=array()) {
 377    if (is_null($label)) $label = $name;
 378    $elem = array('_elem'=>'field', '_text'=>$label, '_class'=>$class,
 379                  'type'=>$type, 'id'=>$id, 'name'=>$name, 'value'=>$value);
 380    return array_merge($elem, $attrs);
 381  }
 382  
 383  /**
 384   * form_makeFieldRight
 385   *
 386   * Create a form element for a labelled input element.
 387   * The label text will be printed after the input.
 388   *
 389   * @see     form_makeField
 390   * @author  Tom N Harris <tnharris@whoopdedo.org>
 391   */
 392  function form_makeFieldRight($type, $name, $value='', $label=null, $id='', $class='', $attrs=array()) {
 393    if (is_null($label)) $label = $name;
 394    $elem = array('_elem'=>'fieldright', '_text'=>$label, '_class'=>$class,
 395                  'type'=>$type, 'id'=>$id, 'name'=>$name, 'value'=>$value);
 396    return array_merge($elem, $attrs);
 397  }
 398  
 399  /**
 400   * form_makeTextField
 401   *
 402   * Create a form element for a text input element with label.
 403   *
 404   * @see     form_makeField
 405   * @author  Tom N Harris <tnharris@whoopdedo.org>
 406   */
 407  function form_makeTextField($name, $value='', $label=null, $id='', $class='', $attrs=array()) {
 408    if (is_null($label)) $label = $name;
 409    $elem = array('_elem'=>'textfield', '_text'=>$label, '_class'=>$class,
 410                  'id'=>$id, 'name'=>$name, 'value'=>$value, 'class'=>'edit');
 411    return array_merge($elem, $attrs);
 412  }
 413  
 414  /**
 415   * form_makePasswordField
 416   *
 417   * Create a form element for a password input element with label.
 418   * Password elements have no default value, for obvious reasons.
 419   *
 420   * @see     form_makeField
 421   * @author  Tom N Harris <tnharris@whoopdedo.org>
 422   */
 423  function form_makePasswordField($name, $label=null, $id='', $class='', $attrs=array()) {
 424    if (is_null($label)) $label = $name;
 425    $elem = array('_elem'=>'passwordfield', '_text'=>$label, '_class'=>$class,
 426                  'id'=>$id, 'name'=>$name, 'class'=>'edit');
 427    return array_merge($elem, $attrs);
 428  }
 429  
 430  /**
 431   * form_makeFileField
 432   *
 433   * Create a form element for a file input element with label
 434   * 
 435   * @see     form_makeField
 436   * @author  Michael Klier <chi@chimeric.de>
 437   */
 438  function form_makeFileField($name, $label=null, $id='', $class='', $attrs=array()) {
 439    if (is_null($label)) $label = $name;
 440    $elem = array('_elem'=>'filefield', '_text'=>$label, '_class'=>$class,
 441                  'id'=>$id, 'name'=>$name, 'class'=>'edit');
 442    return array_merge($elem, $attrs);
 443  }
 444  
 445  /**
 446   * form_makeCheckboxField
 447   *
 448   * Create a form element for a checkbox input element with label.
 449   *
 450   * @see     form_makeFieldRight
 451   * @author  Tom N Harris <tnharris@whoopdedo.org>
 452   */
 453  function form_makeCheckboxField($name, $value='1', $label=null, $id='', $class='', $attrs=array()) {
 454    if (is_null($label)) $label = $name;
 455    if (is_null($value) || $value=='') $value='0';
 456    $elem = array('_elem'=>'checkboxfield', '_text'=>$label, '_class'=>$class,
 457                  'id'=>$id, 'name'=>$name, 'value'=>$value);
 458    return array_merge($elem, $attrs);
 459  }
 460  
 461  /**
 462   * form_makeRadioField
 463   *
 464   * Create a form element for a radio button input element with label.
 465   *
 466   * @see     form_makeFieldRight
 467   * @author  Tom N Harris <tnharris@whoopdedo.org>
 468   */
 469  function form_makeRadioField($name, $value='1', $label=null, $id='', $class='', $attrs=array()) {
 470    if (is_null($label)) $label = $name;
 471    if (is_null($value) || $value=='') $value='0';
 472    $elem = array('_elem'=>'radiofield', '_text'=>$label, '_class'=>$class,
 473                  'id'=>$id, 'name'=>$name, 'value'=>$value);
 474    return array_merge($elem, $attrs);
 475  }
 476  
 477  /**
 478   * form_makeMenuField
 479   *
 480   * Create a form element for a drop-down menu with label.
 481   * The list of values can be strings, arrays of (value,text),
 482   * or an associative array with the values as keys and labels as values.
 483   * An item is selected by supplying its value or integer index.
 484   * If the list of values is an associative array, the selected item must be
 485   * a string.
 486   *
 487   * @author  Tom N Harris <tnharris@whoopdedo.org>
 488   */
 489  function form_makeMenuField($name, $values, $selected='', $label=null, $id='', $class='', $attrs=array()) {
 490    if (is_null($label)) $label = $name;
 491    $options = array();
 492    reset($values);
 493    // FIXME: php doesn't know the difference between a string and an integer
 494    if (is_string(key($values))) {
 495      foreach ($values as $val=>$text) {
 496        $options[] = array($val,$text, (!is_null($selected) && $val==$selected));
 497      }
 498    } else {
 499      if (is_integer($selected)) $selected = $values[$selected];
 500      foreach ($values as $val) {
 501        if (is_array($val))
 502          @list($val,$text) = $val;
 503        else
 504          $text = null;
 505        $options[] = array($val,$text,$val===$selected);
 506      }
 507    }
 508    $elem = array('_elem'=>'menufield', '_options'=>$options, '_text'=>$label, '_class'=>$class,
 509                  'id'=>$id, 'name'=>$name);
 510    return array_merge($elem, $attrs);
 511  }
 512  
 513  /**
 514   * form_makeListboxField
 515   *
 516   * Create a form element for a list box with label.
 517   * The list of values can be strings, arrays of (value,text),
 518   * or an associative array with the values as keys and labels as values.
 519   * Items are selected by supplying its value or an array of values.
 520   *
 521   * @author  Tom N Harris <tnharris@whoopdedo.org>
 522   */
 523  function form_makeListboxField($name, $values, $selected='', $label=null, $id='', $class='', $attrs=array()) {
 524    if (is_null($label)) $label = $name;
 525    $options = array();
 526    reset($values);
 527    if (is_null($selected) || $selected == '')
 528      $selected = array();
 529    elseif (!is_array($selected))
 530      $selected = array($selected);
 531    // FIXME: php doesn't know the difference between a string and an integer
 532    if (is_string(key($values))) {
 533      foreach ($values as $val=>$text) {
 534        $options[] = array($val,$text,in_array($val,$selected));
 535      }
 536    } else {
 537      foreach ($values as $val) {
 538        if (is_array($val))
 539          @list($val,$text) = $val;
 540        else
 541          $text = null;
 542        $options[] = array($val,$text,in_array($val,$selected));
 543      }
 544    }
 545    $elem = array('_elem'=>'listboxfield', '_options'=>$options, '_text'=>$label, '_class'=>$class,
 546                  'id'=>$id, 'name'=>$name);
 547    return array_merge($elem, $attrs);
 548  }
 549  
 550  /**
 551   * form_tag
 552   *
 553   * Print the HTML for a generic empty tag.
 554   * Requires '_tag' key with name of the tag.
 555   * Attributes are passed to buildAttributes()
 556   *
 557   * @author  Tom N Harris <tnharris@whoopdedo.org>
 558   */
 559  function