Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
94.44% covered (success)
94.44%
153 / 162
0.00% covered (danger)
0.00%
0 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
Fields
94.44% covered (success)
94.44%
153 / 162
0.00% covered (danger)
0.00%
0 / 2
71.86
0.00% covered (danger)
0.00%
0 / 1
 create
93.10% covered (success)
93.10%
108 / 116
0.00% covered (danger)
0.00%
0 / 1
45.66
 getConfigFromTable
97.83% covered (success)
97.83%
45 / 46
0.00% covered (danger)
0.00%
0 / 1
26
1<?php
2/**
3 * Pop PHP Framework (http://www.popphp.org/)
4 *
5 * @link       https://github.com/popphp/popphp-framework
6 * @author     Nick Sagona, III <dev@nolainteractive.com>
7 * @copyright  Copyright (c) 2009-2024 NOLA Interactive, LLC. (http://www.nolainteractive.com)
8 * @license    http://www.popphp.org/license     New BSD License
9 */
10
11/**
12 * @namespace
13 */
14namespace Pop\Form;
15
16use Pop\Form\Element\AbstractElement;
17
18/**
19 * Form fields config class
20 *
21 * @category   Pop
22 * @package    Pop\Form
23 * @author     Nick Sagona, III <dev@nolainteractive.com>
24 * @copyright  Copyright (c) 2009-2024 NOLA Interactive, LLC. (http://www.nolainteractive.com)
25 * @license    http://www.popphp.org/license     New BSD License
26 * @version    4.0.0
27 */
28class Fields
29{
30
31    /**
32     * Static factory method to create a field element object from a field config array
33     *
34     * @param  string $name
35     * @param  array  $field
36     * @throws Exception|Element\Exception
37     * @return AbstractElement
38     */
39    public static function create(string $name, array $field): AbstractElement
40    {
41        if (!isset($field['type'])) {
42            throw new Exception('Error: The field type was not set.');
43        }
44
45        $type         = $field['type'];
46        $value        = $field['value'] ?? null;
47        $values       = $field['values'] ?? [];
48        $label        = $field['label'] ?? null;
49        $indent       = $field['indent'] ?? null;
50        $checked      = $field['checked'] ?? null;
51        $selected     = $field['selected'] ?? null;
52        $required     = $field['required'] ?? null;
53        $disabled     = $field['disabled'] ?? null;
54        $readonly     = $field['readonly'] ?? null;
55        $attributes   = $field['attributes'] ?? null;
56        $validators   = $field['validators'] ?? null;
57        $render       = $field['render'] ?? false;
58        $expire       = $field['expire'] ?? 300;
59        $captcha      = $field['captcha'] ?? null;
60        $answer       = $field['answer'] ?? null;
61        $min          = $field['min'] ?? false;
62        $max          = $field['max'] ?? false;
63        $xmlFile      = $field['xml'] ?? null;
64        $hint         = $field['hint'] ?? null;
65        $hintAttribs  = $field['hint-attributes'] ?? null;
66        $labelAttribs = $field['label-attributes'] ?? null;
67        $prepend      = $field['prepend'] ?? null;
68        $append       = $field['append'] ?? null;
69
70        $errorPre = (isset($field['error']) && ($field['error'] == 'pre'));
71
72        // Initialize the form element.
73        switch (strtolower($type)) {
74            case 'button':
75                $element = new Element\Button($name, $value, $indent);
76                break;
77            case 'select':
78                $element = new Element\Select($name, $values, $selected, $xmlFile, $indent);
79                break;
80            case 'select-multiple':
81                $element = new Element\SelectMultiple($name, $values, $selected, $xmlFile, $indent);
82                break;
83            case 'textarea':
84                $element = new Element\Textarea($name, $value, $indent);
85                break;
86            case 'checkbox':
87                $element = new Element\Input\Checkbox($name, $value, $indent);
88                if (($checked === true) || ($value == $checked)) {
89                    $element->check();
90                }
91                break;
92            case 'checkbox-set':
93                $element = new Element\CheckboxSet($name, $values, $checked, $indent);
94                break;
95            case 'radio':
96                $element = new Element\Input\Radio($name, $value, $indent);
97                if (($checked === true) || ($value == $checked)) {
98                    $element->check();
99                }
100                break;
101            case 'radio-set':
102                $element = new Element\RadioSet($name, $values, $checked, $indent);
103                break;
104            case 'csrf':
105                $element = new Element\Input\Csrf($name, $value, $expire, $indent);
106                break;
107            case 'captcha':
108                $element = new Element\Input\Captcha($name, $value, $captcha, $answer, $expire, $indent);
109                break;
110            case 'input-button':
111                $element = new Element\Input\Button($name, $value);
112                break;
113            case 'datalist':
114                $element = new Element\Input\Datalist($name, $values, $value);
115                break;
116            case 'datetime':
117                $element = new Element\Input\DateTime($name, $value);
118                break;
119            case 'datetime-local':
120                $element = new Element\Input\DateTimeLocal($name, $value);
121                break;
122            case 'number':
123                $element = new Element\Input\Number($name, $min, $max, $value);
124                break;
125            case 'range':
126                $element = new Element\Input\Range($name, $min, $max, $value);
127                break;
128            default:
129                $class = 'Pop\\Form\\Element\\Input\\' . ucfirst(strtolower($type));
130                if (!class_exists($class)) {
131                    throw new Exception('Error: That class for that form element (' . $type . ') does not exist.');
132                }
133                $element = new $class($name, $value);
134                if ($class == 'Pop\\Form\\Element\\Input\\Password') {
135                    $element->setRenderValue($render);
136                }
137        }
138
139        // Set the label.
140        if ($label !== null) {
141            $element->setLabel($label);
142        }
143        // Set the label attributes.
144        if (($labelAttribs !== null) && is_array($labelAttribs)) {
145            $element->setLabelAttributes($labelAttribs);
146        }
147        // Set prepend content.
148        if ($prepend !== null) {
149            $element->setPrepend($prepend);
150        }
151        // Set append content.
152        if ($append !== null) {
153            $element->setAppend($append);
154        }
155        // Set the hint.
156        if ($hint !== null) {
157            $element->setHint($hint);
158        }
159        // Set the hint attributes.
160        if (($hintAttribs !== null) && is_array($hintAttribs)) {
161            $element->setHintAttributes($hintAttribs);
162        }
163        // Set if required.
164        if (($required !== null) && ($required)) {
165            $element->setRequired($required, ($field['required_message'] ?? 'This field is required.'));
166        }
167        // Set if disabled.
168        if (($disabled !== null) && ($disabled)) {
169            $element->setDisabled($disabled);
170        }
171        // Set if readonly.
172        if (($readonly !== null) && ($readonly)) {
173            $element->setReadonly($readonly);
174        }
175
176        $element->setErrorPre($errorPre);
177
178        // Set any attributes.
179        if ($attributes !== null) {
180            if ($element instanceof Element\CheckboxSet) {
181                $element->setCheckboxAttributes($attributes);
182            } else if ($element instanceof Element\RadioSet) {
183                $element->setRadioAttributes($attributes);
184            } else {
185                $element->setAttributes($attributes);
186            }
187        }
188        // Set any validators.
189        if ($validators !== null) {
190            if (is_array($validators)) {
191                $element->addValidators($validators);
192            } else {
193                $element->addValidator($validators);
194            }
195        }
196
197        return $element;
198    }
199
200    /**
201     * Static factory method to get field configs from a database table
202     *
203     * @param  array  $tableInfo
204     * @param  ?array $attribs
205     * @param  ?array $config
206     * @param  mixed  $omit
207     * @throws Exception
208     * @return array
209     */
210    public static function getConfigFromTable(
211        array $tableInfo, ?array $attribs = null, ?array $config = null, mixed $omit = null
212    ): array
213    {
214        $fields = [];
215
216        if (!isset($tableInfo['tableName']) || !isset($tableInfo['columns'])) {
217            throw new Exception('Error: The table info parameter is not in the correct format');
218        }
219
220        if ($omit !== null) {
221            if (!is_array($omit)) {
222                $omit = [$omit];
223            }
224        } else {
225            $omit = [];
226        }
227
228        if ($config === null) {
229            $config = [];
230        }
231
232        foreach ($tableInfo['columns'] as $name => $value) {
233            if (!in_array($name, $omit)) {
234                $fieldValue = null;
235                $fieldLabel = null;
236                $attributes = null;
237
238                if (isset($config[$name]) && isset($config[$name]['validators'])) {
239                    $validators = (!is_array($config[$name]['validators'])) ?
240                        [$config[$name]['validators']] : $config[$name]['validators'];
241                } else {
242                    $validators = null;
243                }
244
245                if (isset($config[$name]) && isset($config[$name]['type'])) {
246                    $fieldType = $config[$name]['type'];
247                } else if (stripos($name, 'password') !== false) {
248                    $fieldType = 'password';
249                } else if ((stripos($name, 'email') !== false) || (stripos($name, 'e-mail') !== false) ||
250                    (stripos($name, 'e_mail') !== false)) {
251                    $fieldType = 'email';
252                    if ($validators !== null) {
253                        $validators[] = new \Pop\Validator\Email();
254                    } else {
255                        $validators = [new \Pop\Validator\Email()];
256                    }
257                } else {
258                    $fieldType = (stripos($value['type'], 'text') !== false) ? 'textarea' : 'text';
259                }
260
261                $fieldValue = (isset($config[$name]) && isset($config[$name]['value'])) ? $config[$name]['value'] : null;
262
263                if ($fieldType != 'hidden') {
264                    $fieldLabel = ucwords(str_replace('_', ' ', $name)) . ':';
265                }
266
267                if ($attribs !== null) {
268                    if (isset($attribs[$fieldType])) {
269                        $attributes =  $attribs[$fieldType];
270                    }
271                }
272
273                $required = (isset($config[$name]) && isset($config[$name]['required'])) ?
274                    (bool)$config[$name]['required'] : !($value['null']);
275
276                $fields[$name] = [
277                    'type'       => $fieldType,
278                    'label'      => $fieldLabel,
279                    'value'      => $fieldValue,
280                    'required'   => $required,
281                    'attributes' => $attributes,
282                    'validators' => $validators
283                ];
284            }
285        }
286
287        return $fields;
288    }
289
290}