Passed
Push — main ( fac3c3...502827 )
by Stefan
02:24
created

FormElement::getStdImage()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 20
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 13
c 0
b 0
f 0
nc 4
nop 1
dl 0
loc 20
rs 9.8333
1
<?php
2
declare(strict_types=1);
3
4
namespace SKien\Formgenerator;
5
6
/**
7
 * Base-class for all elements of a form.
8
 * Starting with a FormGenerator-element, the form can contain any count 
9
 * of elements.
10
 * The elements usuallay be arranged within FormFieldSet- and FormLine-elements
11
 *
12
 * #### History
13
 * - *2020-05-12*   initial version
14
 * - *2021-01-07*   PHP 7.4
15
 *
16
 * @package Formgenerator
17
 * @version 1.1.0
18
 * @author Stefanius <[email protected]>
19
 * @copyright MIT License - see the LICENSE file for details
20
 */
21
abstract class FormElement
22
{
23
    /** @var FormGenerator the FormGenerator this element belongs to     */
24
    protected FormGenerator $oFG;
25
    /** @var FormCollection the parent element - only FormGenerator must has no parent     */
26
    protected ?FormCollection $oParent = null;
27
    /** @var int tab index of the element if it can get focus     */
28
    protected int $iTabindex = -1;
29
    /** @var int col inside current line     */
30
    protected int $iCol = 0;
31
    /** @var string element name     */
32
    protected string $strName = '';
33
    /** @var string element id     */
34
    protected string $strID = '';
35
    /** @var string CSS class of the element     */
36
    protected string $strClass = '';
37
    /** @var FormFlags flags that specify the appearance and behaviour     */
38
    protected FormFlags $oFlags;
39
    /** @var array attributes of the element     */
40
    protected ?array $aAttrib = null;
41
    /** @var array (CSS) styles of the element     */
42
    protected ?array $aStyle = null;
43
    /** @var bool set to true, if element creates some CSS style     */
44
    protected bool $bCreateStyle = false;
45
    
46
    /**
47
     * @param int $wFlags
48
     */
49
    public function __construct(int $wFlags)
50
    {
51
        $this->oFlags = new FormFlags($wFlags);
52
    }
53
54
    /**
55
     * Return the FormGenerator this element belongs to.
56
     * @return FormGenerator
57
     */
58
    public function getFG() : ?FormGenerator
59
    {
60
        return $this->oFG;
61
    }
62
63
    /**
64
     * Set the parent of this element.
65
     * The Formgenerator of the parent is adopted for this element. 
66
     * If there are global flags set for the FormGenerator, this flags are added.
67
     * @param FormCollection $oParent
68
     */
69
    public function setParent(FormCollection $oParent) : void 
70
    {
71
        $this->oParent = $oParent;
72
        $this->oFG = $oParent->oFG;
73
        $this->addFlags($this->oFG->getGlobalFlags());
74
        $this->onParentSet();
75
    }
76
    
77
    /**
78
     * Set the current col.
79
     * If this element is added as a child of a FormLine, the column is set in 
80
     * order to be able to calculate the correct width of the element.
81
     * @param int $iCol
82
     */
83
    public function setCol(int $iCol) : void
84
    {
85
        $this->iCol = $iCol;
86
    }
87
    
88
    /**
89
     * Set ID for the element.
90
     * @param string $strID
91
     */
92
    public function setID(string $strID) : void 
93
    {
94
        $this->strID = $strID;
95
    }
96
    
97
    /**
98
     * Set text for the elements title attribute.
99
     * @param string $strTitle
100
     */
101
    public function setTitle(string $strTitle) : void 
102
    {
103
        if (strlen($strTitle) > 0) {
104
            $this->addAttribute('title', $strTitle);
105
        }
106
    }
107
    
108
    /**
109
     * Set the tab index of the element.
110
     * Method is called from the PageGenerator after an element is added to the form.
111
     * @param int $iTabindex
112
     * @return int the number of indexes, the element needs
113
     */
114
    public function setTabindex(/** @scrutinizer ignore-unused */ int $iTabindex) : int
115
    {
116
        return 0;
117
    }
118
    
119
    /**
120
     * Add flags to element. 
121
     * @param int $wFlags
122
     */
123
    public function addFlags(int $wFlags) : void 
124
    {
125
        $this->oFlags->add($wFlags);
126
    }
127
    
128
    /**
129
     * Add any attribute.
130
     * If the attribute allready exist, the value will be overwritten.
131
     * @param string $strName
132
     * @param string $strValue
133
     */
134
    public function addAttribute(string $strName, string $strValue = '') : void 
135
    {
136
        $strName = strtolower($strName);
137
        if ($this->aAttrib == null) {
138
            $this->aAttrib = array();
139
        }
140
        if ($strName == 'style') {
141
            // style should no longer be set through AddAttribute()
142
            trigger_error('use AddStyle() to define additional styles for element!', E_USER_ERROR);
143
        }
144
        $this->aAttrib[$strName] = $strValue;
145
    }
146
147
    /**
148
     * Add any style.
149
     * If the attribute allready exist, the value will be overwritten.
150
     * @param string $strName
151
     * @param string $strValue
152
     */
153
    public function addStyle(string $strName, string $strValue) : void 
154
    {
155
        $strName = strtolower($strName);
156
        if ($this->aStyle == null) {
157
            $this->aStyle = array();
158
        }
159
        $this->aStyle[$strName] = $strValue;
160
    }
161
162
    /**
163
     * Set the CSS class of the element.
164
     * Any previously setting will be overwritten.
165
     * @param string $strClass
166
     */
167
    public function setClass(string $strClass) : void 
168
    {
169
        $this->strClass = $strClass;
170
    }
171
    
172
    /**
173
     * Add additional class to element.
174
     * Class is added to the existing classname separated with a blank <br/>
175
     * Generates a notice, if no class set so far!
176
     * @param string $strClass
177
     */
178
    public function addClass(string $strClass) : void 
179
    {
180
        if (strlen($this->strClass) == 0) {
181
            trigger_error('no class set so far!', E_USER_NOTICE);
182
        }
183
        $this->strClass .= ' ' . $strClass;
184
    }
185
    
186
    /**
187
     * Get styles related to this element.
188
     * This method gives each element the chance to add special styles to the 
189
     * current page. <br/>
190
     * <b>This method is only called for elements having member bCreateStyle set to true!</b>
191
     * @return string
192
     */
193
    public function getStyle() : string
194
    {
195
        return '';
196
    }
197
198
    /**
199
     * @return string
200
     */
201
    abstract public function getHTML() : string;
202
203
    /**
204
     * Method called, after parent amd formgenerator is set properly.
205
     * Enhancing classes can use this method, to initialize properties that
206
     * nneds the parent or formgenerator (... configuration, global settings) 
207
     */
208
    protected function onParentSet() : void
209
    {
210
    }
211
    
212
    /**
213
     * Build the 'container' div arround the current element.
214
     * Additional styles (alignment, ...) can be passed.
215
     * @param string $strStyle
216
     * @return string
217
     */
218
    protected function buildContainerDiv(string $strStyle = '') : string
219
    {
220
        if (strpos($strStyle, 'float') === false) {
221
            $strStyle = 'float: left; ' . $strStyle;
222
        }
223
        $strWidth = ($this->oParent ? $this->oParent->getColWidth($this->iCol) : '');
224
        if (!empty($strWidth)) {
225
            $strStyle = rtrim($strStyle, ';');
226
            $strStyle .= '; width: ' . $strWidth . ';';
227
        }
228
        $strHTML = '<div style="' . $strStyle . '">';
229
230
        return $strHTML;
231
    }
232
    
233
    /**
234
     * Build the style attribute for the element.
235
     * @return string
236
     */
237
    protected function buildStyle() : string
238
    {
239
        $strStyle = '';
240
        if ($this->aStyle != null) {
241
            $strStyle = ' style="';
242
            foreach ($this->aStyle as $strName => $strValue) {
243
                $strStyle .= ' ' . $strName . ': ' . $strValue . ';';
244
            }
245
            $strStyle .= '"';
246
        }
247
        return $strStyle;
248
    }
249
250
    /**
251
     * Build all defined attributes for the element.
252
     * @return string
253
     */
254
    protected function buildAttributes() : string
255
    {
256
        $strAttrib = '';
257
        if ($this->aAttrib != null) {
258
            foreach ($this->aAttrib as $strName => $strValue) {
259
                $strAttrib .= ' ' . $strName;
260
                if (strlen($strValue) > 0) {
261
                    $strAttrib .= '="' . $strValue . '"';
262
                }
263
            }
264
        }
265
        return $strAttrib;
266
    }
267
    
268
    /**
269
     * Build the markup for the value attribute.
270
     * Retrieve value for the element from the FormData. 
271
     * @return string Empty string if no value set, complete attribute if set
272
     */
273
    protected function buildValue() : string
274
    {
275
        $strHTML = '';
276
        $strValue = $this->oFG->getData()->getValue($this->strName);
277
        
278
        if ($this->oFlags->isSet(FormFlags::TRIM)) {
279
            $strValue = trim($strValue);
280
        }
281
        if (!$this->oFlags->isSet(FormFlags::NO_ZERO) || ($strValue != 0 && $strValue != '0')) {
282
            $strHTML = ' value="' . str_replace('"', '&quot;', $strValue) . '"';
283
        }
284
        return $strHTML;
285
    }
286
287
    /**
288
     * Build the markup for the class attribute.
289
     * @return string Empty string if no class set, complete attribute if set
290
     */
291
    protected function buildClass() : string
292
    {
293
        $strClass = '';
294
        if (!empty($this->strClass)) {
295
            $strClass .= ' class="' . $this->strClass . '"';
296
        }
297
        return $strClass;
298
    }
299
300
    /**
301
     * Build the markup for the ID attribute.
302
     * @return string Empty string if no id set, complete attribute if set
303
     */
304
    protected function buildID() : string
305
    {
306
        $strID = '';
307
        if (!empty($this->strID)) {
308
            $strID .= ' id=' . $this->strID;
309
        }
310
        return $strID;
311
    }
312
    
313
    /**
314
     * Build the markup for the tabindex attribute.
315
     * @return string Empty string if $iTabindex = 0, complete attribute if set
316
     */
317
    protected function buildTabindex() : string
318
    {
319
        $strTabindex = '';
320
        if ($this->iTabindex > 0) {
321
            $strTabindex = ' tabindex="' . $this->iTabindex . '"';
322
        }
323
        return $strTabindex;
324
    }
325
    
326
    /**
327
     * Parse a given style attribute into the components it contains.
328
     * @param string $strStyle
329
     * @return array
330
     */
331
    static public function parseStyle($strStyle) : array
332
    {
333
        $aStyle = array();
334
        $aStyles = explode(';', trim($strStyle));
335
        foreach ($aStyles as $strStyleDef) {
336
            $aStyleDef = explode(':', trim($strStyleDef));
337
            if (count($aStyleDef) == 2) {
338
                $strName = trim($aStyleDef[0]);
339
                $strValue = trim($aStyleDef[1]);
340
                $strValue = rtrim($strValue, ';');
341
                $aStyle[$strName] = $strValue;
342
            }
343
        }
344
        return $aStyle;
345
    }
346
    
347
}
348
349