FormCheck::readAdditionalXML()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
c 0
b 0
f 0
nc 2
nop 1
dl 0
loc 6
rs 10
1
<?php
2
declare(strict_types=1);
3
4
namespace SKien\Formgenerator;
5
6
/**
7
 * Checkbox input field.
8
 * As default, the value 'on' is submitted for a checked element. This value can be
9
 * changed with the `setBtnValue()` method.<br/>
10
 *
11
 *
12
 * The checkbox element is a special case, as it behaves particularly regarding to the
13
 * transferred value and does not support read-only mode.
14
 *
15
 *
16
 * > <b>transfering 'unchecked' state</b><br/>
17
 *   A hidden edit field with same name is inserted BEFORE the checkbox is crated and
18
 *   always set its value to 'off'.<br/>
19
 *   If the checkbox is activated, 'on' (or the value set with `setBtnValue`) is posted
20
 *   as normal.<br/>
21
 *   However, since the value of a non-activated checkbox is not transferred at all, in this
22
 *   case the hidden field defined in the previous order comes into play and the fixed value
23
 *   'off' is transferred.<br/>
24
 *   This is particularly helpful/important if a database operation is to be carried out
25
 *   dynamically on the basis of the transferred fields: If the 'off' were not transferred,
26
 *   the field would not be taken into account either and would therefore never be set from
27
 *   'on' to 'off'!!
28
 *
29
 *
30
 * > <b>workaround for readonly state</b><br/>
31
 *   Because checkboxes don't support readonly-attribute and disabled checkboxes
32
 *   are not posted to reciever, we insert an hidden field with name and id to keep
33
 *   value 'alive'.<br/>
34
 *
35
 * @package Formgenerator
36
 * @author Stefanius <[email protected]>
37
 * @copyright MIT License - see the LICENSE file for details
38
 */
39
class FormCheck extends FormInput
40
{
41
    /** @var string value for the button, if checked (default = 'on')  */
42
    protected string $strBtnValue = 'on';
43
44
    /**
45
     * Create a checkbox.
46
     * @param string $strName   name AND id of the element
47
     * @param int $wFlags       any combination of FormFlag constants
48
     * @param string $strSuffix Text after the checkbox (default: '')
49
     */
50
    public function __construct(string $strName, int $wFlags = 0, string $strSuffix = '')
51
    {
52
        $this->oFlags = new FormFlags($wFlags);
53
        $this->strName = $strName;
54
        $this->strSuffix = $strSuffix;
55
        if ($this->oFlags->isSet(FormFlags::READ_ONLY | FormFlags::DISABLED)) {
56
            $this->addAttribute('disabled');
57
        }
58
    }
59
60
    /**
61
     * {@inheritDoc}
62
     * @see \SKien\Formgenerator\FormElement::fromXML()
63
     * @internal
64
     */
65
    static public function fromXML(\DOMElement $oXMLElement, FormCollection $oFormParent) : ?FormElement
66
    {
67
        $strName = self::getAttribString($oXMLElement, 'name');
68
        $wFlags = self::getAttribFlags($oXMLElement);
69
        $oFormElement = new self($strName, $wFlags);
70
        $oFormParent->add($oFormElement);
71
        $oFormElement->readAdditionalXML($oXMLElement);
72
        return $oFormElement;
73
    }
74
75
    /**
76
     * {@inheritDoc}
77
     * @see \SKien\Formgenerator\FormElement::readAdditionalXML()
78
     * @internal
79
     */
80
    public function readAdditionalXML(\DOMElement $oXMLElement) : void
81
    {
82
        parent::readAdditionalXML($oXMLElement);
83
        if (self::hasAttrib($oXMLElement, 'btnvalue')) {
84
            $strBtnValue = self::getAttribString($oXMLElement, 'btnvalue');
85
            $this->setBtnValue($strBtnValue);
86
        }
87
    }
88
89
    /**
90
     * Set the value that is posted, when the element is checked.
91
     * @param string $strBtnValue
92
     */
93
    public function setBtnValue(string $strBtnValue) : void
94
    {
95
        $this->strBtnValue = $strBtnValue;
96
    }
97
98
    /**
99
     * Build the HTML-markup for the checkbox.
100
     * @return string
101
     * @internal
102
     */
103
    public function getHTML() : string
104
    {
105
        $this->processFlags();
106
        $bChecked = $this->getBoolValue();
107
        if ($bChecked) {
108
            $this->addAttribute('checked');
109
        }
110
111
        $strHTML = $this->buildContainerDiv();
112
113
        $strHTML .= $this->buildUncheckedSurrogate();
114
        $strHTML .= $this->buildCheckBox();
115
        $strHTML .= $this->buildReadonlySurrogate($bChecked);
116
117
        if (!empty($this->strSuffix)) {
118
            $strHTML .= '&nbsp;' . $this->strSuffix;
119
        }
120
121
        $strHTML .= '</div>' . PHP_EOL;
122
123
        return $strHTML;
124
    }
125
126
    /**
127
     * Get the value as bool. <ul>
128
     * <li> 'real' bool values as is </li>
129
     * <li> numeric: 0 -> false, all other -> true </li>
130
     * <li> string: '1', 'on', 'true', 'yes' (case insensitive) -> true, all other -> false </li></ul>
131
     * @return bool
132
     */
133
    protected function getBoolValue() : bool
134
    {
135
        $bChecked = false;
136
        $value = $this->oFG->getData()->getValue($this->strName);
137
        if (is_bool($value)) {
138
            $bChecked = $value;
139
        } else {
140
            if (is_numeric($value)) {
141
                $bChecked = ($value !== 0);
142
            } else {
143
                $value = strtolower($value);
144
                $bChecked = in_array($value, ['1', 'on', 'true', 'yes']);
145
            }
146
        }
147
        return $bChecked;
148
    }
149
150
    /**
151
     * Build the checkbox.
152
     * @return string
153
     */
154
    protected function buildCheckBox() : string
155
    {
156
        $strHTML = '<input type="checkbox"';
157
        $strHTML .= $this->buildStyle();
158
        $strHTML .= $this->buildAttributes();
159
        $strHTML .= $this->buildTabindex();
160
        $strHTML .= ' id="' . $this->strName . '"';
161
        if (!$this->oFlags->isSet(FormFlags::READ_ONLY | FormFlags::DISABLED)) {
162
            $strHTML .= ' name="' . $this->strName . '"';
163
            $strHTML .= ' value="' . $this->strBtnValue . '"';
164
        }
165
        $strHTML .= '>';
166
167
        return $strHTML;
168
    }
169
170
    /**
171
     * Build the surrogate for unchecked box.
172
     * @return string
173
     */
174
    protected function buildUncheckedSurrogate() : string
175
    {
176
        // We insert a hidden edit field with same name BEFORE we create the checkbox
177
        // and  alwas set its value to 'off'.
178
        // If the checkbox is activated, 'on' (or the value set with BtnValue) is posted as normal.
179
        // However, since the value of a non-activated checkbox is not transferred at all, in this
180
        // case the hidden field defined in the previous order comes into play and the fixed value
181
        // 'off' is transferred.
182
        // This is particularly helpful/important if a database operation is to be carried out
183
        // dynamically on the basis of the transferred fields: If the 'off' were not transferred,
184
        // the field would not be taken into account either and would therefore never be set from
185
        // 'on' to 'off'!!
186
        $strHTML = '<input type="hidden" value="off" name="' . $this->strName . '">';
187
188
        return $strHTML;
189
    }
190
191
    /**
192
     * Build the surrogate in case of readonly checkbox.
193
     * @param bool $bChecked
194
     * @return string
195
     */
196
    protected function buildReadonlySurrogate(bool $bChecked) : string
197
    {
198
        // NOTE: because checkboxes don't support readonly-attribute and disabled checkboxes
199
        // are not posted to reciever, we insert an hidden field with name and id to keep
200
        // value 'alive'
201
        // -> so we dont set name and id for readonly or disabled checkbox!
202
        $strHTML = '';
203
        if ($this->oFlags->isSet(FormFlags::READ_ONLY | FormFlags::DISABLED)) {
204
            $strHTML .= '<input';
205
            $strHTML .= ' type="hidden"';
206
            $strHTML .= ' name="' . $this->strName . '"';
207
            $strValue = ($bChecked) ? $this->strBtnValue : 'off';
208
            $strHTML .= ' value="' . $strValue . '">';
209
        }
210
        return $strHTML;
211
    }
212
}
213