Issues (3627)

bundles/FormBundle/Controller/FieldController.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\Controller;
13
14
use Mautic\CoreBundle\Controller\FormController as CommonFormController;
15
use Mautic\FormBundle\Entity\Field;
16
use Mautic\FormBundle\Event\FormBuilderEvent;
17
use Mautic\FormBundle\FormEvents;
18
use Mautic\FormBundle\Model\FormModel;
19
use Symfony\Component\HttpFoundation\JsonResponse;
20
21
/**
22
 * Class FieldController.
23
 */
24
class FieldController extends CommonFormController
25
{
26
    /**
27
     * Generates new form and processes post data.
28
     *
29
     * @return JsonResponse
30
     */
31
    public function newAction()
32
    {
33
        $success = 0;
34
        $valid   = $cancelled   = false;
35
        $method  = $this->request->getMethod();
36
        $session = $this->get('session');
37
38
        if ('POST' == $method) {
39
            $formField = $this->request->request->get('formfield');
40
            $fieldType = $formField['type'];
41
            $formId    = $formField['formId'];
42
        } else {
43
            $fieldType = $this->request->query->get('type');
44
            $formId    = $this->request->query->get('formId');
45
            $formField = [
46
                'type'   => $fieldType,
47
                'formId' => $formId,
48
            ];
49
        }
50
51
        $customComponents = $this->getModel('form')->getCustomComponents();
0 ignored issues
show
The method getCustomComponents() does not exist on Mautic\CoreBundle\Model\AbstractCommonModel. It seems like you code against a sub-type of Mautic\CoreBundle\Model\AbstractCommonModel such as Mautic\FormBundle\Model\FormModel. ( Ignorable by Annotation )

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

51
        $customComponents = $this->getModel('form')->/** @scrutinizer ignore-call */ getCustomComponents();
Loading history...
52
        $customParams     = (isset($customComponents['fields'][$fieldType])) ? $customComponents['fields'][$fieldType] : false;
53
        //ajax only for form fields
54
        if (!$fieldType ||
55
            !$this->request->isXmlHttpRequest() ||
56
            !$this->get('mautic.security')->isGranted(['form:forms:editown', 'form:forms:editother', 'form:forms:create'], 'MATCH_ONE')
57
        ) {
58
            return $this->modalAccessDenied();
59
        }
60
61
        // Generate the form
62
        $form = $this->getFieldForm($formId, $formField);
63
64
        if (!empty($customParams)) {
65
            $formField['isCustom']         = true;
66
            $formField['customParameters'] = $customParams;
67
        }
68
69
        //Check for a submitted form and process it
70
        if ('POST' == $method) {
71
            if (!$cancelled = $this->isFormCancelled($form)) {
72
                if ($valid = $this->isFormValid($form)) {
73
                    $success = 1;
74
75
                    //form is valid so process the data
76
                    $keyId = 'new'.hash('sha1', uniqid(mt_rand()));
77
78
                    //save the properties to session
79
                    $fields          = $session->get('mautic.form.'.$formId.'.fields.modified', []);
80
                    $formData        = $form->getData();
81
                    $formField       = array_merge($formField, $formData);
82
                    $formField['id'] = $keyId;
83
84
                    // Get aliases in order to generate a new one for the new field
85
                    $aliases = [];
86
                    foreach ($fields as $f) {
87
                        $aliases[] = $f['alias'];
88
                    }
89
90
                    // Generate or ensure a unique alias
91
                    $alias              = empty($formField['alias']) ? $formField['label'] : $formField['alias'];
92
                    $formField['alias'] = $this->getModel('form.field')->generateAlias($alias, $aliases);
93
94
                    // Force required for captcha if not a honeypot
95
                    if ('captcha' == $formField['type']) {
96
                        $formField['isRequired'] = !empty($formField['properties']['captcha']);
97
                    }
98
99
                    // Add it to the next to last assuming the last is the submit button
100
                    if (count($fields)) {
101
                        $lastField = end($fields);
102
                        $lastKey   = key($fields);
103
                        array_pop($fields);
104
105
                        $fields[$keyId]   = $formField;
106
                        $fields[$lastKey] = $lastField;
107
                    } else {
108
                        $fields[$keyId] = $formField;
109
                    }
110
111
                    $session->set('mautic.form.'.$formId.'.fields.modified', $fields);
112
113
                    // Keep track of used lead fields
114
                    $usedLeadFields = $this->get('session')->get('mautic.form.'.$formId.'.fields.leadfields', []);
115
                    if (!empty($formData['leadField'])) {
116
                        $usedLeadFields[$keyId] = $formData['leadField'];
117
                    } else {
118
                        unset($usedLeadFields[$keyId]);
119
                    }
120
                    $session->set('mautic.form.'.$formId.'.fields.leadfields', $usedLeadFields);
121
                } else {
122
                    $success = 0;
123
                }
124
            }
125
        }
126
127
        $viewParams = ['type' => $fieldType];
128
        if ($cancelled || $valid) {
129
            $closeModal = true;
130
        } else {
131
            $closeModal                = false;
132
            $viewParams['tmpl']        = 'field';
133
            $viewParams['form']        = (isset($customParams['formTheme'])) ? $this->setFormTheme($form, 'MauticFormBundle:Builder:field.html.php', $customParams['formTheme']) : $form->createView();
134
            $viewParams['fieldHeader'] = (!empty($customParams)) ? $this->get('translator')->trans($customParams['label']) : $this->get('translator')->transConditional('mautic.core.type.'.$fieldType, 'mautic.form.field.type.'.$fieldType);
135
        }
136
137
        $passthroughVars = [
138
            'mauticContent' => 'formField',
139
            'success'       => $success,
140
            'route'         => false,
141
        ];
142
143
        if (!empty($keyId)) {
144
            //prevent undefined errors
145
            $entity    = new Field();
146
            $blank     = $entity->convertToArray();
147
            $formField = array_merge($blank, $formField);
148
149
            /** @var FormModel $formModel */
150
            $formModel  = $this->getModel('form');
151
            $formEntity = $formModel->getEntity($formId);
152
153
            $passthroughVars['fieldId']   = $keyId;
154
            $template                     = (!empty($customParams)) ? $customParams['template'] : 'MauticFormBundle:Field:'.$fieldType.'.html.php';
155
            $passthroughVars['fieldHtml'] = $this->renderView(
156
                'MauticFormBundle:Builder:fieldwrapper.html.php',
157
                [
158
                    'template'      => $template,
159
                    'inForm'        => true,
160
                    'field'         => $formField,
161
                    'id'            => $keyId,
162
                    'formId'        => $formId,
163
                    'formName'      => null === $formEntity ? 'newform' : $formEntity->generateFormName(),
164
                    'contactFields' => $this->getModel('lead.field')->getFieldListWithProperties(),
165
                    'companyFields' => $this->getModel('lead.field')->getFieldListWithProperties('company'),
166
                    'inBuilder'     => true,
167
                ]
168
            );
169
        }
170
171
        if ($closeModal) {
172
            //just close the modal
173
            $passthroughVars['closeModal'] = 1;
174
175
            return new JsonResponse($passthroughVars);
176
        }
177
178
        return $this->ajaxAction([
179
            'contentTemplate' => 'MauticFormBundle:Builder:'.$viewParams['tmpl'].'.html.php',
180
            'viewParameters'  => $viewParams,
181
            'passthroughVars' => $passthroughVars,
182
        ]);
183
    }
184
185
    /**
186
     * Generates edit form and processes post data.
187
     *
188
     * @param int $objectId
189
     *
190
     * @return JsonResponse
191
     */
192
    public function editAction($objectId)
193
    {
194
        $session   = $this->get('session');
195
        $method    = $this->request->getMethod();
196
        $formfield = $this->request->request->get('formfield', []);
197
        $formId    = 'POST' === $method ? ($formfield['formId'] ?? '') : $this->request->query->get('formId');
198
        $fields    = $session->get('mautic.form.'.$formId.'.fields.modified', []);
199
        $success   = 0;
200
        $valid     = $cancelled = false;
201
        $formField = array_key_exists($objectId, $fields) ? $fields[$objectId] : [];
202
203
        if (null !== $formField) {
204
            $fieldType = $formField['type'];
205
206
            //ajax only for form fields
207
            if (!$fieldType ||
208
                !$this->request->isXmlHttpRequest() ||
209
                !$this->get('mautic.security')->isGranted(['form:forms:editown', 'form:forms:editother', 'form:forms:create'], 'MATCH_ONE')
210
            ) {
211
                return $this->modalAccessDenied();
212
            }
213
214
            // Generate the form
215
            $form = $this->getFieldForm($formId, $formField);
216
217
            //Check for a submitted form and process it
218
            if ('POST' == $method) {
219
                if (!$cancelled = $this->isFormCancelled($form)) {
220
                    if ($valid = $this->isFormValid($form)) {
221
                        $success = 1;
222
223
                        //form is valid so process the data
224
225
                        //save the properties to session
226
                        $session  = $this->get('session');
227
                        $fields   = $session->get('mautic.form.'.$formId.'.fields.modified');
228
                        $formData = $form->getData();
229
230
                        //overwrite with updated data
231
                        $formField = array_merge($fields[$objectId], $formData);
232
233
                        if (false !== strpos($objectId, 'new')) {
234
                            // Get aliases in order to generate update for this one
235
                            $aliases = [];
236
                            foreach ($fields as $k => $f) {
237
                                if ($k != $objectId) {
238
                                    $aliases[] = $f['alias'];
239
                                }
240
                            }
241
                            $formField['alias'] = $this->getModel('form.field')->generateAlias($formField['label'], $aliases);
242
                        }
243
244
                        // Force required for captcha if not a honeypot
245
                        if ('captcha' == $formField['type']) {
246
                            $formField['isRequired'] = !empty($formField['properties']['captcha']);
247
                        }
248
249
                        $fields[$objectId] = $formField;
250
                        $session->set('mautic.form.'.$formId.'.fields.modified', $fields);
251
252
                        // Keep track of used lead fields
253
                        $usedLeadFields = $this->get('session')->get('mautic.form.'.$formId.'.fields.leadfields', []);
254
                        if (!empty($formData['leadField'])) {
255
                            $usedLeadFields[$objectId] = $formData['leadField'];
256
                        } else {
257
                            unset($usedLeadFields[$objectId]);
258
                        }
259
                        $session->set('mautic.form.'.$formId.'.fields.leadfields', $usedLeadFields);
260
                    }
261
                }
262
            }
263
264
            $viewParams       = ['type' => $fieldType];
265
            $customComponents = $this->getModel('form.form')->getCustomComponents();
266
            $customParams     = (isset($customComponents['fields'][$fieldType])) ? $customComponents['fields'][$fieldType] : false;
267
268
            if ($cancelled || $valid) {
269
                $closeModal = true;
270
            } else {
271
                $closeModal         = false;
272
                $viewParams['tmpl'] = 'field';
273
                $viewParams['form'] = (isset($customParams['formTheme'])) ? $this->setFormTheme(
274
                    $form,
275
                    'MauticFormBundle:Builder:field.html.php',
276
                    $customParams['formTheme']
277
                ) : $form->createView();
278
                $viewParams['fieldHeader'] = (!empty($customParams))
279
                    ? $this->get('translator')->trans($customParams['label'])
280
                    : $this->get(
281
                        'translator'
282
                    )->transConditional('mautic.core.type.'.$fieldType, 'mautic.form.field.type.'.$fieldType);
283
            }
284
285
            $passthroughVars = [
286
                'mauticContent' => 'formField',
287
                'success'       => $success,
288
                'route'         => false,
289
            ];
290
291
            $passthroughVars['fieldId'] = $objectId;
292
            $template                   = (!empty($customParams)) ? $customParams['template'] : 'MauticFormBundle:Field:'.$fieldType.'.html.php';
293
294
            //prevent undefined errors
295
            $entity    = new Field();
296
            $blank     = $entity->convertToArray();
297
            $formField = array_merge($blank, $formField);
298
299
            $passthroughVars['fieldHtml'] = $this->renderView(
300
                'MauticFormBundle:Builder:fieldwrapper.html.php',
301
                [
302
                    'template'      => $template,
303
                    'inForm'        => true,
304
                    'field'         => $formField,
305
                    'id'            => $objectId,
306
                    'formId'        => $formId,
307
                    'contactFields' => $this->getModel('lead.field')->getFieldListWithProperties(),
308
                    'companyFields' => $this->getModel('lead.field')->getFieldListWithProperties('company'),
309
                    'inBuilder'     => true,
310
                ]
311
            );
312
313
            if ($closeModal) {
314
                //just close the modal
315
                $passthroughVars['closeModal'] = 1;
316
317
                return new JsonResponse($passthroughVars);
318
            }
319
320
            return $this->ajaxAction(
321
                [
322
                    'contentTemplate' => 'MauticFormBundle:Builder:'.$viewParams['tmpl'].'.html.php',
323
                    'viewParameters'  => $viewParams,
324
                    'passthroughVars' => $passthroughVars,
325
                ]
326
            );
327
        }
328
329
        return new JsonResponse(['success' => 0]);
330
    }
331
332
    /**
333
     * Deletes the entity.
334
     *
335
     * @param int $objectId
336
     *
337
     * @return JsonResponse
338
     */
339
    public function deleteAction($objectId)
340
    {
341
        $session = $this->get('session');
342
        $formId  = $this->request->query->get('formId');
343
        $fields  = $session->get('mautic.form.'.$formId.'.fields.modified', []);
344
        $delete  = $session->get('mautic.form.'.$formId.'.fields.deleted', []);
345
346
        //ajax only for form fields
347
        if (!$this->request->isXmlHttpRequest() ||
348
            !$this->get('mautic.security')->isGranted(['form:forms:editown', 'form:forms:editother', 'form:forms:create'], 'MATCH_ONE')
349
        ) {
350
            return $this->accessDenied();
351
        }
352
353
        $formField = (array_key_exists($objectId, $fields)) ? $fields[$objectId] : null;
354
355
        if ('POST' === $this->request->getMethod() && null !== $formField) {
356
            $usedLeadFields = $session->get('mautic.form.'.$formId.'.fields.leadfields');
357
358
            // Allow to select the lead field from the delete field again
359
            $unusedLeadField = array_search($formField['leadField'], $usedLeadFields);
360
            if (!empty($formField['leadField']) && false !== $unusedLeadField) {
361
                unset($usedLeadFields[$unusedLeadField]);
362
                $session->set('mautic.form.'.$formId.'.fields.leadfields', $usedLeadFields);
363
            }
364
365
            //add the field to the delete list
366
            if (!in_array($objectId, $delete)) {
367
                $delete[] = $objectId;
368
                $session->set('mautic.form.'.$formId.'.fields.deleted', $delete);
369
            }
370
371
            $dataArray = [
372
                'mauticContent' => 'formField',
373
                'success'       => 1,
374
                'route'         => false,
375
            ];
376
        } else {
377
            $dataArray = ['success' => 0];
378
        }
379
380
        return new JsonResponse($dataArray);
381
    }
382
383
    /**
384
     * @param $formId
385
     *
386
     * @return mixed
387
     */
388
    private function getFieldForm($formId, array $formField)
389
    {
390
        //fire the form builder event
391
        $customComponents = $this->getModel('form.form')->getCustomComponents();
392
        $customParams     = (isset($customComponents['fields'][$formField['type']])) ? $customComponents['fields'][$formField['type']] : false;
393
394
        $form = $this->getModel('form.field')->createForm(
395
            $formField,
396
            $this->get('form.factory'),
397
            (!empty($formField['id'])) ?
398
                $this->generateUrl('mautic_formfield_action', ['objectAction' => 'edit', 'objectId' => $formField['id']])
399
                : $this->generateUrl('mautic_formfield_action', ['objectAction' => 'new']),
400
            ['customParameters' => $customParams]
401
        );
402
        $form->get('formId')->setData($formId);
403
404
        $event      = new FormBuilderEvent($this->get('translator'));
405
        $this->dispatcher->dispatch(FormEvents::FORM_ON_BUILD, $event);
406
        $event->addValidatorsToBuilder($form);
407
408
        return $form;
409
    }
410
}
411