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
Bug
introduced
by
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 |