xref: /dokuwiki/inc/Form/InputElement.php (revision 12a4e4d1ed827c59290838d5a11d75ad32aa28f1)
1*12a4e4d1SAndreas Gohr<?php
2*12a4e4d1SAndreas Gohrnamespace dokuwiki\Form;
3*12a4e4d1SAndreas Gohr
4*12a4e4d1SAndreas Gohr/**
5*12a4e4d1SAndreas Gohr * Class InputElement
6*12a4e4d1SAndreas Gohr *
7*12a4e4d1SAndreas Gohr * Base class for all input elements. Uses a wrapping label.
8*12a4e4d1SAndreas Gohr *
9*12a4e4d1SAndreas Gohr * @todo figure out how to make wrapping or related label configurable
10*12a4e4d1SAndreas Gohr * @package dokuwiki\Form
11*12a4e4d1SAndreas Gohr */
12*12a4e4d1SAndreas Gohrclass InputElement extends Element {
13*12a4e4d1SAndreas Gohr    /**
14*12a4e4d1SAndreas Gohr     * @var Label
15*12a4e4d1SAndreas Gohr     */
16*12a4e4d1SAndreas Gohr    protected $label;
17*12a4e4d1SAndreas Gohr
18*12a4e4d1SAndreas Gohr    /**
19*12a4e4d1SAndreas Gohr     * @var bool if the element should reflect posted values
20*12a4e4d1SAndreas Gohr     */
21*12a4e4d1SAndreas Gohr    protected $useInput = true;
22*12a4e4d1SAndreas Gohr
23*12a4e4d1SAndreas Gohr    /**
24*12a4e4d1SAndreas Gohr     * @param string $type The type of this element
25*12a4e4d1SAndreas Gohr     * @param string $name The name of this form element
26*12a4e4d1SAndreas Gohr     * @param string $label The label text for this element
27*12a4e4d1SAndreas Gohr     */
28*12a4e4d1SAndreas Gohr    public function __construct($type, $name, $label) {
29*12a4e4d1SAndreas Gohr        parent::__construct($type, array('name' => $name));
30*12a4e4d1SAndreas Gohr        $this->attr('name', $name);
31*12a4e4d1SAndreas Gohr    }
32*12a4e4d1SAndreas Gohr
33*12a4e4d1SAndreas Gohr    /**
34*12a4e4d1SAndreas Gohr     * Should the user sent input be used to initialize the input field
35*12a4e4d1SAndreas Gohr     *
36*12a4e4d1SAndreas Gohr     * The default is true. Any set values will be overwritten by the INPUT
37*12a4e4d1SAndreas Gohr     * provided values.
38*12a4e4d1SAndreas Gohr     *
39*12a4e4d1SAndreas Gohr     * @param bool $useinput
40*12a4e4d1SAndreas Gohr     * @return $this
41*12a4e4d1SAndreas Gohr     */
42*12a4e4d1SAndreas Gohr    public function useInput($useinput) {
43*12a4e4d1SAndreas Gohr        $this->useInput = (bool) $useinput;
44*12a4e4d1SAndreas Gohr        return $this;
45*12a4e4d1SAndreas Gohr    }
46*12a4e4d1SAndreas Gohr
47*12a4e4d1SAndreas Gohr    /**
48*12a4e4d1SAndreas Gohr     * Get or set the element's ID
49*12a4e4d1SAndreas Gohr     *
50*12a4e4d1SAndreas Gohr     * @param null|string $id
51*12a4e4d1SAndreas Gohr     * @return string|$this
52*12a4e4d1SAndreas Gohr     */
53*12a4e4d1SAndreas Gohr    public function id($id = null) {
54*12a4e4d1SAndreas Gohr        $this->label->attr('for', $id);
55*12a4e4d1SAndreas Gohr        return parent::id($id);
56*12a4e4d1SAndreas Gohr    }
57*12a4e4d1SAndreas Gohr
58*12a4e4d1SAndreas Gohr    /**
59*12a4e4d1SAndreas Gohr     * Adds a class to the class attribute
60*12a4e4d1SAndreas Gohr     *
61*12a4e4d1SAndreas Gohr     * This is the preferred method of setting the element's class
62*12a4e4d1SAndreas Gohr     *
63*12a4e4d1SAndreas Gohr     * @param string $class the new class to add
64*12a4e4d1SAndreas Gohr     * @return $this
65*12a4e4d1SAndreas Gohr     */
66*12a4e4d1SAndreas Gohr    public function addClass($class) {
67*12a4e4d1SAndreas Gohr        $this->label->addClass($class);
68*12a4e4d1SAndreas Gohr        return parent::addClass($class);
69*12a4e4d1SAndreas Gohr    }
70*12a4e4d1SAndreas Gohr
71*12a4e4d1SAndreas Gohr    /**
72*12a4e4d1SAndreas Gohr     * Figures out how to access the value for this field from INPUT data
73*12a4e4d1SAndreas Gohr     *
74*12a4e4d1SAndreas Gohr     * The element's name could have been given as a simple string ('foo')
75*12a4e4d1SAndreas Gohr     * or in array notation ('foo[bar]').
76*12a4e4d1SAndreas Gohr     *
77*12a4e4d1SAndreas Gohr     * Note: this function only handles one level of arrays. If your data
78*12a4e4d1SAndreas Gohr     * is nested deeper, you should call useInput(false) and set the
79*12a4e4d1SAndreas Gohr     * correct value yourself
80*12a4e4d1SAndreas Gohr     *
81*12a4e4d1SAndreas Gohr     * @return array name and array key (null if not an array)
82*12a4e4d1SAndreas Gohr     */
83*12a4e4d1SAndreas Gohr    protected function getInputName() {
84*12a4e4d1SAndreas Gohr        $name = $this->attr('name');
85*12a4e4d1SAndreas Gohr        parse_str("$name=1", $parsed);
86*12a4e4d1SAndreas Gohr
87*12a4e4d1SAndreas Gohr        $name = array_keys($parsed);
88*12a4e4d1SAndreas Gohr        $name = array_shift($name);
89*12a4e4d1SAndreas Gohr
90*12a4e4d1SAndreas Gohr        if(is_array($parsed[$name])) {
91*12a4e4d1SAndreas Gohr            $key = array_keys($parsed[$name]);
92*12a4e4d1SAndreas Gohr            $key = array_shift($key);
93*12a4e4d1SAndreas Gohr        } else {
94*12a4e4d1SAndreas Gohr            $key = null;
95*12a4e4d1SAndreas Gohr        }
96*12a4e4d1SAndreas Gohr
97*12a4e4d1SAndreas Gohr        return array($name, $key);
98*12a4e4d1SAndreas Gohr    }
99*12a4e4d1SAndreas Gohr
100*12a4e4d1SAndreas Gohr    /**
101*12a4e4d1SAndreas Gohr     * Handles the useInput flag and set the value attribute accordingly
102*12a4e4d1SAndreas Gohr     */
103*12a4e4d1SAndreas Gohr    protected function prefillInput() {
104*12a4e4d1SAndreas Gohr        global $INPUT;
105*12a4e4d1SAndreas Gohr
106*12a4e4d1SAndreas Gohr        list($name, $key) = $this->getInputName();
107*12a4e4d1SAndreas Gohr        if(!$INPUT->has($name)) return;
108*12a4e4d1SAndreas Gohr
109*12a4e4d1SAndreas Gohr        if($key === null) {
110*12a4e4d1SAndreas Gohr            $value = $INPUT->str($name);
111*12a4e4d1SAndreas Gohr        } else {
112*12a4e4d1SAndreas Gohr            $value = $INPUT->arr($name);
113*12a4e4d1SAndreas Gohr            if(isset($value[$key])) {
114*12a4e4d1SAndreas Gohr                $value = $value[$key];
115*12a4e4d1SAndreas Gohr            } else {
116*12a4e4d1SAndreas Gohr                $value = '';
117*12a4e4d1SAndreas Gohr            }
118*12a4e4d1SAndreas Gohr        }
119*12a4e4d1SAndreas Gohr        if($value !== '') {
120*12a4e4d1SAndreas Gohr            $this->val($value);
121*12a4e4d1SAndreas Gohr        }
122*12a4e4d1SAndreas Gohr    }
123*12a4e4d1SAndreas Gohr
124*12a4e4d1SAndreas Gohr    /**
125*12a4e4d1SAndreas Gohr     * The HTML representation of this element
126*12a4e4d1SAndreas Gohr     *
127*12a4e4d1SAndreas Gohr     * @return string
128*12a4e4d1SAndreas Gohr     */
129*12a4e4d1SAndreas Gohr    protected function mainElementHTML() {
130*12a4e4d1SAndreas Gohr        if($this->useInput) $this->prefillInput();
131*12a4e4d1SAndreas Gohr        return '<input ' . buildAttributes($this->attrs()) . ' />';
132*12a4e4d1SAndreas Gohr    }
133*12a4e4d1SAndreas Gohr
134*12a4e4d1SAndreas Gohr    /**
135*12a4e4d1SAndreas Gohr     * The HTML representation of this element wrapped in a label
136*12a4e4d1SAndreas Gohr     *
137*12a4e4d1SAndreas Gohr     * @return string
138*12a4e4d1SAndreas Gohr     */
139*12a4e4d1SAndreas Gohr    public function toHTML() {
140*12a4e4d1SAndreas Gohr        return '<label ' . buildAttributes($this->label->attrs()) . '>' . DOKU_LF .
141*12a4e4d1SAndreas Gohr        '<span>' . hsc($this->label->label) . '</span>' . DOKU_LF .
142*12a4e4d1SAndreas Gohr        $this->mainElementHTML() . DOKU_LF .
143*12a4e4d1SAndreas Gohr        '</label>';
144*12a4e4d1SAndreas Gohr    }
145*12a4e4d1SAndreas Gohr}
146