Issues (281)

Branch: master

src/Common/Core/Form.php (1 issue)

1
<?php
2
3
namespace Common\Core;
4
5
use Backend\Core\Engine\Header as BackendHeader;
6
use Exception;
7
use Frontend\Core\Header\Header as FrontendHeader;
8
use Backend\Core\Engine\Url as BackendUrl;
9
use Frontend\Core\Engine\Url as FrontendUrl;
10
use SpoonFilter;
11
use SpoonFormButton;
12
use SpoonFormDropdown;
13
use SpoonFormPassword;
14
use SpoonFormRadiobutton;
15
use SpoonFormText;
16
use SpoonFormTextarea;
17
use SpoonFormTime;
18
19
/**
20
 * This class will initiate the frontend-application
21
 */
22
class Form extends \SpoonForm
23
{
24
    /**
25
     * The header instance
26
     *
27
     * @var BackendHeader|FrontendHeader
28
     */
29
    protected $header;
30
31
    /**
32
     * The URL instance
33
     *
34
     * @var BackendUrl|FrontendUrl
35
     */
36
    protected $url;
37
38
    /**
39
     * @param string $name Name of the form
40
     * @param string|null $action The action (URL) whereto the form will be submitted, if not provided it
41
     *                            will be auto generated.
42
     * @param string|null $method The method to use when submitting the form, default is POST.
43
     * @param string $hash The id of the anchor to append to the action-URL.
44
     * @param bool $useToken Should we automatically add a formtoken?
45
     */
46 90
    public function __construct(
47
        string $name,
48
        string $action = null,
49
        ?string $method = 'post',
50
        string $hash = null,
51
        bool $useToken = true
52
    ) {
53 90
        $this->url = Model::getContainer()->get('url');
54 90
        if (Model::getContainer()->has('header')) {
55 90
            $this->header = Model::getContainer()->get('header');
56
        }
57
58 90
        $action = ($action === null) ? rtrim(Model::getRequest()->getRequestUri(), '/') : (string) $action;
59
60 90
        if ($hash !== null && mb_strlen($hash) > 0) {
61
            // check if the # is present
62
            if ($hash[0] !== '#') {
63
                $hash = '#' . $hash;
64
            }
65
66
            $action .= $hash;
67
        }
68
69 90
        parent::__construct($name, $action, $method ?? 'post', $useToken);
70
71 90
        $this->setParameter('id', $name);
72 90
        $this->setParameter('class', 'fork-form submitWithLink');
73 90
    }
74
75
    /**
76
     * Adds a button to the form
77
     *
78
     * @param string $name Name of the button.
79
     * @param string $value The value (or label) that will be printed.
80
     * @param string $type The type of the button (submit is default).
81
     * @param string $class Class(es) that will be applied on the button.
82
     *
83
     * @throws Exception
84
     *
85
     * @return SpoonFormButton
86
     */
87
    public function addButton($name, $value, $type = 'submit', $class = null): SpoonFormButton
88
    {
89
        $name = (string) $name;
90
        $value = (string) $value;
91
        $type = (string) $type;
92
        $class = (string) ($class ?? 'btn btn-primary');
93
94
        // do a check
95
        if ($type === 'submit' && $name === 'submit') {
96
            throw new Exception(
97
                'You can\'t add buttons with the name submit. JS freaks out when we
98
                replace the buttons with a link and use that link to submit the form.'
99
            );
100
        }
101
102
        // create and return a button
103
        return parent::addButton($name, $value, $type, $class);
104
    }
105
106
    /**
107
     * Adds a date field to the form
108
     *
109
     * @param string $name Name of the element.
110
     * @param mixed $value The value for the element.
111
     * @param string $type The type (from, till, range) of the datepicker.
112
     * @param int $date The date to use.
113
     * @param int $date2 The second date for a rangepicker.
114
     * @param string $class Class(es) that have to be applied on the element.
115
     * @param string $classError Class(es) that have to be applied when an error occurs on the element.
116
     *
117
     * @throws Exception
118
     *
119
     * @return FormDate
120
     */
121 7
    public function addDate(
122
        $name,
123
        $value = null,
124
        $type = null,
125
        $date = null,
126
        $date2 = null,
127
        $class = null,
128
        $classError = null
129
    ): FormDate {
0 ignored issues
show
The type Common\Core\FormDate was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
130 7
        $name = (string) $name;
131 7
        $value = ($value === null || $value === '') ? null : (int) $value;
132 7
        $type = SpoonFilter::getValue($type, ['from', 'till', 'range'], 'none');
133 7
        $date = ($date !== null) ? (int) $date : null;
134 7
        $date2 = ($date2 !== null) ? (int) $date2 : null;
135 7
        $class = (string) ($class ?? 'form-control fork-form-date inputDate');
136 7
        $classError = (string) ($classError ?? 'error form-control-danger is-invalid');
137
138
        // validate
139 7
        if ($type === 'from' && ($date === 0 || $date === null)) {
140
            throw new Exception('A date field with type "from" should have a valid date-parameter.');
141
        }
142 7
        if ($type === 'till' && ($date === 0 || $date === null)) {
143
            throw new Exception('A date field with type "till" should have a valid date-parameter.');
144
        }
145 7
        if ($type === 'range' && ($date === 0 || $date2 === 0 || $date === null || $date2 === null)) {
146
            throw new Exception('A date field with type "range" should have 2 valid date-parameters.');
147
        }
148
149
        // set mask and firstday
150 7
        $mask = 'd/m/Y';
151 7
        $firstDay = 1;
152
153
        // build attributes
154 7
        $attributes = [];
155 7
        $attributes['data-mask'] = str_replace(
156 7
            ['d', 'm', 'Y', 'j', 'n'],
157 7
            ['dd', 'mm', 'yy', 'd', 'm'],
158 7
            $mask
159
        );
160 7
        $attributes['data-firstday'] = $firstDay;
161 7
        $attributes['data-year'] = date('Y', $value);
162
        // -1 because javascript starts at 0
163 7
        $attributes['data-month'] = date('n', $value) - 1;
164 7
        $attributes['data-day'] = date('j', $value);
165
166
        // add extra classes based on type
167
        switch ($type) {
168 7
            case 'from':
169
                $class .= ' fork-form-date-from inputDatefieldFrom form-control';
170
                $classError .= ' inputDatefieldFrom';
171
                $attributes['data-startdate'] = date('Y-m-d', $date);
172
                break;
173
174 7
            case 'till':
175
                $class .= ' fork-form-date-till inputDatefieldTill form-control';
176
                $classError .= ' inputDatefieldTill';
177
                $attributes['data-enddate'] = date('Y-m-d', $date);
178
                break;
179
180 7
            case 'range':
181 2
                $class .= ' fork-form-date-range inputDatefieldRange form-control';
182 2
                $classError .= ' inputDatefieldRange';
183 2
                $attributes['data-startdate'] = date('Y-m-d', $date);
184 2
                $attributes['data-enddate'] = date('Y-m-d', $date2);
185 2
                break;
186
187
            default:
188 5
                $class .= ' inputDatefieldNormal form-control';
189 5
                $classError .= ' inputDatefieldNormal';
190 5
                break;
191
        }
192
193 7
        $this->add(new FormDate($name, $value, $mask, $class, $classError));
194
195 7
        parent::getField($name)->setAttributes($attributes);
196
197 7
        return parent::getField($name);
198
    }
199
200
    /**
201
     * Adds a single checkbox.
202
     *
203
     * @param string $name       The name of the element.
204
     * @param bool   $checked    Should the checkbox be checked?
205
     * @param string $class      Class(es) that will be applied on the element.
206
     * @param string $classError Class(es) that will be applied on the element when an error occurs.
207
     *
208
     * @return CommonFormCheckbox
209
     */
210 8
    public function addCheckbox($name, $checked = false, $class = null, $classError = null)
211
    {
212 8
        $name = (string) $name;
213 8
        $checked = (bool) $checked;
214 8
        $class = (string) ($class ?? 'fork-form-checkbox');
215 8
        $classError = (string) ($classError ?? 'error form-control-danger is-invalid');
216
217
        // create and return a checkbox
218 8
        $this->add(new CommonFormCheckbox($name, $checked, $class, $classError));
219
220
        // return element
221 8
        return $this->getField($name);
222
    }
223
224
    /**
225
     * Adds a single dropdown.
226
     *
227
     * @param string $name              Name of the element.
228
     * @param array  $values            Values for the dropdown.
229
     * @param string $selected          The selected elements.
230
     * @param bool   $multipleSelection Is it possible to select multiple items?
231
     * @param string $class             Class(es) that will be applied on the element.
232
     * @param string $classError        Class(es) that will be applied on the element when an error occurs.
233
     *
234
     * @return SpoonFormDropdown
235
     */
236 11
    public function addDropdown(
237
        $name,
238
        array $values = null,
239
        $selected = null,
240
        $multipleSelection = false,
241
        $class = null,
242
        $classError = null
243
    ): SpoonFormDropdown {
244 11
        $name = (string) $name;
245 11
        $multipleSelection = (bool) $multipleSelection;
246 11
        $class = (string) ($class ?? 'form-control fork-form-select');
247 11
        $classError = (string) ($classError ?? 'error form-control-danger is-invalid');
248
249
        // special classes for multiple
250 11
        if ($multipleSelection) {
251
            $class .= ' fork-form-select-multiple';
252
        }
253
254
        // create and return a dropdown
255 11
        return parent::addDropdown($name, Model::recursiveHtmlspecialchars($values), $selected, $multipleSelection, $class, $classError);
256
    }
257
258
    /**
259
     * Adds a multiple checkbox.
260
     *
261
     * @param string $name       The name of the element.
262
     * @param array  $values     The values for the checkboxes.
263
     * @param mixed  $checked    Should the checkboxes be checked?
264
     * @param string $class      Class(es) that will be applied on the element.
265
     *
266
     * @return \SpoonFormMultiCheckbox
267
     */
268
    public function addMultiCheckbox($name, array $values, $checked = null, $class = null)
269
    {
270
        $name = (string) $name;
271
        $checked = ($checked !== null) ? (array) $checked : null;
272
        $class = (string) ($class ?? 'fork-form-multi-checkbox');
273
274
        // create and return a multi checkbox
275
        return parent::addMultiCheckbox($name, $values, $checked, $class);
276
    }
277
278
    /**
279
     * Adds a single password field.
280
     *
281
     * @param string $name       The name of the field.
282
     * @param string $value      The value for the field.
283
     * @param int    $maxLength  The maximum length for the field.
284
     * @param string $class      Class(es) that will be applied on the element.
285
     * @param string $classError Class(es) that will be applied on the element when an error occurs.
286
     * @param bool   $HTML       Will the field contain HTML?
287
     *
288
     * @return SpoonFormPassword
289
     */
290 67
    public function addPassword(
291
        $name,
292
        $value = null,
293
        $maxLength = null,
294
        $class = null,
295
        $classError = null,
296
        $HTML = false
297
    ): SpoonFormPassword {
298 67
        $name = (string) $name;
299 67
        $value = ($value !== null) ? (string) $value : null;
300 67
        $maxLength = ($maxLength !== null) ? (int) $maxLength : null;
301 67
        $class = (string) ($class ?? 'form-control fork-form-password inputPassword');
302 67
        $classError = (string) ($classError ?? 'error form-control-danger is-invalid');
303 67
        $HTML = (bool) $HTML;
304
305
        // create and return a password field
306 67
        return parent::addPassword($name, $value, $maxLength, $class, $classError, $HTML);
307
    }
308
309
    /**
310
     * Adds a single radio button.
311
     *
312
     * @param string $name       The name of the element.
313
     * @param array  $values     The possible values for the radio button.
314
     * @param string $checked    Should the element be checked?
315
     * @param string $class      Class(es) that will be applied on the element.
316
     *
317
     * @return SpoonFormRadiobutton
318
     */
319 10
    public function addRadiobutton($name, array $values, $checked = null, $class = null): SpoonFormRadiobutton
320
    {
321 10
        $name = (string) $name;
322 10
        $checked = ($checked !== null) ? (string) $checked : null;
323 10
        $class = (string) ($class ?? 'fork-form-radio');
324
325
        // create and return a radio button
326 10
        return parent::addRadiobutton($name, $values, $checked, $class);
327
    }
328
329
    /**
330
     * Adds a single textfield.
331
     *
332
     * @param string $name The name of the element.
333
     * @param string $value The value inside the element.
334
     * @param int $maxLength The maximum length for the value.
335
     * @param string $class Class(es) that will be applied on the element.
336
     * @param string $classError Class(es) that will be applied on the element when an error occurs.
337
     * @param bool $HTML Will this element contain HTML?
338
     *
339
     * @return SpoonFormText
340
     */
341 88
    public function addText(
342
        $name,
343
        $value = null,
344
        $maxLength = 255,
345
        $class = null,
346
        $classError = null,
347
        $HTML = true
348
    ): SpoonFormText {
349 88
        $name = (string) $name;
350 88
        $value = ($value !== null) ? (string) $value : null;
351 88
        $maxLength = (int) ($maxLength ?? 255);
352 88
        $class = (string) ($class ?? 'form-control fork-form-text');
353 88
        $classError = (string) ($classError ?? 'error form-control-danger is-invalid');
354 88
        $HTML = (bool) $HTML;
355
356
        // create and return a textfield
357 88
        return parent::addText($name, $value, $maxLength, $class, $classError, $HTML);
358
    }
359
360
    /**
361
     * Adds a single textarea.
362
     *
363
     * @param string $name       The name of the element.
364
     * @param string $value      The value inside the element.
365
     * @param string $class      Class(es) that will be applied on the element.
366
     * @param string $classError Class(es) that will be applied on the element when an error occurs.
367
     * @param bool   $HTML       Will the element contain HTML?
368
     *
369
     * @return SpoonFormTextarea
370
     */
371 11
    public function addTextarea(
372
        $name,
373
        $value = null,
374
        $class = null,
375
        $classError = null,
376
        $HTML = true
377
    ): SpoonFormTextarea {
378 11
        $name = (string) $name;
379 11
        $value = ($value !== null) ? (string) $value : null;
380 11
        $class = (string) ($class ?? 'form-control fork-form-textarea');
381 11
        $classError = (string) ($classError ?? 'error form-control-danger is-invalid');
382 11
        $HTML = (bool) $HTML;
383
384
        // create and return a textarea
385 11
        return parent::addTextarea($name, $value, $class, $classError, $HTML);
386
    }
387
388
    /**
389
     * Adds a single time field.
390
     *
391
     * @param string $name       The name of the element.
392
     * @param string $value      The value inside the element.
393
     * @param string $class      Class(es) that will be applied on the element.
394
     * @param string $classError Class(es) that will be applied on the element when an error occurs.
395
     *
396
     * @return SpoonFormTime
397
     */
398 5
    public function addTime($name, $value = null, $class = null, $classError = null): SpoonFormTime
399
    {
400 5
        $name = (string) $name;
401 5
        $value = ($value !== null) ? (string) $value : null;
402 5
        $class = (string) ($class ?? 'form-control fork-form-time inputTime');
403 5
        $classError = (string) ($classError ?? 'error form-control-danger is-invalid');
404
405
        // create and return a time field
406 5
        return parent::addTime($name, $value, $class, $classError);
407
    }
408
409
    /**
410
     * @return string|null
411
     */
412 14
    public static function getUploadMaxFileSize(): ?string
413
    {
414 14
        $uploadMaxFileSize = ini_get('upload_max_filesize');
415 14
        if ($uploadMaxFileSize === false) {
416
            return null;
417
        }
418
419
        // reformat if defined as an integer
420 14
        if (is_numeric($uploadMaxFileSize)) {
421
            return $uploadMaxFileSize / 1024 . 'MB';
422
        }
423
424
        // reformat if specified in kB
425 14
        if (mb_strtoupper(mb_substr($uploadMaxFileSize, -1, 1)) === 'K') {
426
            return mb_substr($uploadMaxFileSize, 0, -1) . 'kB';
427
        }
428
429
        // reformat if specified in MB
430 14
        if (mb_strtoupper(mb_substr($uploadMaxFileSize, -1, 1)) === 'M') {
431 14
            return $uploadMaxFileSize . 'B';
432
        }
433
434
        // reformat if specified in GB
435
        if (mb_strtoupper(mb_substr($uploadMaxFileSize, -1, 1)) === 'G') {
436
            return $uploadMaxFileSize . 'B';
437
        }
438
439
        return $uploadMaxFileSize;
440
    }
441
442 71
    protected function sessionHasFormToken(): bool
443
    {
444 71
        return Model::getSession()->has('form_token');
445
    }
446
447 71
    protected function saveTokenToSession($token): void
448
    {
449 71
        Model::getSession()->set('form_token', $token);
450 71
    }
451
452 71
    protected function getSessionId(): string
453
    {
454 71
        return Model::getSession()->getId();
455
    }
456
457 71
    protected function getTokenFromSession(): ?string
458
    {
459 71
        return Model::getSession()->get('form_token');
460
    }
461
}
462