Total Complexity | 63 |
Total Lines | 389 |
Duplicated Lines | 0 % |
Changes | 3 | ||
Bugs | 0 | Features | 1 |
Complex classes like FormInput often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use FormInput, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
13 | class FormInput extends FormElement |
||
14 | { |
||
15 | /** @var string value input type */ |
||
16 | protected string $strType = ''; |
||
17 | /** @var int|string size as number or as string including dimension ('%', 'px', 'em') */ |
||
18 | protected $size = 0; |
||
19 | /** @var string image displayed, if selectbutton is enabled */ |
||
20 | protected string $strSelectImg = ''; |
||
21 | /** @var string tooltip for selectbutton */ |
||
22 | protected string $strSelectImgTitle = ''; |
||
23 | /** @var string folder to expand when call the filemanager */ |
||
24 | protected string $strExpandFolder = ''; |
||
25 | /** @var string suffix directly after the element */ |
||
26 | protected string $strSuffix = ''; |
||
27 | |||
28 | /** |
||
29 | * @param string $strName Name (also used as ID, if not set separate) |
||
30 | * @param int|string $size number set the size-attribute, a string is used for the width attribute |
||
31 | * @param int $wFlags |
||
32 | */ |
||
33 | public function __construct(string $strName, $size, int $wFlags = 0, int $iMaxLength = 0) |
||
46 | } |
||
47 | } |
||
48 | |||
49 | /** |
||
50 | * {@inheritDoc} |
||
51 | * @see \SKien\Formgenerator\FormElement::fromXML() |
||
52 | */ |
||
53 | static public function fromXML(\DOMElement $oXMLElement, FormCollection $oFormParent) : ?FormElement |
||
54 | { |
||
55 | if ($oXMLElement->nodeName !== 'Input') { |
||
56 | trigger_error('Try to create Form' . $oXMLElement->nodeName . ' - Element from XML without defined method!', E_USER_ERROR); |
||
57 | } |
||
58 | $strName = self::getAttribString($oXMLElement, 'name', ''); |
||
59 | $strSize = self::getAttribString($oXMLElement, 'size', ''); |
||
60 | $wFlags = self::getAttribFlags($oXMLElement); |
||
61 | $oFormElement = new self($strName, $strSize, $wFlags); |
||
62 | $oFormParent->add($oFormElement); |
||
63 | $oFormElement->readAdditionalXML($oXMLElement); |
||
64 | return $oFormElement; |
||
65 | } |
||
66 | |||
67 | /** |
||
68 | * {@inheritDoc} |
||
69 | * @see \SKien\Formgenerator\FormElement::readAdditionalXML() |
||
70 | */ |
||
71 | public function readAdditionalXML(\DOMElement $oXMLElement) : void |
||
72 | { |
||
73 | parent::readAdditionalXML($oXMLElement); |
||
74 | if (($strSuffix = self::getAttribString($oXMLElement, 'suffix')) !== null) { |
||
75 | $this->setSuffix($strSuffix); |
||
76 | } |
||
77 | if (($strSelectImg = self::getAttribString($oXMLElement, 'selectimg')) !== null) { |
||
78 | $this->setSelectImg($strSelectImg, self::getAttribString($oXMLElement, 'selectimgtitle', '')); |
||
79 | } |
||
80 | if (($strExpandFolder = self::getAttribString($oXMLElement, 'expandfolder')) !== null) { |
||
81 | $this->setExpandFolder($strExpandFolder); |
||
82 | } |
||
83 | } |
||
84 | |||
85 | /** |
||
86 | * Set the maxlength attribute of the element. |
||
87 | * @param int $iMaxLength |
||
88 | */ |
||
89 | public function setMaxLength(int $iMaxLength) : void |
||
90 | { |
||
91 | $this->addAttribute('maxlength', (string)$iMaxLength); |
||
92 | } |
||
93 | |||
94 | /** |
||
95 | * Set placeholder to display on empty input element. |
||
96 | * @param string $strPlaceholder |
||
97 | */ |
||
98 | public function setPlaceholder(string $strPlaceholder) : void |
||
99 | { |
||
100 | if (strlen($strPlaceholder) > 0) { |
||
101 | $this->addAttribute('placeholder', $strPlaceholder); |
||
102 | } |
||
103 | } |
||
104 | |||
105 | /** |
||
106 | * set image and title for select-button (leave strImg blank for default 'search') |
||
107 | * @param string $strImg |
||
108 | * @param string $strTitle (default = '') |
||
109 | */ |
||
110 | public function setSelectImg(string $strImg, string $strTitle = '') : void |
||
111 | { |
||
112 | $this->strSelectImg = $strImg; |
||
113 | $this->strSelectImgTitle = $strTitle; |
||
114 | } |
||
115 | |||
116 | /** |
||
117 | * Set the folder to expand when call the filemanager. |
||
118 | * @param string $strExpandFolder |
||
119 | */ |
||
120 | public function setExpandFolder(string $strExpandFolder) : void |
||
121 | { |
||
122 | $this->strExpandFolder = $strExpandFolder; |
||
123 | } |
||
124 | |||
125 | /** |
||
126 | * @param string $strSuffix |
||
127 | */ |
||
128 | public function setSuffix(string $strSuffix) : void |
||
129 | { |
||
130 | $this->strSuffix = $strSuffix; |
||
131 | } |
||
132 | |||
133 | /** |
||
134 | * {@inheritDoc} |
||
135 | * @see \SKien\Formgenerator\FormElement::onParentSet() |
||
136 | */ |
||
137 | protected function onParentSet() : void |
||
141 | } |
||
142 | } |
||
143 | |||
144 | /** |
||
145 | * Build the HTML-notation for the input element. |
||
146 | * {@inheritDoc} |
||
147 | * @see \SKien\Formgenerator\FormElement::getHTML() |
||
148 | */ |
||
149 | public function getHTML() : string |
||
150 | { |
||
151 | $this->processFlags(); |
||
152 | $this->setSize(); |
||
153 | $strHTML = $this->buildContainerDiv(); |
||
154 | |||
155 | $this->strID = $this->strID ?: $this->strName; |
||
156 | |||
157 | $strHTML .= '<input'; |
||
158 | $strHTML .= ' type="' . $this->strType . '"'; |
||
159 | $strHTML .= ' name="' . $this->strName . '"'; |
||
160 | $strHTML .= $this->buildClass(); |
||
161 | $strHTML .= $this->buildID(); |
||
162 | $strHTML .= $this->buildStyle(); |
||
163 | $strHTML .= $this->buildTabindex(); |
||
164 | $strHTML .= $this->buildValue(); |
||
165 | $strHTML .= $this->buildAttributes(); |
||
166 | $strHTML .= $this->buildListLink(); |
||
167 | $strHTML .= '>'; |
||
168 | |||
169 | $strHTML .= $this->buildSelectButton(); |
||
170 | $strHTML .= $this->buildSuffix(); |
||
171 | $strHTML .= $this->buildDatalist(); |
||
172 | |||
173 | $strHTML .= '</div>' . PHP_EOL; |
||
174 | |||
175 | return $strHTML; |
||
176 | } |
||
177 | |||
178 | /** |
||
179 | * Set the tab index of the element. |
||
180 | * Method is called from the PageGenerator after an element is added to the form. |
||
181 | * @param int $iTabindex |
||
182 | * @return int the number of indexes, the element needs |
||
183 | */ |
||
184 | public function setTabindex(int $iTabindex) : int |
||
185 | { |
||
186 | if ($this->oFlags->isSet(FormFlags::HIDDEN | FormFlags::READ_ONLY | FormFlags::DISABLED)) { |
||
187 | return 0; |
||
188 | } |
||
189 | $this->iTabindex = $iTabindex; |
||
190 | return 1; |
||
191 | } |
||
192 | |||
193 | /** |
||
194 | * Process the current flags before the HTML is generated. |
||
195 | */ |
||
196 | protected function processFlags() : void |
||
197 | { |
||
198 | $this->setTypeFromFlags(); |
||
199 | |||
200 | if ($this->oFlags->isSet(FormFlags::MANDATORY)) { |
||
201 | $this->addAttribute('required'); |
||
202 | } |
||
203 | if ($this->oFlags->isSet(FormFlags::READ_ONLY)) { |
||
204 | $this->addAttribute('readonly'); |
||
205 | } else if ($this->oFlags->isSet(FormFlags::DISABLED)) { |
||
206 | $this->addAttribute('disabled'); |
||
207 | } |
||
208 | } |
||
209 | |||
210 | /** |
||
211 | * Set the type depending on some flags |
||
212 | */ |
||
213 | protected function setTypeFromFlags() : void |
||
225 | } |
||
226 | } |
||
227 | } |
||
228 | |||
229 | /** |
||
230 | * Set the size of the element. |
||
231 | * If property $size contains numeric value, the HTML attrib 'size' is set, in case of a |
||
232 | * string a width information including dimension (px, em, ...) is assumed. |
||
233 | * |
||
234 | */ |
||
235 | protected function setSize() : void |
||
236 | { |
||
237 | if ($this->oFlags->isSet(FormFlags::HIDDEN)) { |
||
238 | $this->size = ''; |
||
239 | } |
||
240 | if ((is_numeric($this->size)) && ($this->size > 0)) { |
||
241 | $this->addAttribute('size', (string)$this->size); |
||
242 | } else if (!empty($this->size)) { |
||
243 | // size given as string including dimension |
||
244 | $this->addStyle('width', $this->size); |
||
245 | } |
||
246 | } |
||
247 | |||
248 | /** |
||
249 | * {@inheritDoc} |
||
250 | * @see \SKien\Formgenerator\FormElement::buildClass() |
||
251 | */ |
||
252 | protected function buildClass() : string |
||
253 | { |
||
254 | if (!empty($this->strClass)) { |
||
255 | $this->strClass .= ' '; |
||
256 | } |
||
257 | $this->strClass .= ($this->oFlags->isSet(FormFlags::MANDATORY)) ? ' inputMand' : ' inputOK'; |
||
258 | if ($this->oFlags->isSet(FormFlags::ALIGN_RIGHT)) { |
||
259 | $this->strClass .= '_R'; |
||
260 | } |
||
261 | return parent::buildClass(); |
||
262 | } |
||
263 | |||
264 | /** |
||
265 | * Build the markup for a suffix succeeding the input element. |
||
266 | * @return string |
||
267 | */ |
||
268 | protected function buildSuffix() : string |
||
269 | { |
||
270 | $strHTML = ''; |
||
271 | if (!empty($this->strSuffix)) { |
||
272 | if ($this->oFlags->isSet(FormFlags::READ_ONLY)) { |
||
273 | $strHTML .= ' <span class="readonly">' . $this->strSuffix . '</span>'; |
||
274 | } else { |
||
275 | $strHTML .= ' ' . $this->strSuffix; |
||
276 | } |
||
277 | } |
||
278 | return $strHTML; |
||
279 | } |
||
280 | |||
281 | /** |
||
282 | * Build attrib for associated datalist. |
||
283 | * If the dataprovider contains a datalist in the selectoptions with the same name |
||
284 | * as the element, we add the attrib to conect to this list. |
||
285 | * @return string |
||
286 | */ |
||
287 | protected function buildListLink() : string |
||
288 | { |
||
289 | $strLink = ''; |
||
290 | $aOptions = $this->oFG->getData()->getSelectOptions($this->strName); |
||
291 | if (count($aOptions) > 0) { |
||
292 | $strLink = ' list="list' . $this->strName . '"'; |
||
293 | } |
||
294 | return $strLink; |
||
295 | } |
||
296 | |||
297 | /** |
||
298 | * Build the markup for associated datalist. |
||
299 | * If the dataprovider contains a datalist in the selectoptions with the same name |
||
300 | * as the element, we build this datalist. |
||
301 | * @return string |
||
302 | */ |
||
303 | protected function buildDatalist() : string |
||
304 | { |
||
305 | $strHTML = ''; |
||
306 | $aOptions = $this->oFG->getData()->getSelectOptions($this->strName); |
||
307 | if (count($aOptions) > 0) { |
||
308 | $strHTML .= '<datalist id="list' . $this->strName . '">' . PHP_EOL; |
||
309 | foreach ($aOptions as $strValue) { |
||
310 | $strHTML .= ' '; |
||
311 | $strHTML .= '<option '; |
||
312 | $strHTML .= 'value="' . $strValue . '">' . PHP_EOL; |
||
313 | } |
||
314 | $strHTML .= '</datalist>' . PHP_EOL; |
||
315 | } |
||
316 | return $strHTML; |
||
317 | } |
||
318 | |||
319 | /** |
||
320 | * Build the markup for the select button(s). |
||
321 | * If input is set to readonly, an additional 'delete' button is appended. |
||
322 | * @param string $strCssClass |
||
323 | * @return string |
||
324 | */ |
||
325 | protected function buildSelectButton(string $strCssClass = 'picker') : string |
||
374 | } |
||
375 | |||
376 | /** |
||
377 | * Build the markup for a selectimage. |
||
378 | * @param string $strImg |
||
379 | * @param string $strTitle |
||
380 | * @param string $strOnClick |
||
381 | * @param string $strID |
||
382 | * @param string $strCssClass |
||
383 | * @return string |
||
384 | */ |
||
385 | protected function buildSelectImage(string $strImg, string $strTitle, string $strOnClick, string $strID, string $strCssClass) : string |
||
402 | } |
||
403 | } |
||
404 |