Issues (3627)

bundles/FormBundle/Controller/PublicController.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\CoreBundle\Helper\InputHelper;
16
use Mautic\FormBundle\Event\SubmissionEvent;
17
use Mautic\FormBundle\Model\FormModel;
18
use Mautic\LeadBundle\Helper\TokenHelper;
19
use Symfony\Component\HttpFoundation\JsonResponse;
20
use Symfony\Component\HttpFoundation\RedirectResponse;
21
use Symfony\Component\HttpFoundation\Response;
22
23
/**
24
 * Class PublicController.
25
 */
26
class PublicController extends CommonFormController
27
{
28
    /**
29
     * @var array
30
     */
31
    private $tokens = [];
32
33
    /**
34
     * @return \Symfony\Component\HttpFoundation\RedirectResponse|Response
35
     */
36
    public function submitAction()
37
    {
38
        if ('POST' !== $this->request->getMethod()) {
39
            return $this->accessDenied();
40
        }
41
        $isAjax        = $this->request->query->get('ajax', false);
42
        $form          = null;
43
        $post          = $this->request->request->get('mauticform');
44
        $messengerMode = (!empty($post['messenger']));
45
        $server        = $this->request->server->all();
46
        $return        = (isset($post['return'])) ? $post['return'] : false;
47
48
        if (empty($return)) {
49
            //try to get it from the HTTP_REFERER
50
            $return = (isset($server['HTTP_REFERER'])) ? $server['HTTP_REFERER'] : false;
51
        }
52
53
        if (!empty($return)) {
54
            //remove mauticError and mauticMessage from the referer so it doesn't get sent back
55
            $return = InputHelper::url($return, null, null, null, ['mauticError', 'mauticMessage'], true);
56
            $query  = (false === strpos($return, '?')) ? '?' : '&';
57
        }
58
59
        $translator = $this->get('translator');
60
61
        if (!isset($post['formId']) && isset($post['formid'])) {
62
            $post['formId'] = $post['formid'];
63
        } elseif (isset($post['formId']) && !isset($post['formid'])) {
64
            $post['formid'] = $post['formId'];
65
        }
66
67
        //check to ensure there is a formId
68
        if (!isset($post['formId'])) {
69
            $error = $translator->trans('mautic.form.submit.error.unavailable', [], 'flashes');
70
        } else {
71
            $formModel = $this->getModel('form.form');
72
            $form      = $formModel->getEntity($post['formId']);
73
74
            //check to see that the form was found
75
            if (null === $form) {
76
                $error = $translator->trans('mautic.form.submit.error.unavailable', [], 'flashes');
77
            } else {
78
                //get what to do immediately after successful post
79
                $postAction         = $form->getPostAction();
80
                $postActionProperty = $form->getPostActionProperty();
81
82
                //check to ensure the form is published
83
                $status             = $form->getPublishStatus();
84
                $dateTemplateHelper = $this->get('mautic.helper.template.date');
85
                if ('pending' == $status) {
86
                    $error = $translator->trans(
87
                        'mautic.form.submit.error.pending',
88
                        [
89
                            '%date%' => $dateTemplateHelper->toFull($form->getPublishUp()),
90
                        ],
91
                        'flashes'
92
                    );
93
                } elseif ('expired' == $status) {
94
                    $error = $translator->trans(
95
                        'mautic.form.submit.error.expired',
96
                        [
97
                            '%date%' => $dateTemplateHelper->toFull($form->getPublishDown()),
98
                        ],
99
                        'flashes'
100
                    );
101
                } elseif ('published' != $status) {
102
                    $error = $translator->trans('mautic.form.submit.error.unavailable', [], 'flashes');
103
                } else {
104
                    $result = $this->getModel('form.submission')->saveSubmission($post, $server, $form, $this->request, true);
105
                    if (!empty($result['errors'])) {
106
                        if ($messengerMode || $isAjax) {
107
                            $error = $result['errors'];
108
                        } else {
109
                            $error = ($result['errors']) ?
110
                                $this->get('translator')->trans('mautic.form.submission.errors').'<br /><ol><li>'.
111
                                implode('</li><li>', $result['errors']).'</li></ol>' : false;
112
                        }
113
                    } elseif (!empty($result['callback'])) {
114
                        /** @var SubmissionEvent $submissionEvent */
115
                        $submissionEvent   = $result['callback'];
116
                        $callbackResponses = $submissionEvent->getPostSubmitCallbackResponse();
117
                        // These submit actions have requested a callback after all is said and done
118
                        $callbacksRequested = $submissionEvent->getPostSubmitCallback();
119
                        foreach ($callbacksRequested as $key => $callbackRequested) {
120
                            $callbackRequested['messengerMode'] = $messengerMode;
121
                            $callbackRequested['ajaxMode']      = $isAjax;
122
123
                            if (isset($callbackRequested['eventName'])) {
124
                                $submissionEvent->setPostSubmitCallback($key, $callbackRequested);
125
                                $submissionEvent->setContext($key);
126
127
                                $this->get('event_dispatcher')->dispatch($callbackRequested['eventName'], $submissionEvent);
128
                            }
129
130
                            if ($submissionEvent->isPropagationStopped() && $submissionEvent->hasPostSubmitResponse()) {
131
                                if ($messengerMode) {
132
                                    $callbackResponses[$key] = $submissionEvent->getPostSubmitResponse();
133
                                } else {
134
                                    return $submissionEvent->getPostSubmitResponse();
135
                                }
136
                            }
137
                        }
138
                    } elseif (isset($result['submission'])) {
139
                        /** @var SubmissionEvent $submissionEvent */
140
                        $submissionEvent = $result['submission'];
141
                    }
142
                }
143
            }
144
        }
145
146
        if (isset($submissionEvent) && !empty($postActionProperty)) {
147
            // Replace post action property with tokens to support custom redirects, etc
148
            $postActionProperty = $this->replacePostSubmitTokens($postActionProperty, $submissionEvent);
149
        }
150
151
        if ($messengerMode || $isAjax) {
152
            // Return the call via postMessage API
153
            $data = ['success' => 1];
154
            if (!empty($error)) {
155
                if (is_array($error)) {
156
                    $data['validationErrors'] = $error;
157
                } else {
158
                    $data['errorMessage'] = $error;
159
                }
160
                $data['success'] = 0;
161
            } else {
162
                // Include results in ajax response for JS callback use
163
                if (isset($submissionEvent)) {
164
                    $data['results'] = $submissionEvent->getResults();
165
                }
166
167
                if ('redirect' == $postAction) {
168
                    $data['redirect'] = $postActionProperty;
169
                } elseif (!empty($postActionProperty)) {
170
                    $data['successMessage'] = [$postActionProperty];
171
                }
172
173
                if (!empty($callbackResponses)) {
174
                    foreach ($callbackResponses as $response) {
175
                        // Convert the responses to something useful for a JS response
176
                        if ($response instanceof RedirectResponse && !isset($data['redirect'])) {
177
                            $data['redirect'] = $response->getTargetUrl();
178
                        } elseif ($response instanceof Response) {
179
                            if (!isset($data['successMessage'])) {
180
                                $data['successMessage'] = [];
181
                            }
182
                            $data['successMessage'][] = $response->getContent();
183
                        } elseif (is_array($response)) {
184
                            $data = array_merge($data, $response);
185
                        } elseif (is_string($response)) {
186
                            if (!isset($data['successMessage'])) {
187
                                $data['successMessage'] = [];
188
                            }
189
                            $data['successMessage'][] = $response;
190
                        } // ignore anything else
191
                    }
192
                }
193
194
                // Combine all messages into one
195
                if (isset($data['successMessage'])) {
196
                    $data['successMessage'] = implode('<br /><br />', $data['successMessage']);
197
                }
198
            }
199
200
            if (isset($post['formName'])) {
201
                $data['formName'] = $post['formName'];
202
            }
203
204
            if ($isAjax) {
205
                // Post via ajax so return a json response
206
                return new JsonResponse($data);
207
            } else {
208
                $response = json_encode($data);
209
210
                return $this->render('MauticFormBundle::messenger.html.php', ['response' => $response]);
211
            }
212
        } else {
213
            if (!empty($error)) {
214
                if ($return) {
215
                    $hash = (null !== $form) ? '#'.strtolower($form->getAlias()) : '';
216
217
                    return $this->redirect($return.$query.'mauticError='.rawurlencode($error).$hash);
218
                } else {
219
                    $msg     = $error;
220
                    $msgType = 'error';
221
                }
222
            } elseif ('redirect' == $postAction) {
223
                return $this->redirect($postActionProperty);
224
            } elseif ('return' == $postAction) {
225
                if (!empty($return)) {
226
                    if (!empty($postActionProperty)) {
227
                        $return .= $query.'mauticMessage='.rawurlencode($postActionProperty);
228
                    }
229
230
                    return $this->redirect($return);
231
                } else {
232
                    $msg = $this->get('translator')->trans('mautic.form.submission.thankyou');
233
                }
234
            } else {
235
                $msg = $postActionProperty;
236
            }
237
238
            $session = $this->get('session');
239
            $session->set(
240
                'mautic.emailbundle.message',
241
                [
242
                    'message' => $msg,
243
                    'type'    => (empty($msgType)) ? 'notice' : $msgType,
244
                ]
245
            );
246
247
            return $this->redirect($this->generateUrl('mautic_form_postmessage'));
248
        }
249
    }
250
251
    /**
252
     * Displays a message.
253
     *
254
     * @return Response
255
     */
256
    public function messageAction()
257
    {
258
        $session = $this->get('session');
259
        $message = $session->get('mautic.emailbundle.message', []);
260
261
        $msg     = (!empty($message['message'])) ? $message['message'] : '';
262
        $msgType = (!empty($message['type'])) ? $message['type'] : 'notice';
263
264
        $analytics = $this->factory->getHelper('template.analytics')->getCode();
265
266
        if (!empty($analytics)) {
267
            $this->factory->getHelper('template.assets')->addCustomDeclaration($analytics);
268
        }
269
270
        $logicalName = $this->factory->getHelper('theme')->checkForTwigTemplate(':'.$this->coreParametersHelper->get('theme').':message.html.php');
271
272
        return $this->render($logicalName, [
273
            'message'  => $msg,
274
            'type'     => $msgType,
275
            'template' => $this->coreParametersHelper->get('theme'),
276
        ]);
277
    }
278
279
    /**
280
     * Gives a preview of the form.
281
     *
282
     * @param int $id
283
     *
284
     * @return Response
285
     *
286
     * @throws \Exception
287
     * @throws \Mautic\CoreBundle\Exception\FileNotFoundException
288
     */
289
    public function previewAction($id = 0)
290
    {
291
        /** @var FormModel $model */
292
        $objectId          = (empty($id)) ? (int) $this->request->get('id') : $id;
293
        $css               = InputHelper::string($this->request->get('css'));
294
        $model             = $this->getModel('form.form');
295
        $form              = $model->getEntity($objectId);
296
        $customStylesheets = (!empty($css)) ? explode(',', $css) : [];
297
        $template          = null;
298
299
        if (null === $form || !$form->isPublished()) {
300
            return $this->notFound();
301
        } else {
302
            $html = $model->getContent($form);
303
304
            $model->populateValuesWithGetParameters($form, $html);
305
306
            $viewParams = [
307
                'content'     => $html,
308
                'stylesheets' => $customStylesheets,
309
                'name'        => $form->getName(),
310
                'metaRobots'  => '<meta name="robots" content="index">',
311
            ];
312
313
            if ($form->getNoIndex()) {
314
                $viewParams['metaRobots'] = '<meta name="robots" content="noindex">';
315
            }
316
317
            $template = $form->getTemplate();
318
            if (!empty($template)) {
319
                $theme = $this->factory->getTheme($template);
320
                if ($theme->getTheme() != $template) {
321
                    $config = $theme->getConfig();
322
                    if (in_array('form', $config['features'])) {
323
                        $template = $theme->getTheme();
324
                    } else {
325
                        $template = null;
326
                    }
327
                }
328
            }
329
        }
330
331
        $viewParams['template'] = $template;
332
333
        if (!empty($template)) {
334
            $logicalName  = $this->factory->getHelper('theme')->checkForTwigTemplate(':'.$template.':form.html.php');
335
            $assetsHelper = $this->factory->getHelper('template.assets');
336
            $analytics    = $this->factory->getHelper('template.analytics')->getCode();
337
338
            if (!empty($customStylesheets)) {
339
                foreach ($customStylesheets as $css) {
340
                    $assetsHelper->addStylesheet($css);
341
                }
342
            }
343
344
            $this->factory->getHelper('template.slots')->set('pageTitle', $form->getName());
345
346
            if (!empty($analytics)) {
347
                $assetsHelper->addCustomDeclaration($analytics);
348
            }
349
            if ($form->getNoIndex()) {
350
                $assetsHelper->addCustomDeclaration('<meta name="robots" content="noindex">');
351
            }
352
353
            return $this->render($logicalName, $viewParams);
354
        }
355
356
        return $this->render('MauticFormBundle::form.html.php', $viewParams);
357
    }
358
359
    /**
360
     * Generates JS file for automatic form generation.
361
     *
362
     * @return Response
363
     */
364
    public function generateAction()
365
    {
366
        // Don't store a visitor with this request
367
        defined('MAUTIC_NON_TRACKABLE_REQUEST') || define('MAUTIC_NON_TRACKABLE_REQUEST', 1);
368
369
        $formId = (int) $this->request->get('id');
370
371
        $model = $this->getModel('form.form');
372
        $form  = $model->getEntity($formId);
373
        $js    = '';
374
375
        if (null !== $form) {
376
            $status = $form->getPublishStatus();
377
            if ('published' == $status) {
378
                $js = $model->getAutomaticJavascript($form);
0 ignored issues
show
The method getAutomaticJavascript() 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

378
                /** @scrutinizer ignore-call */ 
379
                $js = $model->getAutomaticJavascript($form);
Loading history...
379
            }
380
        }
381
382
        $response = new Response();
383
        $response->setContent($js);
384
        $response->setStatusCode(Response::HTTP_OK);
385
        $response->headers->set('Content-Type', 'text/javascript');
386
387
        return $response;
388
    }
389
390
    /**
391
     * @return Response
392
     */
393
    public function embedAction()
394
    {
395
        $formId = (int) $this->request->get('id');
396
        /** @var FormModel $model */
397
        $model = $this->getModel('form');
398
        $form  = $model->getEntity($formId);
399
400
        if (null !== $form) {
401
            $status = $form->getPublishStatus();
402
            if ('published' === $status) {
403
                if ($this->request->get('video')) {
404
                    return $this->render(
405
                        'MauticFormBundle:Public:videoembed.html.php',
406
                        ['form' => $form, 'fieldSettings' => $model->getCustomComponents()['fields']]
407
                    );
408
                }
409
410
                $content = $model->getContent($form, false, true);
411
412
                return new Response($content);
413
            }
414
        }
415
416
        return new Response('', Response::HTTP_NOT_FOUND);
417
    }
418
419
    /**
420
     * @param $string
421
     * @param $submissionEvent
422
     */
423
    private function replacePostSubmitTokens($string, SubmissionEvent $submissionEvent)
424
    {
425
        if (empty($this->tokens)) {
426
            if ($lead = $submissionEvent->getLead()) {
427
                $this->tokens = array_merge(
428
                    $submissionEvent->getTokens(),
429
                    TokenHelper::findLeadTokens(
430
                        $string,
431
                        $lead->getProfileFields()
432
                    )
433
                );
434
            }
435
        }
436
437
        return str_replace(array_keys($this->tokens), array_values($this->tokens), $string);
438
    }
439
}
440