Form::options()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 7
c 1
b 0
f 0
nc 3
nop 2
dl 0
loc 12
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace HexMakina\Marker;
6
7
/**
8
 * Provides a convenient way to generate form input elements with minimal code,
9
 * making it easier and faster to build forms in PHP.
10
 */
11
12
class Form
13
{
14
    /**
15
     * Used as a shortcut for creating form input elements with a single line of code
16
     *
17
     * When called on the Form class with a name that matches an HTML input element type (such as hidden, date, time, radio, datetime, etc.),
18
     * it intercepts the call and dynamically creates an input element of that type with the provided attributes.
19
     */
20
    public static function __callStatic(string $input_type, array $arguments): string
21
    {
22
        // arguments [name, value, [attributes]]
23
        $i = 0;
24
        $name         = $arguments[$i++] ?? null;
25
        $value        = $arguments[$i++] ?? null;
26
        $attributes   = (array)($arguments[$i++] ?? []);
27
28
        $attributes['type'] = $input_type;
29
        $attributes['name'] ??= $name;
30
        $attributes['value'] ??= $value;
31
32
        if ($attributes['type'] == 'datetime') {
33
            $attributes['type'] = 'datetime-local';
34
        } elseif ($attributes['type'] == 'password') {
35
            $attributes['value'] = '';
36
        }
37
38
        return self::input($name, $value, $attributes);
39
    }
40
41
    /**
42
     * Generates an HTML input element with the provided attributes.
43
     *
44
     * @param string|null $name The name of the input element
45
     * @param mixed|null $value The value of the input element
46
     * @param array $attributes An array containing the attributes of the input element
47
     * @return string The generated HTML code for the input element
48
     */
49
    public static function input(string $name = null, $value = null, array $attributes = []): string
50
    {
51
        $attributes['name'] ??= $name;
52
        $attributes['value'] ??= $value;
53
54
        if (
55
            !isset($attributes['type'])
56
            || isset($attributes['disabled'])
57
            || in_array('disabled', $attributes, true)
58
        ) {
59
            // why are disabled field textual ?
60
            // radio or checkbox can be disabled too..
61
            $attributes['type'] = 'text';
62
        }
63
64
        return self::labelledField('input', null, $attributes);
65
    }
66
67
    /**
68
     * Generates an HTML textarea element with the provided attributes.
69
     *
70
     * @param string $name The name of the textarea element
71
     * @param mixed|null $value The value of the textarea element
72
     * @param array $attributes An array containing the attributes of the textarea element
73
     * @return string The generated HTML code for the textarea element
74
     */
75
    public static function textarea(string $name, $value = null, array $attributes = []): string
76
    {
77
        $attributes['name'] ??= $name;
78
        return self::labelledField('textarea', $value ?? '', $attributes);
79
    }
80
81
    /**
82
     * Generates an HTML select element with the provided options and attributes.
83
     *
84
     * @param string $name The name of the select element
85
     * @param array $option_list An array containing the options of the select element
86
     * @param mixed|null $selected The selected option of the select element
87
     * @param array $attributes An array containing the attributes of the select element
88
     * @return string The generated HTML code for the select element
89
     */
90
    public static function select(string $name, array $option_list, $selected = null, array $attributes = []): string
91
    {
92
        $attributes['name'] ??= $name;
93
        $options = self::options($option_list, $selected);
94
        return self::labelledField('select', $options, $attributes);
95
    }
96
97
    /**
98
     * Generates an HTML options string for the provided option list and selected value.
99
     *
100
     * @param array $list An array containing the options of the select element
101
     * @param mixed|null $selected The selected option of the select element
102
     * @return string The generated HTML options string
103
     */
104
    public static function options(array $list, $selected = null): string
105
    {
106
        $options = '';
107
        foreach ($list as $value => $label) {
108
            $option_attributes = ['value' => $value];
109
            if ($selected == $value) {
110
                $option_attributes['selected'] =  'selected';
111
            }
112
113
            $options .= new Element('option', (string)$label, $option_attributes);
114
        }
115
        return $options;
116
    }
117
118
    /**
119
     * Generates an HTML legend element with the provided label and attributes.
120
     *
121
     * @param string $label The label of the legend element
122
     * @param array $attributes An array containing the attributes of the legend element
123
     * @return string The generated HTML code for the legend element
124
     */
125
    public static function legend(string $label, array $attributes = []): string
126
    {
127
        return '' . (new Element('legend', $label, $attributes));
128
    }
129
130
    /**
131
     * Generates an HTML label element with the provided for attribute, label text, and attributes.
132
     *
133
     * @param string $for The ID of the input element associated with the label
134
     * @param string $label The text of the label element
135
     * @param array $attributes An array containing the attributes of the label element
136
     * @return string The generated HTML code for the label element
137
     */
138
    public static function label(string $for, string $label, array $attributes = []): string
139
    {
140
        $attributes['for'] = $for;
141
        unset($attributes['label']);
142
143
        return self::labelledField('label', $label, $attributes);
144
    }
145
146
    public static function button(string $label, array $attributes = []): string
147
    {
148
        return  '' . (new Element('button', $label, $attributes));
149
    }
150
151
    /**
152
     * Generates a submit button element for a form.
153
     *
154
     * @param string $id The ID of the button element.
155
     * @param string $label The label for the button element.
156
     * @param array $attributes An optional array of attributes for the button element.
157
     *      The 'type' attribute is set to 'submit' by default and the 'name' attribute is omitted.
158
     *      The 'id' and 'value' attributes are automatically set based on the provided arguments.
159
     *      If the 'tag' attribute is set to 'input', an input element will be generated instead of a button element.
160
     * @return string The generated HTML for the button element.
161
     */
162
    public static function submit(string $id, string $label, array $attributes = []): string
163
    {
164
        $ret = '';
165
166
        $attributes['type'] = 'submit';
167
        unset($attributes['name']);
168
169
        $attributes['id'] ??= $id;
170
        $attributes['value'] ??= $label;
171
172
        if (isset($attributes['tag']) && $attributes['tag'] === 'input') {
173
            unset($attributes['tag']);
174
            $ret .= new Element('input', '', $attributes);
175
        } else {
176
            unset($attributes['tag']);
177
            unset($attributes['value']);
178
            $ret .= self::button($label, $attributes);
179
        }
180
181
        return $ret;
182
    }
183
184
    /**
185
     * Generates a labelled HTML form field, combining a form field with a label element.
186
     *
187
     * @param string $tag The HTML tag of the form field element
188
     * @param string|null $content The content of the form field element
189
     * @param array $attributes Additional attributes to add to the form field element
190
     * @return string The HTML for the labelled form field
191
     */
192
    private static function labelledField(string $tag, string $content = null, array $attributes = []): string
193
    {
194
        $ret = '';
195
        
196
        $attributes['id'] ??= $attributes['name'] ?? '';
197
198
        $label_text = $attributes['label'] ?? '';
199
        unset($attributes['label']);
200
        $input = new Element($tag, $content, $attributes, false);
201
202
        if($label_text){
203
            if (!empty($attributes['label-wrap']))
204
                $ret = self::label(null, $label_text.$input);
0 ignored issues
show
Bug introduced by
null of type null is incompatible with the type string expected by parameter $for of HexMakina\Marker\Form::label(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

204
                $ret = self::label(/** @scrutinizer ignore-type */ null, $label_text.$input);
Loading history...
205
            else
206
                $ret = self::label($attributes['id'], $label_text).$input;
207
        }
208
        else
209
            $ret = $input;
210
211
        return (string)$ret;
212
    }
213
}
214