Issues (3627)

app/bundles/FormBundle/Form/Type/FieldType.php (1 issue)

1
<?php
2
3
/*
4
 * @copyright   2014 Mautic Contributors. All rights reserved
5
 * @author      Mautic
6
 *
7
 * @link        http://mautic.org
8
 *
9
 * @license     GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
10
 */
11
12
namespace Mautic\FormBundle\Form\Type;
13
14
use Mautic\CoreBundle\Form\EventListener\CleanFormSubscriber;
15
use Mautic\CoreBundle\Form\Type\FormButtonsType;
16
use Mautic\CoreBundle\Form\Type\YesNoButtonGroupType;
17
use Mautic\LeadBundle\Helper\FormFieldHelper;
18
use Symfony\Component\Form\AbstractType;
19
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
20
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
21
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
22
use Symfony\Component\Form\Extension\Core\Type\TextType;
23
use Symfony\Component\Form\FormBuilderInterface;
24
use Symfony\Component\OptionsResolver\OptionsResolver;
25
use Symfony\Component\Translation\TranslatorInterface;
26
use Symfony\Component\Validator\Constraints as Assert;
27
28
/**
29
 * Class FieldType.
30
 */
31
class FieldType extends AbstractType
32
{
33
    use FormFieldTrait;
34
35
    /**
36
     * @var TranslatorInterface
37
     */
38
    private $translator;
39
40
    /**
41
     * FieldType constructor.
42
     */
43
    public function __construct(TranslatorInterface $translator)
44
    {
45
        $this->translator = $translator;
46
    }
47
48
    /**
49
     * {@inheritdoc}
50
     */
51
    public function buildForm(FormBuilderInterface $builder, array $options)
52
    {
53
        // Populate settings
54
        $cleanMasks = [
55
            'labelAttributes'     => 'string',
56
            'inputAttributes'     => 'string',
57
            'containerAttributes' => 'string',
58
            'label'               => 'strict_html',
59
        ];
60
61
        $addHelpMessage         =
62
        $addShowLabel           =
63
        $allowCustomAlias       =
64
        $addDefaultValue        =
65
        $addLabelAttributes     =
66
        $addInputAttributes     =
67
        $addContainerAttributes =
68
        $addLeadFieldList       =
69
        $addSaveResult          =
70
        $addBehaviorFields      =
71
        $addIsRequired          = true;
72
73
        if (!empty($options['customParameters'])) {
74
            $type = 'custom';
75
76
            $customParams    = $options['customParameters'];
77
            $formTypeOptions = [
78
                'required' => false,
79
                'label'    => false,
80
            ];
81
            if (!empty($customParams['formTypeOptions'])) {
82
                $formTypeOptions = array_merge($formTypeOptions, $customParams['formTypeOptions']);
83
            }
84
85
            $addFields = [
86
                'labelText',
87
                'addHelpMessage',
88
                'addShowLabel',
89
                'labelText',
90
                'addDefaultValue',
91
                'addLabelAttributes',
92
                'labelAttributesText',
93
                'addInputAttributes',
94
                'inputAttributesText',
95
                'addContainerAttributes',
96
                'containerAttributesText',
97
                'addLeadFieldList',
98
                'addSaveResult',
99
                'addBehaviorFields',
100
                'addIsRequired',
101
                'addHtml',
102
            ];
103
            foreach ($addFields as $f) {
104
                if (isset($customParams['builderOptions'][$f])) {
105
                    $$f = (bool) $customParams['builderOptions'][$f];
106
                }
107
            }
108
        } else {
109
            $type = $options['data']['type'];
110
            switch ($type) {
111
                case 'freetext':
112
                    $addHelpMessage      = $addDefaultValue      = $addIsRequired      = $addLeadFieldList      = $addSaveResult      = $addBehaviorFields      = false;
113
                    $labelText           = 'mautic.form.field.form.header';
114
                    $showLabelText       = 'mautic.form.field.form.showheader';
115
                    $inputAttributesText = 'mautic.form.field.form.freetext_attributes';
116
                    $labelAttributesText = 'mautic.form.field.form.header_attributes';
117
118
                    // Allow html
119
                    $cleanMasks['properties'] = 'html';
120
                    break;
121
                case 'freehtml':
122
                    $addHelpMessage      = $addDefaultValue      = $addIsRequired      = $addLeadFieldList      = $addSaveResult      = $addBehaviorFields      = false;
123
                    $labelText           = 'mautic.form.field.form.header';
124
                    $showLabelText       = 'mautic.form.field.form.showheader';
125
                    $inputAttributesText = 'mautic.form.field.form.freehtml_attributes';
126
                    $labelAttributesText = 'mautic.form.field.form.header_attributes';
127
                    // Allow html
128
                    $cleanMasks['properties'] = 'html';
129
                    break;
130
                case 'button':
131
                    $addHelpMessage = $addShowLabel = $addDefaultValue = $addLabelAttributes = $addIsRequired = $addLeadFieldList = $addSaveResult = $addBehaviorFields = false;
132
                    break;
133
                case 'hidden':
134
                    $addHelpMessage = $addShowLabel = $addLabelAttributes = $addIsRequired = false;
135
                    break;
136
                case 'captcha':
137
                    $addShowLabel = $addIsRequired = $addDefaultValue = $addLeadFieldList = $addSaveResult = $addBehaviorFields = false;
138
                    break;
139
                case 'pagebreak':
140
                    $addShowLabel = $allowCustomAlias = $addHelpMessage = $addIsRequired = $addDefaultValue = $addLeadFieldList = $addSaveResult = $addBehaviorFields = false;
141
                    break;
142
                case 'select':
143
                    $cleanMasks['properties']['list']['list']['label'] = 'strict_html';
144
                    break;
145
                case 'checkboxgrp':
146
                case 'radiogrp':
147
                    $cleanMasks['properties']['optionlist']['list']['label'] = 'strict_html';
148
                    break;
149
                case 'file':
150
                    $addShowLabel = $addDefaultValue = $addBehaviorFields = false;
151
                    break;
152
            }
153
        }
154
155
        // Build form fields
156
        $builder->add(
157
            'label',
158
            TextType::class,
159
            [
160
                'label'       => !empty($labelText) ? $labelText : 'mautic.form.field.form.label',
161
                'label_attr'  => ['class' => 'control-label'],
162
                'attr'        => ['class' => 'form-control'],
163
                'constraints' => [
164
                    new Assert\NotBlank(
165
                        ['message' => 'mautic.form.field.label.notblank']
166
                    ),
167
                ],
168
            ]
169
        );
170
171
        if ($allowCustomAlias) {
172
            $builder->add(
173
                'alias',
174
                TextType::class,
175
                [
176
                    'label'      => 'mautic.form.field.form.alias',
177
                    'label_attr' => ['class' => 'control-label'],
178
                    'attr'       => [
179
                        'class'   => 'form-control',
180
                        'tooltip' => 'mautic.form.field.form.alias.tooltip',
181
                    ],
182
                    'disabled' => (!empty($options['data']['id']) && false === strpos($options['data']['id'], 'new')) ? true : false,
183
                    'required' => false,
184
                ]
185
            );
186
        }
187
188
        if ($addShowLabel) {
189
            $default = (!isset($options['data']['showLabel'])) ? true : (bool) $options['data']['showLabel'];
190
            $builder->add(
191
                'showLabel',
192
                YesNoButtonGroupType::class,
193
                [
194
                    'label' => (!empty($showLabelText)) ? $showLabelText : 'mautic.form.field.form.showlabel',
195
                    'data'  => $default,
196
                ]
197
            );
198
        }
199
200
        if ($addDefaultValue) {
201
            $builder->add(
202
                'defaultValue',
203
                ('textarea' == $type) ? TextareaType::class : TextType::class,
204
                [
205
                    'label'      => 'mautic.core.defaultvalue',
206
                    'label_attr' => ['class' => 'control-label'],
207
                    'attr'       => ['class' => 'form-control'],
208
                    'required'   => false,
209
                ]
210
            );
211
        }
212
213
        if ($addHelpMessage) {
214
            $builder->add(
215
                'helpMessage',
216
                TextType::class,
217
                [
218
                    'label'      => 'mautic.form.field.form.helpmessage',
219
                    'label_attr' => ['class' => 'control-label'],
220
                    'attr'       => [
221
                        'class'   => 'form-control',
222
                        'tooltip' => 'mautic.form.field.help.helpmessage',
223
                    ],
224
                    'required' => false,
225
                ]
226
            );
227
        }
228
229
        if ($addIsRequired) {
230
            $default = (!isset($options['data']['isRequired'])) ? false : (bool) $options['data']['isRequired'];
231
            $builder->add(
232
                'isRequired',
233
                YesNoButtonGroupType::class,
234
                [
235
                    'label' => 'mautic.core.required',
236
                    'data'  => $default,
237
                ]
238
            );
239
240
            $builder->add(
241
                'validationMessage',
242
                TextType::class,
243
                [
244
                    'label'      => 'mautic.form.field.form.validationmsg',
245
                    'label_attr' => ['class' => 'control-label'],
246
                    'attr'       => [
247
                        'class'        => 'form-control',
248
                        'tooltip'      => $this->translator->trans('mautic.core.form.default').': '.$this->translator->trans('mautic.form.field.generic.required', [], 'validators'),
249
                        'data-show-on' => '{"formfield_isRequired_1": "checked"}',
250
                    ],
251
                    'required'   => false,
252
                ]
253
            );
254
        }
255
256
        if ($addLabelAttributes) {
257
            $builder->add(
258
                'labelAttributes',
259
                TextType::class,
260
                [
261
                    'label'      => (!empty($labelAttributesText)) ? $labelAttributesText : 'mautic.form.field.form.labelattr',
262
                    'label_attr' => ['class' => 'control-label'],
263
                    'attr'       => [
264
                        'class'     => 'form-control',
265
                        'tooltip'   => 'mautic.form.field.help.attr',
266
                        'maxlength' => '191',
267
                    ],
268
                    'required' => false,
269
                ]
270
            );
271
        }
272
273
        if ($addInputAttributes) {
274
            $builder->add(
275
                'inputAttributes',
276
                TextType::class,
277
                [
278
                    'label'      => (!empty($inputAttributesText)) ? $inputAttributesText : 'mautic.form.field.form.inputattr',
279
                    'label_attr' => ['class' => 'control-label'],
280
                    'attr'       => [
281
                        'class'     => 'form-control',
282
                        'tooltip'   => 'mautic.form.field.help.attr',
283
                        'maxlength' => '191',
284
                    ],
285
                    'required' => false,
286
                ]
287
            );
288
        }
289
290
        if ($addContainerAttributes) {
291
            $builder->add(
292
                'containerAttributes',
293
                TextType::class,
294
                [
295
                    'label'      => (!empty($containerAttributesText)) ? $containerAttributesText : 'mautic.form.field.form.container_attr',
296
                    'label_attr' => ['class' => 'control-label'],
297
                    'attr'       => [
298
                        'class'     => 'form-control',
299
                        'tooltip'   => 'mautic.form.field.help.container_attr',
300
                        'maxlength' => '191',
301
                    ],
302
                    'required' => false,
303
                ]
304
            );
305
        }
306
307
        if ($addSaveResult) {
308
            $default = (!isset($options['data']['saveResult']) || null === $options['data']['saveResult']) ? true
309
                : (bool) $options['data']['saveResult'];
310
            $builder->add(
311
                'saveResult',
312
                YesNoButtonGroupType::class,
313
                [
314
                    'label' => 'mautic.form.field.form.saveresult',
315
                    'data'  => $default,
316
                    'attr'  => [
317
                        'tooltip' => 'mautic.form.field.help.saveresult',
318
                    ],
319
                ]
320
            );
321
        }
322
323
        if ($addBehaviorFields) {
324
            $default = (!isset($options['data']['showWhenValueExists']) || null === $options['data']['showWhenValueExists']) ? true
325
                : (bool) $options['data']['showWhenValueExists'];
326
            $builder->add(
327
                'showWhenValueExists',
328
                YesNoButtonGroupType::class,
329
                [
330
                    'label' => 'mautic.form.field.form.show.when.value.exists',
331
                    'data'  => $default,
332
                    'attr'  => [
333
                        'tooltip' => 'mautic.form.field.help.show.when.value.exists',
334
                    ],
335
                ]
336
            );
337
338
            $builder->add(
339
                'showAfterXSubmissions',
340
                TextType::class,
341
                [
342
                    'label'      => 'mautic.form.field.form.show.after.x.submissions',
343
                    'label_attr' => ['class' => 'control-label'],
344
                    'attr'       => [
345
                        'class'   => 'form-control',
346
                        'tooltip' => 'mautic.form.field.help.show.after.x.submissions',
347
                    ],
348
                    'required' => false,
349
                ]
350
            );
351
352
            $isAutoFillValue = (!isset($options['data']['isAutoFill'])) ? false : (bool) $options['data']['isAutoFill'];
353
            $builder->add(
354
                'isAutoFill',
355
                YesNoButtonGroupType::class,
356
                [
357
                    'label' => 'mautic.form.field.form.auto_fill',
358
                    'data'  => $isAutoFillValue,
359
                    'attr'  => [
360
                        'class'   => 'auto-fill-data',
361
                        'tooltip' => 'mautic.form.field.help.auto_fill',
362
                    ],
363
                ]
364
            );
365
        }
366
367
        if ($addLeadFieldList) {
368
            if (!isset($options['data']['leadField'])) {
369
                switch ($type) {
370
                    case 'email':
371
                        $data = 'email';
372
                        break;
373
                    case 'country':
374
                        $data = 'country';
375
                        break;
376
                    case 'tel':
377
                        $data = 'phone';
378
                        break;
379
                    default:
380
                        $data = '';
381
                        break;
382
                }
383
            } elseif (isset($options['data']['leadField'])) {
384
                $data = $options['data']['leadField'];
385
            } else {
386
                $data = '';
387
            }
388
389
            $builder->add(
390
                'leadField',
391
                ChoiceType::class,
392
                [
393
                    'choices'           => $options['leadFields'],
394
                    'choice_attr'       => function ($val, $key, $index) use ($options) {
395
                        $objects = ['lead', 'company'];
396
                        foreach ($objects as $object) {
397
                            if (!empty($options['leadFieldProperties'][$object][$val]) && (in_array($options['leadFieldProperties'][$object][$val]['type'], FormFieldHelper::getListTypes()) || !empty($options['leadFieldProperties'][$object][$val]['properties']['list']) || !empty($options['leadFieldProperties'][$object][$val]['properties']['optionlist']))) {
398
                                return ['data-list-type' => 1];
399
                            }
400
                        }
401
402
                        return [];
403
                    },
404
                    'label'      => 'mautic.form.field.form.lead_field',
405
                    'label_attr' => ['class' => 'control-label'],
406
                    'attr'       => [
407
                        'class'   => 'form-control',
408
                        'tooltip' => 'mautic.form.field.help.lead_field',
409
                    ],
410
                    'required' => false,
411
                    'data'     => $data,
412
                ]
413
            );
414
        }
415
416
        $builder->add('type', HiddenType::class);
417
418
        $update = (!empty($options['data']['id'])) ? true : false;
419
        if (!empty($update)) {
420
            $btnValue = 'mautic.core.form.update';
421
            $btnIcon  = 'fa fa-pencil';
422
        } else {
423
            $btnValue = 'mautic.core.form.add';
424
            $btnIcon  = 'fa fa-plus';
425
        }
426
427
        $builder->add(
428
            'buttons',
429
            FormButtonsType::class,
430
            [
431
                'save_text'       => $btnValue,
432
                'save_icon'       => $btnIcon,
433
                'apply_text'      => false,
434
                'container_class' => 'bottom-form-buttons',
435
            ]
436
        );
437
438
        $builder->add(
439
            'formId',
440
            HiddenType::class,
441
            [
442
                'mapped' => false,
443
            ]
444
        );
445
446
        // Put properties last so that the other values are available to form events
447
        $propertiesData = (isset($options['data']['properties'])) ? $options['data']['properties'] : [];
448
        if (!empty($options['customParameters'])) {
449
            $formTypeOptions = array_merge($formTypeOptions, ['data' => $propertiesData]);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $formTypeOptions does not seem to be defined for all execution paths leading up to this point.
Loading history...
450
            $builder->add('properties', $customParams['formType'], $formTypeOptions);
451
        } else {
452
            switch ($type) {
453
                case 'select':
454
                case 'country':
455
                    $builder->add(
456
                        'properties',
457
                        FormFieldSelectType::class,
458
                        [
459
                            'field_type' => $type,
460
                            'label'      => false,
461
                            'parentData' => $options['data'],
462
                            'data'       => $propertiesData,
463
                        ]
464
                    );
465
                    break;
466
                case 'checkboxgrp':
467
                case 'radiogrp':
468
                    $builder->add(
469
                        'properties',
470
                        FormFieldGroupType::class,
471
                        [
472
                            'label' => false,
473
                            'data'  => $propertiesData,
474
                        ]
475
                    );
476
                    break;
477
                case 'freetext':
478
                    $builder->add(
479
                        'properties',
480
                        FormFieldTextType::class,
481
                        [
482
                            'required' => false,
483
                            'label'    => false,
484
                            'editor'   => true,
485
                            'data'     => $propertiesData,
486
                        ]
487
                    );
488
                    break;
489
                case 'freehtml':
490
                    $builder->add(
491
                        'properties',
492
                        FormFieldHTMLType::class,
493
                        [
494
                            'required' => false,
495
                            'label'    => false,
496
                            'editor'   => true,
497
                            'data'     => $propertiesData,
498
                        ]
499
                    );
500
                    break;
501
                case 'date':
502
                case 'email':
503
                case 'number':
504
                case 'text':
505
                case 'url':
506
                case 'tel':
507
                    $builder->add(
508
                        'properties',
509
                        FormFieldPlaceholderType::class,
510
                        [
511
                            'label' => false,
512
                            'data'  => $propertiesData,
513
                        ]
514
                    );
515
                    break;
516
                case 'captcha':
517
                    $builder->add(
518
                        'properties',
519
                        FormFieldCaptchaType::class,
520
                        [
521
                            'label' => false,
522
                            'data'  => $propertiesData,
523
                        ]
524
                    );
525
                    break;
526
                case 'pagebreak':
527
                    $builder->add(
528
                        'properties',
529
                        FormFieldPageBreakType::class,
530
                        [
531
                            'label' => false,
532
                            'data'  => $propertiesData,
533
                        ]
534
                    );
535
                    break;
536
                case 'file':
537
                    if (!isset($propertiesData['public'])) {
538
                        $propertiesData['public'] = false;
539
                    }
540
                    $builder->add(
541
                        'properties',
542
                        FormFieldFileType::class,
543
                        [
544
                            'label' => false,
545
                            'data'  => $propertiesData,
546
                        ]
547
                    );
548
                    break;
549
            }
550
        }
551
552
        $builder->addEventSubscriber(new CleanFormSubscriber($cleanMasks));
553
554
        if (!empty($options['action'])) {
555
            $builder->setAction($options['action']);
556
        }
557
    }
558
559
    /**
560
     * {@inheritdoc}
561
     */
562
    public function configureOptions(OptionsResolver $resolver)
563
    {
564
        $resolver->setDefaults(
565
            [
566
                'customParameters' => false,
567
            ]
568
        );
569
570
        $resolver->setDefined(['customParameters', 'leadFieldProperties']);
571
572
        $resolver->setRequired(['leadFields']);
573
    }
574
575
    /**
576
     * {@inheritdoc}
577
     */
578
    public function getBlockPrefix()
579
    {
580
        return 'formfield';
581
    }
582
}
583