xref: /dokuwiki/inc/Form/InputElement.php (revision 08099e4fe1e56308bc42cc639d187863088494bd)
112a4e4d1SAndreas Gohr<?php
212a4e4d1SAndreas Gohrnamespace dokuwiki\Form;
312a4e4d1SAndreas Gohr
412a4e4d1SAndreas Gohr/**
512a4e4d1SAndreas Gohr * Class InputElement
612a4e4d1SAndreas Gohr *
7de19515fSAndreas Gohr * Base class for all input elements. Uses a wrapping label when label
8de19515fSAndreas Gohr * text is given.
912a4e4d1SAndreas Gohr *
1012a4e4d1SAndreas Gohr * @todo figure out how to make wrapping or related label configurable
1112a4e4d1SAndreas Gohr * @package dokuwiki\Form
1212a4e4d1SAndreas Gohr */
1312a4e4d1SAndreas Gohrclass InputElement extends Element {
1412a4e4d1SAndreas Gohr    /**
1512a4e4d1SAndreas Gohr     * @var Label
1612a4e4d1SAndreas Gohr     */
17de19515fSAndreas Gohr    protected $label = null;
1812a4e4d1SAndreas Gohr
1912a4e4d1SAndreas Gohr    /**
2012a4e4d1SAndreas Gohr     * @var bool if the element should reflect posted values
2112a4e4d1SAndreas Gohr     */
2212a4e4d1SAndreas Gohr    protected $useInput = true;
2312a4e4d1SAndreas Gohr
2412a4e4d1SAndreas Gohr    /**
2512a4e4d1SAndreas Gohr     * @param string $type The type of this element
2612a4e4d1SAndreas Gohr     * @param string $name The name of this form element
2712a4e4d1SAndreas Gohr     * @param string $label The label text for this element
2812a4e4d1SAndreas Gohr     */
29de19515fSAndreas Gohr    public function __construct($type, $name, $label = '') {
3012a4e4d1SAndreas Gohr        parent::__construct($type, array('name' => $name));
3112a4e4d1SAndreas Gohr        $this->attr('name', $name);
32*08099e4fSAndreas Gohr        $this->attr('type', $type);
33de19515fSAndreas Gohr        if($label) $this->label = new Label($label);
34de19515fSAndreas Gohr    }
35de19515fSAndreas Gohr
36de19515fSAndreas Gohr    /**
37de19515fSAndreas Gohr     * Returns the label element if there's one set
38de19515fSAndreas Gohr     *
39de19515fSAndreas Gohr     * @return Label|null
40de19515fSAndreas Gohr     */
41de19515fSAndreas Gohr    public function getLabel() {
42de19515fSAndreas Gohr        return $this->label;
4312a4e4d1SAndreas Gohr    }
4412a4e4d1SAndreas Gohr
4512a4e4d1SAndreas Gohr    /**
4612a4e4d1SAndreas Gohr     * Should the user sent input be used to initialize the input field
4712a4e4d1SAndreas Gohr     *
4812a4e4d1SAndreas Gohr     * The default is true. Any set values will be overwritten by the INPUT
4912a4e4d1SAndreas Gohr     * provided values.
5012a4e4d1SAndreas Gohr     *
5112a4e4d1SAndreas Gohr     * @param bool $useinput
5212a4e4d1SAndreas Gohr     * @return $this
5312a4e4d1SAndreas Gohr     */
5412a4e4d1SAndreas Gohr    public function useInput($useinput) {
5512a4e4d1SAndreas Gohr        $this->useInput = (bool) $useinput;
5612a4e4d1SAndreas Gohr        return $this;
5712a4e4d1SAndreas Gohr    }
5812a4e4d1SAndreas Gohr
5912a4e4d1SAndreas Gohr    /**
6012a4e4d1SAndreas Gohr     * Get or set the element's ID
6112a4e4d1SAndreas Gohr     *
6212a4e4d1SAndreas Gohr     * @param null|string $id
6312a4e4d1SAndreas Gohr     * @return string|$this
6412a4e4d1SAndreas Gohr     */
6512a4e4d1SAndreas Gohr    public function id($id = null) {
66de19515fSAndreas Gohr        if($this->label) $this->label->attr('for', $id);
6712a4e4d1SAndreas Gohr        return parent::id($id);
6812a4e4d1SAndreas Gohr    }
6912a4e4d1SAndreas Gohr
7012a4e4d1SAndreas Gohr    /**
7112a4e4d1SAndreas Gohr     * Adds a class to the class attribute
7212a4e4d1SAndreas Gohr     *
7312a4e4d1SAndreas Gohr     * This is the preferred method of setting the element's class
7412a4e4d1SAndreas Gohr     *
7512a4e4d1SAndreas Gohr     * @param string $class the new class to add
7612a4e4d1SAndreas Gohr     * @return $this
7712a4e4d1SAndreas Gohr     */
7812a4e4d1SAndreas Gohr    public function addClass($class) {
79de19515fSAndreas Gohr        if($this->label) $this->label->addClass($class);
8012a4e4d1SAndreas Gohr        return parent::addClass($class);
8112a4e4d1SAndreas Gohr    }
8212a4e4d1SAndreas Gohr
8312a4e4d1SAndreas Gohr    /**
8412a4e4d1SAndreas Gohr     * Figures out how to access the value for this field from INPUT data
8512a4e4d1SAndreas Gohr     *
8612a4e4d1SAndreas Gohr     * The element's name could have been given as a simple string ('foo')
8712a4e4d1SAndreas Gohr     * or in array notation ('foo[bar]').
8812a4e4d1SAndreas Gohr     *
8912a4e4d1SAndreas Gohr     * Note: this function only handles one level of arrays. If your data
9012a4e4d1SAndreas Gohr     * is nested deeper, you should call useInput(false) and set the
9112a4e4d1SAndreas Gohr     * correct value yourself
9212a4e4d1SAndreas Gohr     *
9312a4e4d1SAndreas Gohr     * @return array name and array key (null if not an array)
9412a4e4d1SAndreas Gohr     */
9512a4e4d1SAndreas Gohr    protected function getInputName() {
9612a4e4d1SAndreas Gohr        $name = $this->attr('name');
9712a4e4d1SAndreas Gohr        parse_str("$name=1", $parsed);
9812a4e4d1SAndreas Gohr
9912a4e4d1SAndreas Gohr        $name = array_keys($parsed);
10012a4e4d1SAndreas Gohr        $name = array_shift($name);
10112a4e4d1SAndreas Gohr
10212a4e4d1SAndreas Gohr        if(is_array($parsed[$name])) {
10312a4e4d1SAndreas Gohr            $key = array_keys($parsed[$name]);
10412a4e4d1SAndreas Gohr            $key = array_shift($key);
10512a4e4d1SAndreas Gohr        } else {
10612a4e4d1SAndreas Gohr            $key = null;
10712a4e4d1SAndreas Gohr        }
10812a4e4d1SAndreas Gohr
10912a4e4d1SAndreas Gohr        return array($name, $key);
11012a4e4d1SAndreas Gohr    }
11112a4e4d1SAndreas Gohr
11212a4e4d1SAndreas Gohr    /**
11312a4e4d1SAndreas Gohr     * Handles the useInput flag and set the value attribute accordingly
11412a4e4d1SAndreas Gohr     */
11512a4e4d1SAndreas Gohr    protected function prefillInput() {
11612a4e4d1SAndreas Gohr        global $INPUT;
11712a4e4d1SAndreas Gohr
11812a4e4d1SAndreas Gohr        list($name, $key) = $this->getInputName();
11912a4e4d1SAndreas Gohr        if(!$INPUT->has($name)) return;
12012a4e4d1SAndreas Gohr
12112a4e4d1SAndreas Gohr        if($key === null) {
12212a4e4d1SAndreas Gohr            $value = $INPUT->str($name);
12312a4e4d1SAndreas Gohr        } else {
12412a4e4d1SAndreas Gohr            $value = $INPUT->arr($name);
12512a4e4d1SAndreas Gohr            if(isset($value[$key])) {
12612a4e4d1SAndreas Gohr                $value = $value[$key];
12712a4e4d1SAndreas Gohr            } else {
12812a4e4d1SAndreas Gohr                $value = '';
12912a4e4d1SAndreas Gohr            }
13012a4e4d1SAndreas Gohr        }
13112a4e4d1SAndreas Gohr        if($value !== '') {
13212a4e4d1SAndreas Gohr            $this->val($value);
13312a4e4d1SAndreas Gohr        }
13412a4e4d1SAndreas Gohr    }
13512a4e4d1SAndreas Gohr
13612a4e4d1SAndreas Gohr    /**
13712a4e4d1SAndreas Gohr     * The HTML representation of this element
13812a4e4d1SAndreas Gohr     *
13912a4e4d1SAndreas Gohr     * @return string
14012a4e4d1SAndreas Gohr     */
14112a4e4d1SAndreas Gohr    protected function mainElementHTML() {
14212a4e4d1SAndreas Gohr        if($this->useInput) $this->prefillInput();
14312a4e4d1SAndreas Gohr        return '<input ' . buildAttributes($this->attrs()) . ' />';
14412a4e4d1SAndreas Gohr    }
14512a4e4d1SAndreas Gohr
14612a4e4d1SAndreas Gohr    /**
14712a4e4d1SAndreas Gohr     * The HTML representation of this element wrapped in a label
14812a4e4d1SAndreas Gohr     *
14912a4e4d1SAndreas Gohr     * @return string
15012a4e4d1SAndreas Gohr     */
15112a4e4d1SAndreas Gohr    public function toHTML() {
152de19515fSAndreas Gohr        if($this->label) {
15312a4e4d1SAndreas Gohr            return '<label ' . buildAttributes($this->label->attrs()) . '>' . DOKU_LF .
154370c6450SAndreas Gohr            '<span>' . hsc($this->label->val()) . '</span>' . DOKU_LF .
15512a4e4d1SAndreas Gohr            $this->mainElementHTML() . DOKU_LF .
15612a4e4d1SAndreas Gohr            '</label>';
157de19515fSAndreas Gohr        } else {
158de19515fSAndreas Gohr            return $this->mainElementHTML();
159de19515fSAndreas Gohr        }
16012a4e4d1SAndreas Gohr    }
16112a4e4d1SAndreas Gohr}
162