xref: /dokuwiki/inc/Form/InputElement.php (revision 90fb952c4c30c09c8446076ba05991c89a3f0b01)
112a4e4d1SAndreas Gohr<?php
29d01c1d9SSatoshi Sahara
312a4e4d1SAndreas Gohrnamespace dokuwiki\Form;
412a4e4d1SAndreas Gohr
512a4e4d1SAndreas Gohr/**
612a4e4d1SAndreas Gohr * Class InputElement
712a4e4d1SAndreas Gohr *
8de19515fSAndreas Gohr * Base class for all input elements. Uses a wrapping label when label
9de19515fSAndreas Gohr * text is given.
1012a4e4d1SAndreas Gohr *
1112a4e4d1SAndreas Gohr * @todo figure out how to make wrapping or related label configurable
1212a4e4d1SAndreas Gohr * @package dokuwiki\Form
1312a4e4d1SAndreas Gohr */
149d01c1d9SSatoshi Saharaclass InputElement extends Element
159d01c1d9SSatoshi Sahara{
1612a4e4d1SAndreas Gohr    /**
17a453c16bSAndreas Gohr     * @var LabelElement
1812a4e4d1SAndreas Gohr     */
19*6fd0861fSAndreas Gohr    protected $label;
2012a4e4d1SAndreas Gohr
2112a4e4d1SAndreas Gohr    /**
2212a4e4d1SAndreas Gohr     * @var bool if the element should reflect posted values
2312a4e4d1SAndreas Gohr     */
2412a4e4d1SAndreas Gohr    protected $useInput = true;
2512a4e4d1SAndreas Gohr
2612a4e4d1SAndreas Gohr    /**
2712a4e4d1SAndreas Gohr     * @param string $type The type of this element
2812a4e4d1SAndreas Gohr     * @param string $name The name of this form element
29a453c16bSAndreas Gohr     * @param string $label The label text for this element (will be autoescaped)
3012a4e4d1SAndreas Gohr     */
319d01c1d9SSatoshi Sahara    public function __construct($type, $name, $label = '')
329d01c1d9SSatoshi Sahara    {
33*6fd0861fSAndreas Gohr        parent::__construct($type, ['name' => $name]);
3412a4e4d1SAndreas Gohr        $this->attr('name', $name);
3508099e4fSAndreas Gohr        $this->attr('type', $type);
36a453c16bSAndreas Gohr        if ($label) $this->label = new LabelElement($label);
37de19515fSAndreas Gohr    }
38de19515fSAndreas Gohr
39de19515fSAndreas Gohr    /**
40de19515fSAndreas Gohr     * Returns the label element if there's one set
41de19515fSAndreas Gohr     *
42a453c16bSAndreas Gohr     * @return LabelElement|null
43de19515fSAndreas Gohr     */
449d01c1d9SSatoshi Sahara    public function getLabel()
459d01c1d9SSatoshi Sahara    {
46de19515fSAndreas Gohr        return $this->label;
4712a4e4d1SAndreas Gohr    }
4812a4e4d1SAndreas Gohr
4912a4e4d1SAndreas Gohr    /**
5012a4e4d1SAndreas Gohr     * Should the user sent input be used to initialize the input field
5112a4e4d1SAndreas Gohr     *
5212a4e4d1SAndreas Gohr     * The default is true. Any set values will be overwritten by the INPUT
5312a4e4d1SAndreas Gohr     * provided values.
5412a4e4d1SAndreas Gohr     *
5512a4e4d1SAndreas Gohr     * @param bool $useinput
5612a4e4d1SAndreas Gohr     * @return $this
5712a4e4d1SAndreas Gohr     */
589d01c1d9SSatoshi Sahara    public function useInput($useinput)
599d01c1d9SSatoshi Sahara    {
6012a4e4d1SAndreas Gohr        $this->useInput = (bool) $useinput;
6112a4e4d1SAndreas Gohr        return $this;
6212a4e4d1SAndreas Gohr    }
6312a4e4d1SAndreas Gohr
6412a4e4d1SAndreas Gohr    /**
6512a4e4d1SAndreas Gohr     * Get or set the element's ID
6612a4e4d1SAndreas Gohr     *
6712a4e4d1SAndreas Gohr     * @param null|string $id
6812a4e4d1SAndreas Gohr     * @return string|$this
6912a4e4d1SAndreas Gohr     */
709d01c1d9SSatoshi Sahara    public function id($id = null)
719d01c1d9SSatoshi Sahara    {
72de19515fSAndreas Gohr        if ($this->label) $this->label->attr('for', $id);
7312a4e4d1SAndreas Gohr        return parent::id($id);
7412a4e4d1SAndreas Gohr    }
7512a4e4d1SAndreas Gohr
7612a4e4d1SAndreas Gohr    /**
7712a4e4d1SAndreas Gohr     * Adds a class to the class attribute
7812a4e4d1SAndreas Gohr     *
7912a4e4d1SAndreas Gohr     * This is the preferred method of setting the element's class
8012a4e4d1SAndreas Gohr     *
8112a4e4d1SAndreas Gohr     * @param string $class the new class to add
8212a4e4d1SAndreas Gohr     * @return $this
8312a4e4d1SAndreas Gohr     */
849d01c1d9SSatoshi Sahara    public function addClass($class)
859d01c1d9SSatoshi Sahara    {
86de19515fSAndreas Gohr        if ($this->label) $this->label->addClass($class);
8712a4e4d1SAndreas Gohr        return parent::addClass($class);
8812a4e4d1SAndreas Gohr    }
8912a4e4d1SAndreas Gohr
9012a4e4d1SAndreas Gohr    /**
9112a4e4d1SAndreas Gohr     * Figures out how to access the value for this field from INPUT data
9212a4e4d1SAndreas Gohr     *
9312a4e4d1SAndreas Gohr     * The element's name could have been given as a simple string ('foo')
9412a4e4d1SAndreas Gohr     * or in array notation ('foo[bar]').
9512a4e4d1SAndreas Gohr     *
9612a4e4d1SAndreas Gohr     * Note: this function only handles one level of arrays. If your data
9712a4e4d1SAndreas Gohr     * is nested deeper, you should call useInput(false) and set the
9812a4e4d1SAndreas Gohr     * correct value yourself
9912a4e4d1SAndreas Gohr     *
10012a4e4d1SAndreas Gohr     * @return array name and array key (null if not an array)
10112a4e4d1SAndreas Gohr     */
1029d01c1d9SSatoshi Sahara    protected function getInputName()
1039d01c1d9SSatoshi Sahara    {
10412a4e4d1SAndreas Gohr        $name = $this->attr('name');
10512a4e4d1SAndreas Gohr        parse_str("$name=1", $parsed);
10612a4e4d1SAndreas Gohr
10712a4e4d1SAndreas Gohr        $name = array_keys($parsed);
10812a4e4d1SAndreas Gohr        $name = array_shift($name);
10912a4e4d1SAndreas Gohr
1103fef852dSDamien Regad        if (isset($parsed[$name]) && is_array($parsed[$name])) {
11112a4e4d1SAndreas Gohr            $key = array_keys($parsed[$name]);
11212a4e4d1SAndreas Gohr            $key = array_shift($key);
11312a4e4d1SAndreas Gohr        } else {
11412a4e4d1SAndreas Gohr            $key = null;
11512a4e4d1SAndreas Gohr        }
11612a4e4d1SAndreas Gohr
117*6fd0861fSAndreas Gohr        return [$name, $key];
11812a4e4d1SAndreas Gohr    }
11912a4e4d1SAndreas Gohr
12012a4e4d1SAndreas Gohr    /**
12112a4e4d1SAndreas Gohr     * Handles the useInput flag and set the value attribute accordingly
12212a4e4d1SAndreas Gohr     */
1239d01c1d9SSatoshi Sahara    protected function prefillInput()
1249d01c1d9SSatoshi Sahara    {
12512a4e4d1SAndreas Gohr        global $INPUT;
12612a4e4d1SAndreas Gohr
127*6fd0861fSAndreas Gohr        [$name, $key] = $this->getInputName();
12812a4e4d1SAndreas Gohr        if (!$INPUT->has($name)) return;
12912a4e4d1SAndreas Gohr
13012a4e4d1SAndreas Gohr        if ($key === null) {
13112a4e4d1SAndreas Gohr            $value = $INPUT->str($name);
13212a4e4d1SAndreas Gohr        } else {
13312a4e4d1SAndreas Gohr            $value = $INPUT->arr($name);
13412a4e4d1SAndreas Gohr            if (isset($value[$key])) {
13512a4e4d1SAndreas Gohr                $value = $value[$key];
13612a4e4d1SAndreas Gohr            } else {
13712a4e4d1SAndreas Gohr                $value = '';
13812a4e4d1SAndreas Gohr            }
13912a4e4d1SAndreas Gohr        }
14012a4e4d1SAndreas Gohr        $this->val($value);
14112a4e4d1SAndreas Gohr    }
14212a4e4d1SAndreas Gohr
14312a4e4d1SAndreas Gohr    /**
14412a4e4d1SAndreas Gohr     * The HTML representation of this element
14512a4e4d1SAndreas Gohr     *
14612a4e4d1SAndreas Gohr     * @return string
14712a4e4d1SAndreas Gohr     */
1489d01c1d9SSatoshi Sahara    protected function mainElementHTML()
1499d01c1d9SSatoshi Sahara    {
15012a4e4d1SAndreas Gohr        if ($this->useInput) $this->prefillInput();
15112a4e4d1SAndreas Gohr        return '<input ' . buildAttributes($this->attrs()) . ' />';
15212a4e4d1SAndreas Gohr    }
15312a4e4d1SAndreas Gohr
15412a4e4d1SAndreas Gohr    /**
15512a4e4d1SAndreas Gohr     * The HTML representation of this element wrapped in a label
15612a4e4d1SAndreas Gohr     *
15712a4e4d1SAndreas Gohr     * @return string
15812a4e4d1SAndreas Gohr     */
1599d01c1d9SSatoshi Sahara    public function toHTML()
1609d01c1d9SSatoshi Sahara    {
161de19515fSAndreas Gohr        if ($this->label) {
16234431439SSatoshi Sahara            return '<label ' . buildAttributes($this->label->attrs()) . '>' . DOKU_LF
16334431439SSatoshi Sahara                . '<span>' . hsc($this->label->val()) . '</span>' . DOKU_LF
16434431439SSatoshi Sahara                . $this->mainElementHTML() . DOKU_LF
16534431439SSatoshi Sahara                . '</label>';
166de19515fSAndreas Gohr        } else {
167de19515fSAndreas Gohr            return $this->mainElementHTML();
168de19515fSAndreas Gohr        }
16912a4e4d1SAndreas Gohr    }
17012a4e4d1SAndreas Gohr}
171