Issues (3627)

bundles/FormBundle/Controller/FormController.php (2 issues)

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\CoreBundle\Factory\PageHelperFactoryInterface;
16
use Mautic\CoreBundle\Form\Type\DateRangeType;
17
use Mautic\FormBundle\Entity\Field;
18
use Mautic\FormBundle\Entity\Form;
19
use Mautic\FormBundle\Exception\ValidationException;
20
use Mautic\FormBundle\Helper\FormFieldHelper;
21
use Mautic\FormBundle\Model\FormModel;
22
use Symfony\Component\Form\FormError;
23
use Symfony\Component\HttpFoundation\Response;
24
25
class FormController extends CommonFormController
26
{
27
    /**
28
     * @param int $page
29
     *
30
     * @return \Symfony\Component\HttpFoundation\JsonResponse|\Symfony\Component\HttpFoundation\RedirectResponse|Response
31
     */
32
    public function indexAction($page = 1)
33
    {
34
        //set some permissions
35
        $permissions = $this->get('mautic.security')->isGranted(
36
            [
37
                'form:forms:viewown',
38
                'form:forms:viewother',
39
                'form:forms:create',
40
                'form:forms:editown',
41
                'form:forms:editother',
42
                'form:forms:deleteown',
43
                'form:forms:deleteother',
44
                'form:forms:publishown',
45
                'form:forms:publishother',
46
            ],
47
            'RETURN_ARRAY'
48
        );
49
50
        if (!$permissions['form:forms:viewown'] && !$permissions['form:forms:viewother']) {
51
            return $this->accessDenied();
52
        }
53
54
        $this->setListFilters();
55
56
        $session = $this->get('session');
57
58
        /** @var PageHelperFactoryInterface $pageHelperFacotry */
59
        $pageHelperFacotry = $this->get('mautic.page.helper.factory');
60
        $pageHelper        = $pageHelperFacotry->make('mautic.form', $page);
61
        $limit             = $pageHelper->getLimit();
62
        $start             = $pageHelper->getStart();
63
        $search            = $this->request->get('search', $session->get('mautic.form.filter', ''));
64
        $filter            = ['string' => $search, 'force' => []];
65
        $session->set('mautic.form.filter', $search);
66
67
        if (!$permissions['form:forms:viewother']) {
68
            $filter['force'][] = ['column' => 'f.createdBy', 'expr' => 'eq', 'value' => $this->user->getId()];
69
        }
70
71
        $orderBy    = $session->get('mautic.form.orderby', 'f.name');
72
        $orderByDir = $session->get('mautic.form.orderbydir', 'ASC');
73
        $forms      = $this->getModel('form.form')->getEntities(
74
            [
75
                'start'      => $start,
76
                'limit'      => $limit,
77
                'filter'     => $filter,
78
                'orderBy'    => $orderBy,
79
                'orderByDir' => $orderByDir,
80
            ]
81
        );
82
83
        $count = count($forms);
84
85
        if ($count && $count < ($start + 1)) {
86
            //the number of entities are now less then the current page so redirect to the last page
87
            $lastPage = $pageHelper->countPage($count);
88
            $pageHelper->rememberPage($lastPage);
89
            $returnUrl = $this->generateUrl('mautic_form_index', ['page' => $lastPage]);
90
91
            return $this->postActionRedirect(
92
                [
93
                    'returnUrl'       => $returnUrl,
94
                    'viewParameters'  => ['page' => $lastPage],
95
                    'contentTemplate' => 'MauticFormBundle:Form:index',
96
                    'passthroughVars' => [
97
                        'activeLink'    => '#mautic_form_index',
98
                        'mauticContent' => 'form',
99
                    ],
100
                ]
101
            );
102
        }
103
104
        $pageHelper->rememberPage($page);
105
106
        return $this->delegateView(
107
            [
108
                'viewParameters'  => [
109
                    'searchValue' => $search,
110
                    'items'       => $forms,
111
                    'totalItems'  => $count,
112
                    'page'        => $page,
113
                    'limit'       => $limit,
114
                    'permissions' => $permissions,
115
                    'security'    => $this->get('mautic.security'),
116
                    'tmpl'        => $this->request->get('tmpl', 'index'),
117
                ],
118
                'contentTemplate' => 'MauticFormBundle:Form:list.html.php',
119
                'passthroughVars' => [
120
                    'activeLink'    => '#mautic_form_index',
121
                    'mauticContent' => 'form',
122
                    'route'         => $this->generateUrl('mautic_form_index', ['page' => $page]),
123
                ],
124
            ]
125
        );
126
    }
127
128
    /**
129
     * Loads a specific form into the detailed panel.
130
     *
131
     * @param int $objectId
132
     *
133
     * @return \Symfony\Component\HttpFoundation\JsonResponse|\Symfony\Component\HttpFoundation\RedirectResponse|Response
134
     */
135
    public function viewAction($objectId)
136
    {
137
        /** @var \Mautic\FormBundle\Model\FormModel $model */
138
        $model      = $this->getModel('form');
139
        $activeForm = $model->getEntity($objectId);
140
141
        //set the page we came from
142
        $page = $this->get('session')->get('mautic.form.page', 1);
143
144
        if (null === $activeForm) {
145
            //set the return URL
146
            $returnUrl = $this->generateUrl('mautic_form_index', ['page' => $page]);
147
148
            return $this->postActionRedirect(
149
                [
150
                    'returnUrl'       => $returnUrl,
151
                    'viewParameters'  => ['page' => $page],
152
                    'contentTemplate' => 'MauticFormBundle:Form:index',
153
                    'passthroughVars' => [
154
                        'activeLink'    => '#mautic_form_index',
155
                        'mauticContent' => 'form',
156
                    ],
157
                    'flashes' => [
158
                        [
159
                            'type'    => 'error',
160
                            'msg'     => 'mautic.form.error.notfound',
161
                            'msgVars' => ['%id%' => $objectId],
162
                        ],
163
                    ],
164
                ]
165
            );
166
        } elseif (!$this->get('mautic.security')->hasEntityAccess(
167
            'form:forms:viewown',
168
            'form:forms:viewother',
169
            $activeForm->getCreatedBy()
170
        )
171
        ) {
172
            return $this->accessDenied();
173
        }
174
175
        $permissions = $this->get('mautic.security')->isGranted(
176
            [
177
                'form:forms:viewown',
178
                'form:forms:viewother',
179
                'form:forms:create',
180
                'form:forms:editown',
181
                'form:forms:editother',
182
                'form:forms:deleteown',
183
                'form:forms:deleteother',
184
                'form:forms:publishown',
185
                'form:forms:publishother',
186
            ],
187
            'RETURN_ARRAY'
188
        );
189
190
        // Audit Log
191
        $logs = $this->getModel('core.auditlog')->getLogForObject('form', $objectId, $activeForm->getDateAdded());
192
193
        // Init the date range filter form
194
        $dateRangeValues = $this->request->get('daterange', []);
195
        $action          = $this->generateUrl('mautic_form_action', ['objectAction' => 'view', 'objectId' => $objectId]);
196
        $dateRangeForm   = $this->get('form.factory')->create(DateRangeType::class, $dateRangeValues, ['action' => $action]);
197
198
        // Submission stats per time period
199
        $timeStats = $this->getModel('form.submission')->getSubmissionsLineChartData(
200
            null,
201
            new \DateTime($dateRangeForm->get('date_from')->getData()),
202
            new \DateTime($dateRangeForm->get('date_to')->getData()),
203
            null,
204
            ['form_id' => $objectId]
205
        );
206
207
        // Only show actions and fields that still exist
208
        $customComponents  = $model->getCustomComponents();
209
        $activeFormActions = [];
210
        foreach ($activeForm->getActions() as $formAction) {
211
            if (!isset($customComponents['actions'][$formAction->getType()])) {
212
                continue;
213
            }
214
            $type                          = explode('.', $formAction->getType());
215
            $activeFormActions[$type[0]][] = $formAction;
216
        }
217
218
        $activeFormFields = [];
219
        $fieldHelper      = $this->get('mautic.helper.form.field_helper');
220
        $availableFields  = array_flip($fieldHelper->getChoiceList($customComponents['fields']));
221
        foreach ($activeForm->getFields() as $field) {
222
            if (!isset($availableFields[$field->getType()])) {
223
                continue;
224
            }
225
226
            $activeFormFields[] = $field;
227
        }
228
229
        $submissionCounts = $this->getModel('form.submission')->getRepository()->getSubmissionCounts($activeForm);
0 ignored issues
show
The method getSubmissionCounts() does not exist on Mautic\CoreBundle\Entity\CommonRepository. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

229
        $submissionCounts = $this->getModel('form.submission')->getRepository()->/** @scrutinizer ignore-call */ getSubmissionCounts($activeForm);
Loading history...
230
231
        return $this->delegateView(
232
            [
233
                'viewParameters' => [
234
                    'activeForm'       => $activeForm,
235
                    'submissionCounts' => $submissionCounts,
236
                    'page'             => $page,
237
                    'logs'             => $logs,
238
                    'permissions'      => $permissions,
239
                    'stats'            => [
240
                        'submissionsInTime' => $timeStats,
241
                    ],
242
                    'dateRangeForm'     => $dateRangeForm->createView(),
243
                    'activeFormActions' => $activeFormActions,
244
                    'activeFormFields'  => $activeFormFields,
245
                    'formScript'        => htmlspecialchars($model->getFormScript($activeForm), ENT_QUOTES, 'UTF-8'),
246
                    'formContent'       => htmlspecialchars($model->getContent($activeForm, false), ENT_QUOTES, 'UTF-8'),
247
                    'availableActions'  => $customComponents['actions'],
248
                ],
249
                'contentTemplate' => 'MauticFormBundle:Form:details.html.php',
250
                'passthroughVars' => [
251
                    'activeLink'    => '#mautic_form_index',
252
                    'mauticContent' => 'form',
253
                    'route'         => $action,
254
                ],
255
            ]
256
        );
257
    }
258
259
    /**
260
     * Generates new form and processes post data.
261
     *
262
     * @return array|\Symfony\Component\HttpFoundation\JsonResponse|\Symfony\Component\HttpFoundation\RedirectResponse|Response
263
     *
264
     * @throws \Exception
265
     */
266
    public function newAction()
267
    {
268
        /** @var \Mautic\FormBundle\Model\FormModel $model */
269
        $model   = $this->getModel('form');
270
        $entity  = $model->getEntity();
271
        $session = $this->get('session');
272
273
        if (!$this->get('mautic.security')->isGranted('form:forms:create')) {
274
            return $this->accessDenied();
275
        }
276
277
        //set the page we came from
278
        $page       = $this->get('session')->get('mautic.form.page', 1);
279
        $mauticform = $this->request->request->get('mauticform', []);
280
        $sessionId  = $mauticform['sessionId'] ?? 'mautic_'.sha1(uniqid(mt_rand(), true));
281
282
        //set added/updated fields
283
        $modifiedFields = $session->get('mautic.form.'.$sessionId.'.fields.modified', []);
284
        $deletedFields  = $session->get('mautic.form.'.$sessionId.'.fields.deleted', []);
285
286
        //set added/updated actions
287
        $modifiedActions = $session->get('mautic.form.'.$sessionId.'.actions.modified', []);
288
        $deletedActions  = $session->get('mautic.form.'.$sessionId.'.actions.deleted', []);
289
290
        $action = $this->generateUrl('mautic_form_action', ['objectAction' => 'new']);
291
        $form   = $model->createForm($entity, $this->get('form.factory'), $action);
292
293
        ///Check for a submitted form and process it
294
        if ('POST' == $this->request->getMethod()) {
295
            $valid = false;
296
            if (!$cancelled = $this->isFormCancelled($form)) {
297
                if ($valid = $this->isFormValid($form)) {
298
                    //only save fields that are not to be deleted
299
                    $fields = array_diff_key($modifiedFields, array_flip($deletedFields));
300
301
                    //make sure that at least one field is selected
302
                    if (empty($fields)) {
303
                        //set the error
304
                        $form->addError(
305
                            new FormError(
306
                                $this->get('translator')->trans('mautic.form.form.fields.notempty', [], 'validators')
307
                            )
308
                        );
309
                        $valid = false;
310
                    } else {
311
                        $model->setFields($entity, $fields);
312
313
                        try {
314
                            // Set alias to prevent SQL errors
315
                            $alias = $model->cleanAlias($entity->getName(), '', 10);
316
                            $entity->setAlias($alias);
317
318
                            // Set timestamps
319
                            $model->setTimestamps($entity, true, false);
320
321
                            // Save the form first and new actions so that new fields are available to actions.
322
                            // Using the repository function to not trigger the listeners twice.
323
324
                            $model->getRepository()->saveEntity($entity);
325
326
                            // Only save actions that are not to be deleted
327
                            $actions = array_diff_key($modifiedActions, array_flip($deletedActions));
328
329
                            // Set and persist actions
330
                            $model->setActions($entity, $actions);
331
332
                            // Save and trigger listeners
333
                            $model->saveEntity($entity, $form->get('buttons')->get('save')->isClicked());
334
335
                            $this->addFlash(
336
                                'mautic.core.notice.created',
337
                                [
338
                                    '%name%'      => $entity->getName(),
339
                                    '%menu_link%' => 'mautic_form_index',
340
                                    '%url%'       => $this->generateUrl(
341
                                        'mautic_form_action',
342
                                        [
343
                                            'objectAction' => 'edit',
344
                                            'objectId'     => $entity->getId(),
345
                                        ]
346
                                    ),
347
                                ]
348
                            );
349
350
                            if ($form->get('buttons')->get('save')->isClicked()) {
351
                                $viewParameters = [
352
                                    'objectAction' => 'view',
353
                                    'objectId'     => $entity->getId(),
354
                                ];
355
                                $returnUrl = $this->generateUrl('mautic_form_action', $viewParameters);
356
                                $template  = 'MauticFormBundle:Form:view';
357
                            } else {
358
                                //return edit view so that all the session stuff is loaded
359
                                return $this->editAction($entity->getId(), true);
360
                            }
361
                        } catch (ValidationException $ex) {
362
                            $form->addError(
363
                                new FormError(
364
                                    $ex->getMessage()
365
                                )
366
                            );
367
                            $valid = false;
368
                        } catch (\Exception $e) {
369
                            $form['name']->addError(
370
                                new FormError($this->get('translator')->trans('mautic.form.schema.failed', [], 'validators'))
371
                            );
372
                            $valid = false;
373
374
                            if ('dev' == $this->container->getParameter('kernel.environment')) {
375
                                throw $e;
376
                            }
377
                        }
378
                    }
379
                }
380
            } else {
381
                $viewParameters = ['page' => $page];
382
                $returnUrl      = $this->generateUrl('mautic_form_index', $viewParameters);
383
                $template       = 'MauticFormBundle:Form:index';
384
            }
385
386
            if ($cancelled || ($valid && $form->get('buttons')->get('save')->isClicked())) {
387
                //clear temporary fields
388
                $this->clearSessionComponents($sessionId);
389
390
                return $this->postActionRedirect(
391
                    [
392
                        'returnUrl'       => $returnUrl,
393
                        'viewParameters'  => $viewParameters,
394
                        'contentTemplate' => $template,
395
                        'passthroughVars' => [
396
                            'activeLink'    => '#mautic_form_index',
397
                            'mauticContent' => 'form',
398
                        ],
399
                    ]
400
                );
401
            }
402
        } else {
403
            //clear out existing fields in case the form was refreshed, browser closed, etc
404
            $this->clearSessionComponents($sessionId);
405
            $modifiedFields = $modifiedActions = $deletedActions = $deletedFields = [];
406
407
            $form->get('sessionId')->setData($sessionId);
408
409
            //add a submit button
410
            $keyId = 'new'.hash('sha1', uniqid(mt_rand()));
411
            $field = new Field();
412
413
            $modifiedFields[$keyId]                    = $field->convertToArray();
414
            $modifiedFields[$keyId]['label']           = $this->translator->trans('mautic.core.form.submit');
415
            $modifiedFields[$keyId]['alias']           = 'submit';
416
            $modifiedFields[$keyId]['showLabel']       = 1;
417
            $modifiedFields[$keyId]['type']            = 'button';
418
            $modifiedFields[$keyId]['id']              = $keyId;
419
            $modifiedFields[$keyId]['inputAttributes'] = 'class="btn btn-default"';
420
            $modifiedFields[$keyId]['formId']          = $sessionId;
421
            unset($modifiedFields[$keyId]['form']);
422
            $session->set('mautic.form.'.$sessionId.'.fields.modified', $modifiedFields);
423
        }
424
425
        //fire the form builder event
426
        $customComponents = $model->getCustomComponents($sessionId);
427
428
        /** @var FormFieldHelper $fieldHelper */
429
        $fieldHelper = $this->get('mautic.helper.form.field_helper');
430
431
        return $this->delegateView(
432
            [
433
                'viewParameters' => [
434
                    'fields'         => $fieldHelper->getChoiceList($customComponents['fields']),
435
                    'actions'        => $customComponents['choices'],
436
                    'actionSettings' => $customComponents['actions'],
437
                    'formFields'     => $modifiedFields,
438
                    'formActions'    => $modifiedActions,
439
                    'deletedFields'  => $deletedFields,
440
                    'deletedActions' => $deletedActions,
441
                    'tmpl'           => $this->request->isXmlHttpRequest() ? $this->request->get('tmpl', 'index') : 'index',
442
                    'activeForm'     => $entity,
443
                    'form'           => $form->createView(),
444
                    'contactFields'  => $this->getModel('lead.field')->getFieldListWithProperties(),
445
                    'companyFields'  => $this->getModel('lead.field')->getFieldListWithProperties('company'),
446
                    'inBuilder'      => true,
447
                ],
448
                'contentTemplate' => 'MauticFormBundle:Builder:index.html.php',
449
                'passthroughVars' => [
450
                    'activeLink'    => '#mautic_form_index',
451
                    'mauticContent' => 'form',
452
                    'route'         => $this->generateUrl(
453
                        'mautic_form_action',
454
                        [
455
                            'objectAction' => (!empty($valid) ? 'edit' : 'new'), //valid means a new form was applied
456
                            'objectId'     => $entity->getId(),
457
                        ]
458
                    ),
459
                ],
460
            ]
461
        );
462
    }
463
464
    /**
465
     * Generates edit form and processes post data.
466
     *
467
     * @param int  $objectId
468
     * @param bool $ignorePost
469
     * @param bool $forceTypeSelection
470
     *
471
     * @return \Symfony\Component\HttpFoundation\JsonResponse|Response
472
     */
473
    public function editAction($objectId, $ignorePost = false, $forceTypeSelection = false)
474
    {
475
        /** @var \Mautic\FormBundle\Model\FormModel $model */
476
        $model            = $this->getModel('form');
477
        $formData         = $this->request->request->get('mauticform');
478
        $sessionId        = isset($formData['sessionId']) ? $formData['sessionId'] : null;
479
        $customComponents = $model->getCustomComponents();
480
481
        if ($objectId instanceof Form) {
482
            $entity   = $objectId;
483
            $objectId = 'mautic_'.sha1(uniqid(mt_rand(), true));
484
        } else {
485
            $entity = $model->getEntity($objectId);
486
487
            // Process submit of cloned form
488
            if (null == $entity && $objectId == $sessionId) {
489
                $entity = $model->getEntity();
490
            }
491
        }
492
493
        $session    = $this->get('session');
494
        $cleanSlate = true;
495
496
        //set the page we came from
497
        $page = $this->get('session')->get('mautic.form.page', 1);
498
499
        //set the return URL
500
        $returnUrl = $this->generateUrl('mautic_form_index', ['page' => $page]);
501
502
        $postActionVars = [
503
            'returnUrl'       => $returnUrl,
504
            'viewParameters'  => ['page' => $page],
505
            'contentTemplate' => 'MauticFormBundle:Form:index',
506
            'passthroughVars' => [
507
                'activeLink'    => '#mautic_form_index',
508
                'mauticContent' => 'form',
509
            ],
510
        ];
511
512
        //form not found
513
        if (null === $entity) {
514
            return $this->postActionRedirect(
515
                array_merge(
516
                    $postActionVars,
517
                    [
518
                        'flashes' => [
519
                            [
520
                                'type'    => 'error',
521
                                'msg'     => 'mautic.form.error.notfound',
522
                                'msgVars' => ['%id%' => $objectId],
523
                            ],
524
                        ],
525
                    ]
526
                )
527
            );
528
        } elseif (!$this->get('mautic.security')->hasEntityAccess(
529
            'form:forms:editown',
530
            'form:forms:editother',
531
            $entity->getCreatedBy()
532
        )
533
        ) {
534
            return $this->accessDenied();
535
        } elseif ($model->isLocked($entity)) {
536
            //deny access if the entity is locked
537
            return $this->isLocked($postActionVars, $entity, 'form.form');
538
        }
539
540
        $action = $this->generateUrl('mautic_form_action', ['objectAction' => 'edit', 'objectId' => $objectId]);
541
        $form   = $model->createForm($entity, $this->get('form.factory'), $action);
542
543
        ///Check for a submitted form and process it
544
        if (!$ignorePost && 'POST' == $this->request->getMethod()) {
545
            $valid = false;
546
            if (!$cancelled = $this->isFormCancelled($form)) {
547
                //set added/updated fields
548
                $modifiedFields = $session->get('mautic.form.'.$objectId.'.fields.modified', []);
549
                $deletedFields  = $session->get('mautic.form.'.$objectId.'.fields.deleted', []);
550
                $fields         = array_diff_key($modifiedFields, array_flip($deletedFields));
551
552
                //set added/updated actions
553
                $modifiedActions = $session->get('mautic.form.'.$objectId.'.actions.modified', []);
554
                $deletedActions  = $session->get('mautic.form.'.$objectId.'.actions.deleted', []);
555
                $actions         = array_diff_key($modifiedActions, array_flip($deletedActions));
556
557
                if ($valid = $this->isFormValid($form)) {
558
                    //make sure that at least one field is selected
559
                    if (empty($fields)) {
560
                        //set the error
561
                        $form->addError(
562
                            new FormError(
563
                                $this->get('translator')->trans('mautic.form.form.fields.notempty', [], 'validators')
564
                            )
565
                        );
566
                        $valid = false;
567
                    } else {
568
                        $model->setFields($entity, $fields);
569
                        $model->deleteFields($entity, $deletedFields);
570
571
                        $alias = $entity->getAlias();
572
573
                        if (empty($alias)) {
574
                            $alias = $model->cleanAlias($entity->getName(), '', 10);
575
                            $entity->setAlias($alias);
576
                        }
577
578
                        if (!$entity->getId()) {
579
                            // Set timestamps because this is a new clone
580
                            $model->setTimestamps($entity, true, false);
581
                        }
582
583
                        // save the form first so that new fields are available to actions
584
                        // use the repository method to not trigger listeners twice
585
                        try {
586
                            $model->getRepository()->saveEntity($entity);
587
588
                            // Ensure actions are compatible with form type
589
                            if (!$entity->isStandalone()) {
590
                                foreach ($actions as $actionId => $action) {
591
                                    if (empty($customComponents['actions'][$action['type']]['allowCampaignForm'])) {
592
                                        unset($actions[$actionId]);
593
                                        $deletedActions[] = $actionId;
594
                                    }
595
                                }
596
                            }
597
598
                            if (count($actions)) {
599
                                // Now set and persist the actions
600
                                $model->setActions($entity, $actions);
601
                            }
602
603
                            // Delete deleted actions
604
                            $model->deleteActions($entity, $deletedActions);
605
606
                            // Persist and execute listeners
607
                            $model->saveEntity($entity, $form->get('buttons')->get('save')->isClicked());
608
609
                            // Reset objectId to entity ID (can be session ID in case of cloned entity)
610
                            $objectId = $entity->getId();
611
612
                            $this->addFlash(
0 ignored issues
show
Deprecated Code introduced by
The function Mautic\CoreBundle\Contro...nController::addFlash() has been deprecated: Will be removed in Mautic 3.0. Use CommonController::flashBag->addFlash() instead. ( Ignorable by Annotation )

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

612
                            /** @scrutinizer ignore-deprecated */ $this->addFlash(

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
613
                                'mautic.core.notice.updated',
614
                                [
615
                                    '%name%'      => $entity->getName(),
616
                                    '%menu_link%' => 'mautic_form_index',
617
                                    '%url%'       => $this->generateUrl(
618
                                        'mautic_form_action',
619
                                        [
620
                                            'objectAction' => 'edit',
621
                                            'objectId'     => $entity->getId(),
622
                                        ]
623
                                    ),
624
                                ]
625
                            );
626
627
                            if ($form->get('buttons')->get('save')->isClicked()) {
628
                                $viewParameters = [
629
                                    'objectAction' => 'view',
630
                                    'objectId'     => $entity->getId(),
631
                                ];
632
                                $returnUrl = $this->generateUrl('mautic_form_action', $viewParameters);
633
                                $template  = 'MauticFormBundle:Form:view';
634
                            }
635
                        } catch (ValidationException $ex) {
636
                            $form->addError(
637
                                new FormError(
638
                                    $ex->getMessage()
639
                                )
640
                            );
641
                            $valid = false;
642
                        }
643
                    }
644
                }
645
            } else {
646
                //unlock the entity
647
                $model->unlockEntity($entity);
648
649
                $viewParameters = ['page' => $page];
650
                $returnUrl      = $this->generateUrl('mautic_form_index', $viewParameters);
651
                $template       = 'MauticFormBundle:Form:index';
652
            }
653
654
            if ($cancelled || ($valid && $form->get('buttons')->get('save')->isClicked())) {
655
                //remove fields from session
656
                $this->clearSessionComponents($objectId);
657
658
                // Clear session items in case columns changed
659
                $session->remove('mautic.formresult.'.$entity->getId().'.orderby');
660
                $session->remove('mautic.formresult.'.$entity->getId().'.orderbydir');
661
                $session->remove('mautic.formresult.'.$entity->getId().'.filters');
662
663
                return $this->postActionRedirect(
664
                    array_merge(
665
                        $postActionVars,
666
                        [
667
                            'returnUrl'       => $returnUrl,
668
                            'viewParameters'  => $viewParameters,
669
                            'contentTemplate' => $template,
670
                        ]
671
                    )
672
                );
673
            } elseif ($valid && $form->get('buttons')->get('apply')->isClicked()) {
674
                // Rebuild everything to include new ids
675
                $cleanSlate = true;
676
                $reorder    = true;
677
678
                if ($valid) {
679
                    // Rebuild the form with new action so that apply doesn't keep creating a clone
680
                    $action = $this->generateUrl('mautic_form_action', ['objectAction' => 'edit', 'objectId' => $entity->getId()]);
681
                    $form   = $model->createForm($entity, $this->get('form.factory'), $action);
682
                }
683
            }
684
        } else {
685
            $cleanSlate = true;
686
687
            //lock the entity
688
            $model->lockEntity($entity);
689
        }
690
691
        if (!$form->isSubmitted()) {
692
            $form->get('sessionId')->setData($objectId);
693
        }
694
695
        // Get field and action settings
696
        $fieldHelper     = $this->get('mautic.helper.form.field_helper');
697
        $availableFields = $fieldHelper->getChoiceList($customComponents['fields']);
698
699
        if ($cleanSlate) {
700
            //clean slate
701
            $this->clearSessionComponents($objectId);
702
703
            //load existing fields into session
704
            $modifiedFields    = [];
705
            $usedLeadFields    = [];
706
            $usedCompanyFields = [];
707
            $existingFields    = $entity->getFields()->toArray();
708
            $submitButton      = false;
709
710
            foreach ($existingFields as $formField) {
711
                // Check to see if the field still exists
712
713
                if ('button' == $formField->getType()) {
714
                    //submit button found
715
                    $submitButton = true;
716
                }
717
                if ('button' !== $formField->getType() && !in_array($formField->getType(), $availableFields)) {
718
                    continue;
719
                }
720
721
                $id    = $formField->getId();
722
                $field = $formField->convertToArray();
723
724
                if (!$id) {
725
                    // Cloned entity
726
                    $id = $field['id'] = $field['sessionId'] = 'new'.hash('sha1', uniqid(mt_rand()));
727
                }
728
729
                unset($field['form']);
730
731
                if (isset($customComponents['fields'][$field['type']])) {
732
                    // Set the custom parameters
733
                    $field['customParameters'] = $customComponents['fields'][$field['type']];
734
                }
735
                $field['formId'] = $objectId;
736
737
                $modifiedFields[$id] = $field;
738
739
                if (!empty($field['leadField'])) {
740
                    $usedLeadFields[$id] = $field['leadField'];
741
                }
742
            }
743
            if (!$submitButton) { //means something deleted the submit button from the form
744
                //add a submit button
745
                $keyId = 'new'.hash('sha1', uniqid(mt_rand()));
746
                $field = new Field();
747
748
                $modifiedFields[$keyId]                    = $field->convertToArray();
749
                $modifiedFields[$keyId]['label']           = $this->translator->trans('mautic.core.form.submit');
750
                $modifiedFields[$keyId]['alias']           = 'submit';
751
                $modifiedFields[$keyId]['showLabel']       = 1;
752
                $modifiedFields[$keyId]['type']            = 'button';
753
                $modifiedFields[$keyId]['id']              = $keyId;
754
                $modifiedFields[$keyId]['inputAttributes'] = 'class="btn btn-default"';
755
                $modifiedFields[$keyId]['formId']          = $objectId;
756
                unset($modifiedFields[$keyId]['form']);
757
            }
758
            $session->set('mautic.form.'.$objectId.'.fields.leadfields', $usedLeadFields);
759
760
            if (!empty($reorder)) {
761
                uasort(
762
                    $modifiedFields,
763
                    function ($a, $b) {
764
                        return $a['order'] > $b['order'];
765
                    }
766
                );
767
            }
768
769
            $session->set('mautic.form.'.$objectId.'.fields.modified', $modifiedFields);
770
            $deletedFields = [];
771
772
            // Load existing actions into session
773
            $modifiedActions = [];
774
            $existingActions = $entity->getActions()->toArray();
775
776
            foreach ($existingActions as $formAction) {
777
                // Check to see if the action still exists
778
                if (!isset($customComponents['actions'][$formAction->getType()])) {
779
                    continue;
780
                }
781
782
                $id     = $formAction->getId();
783
                $action = $formAction->convertToArray();
784
785
                if (!$id) {
786
                    // Cloned entity so use a random Id instead
787
                    $action['id'] = $id = 'new'.hash('sha1', uniqid(mt_rand()));
788
                }
789
                unset($action['form']);
790
791
                $modifiedActions[$id] = $action;
792
            }
793
794
            if (!empty($reorder)) {
795
                uasort(
796
                    $modifiedActions,
797
                    function ($a, $b) {
798
                        return $a['order'] > $b['order'];
799
                    }
800
                );
801
            }
802
803
            $session->set('mautic.form.'.$objectId.'.actions.modified', $modifiedActions);
804
            $deletedActions = [];
805
        }
806
807
        return $this->delegateView(
808
            [
809
                'viewParameters' => [
810
                    'fields'             => $availableFields,
811
                    'actions'            => $customComponents['choices'],
812
                    'actionSettings'     => $customComponents['actions'],
813
                    'formFields'         => $modifiedFields,
814
                    'fieldSettings'      => $customComponents['fields'],
815
                    'formActions'        => $modifiedActions,
816
                    'deletedFields'      => $deletedFields,
817
                    'deletedActions'     => $deletedActions,
818
                    'tmpl'               => $this->request->isXmlHttpRequest() ? $this->request->get('tmpl', 'index') : 'index',
819
                    'activeForm'         => $entity,
820
                    'form'               => $form->createView(),
821
                    'forceTypeSelection' => $forceTypeSelection,
822
                    'contactFields'      => $this->getModel('lead.field')->getFieldListWithProperties('lead'),
823
                    'companyFields'      => $this->getModel('lead.field')->getFieldListWithProperties('company'),
824
                    'inBuilder'          => true,
825
                ],
826
                'contentTemplate' => 'MauticFormBundle:Builder:index.html.php',
827
                'passthroughVars' => [
828
                    'activeLink'    => '#mautic_form_index',
829
                    'mauticContent' => 'form',
830
                    'route'         => $this->generateUrl(
831
                        'mautic_form_action',
832
                        [
833
                            'objectAction' => 'edit',
834
                            'objectId'     => $entity->getId(),
835
                        ]
836
                    ),
837
                ],
838
            ]
839
        );
840
    }
841
842
    /**
843
     * Clone an entity.
844
     *
845
     * @param int $objectId
846
     *
847
     * @return \Symfony\Component\HttpFoundation\JsonResponse|\Symfony\Component\HttpFoundation\RedirectResponse|Response
848
     */
849
    public function cloneAction($objectId)
850
    {
851
        $model = $this->getModel('form.form');
852
853
        /** @var \Mautic\FormBundle\Entity\Form $entity */
854
        $entity = $model->getEntity($objectId);
855
856
        if (null != $entity) {
857
            if (!$this->get('mautic.security')->isGranted('form:forms:create')
858
                || !$this->get('mautic.security')->hasEntityAccess(
859
                    'form:forms:viewown',
860
                    'form:forms:viewother',
861
                    $entity->getCreatedBy()
862
                )
863
            ) {
864
                return $this->accessDenied();
865
            }
866
867
            $entity = clone $entity;
868
            $entity->setIsPublished(false);
869
870
            // Clone the forms's fields
871
            $fields = $entity->getFields()->toArray();
872
            /** @var \Mautic\FormBundle\Entity\Field $field */
873
            foreach ($fields as $field) {
874
                $fieldClone = clone $field;
875
                $fieldClone->setForm($entity);
876
                $fieldClone->setSessionId(null);
877
                $entity->addField($field->getId(), $fieldClone);
878
            }
879
880
            // Clone the forms's actions
881
            $actions = $entity->getActions()->toArray();
882
            /** @var \Mautic\FormBundle\Entity\Action $action */
883
            foreach ($actions as $action) {
884
                $actionClone = clone $action;
885
                $actionClone->setForm($entity);
886
                $entity->addAction($action->getId(), $actionClone);
887
            }
888
        }
889
890
        return $this->editAction($entity, true, true);
891
    }
892
893
    /**
894
     * Gives a preview of the form.
895
     *
896
     * @param int $objectId
897
     *
898
     * @return Response
899
     */
900
    public function previewAction($objectId)
901
    {
902
        /** @var FormModel $model */
903
        $model = $this->getModel('form.form');
904
        $form  = $model->getEntity($objectId);
905
906
        if (null === $form) {
907
            $html =
908
                '<h1>'.
909
                $this->get('translator')->trans('mautic.form.error.notfound', ['%id%' => $objectId], 'flashes').
910
                '</h1>';
911
        } elseif (!$this->get('mautic.security')->hasEntityAccess(
912
            'form:forms:editown',
913
            'form:forms:editother',
914
            $form->getCreatedBy()
915
        )
916
        ) {
917
            $html = '<h1>'.$this->get('translator')->trans('mautic.core.error.accessdenied', [], 'flashes').'</h1>';
918
        } else {
919
            $html = $model->getContent($form, true, false);
920
        }
921
922
        $model->populateValuesWithGetParameters($form, $html);
923
924
        $viewParams = [
925
            'content'     => $html,
926
            'stylesheets' => [],
927
            'name'        => $form->getName(),
928
            'metaRobots'  => '<meta name="robots" content="index">',
929
        ];
930
931
        if ($form->getNoIndex()) {
932
            $viewParams['metaRobots'] = '<meta name="robots" content="noindex">';
933
        }
934
935
        $template = $form->getTemplate();
936
        if (!empty($template)) {
937
            $theme = $this->get('mautic.helper.theme')->getTheme($template);
938
            if ($theme->getTheme() != $template) {
939
                $config = $theme->getConfig();
940
                if (in_array('form', $config['features'])) {
941
                    $template = $theme->getTheme();
942
                } else {
943
                    $template = null;
944
                }
945
            }
946
        }
947
948
        $viewParams['template'] = $template;
949
950
        if (!empty($template)) {
951
            $logicalName     = $this->get('mautic.helper.theme')->checkForTwigTemplate(':'.$template.':form.html.php');
952
            $assetsHelper    = $this->get('templating.helper.assets');
953
            $slotsHelper     = $this->get('templating.helper.slots');
954
            $analyticsHelper = $this->get('mautic.helper.template.analytics');
955
956
            if (!empty($customStylesheets)) {
957
                foreach ($customStylesheets as $css) {
958
                    $assetsHelper->addStylesheet($css);
959
                }
960
            }
961
962
            $slotsHelper->set('pageTitle', $form->getName());
963
964
            $analytics = $analyticsHelper->getCode();
965
966
            if (!empty($analytics)) {
967
                $assetsHelper->addCustomDeclaration($analytics);
968
            }
969
            if ($form->getNoIndex()) {
970
                $assetsHelper->addCustomDeclaration('<meta name="robots" content="noindex">');
971
            }
972
973
            return $this->render($logicalName, $viewParams);
974
        }
975
976
        return $this->render('MauticFormBundle::form.html.php', $viewParams);
977
    }
978
979
    /**
980
     * Deletes the entity.
981
     *
982
     * @param int $objectId
983
     *
984
     * @return \Symfony\Component\HttpFoundation\JsonResponse|\Symfony\Component\HttpFoundation\RedirectResponse
985
     */
986
    public function deleteAction($objectId)
987
    {
988
        $page      = $this->get('session')->get('mautic.form.page', 1);
989
        $returnUrl = $this->generateUrl('mautic_form_index', ['page' => $page]);
990
        $flashes   = [];
991
992
        $postActionVars = [
993
            'returnUrl'       => $returnUrl,
994
            'viewParameters'  => ['page' => $page],
995
            'contentTemplate' => 'MauticFormBundle:Form:index',
996
            'passthroughVars' => [
997
                'activeLink'    => '#mautic_form_index',
998
                'mauticContent' => 'form',
999
            ],
1000
        ];
1001
1002
        if ('POST' == $this->request->getMethod()) {
1003
            $model  = $this->getModel('form.form');
1004
            $entity = $model->getEntity($objectId);
1005
1006
            if (null === $entity) {
1007
                $flashes[] = [
1008
                    'type'    => 'error',
1009
                    'msg'     => 'mautic.form.error.notfound',
1010
                    'msgVars' => ['%id%' => $objectId],
1011
                ];
1012
            } elseif (!$this->get('mautic.security')->hasEntityAccess(
1013
                'form:forms:deleteown',
1014
                'form:forms:deleteother',
1015
                $entity->getCreatedBy()
1016
            )
1017
            ) {
1018
                return $this->accessDenied();
1019
            } elseif ($model->isLocked($entity)) {
1020
                return $this->isLocked($postActionVars, $entity, 'form.form');
1021
            }
1022
1023
            $model->deleteEntity($entity);
1024
1025
            $identifier = $this->get('translator')->trans($entity->getName());
1026
            $flashes[]  = [
1027
                'type'    => 'notice',
1028
                'msg'     => 'mautic.core.notice.deleted',
1029
                'msgVars' => [
1030
                    '%name%' => $identifier,
1031
                    '%id%'   => $objectId,
1032
                ],
1033
            ];
1034
        } //else don't do anything
1035
1036
        return $this->postActionRedirect(
1037
            array_merge(
1038
                $postActionVars,
1039
                [
1040
                    'flashes' => $flashes,
1041
                ]
1042
            )
1043
        );
1044
    }
1045
1046
    /**
1047
     * Deletes a group of entities.
1048
     *
1049
     * @return \Symfony\Component\HttpFoundation\JsonResponse|\Symfony\Component\HttpFoundation\RedirectResponse
1050
     */
1051
    public function batchDeleteAction()
1052
    {
1053
        $page      = $this->get('session')->get('mautic.form.page', 1);
1054
        $returnUrl = $this->generateUrl('mautic_form_index', ['page' => $page]);
1055
        $flashes   = [];
1056
1057
        $postActionVars = [
1058
            'returnUrl'       => $returnUrl,
1059
            'viewParameters'  => ['page' => $page],
1060
            'contentTemplate' => 'MauticFormBundle:Form:index',
1061
            'passthroughVars' => [
1062
                'activeLink'    => '#mautic_form_index',
1063
                'mauticContent' => 'form',
1064
            ],
1065
        ];
1066
1067
        if ('POST' == $this->request->getMethod()) {
1068
            $model     = $this->getModel('form');
1069
            $ids       = json_decode($this->request->query->get('ids', ''));
1070
            $deleteIds = [];
1071
1072
            // Loop over the IDs to perform access checks pre-delete
1073
            foreach ($ids as $objectId) {
1074
                $objectId = (int) $objectId;
1075
                $entity   = $model->getEntity($objectId);
1076
1077
                if (null === $entity) {
1078
                    $flashes[] = [
1079
                        'type'    => 'error',
1080
                        'msg'     => 'mautic.form.error.notfound',
1081
                        'msgVars' => ['%id%' => $objectId],
1082
                    ];
1083
                } elseif (!$this->get('mautic.security')->hasEntityAccess(
1084
                    'form:forms:deleteown',
1085
                    'form:forms:deleteother',
1086
                    $entity->getCreatedBy()
1087
                )
1088
                ) {
1089
                    $flashes[] = $this->accessDenied(true);
1090
                } elseif ($model->isLocked($entity)) {
1091
                    $flashes[] = $this->isLocked($postActionVars, $entity, 'form.form', true);
1092
                } else {
1093
                    $deleteIds[] = $objectId;
1094
                }
1095
            }
1096
1097
            // Delete everything we are able to
1098
            if (!empty($deleteIds)) {
1099
                $entities = $model->deleteEntities($deleteIds);
1100
1101
                $flashes[] = [
1102
                    'type'    => 'notice',
1103
                    'msg'     => 'mautic.form.notice.batch_deleted',
1104
                    'msgVars' => [
1105
                        '%count%' => count($entities),
1106
                    ],
1107
                ];
1108
            }
1109
        } //else don't do anything
1110
1111
        return $this->postActionRedirect(
1112
            array_merge(
1113
                $postActionVars,
1114
                [
1115
                    'flashes' => $flashes,
1116
                ]
1117
            )
1118
        );
1119
    }
1120
1121
    /**
1122
     * Clear field and actions from the session.
1123
     */
1124
    public function clearSessionComponents($sessionId)
1125
    {
1126
        $session = $this->get('session');
1127
        $session->remove('mautic.form.'.$sessionId.'.fields.modified');
1128
        $session->remove('mautic.form.'.$sessionId.'.fields.deleted');
1129
        $session->remove('mautic.form.'.$sessionId.'.fields.leadfields');
1130
1131
        $session->remove('mautic.form.'.$sessionId.'.actions.modified');
1132
        $session->remove('mautic.form.'.$sessionId.'.actions.deleted');
1133
    }
1134
1135
    public function batchRebuildHtmlAction()
1136
    {
1137
        $page      = $this->get('session')->get('mautic.form.page', 1);
1138
        $returnUrl = $this->generateUrl('mautic_form_index', ['page' => $page]);
1139
        $flashes   = [];
1140
1141
        $postActionVars = [
1142
            'returnUrl'       => $returnUrl,
1143
            'viewParameters'  => ['page' => $page],
1144
            'contentTemplate' => 'MauticFormBundle:Form:index',
1145
            'passthroughVars' => [
1146
                'activeLink'    => '#mautic_form_index',
1147
                'mauticContent' => 'form',
1148
            ],
1149
        ];
1150
1151
        if ('POST' == $this->request->getMethod()) {
1152
            /** @var \Mautic\FormBundle\Model\FormModel $model */
1153
            $model = $this->getModel('form');
1154
            $ids   = json_decode($this->request->query->get('ids', ''));
1155
            $count = 0;
1156
            // Loop over the IDs to perform access checks pre-delete
1157
            foreach ($ids as $objectId) {
1158
                $entity = $model->getEntity($objectId);
1159
1160
                if (null === $entity) {
1161
                    $flashes[] = [
1162
                        'type'    => 'error',
1163
                        'msg'     => 'mautic.form.error.notfound',
1164
                        'msgVars' => ['%id%' => $objectId],
1165
                    ];
1166
                } elseif (!$this->get('mautic.security')->hasEntityAccess(
1167
                    'form:forms:editown',
1168
                    'form:forms:editother',
1169
                    $entity->getCreatedBy()
1170
                )
1171
                ) {
1172
                    $flashes[] = $this->accessDenied(true);
1173
                } elseif ($model->isLocked($entity)) {
1174
                    $flashes[] = $this->isLocked($postActionVars, $entity, 'form.form', true);
1175
                } else {
1176
                    $model->generateHtml($entity);
1177
                    ++$count;
1178
                }
1179
            }
1180
1181
            $flashes[] = [
1182
                'type'    => 'notice',
1183
                'msg'     => 'mautic.form.notice.batch_html_generated',
1184
                'msgVars' => [
1185
                    'pluralCount' => $count,
1186
                    '%count%'     => $count,
1187
                ],
1188
            ];
1189
        } //else don't do anything
1190
1191
        return $this->postActionRedirect(
1192
            array_merge(
1193
                $postActionVars,
1194
                [
1195
                    'flashes' => $flashes,
1196
                ]
1197
            )
1198
        );
1199
    }
1200
}
1201