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\PageBundle\Controller; |
||
13 | |||
14 | use Mautic\CoreBundle\Controller\FormController as CommonFormController; |
||
15 | use Mautic\CoreBundle\Exception\InvalidDecodedStringException; |
||
16 | use Mautic\CoreBundle\Helper\TrackingPixelHelper; |
||
17 | use Mautic\CoreBundle\Helper\UrlHelper; |
||
18 | use Mautic\LeadBundle\Helper\PrimaryCompanyHelper; |
||
19 | use Mautic\LeadBundle\Helper\TokenHelper; |
||
20 | use Mautic\LeadBundle\Model\LeadModel; |
||
21 | use Mautic\LeadBundle\Tracker\ContactTracker; |
||
22 | use Mautic\LeadBundle\Tracker\Service\DeviceTrackingService\DeviceTrackingServiceInterface; |
||
23 | use Mautic\PageBundle\Entity\Page; |
||
24 | use Mautic\PageBundle\Event\PageDisplayEvent; |
||
25 | use Mautic\PageBundle\Helper\TrackingHelper; |
||
26 | use Mautic\PageBundle\Model\PageModel; |
||
27 | use Mautic\PageBundle\Model\VideoModel; |
||
28 | use Mautic\PageBundle\PageEvents; |
||
29 | use Symfony\Component\HttpFoundation\JsonResponse; |
||
30 | use Symfony\Component\HttpFoundation\Request; |
||
31 | use Symfony\Component\HttpFoundation\Response; |
||
32 | use Symfony\Component\Routing\Generator\UrlGeneratorInterface; |
||
33 | |||
34 | class PublicController extends CommonFormController |
||
0 ignored issues
–
show
Deprecated Code
introduced
by
![]() |
|||
35 | { |
||
36 | /** |
||
37 | * @param $slug |
||
38 | * |
||
39 | * @return Response |
||
40 | * |
||
41 | * @throws \Exception |
||
42 | * @throws \Mautic\CoreBundle\Exception\FileNotFoundException |
||
43 | */ |
||
44 | public function indexAction($slug, Request $request) |
||
45 | { |
||
46 | /** @var \Mautic\PageBundle\Model\PageModel $model */ |
||
47 | $model = $this->getModel('page'); |
||
48 | $security = $this->get('mautic.security'); |
||
49 | /** @var Page $entity */ |
||
50 | $entity = $model->getEntityBySlugs($slug); |
||
51 | |||
52 | // Do not hit preference center pages |
||
53 | if (!empty($entity) && !$entity->getIsPreferenceCenter()) { |
||
54 | $userAccess = $security->hasEntityAccess('page:pages:viewown', 'page:pages:viewother', $entity->getCreatedBy()); |
||
55 | $published = $entity->isPublished(); |
||
56 | |||
57 | // Make sure the page is published or deny access if not |
||
58 | if (!$published && !$userAccess) { |
||
59 | // If the page has a redirect type, handle it |
||
60 | if (null != $entity->getRedirectType()) { |
||
61 | $model->hitPage($entity, $this->request, $entity->getRedirectType()); |
||
62 | |||
63 | return $this->redirect($entity->getRedirectUrl(), $entity->getRedirectType()); |
||
64 | } else { |
||
65 | $model->hitPage($entity, $this->request, 401); |
||
66 | |||
67 | return $this->accessDenied(); |
||
68 | } |
||
69 | } |
||
70 | |||
71 | $lead = null; |
||
72 | $query = null; |
||
73 | if (!$userAccess) { |
||
74 | /** @var LeadModel $leadModel */ |
||
75 | $leadModel = $this->getModel('lead'); |
||
76 | // Extract the lead from the request so it can be used to determine language if applicable |
||
77 | $query = $model->getHitQuery($this->request, $entity); |
||
78 | $lead = $leadModel->getContactFromRequest($query); |
||
79 | } |
||
80 | |||
81 | // Correct the URL if it doesn't match up |
||
82 | if (!$request->attributes->get('ignore_mismatch', 0)) { |
||
83 | // Make sure URLs match up |
||
84 | $url = $model->generateUrl($entity, false); |
||
85 | $requestUri = $this->request->getRequestUri(); |
||
86 | |||
87 | // Remove query when comparing |
||
88 | $query = $this->request->getQueryString(); |
||
89 | if (!empty($query)) { |
||
90 | $requestUri = str_replace("?{$query}", '', $url); |
||
91 | } |
||
92 | |||
93 | // Redirect if they don't match |
||
94 | if ($requestUri != $url) { |
||
95 | $model->hitPage($entity, $this->request, 301, $lead, $query); |
||
96 | |||
97 | return $this->redirect($url, 301); |
||
98 | } |
||
99 | } |
||
100 | |||
101 | // Check for variants |
||
102 | list($parentVariant, $childrenVariants) = $entity->getVariants(); |
||
103 | |||
104 | // Is this a variant of another? If so, the parent URL should be used unless a user is logged in and previewing |
||
105 | if ($parentVariant != $entity && !$userAccess) { |
||
106 | $model->hitPage($entity, $this->request, 301, $lead, $query); |
||
107 | $url = $model->generateUrl($parentVariant, false); |
||
108 | |||
109 | return $this->redirect($url, 301); |
||
110 | } |
||
111 | |||
112 | // First determine the A/B test to display if applicable |
||
113 | if (!$userAccess) { |
||
114 | // Check to see if a variant should be shown versus the parent but ignore if a user is previewing |
||
115 | if (count($childrenVariants)) { |
||
116 | $variants = []; |
||
117 | $variantWeight = 0; |
||
118 | $totalHits = $entity->getVariantHits(); |
||
119 | |||
120 | foreach ($childrenVariants as $id => $child) { |
||
121 | if ($child->isPublished()) { |
||
122 | $variantSettings = $child->getVariantSettings(); |
||
123 | $variants[$id] = [ |
||
124 | 'weight' => ($variantSettings['weight'] / 100), |
||
125 | 'hits' => $child->getVariantHits(), |
||
126 | ]; |
||
127 | $variantWeight += $variantSettings['weight']; |
||
128 | |||
129 | // Count translations for this variant as well |
||
130 | $translations = $child->getTranslations(true); |
||
131 | /** @var Page $translation */ |
||
132 | foreach ($translations as $translation) { |
||
133 | if ($translation->isPublished()) { |
||
134 | $variants[$id]['hits'] += (int) $translation->getVariantHits(); |
||
135 | } |
||
136 | } |
||
137 | |||
138 | $totalHits += $variants[$id]['hits']; |
||
139 | } |
||
140 | } |
||
141 | |||
142 | if (count($variants)) { |
||
143 | //check to see if this user has already been displayed a specific variant |
||
144 | $variantCookie = $this->request->cookies->get('mautic_page_'.$entity->getId()); |
||
145 | |||
146 | if (!empty($variantCookie)) { |
||
147 | if (isset($variants[$variantCookie])) { |
||
148 | //if not the parent, show the specific variant already displayed to the visitor |
||
149 | if ($variantCookie !== $entity->getId()) { |
||
150 | $entity = $childrenVariants[$variantCookie]; |
||
151 | } //otherwise proceed with displaying parent |
||
152 | } |
||
153 | } else { |
||
154 | // Add parent weight |
||
155 | $variants[$entity->getId()] = [ |
||
156 | 'weight' => ((100 - $variantWeight) / 100), |
||
157 | 'hits' => $entity->getVariantHits(), |
||
158 | ]; |
||
159 | |||
160 | // Count translations for the parent as well |
||
161 | $translations = $entity->getTranslations(true); |
||
162 | /** @var Page $translation */ |
||
163 | foreach ($translations as $translation) { |
||
164 | if ($translation->isPublished()) { |
||
165 | $variants[$entity->getId()]['hits'] += (int) $translation->getVariantHits(); |
||
166 | } |
||
167 | } |
||
168 | $totalHits += $variants[$id]['hits']; |
||
169 | |||
170 | //determine variant to show |
||
171 | foreach ($variants as &$variant) { |
||
172 | $variant['weight_deficit'] = ($totalHits) ? $variant['weight'] - ($variant['hits'] / $totalHits) : $variant['weight']; |
||
173 | } |
||
174 | |||
175 | // Reorder according to send_weight so that campaigns which currently send one at a time alternate |
||
176 | uasort( |
||
177 | $variants, |
||
178 | function ($a, $b) { |
||
179 | if ($a['weight_deficit'] === $b['weight_deficit']) { |
||
180 | if ($a['hits'] === $b['hits']) { |
||
181 | return 0; |
||
182 | } |
||
183 | |||
184 | // if weight is the same - sort by least number displayed |
||
185 | return ($a['hits'] < $b['hits']) ? -1 : 1; |
||
186 | } |
||
187 | |||
188 | // sort by the one with the greatest deficit first |
||
189 | return ($a['weight_deficit'] > $b['weight_deficit']) ? -1 : 1; |
||
190 | } |
||
191 | ); |
||
192 | |||
193 | //find the one with the most difference from weight |
||
194 | |||
195 | reset($variants); |
||
196 | $useId = key($variants); |
||
197 | |||
198 | //set the cookie - 14 days |
||
199 | $this->get('mautic.helper.cookie')->setCookie( |
||
200 | 'mautic_page_'.$entity->getId(), |
||
201 | $useId, |
||
202 | 3600 * 24 * 14 |
||
203 | ); |
||
204 | |||
205 | if ($useId != $entity->getId()) { |
||
206 | $entity = $childrenVariants[$useId]; |
||
207 | } |
||
208 | } |
||
209 | } |
||
210 | } |
||
211 | |||
212 | // Now show the translation for the page or a/b test - only fetch a translation if a slug was not used |
||
213 | if ($entity->isTranslation() && empty($entity->languageSlug)) { |
||
214 | list($translationParent, $translatedEntity) = $model->getTranslatedEntity( |
||
215 | $entity, |
||
216 | $lead, |
||
217 | $this->request |
||
218 | ); |
||
219 | |||
220 | if ($translationParent && $translatedEntity !== $entity) { |
||
221 | if (!$this->request->get('ntrd', 0)) { |
||
222 | $url = $model->generateUrl($translatedEntity, false); |
||
223 | $model->hitPage($entity, $this->request, 302, $lead, $query); |
||
224 | |||
225 | return $this->redirect($url, 302); |
||
226 | } |
||
227 | } |
||
228 | } |
||
229 | } |
||
230 | |||
231 | // Generate contents |
||
232 | $analytics = $this->get('mautic.helper.template.analytics')->getCode(); |
||
233 | |||
234 | $BCcontent = $entity->getContent(); |
||
235 | $content = $entity->getCustomHtml(); |
||
236 | // This condition remains so the Mautic v1 themes would display the content |
||
237 | if (empty($content) && !empty($BCcontent)) { |
||
238 | /** |
||
239 | * @deprecated BC support to be removed in 3.0 |
||
240 | */ |
||
241 | $template = $entity->getTemplate(); |
||
242 | //all the checks pass so display the content |
||
243 | $slots = $this->factory->getTheme($template)->getSlots('page'); |
||
244 | $content = $entity->getContent(); |
||
245 | |||
246 | $this->processSlots($slots, $entity); |
||
247 | |||
248 | // Add the GA code to the template assets |
||
249 | if (!empty($analytics)) { |
||
250 | $this->factory->getHelper('template.assets')->addCustomDeclaration($analytics); |
||
251 | } |
||
252 | |||
253 | $logicalName = $this->factory->getHelper('theme')->checkForTwigTemplate(':'.$template.':page.html.php'); |
||
254 | |||
255 | $response = $this->render( |
||
256 | $logicalName, |
||
257 | [ |
||
258 | 'slots' => $slots, |
||
259 | 'content' => $content, |
||
260 | 'page' => $entity, |
||
261 | 'template' => $template, |
||
262 | 'public' => true, |
||
263 | ] |
||
264 | ); |
||
265 | |||
266 | $content = $response->getContent(); |
||
267 | } else { |
||
268 | if (!empty($analytics)) { |
||
269 | $content = str_replace('</head>', $analytics."\n</head>", $content); |
||
270 | } |
||
271 | if ($entity->getNoIndex()) { |
||
272 | $content = str_replace('</head>', "<meta name=\"robots\" content=\"noindex\">\n</head>", $content); |
||
273 | } |
||
274 | } |
||
275 | |||
276 | $this->get('templating.helper.assets')->addScript( |
||
277 | $this->get('router')->generate('mautic_js', [], UrlGeneratorInterface::ABSOLUTE_URL), |
||
278 | 'onPageDisplay_headClose', |
||
279 | true, |
||
280 | 'mautic_js' |
||
281 | ); |
||
282 | |||
283 | $event = new PageDisplayEvent($content, $entity); |
||
284 | $this->get('event_dispatcher')->dispatch(PageEvents::PAGE_ON_DISPLAY, $event); |
||
285 | $content = $event->getContent(); |
||
286 | |||
287 | $model->hitPage($entity, $this->request, 200, $lead, $query); |
||
288 | |||
289 | return new Response($content); |
||
290 | } |
||
291 | |||
292 | $model->hitPage($entity, $this->request, 404); |
||
293 | |||
294 | return $this->notFound(); |
||
295 | } |
||
296 | |||
297 | /** |
||
298 | * @param $id |
||
299 | * |
||
300 | * @return Response|\Symfony\Component\HttpKernel\Exception\NotFoundHttpException |
||
301 | * |
||
302 | * @throws \Exception |
||
303 | * @throws \Mautic\CoreBundle\Exception\FileNotFoundException |
||
304 | */ |
||
305 | public function previewAction($id) |
||
306 | { |
||
307 | $model = $this->getModel('page'); |
||
308 | $entity = $model->getEntity($id); |
||
309 | |||
310 | if (null === $entity) { |
||
311 | return $this->notFound(); |
||
312 | } |
||
313 | |||
314 | $analytics = $this->factory->getHelper('template.analytics')->getCode(); |
||
315 | |||
316 | $BCcontent = $entity->getContent(); |
||
317 | $content = $entity->getCustomHtml(); |
||
318 | if (empty($content) && !empty($BCcontent)) { |
||
319 | $template = $entity->getTemplate(); |
||
320 | //all the checks pass so display the content |
||
321 | $slots = $this->factory->getTheme($template)->getSlots('page'); |
||
322 | $content = $entity->getContent(); |
||
323 | |||
324 | $this->processSlots($slots, $entity); |
||
325 | |||
326 | // Add the GA code to the template assets |
||
327 | if (!empty($analytics)) { |
||
328 | $this->factory->getHelper('template.assets')->addCustomDeclaration($analytics); |
||
329 | } |
||
330 | |||
331 | $logicalName = $this->factory->getHelper('theme')->checkForTwigTemplate(':'.$template.':page.html.php'); |
||
332 | |||
333 | $response = $this->render( |
||
334 | $logicalName, |
||
335 | [ |
||
336 | 'slots' => $slots, |
||
337 | 'content' => $content, |
||
338 | 'page' => $entity, |
||
339 | 'template' => $template, |
||
340 | 'public' => true, // @deprecated Remove in 2.0 |
||
341 | ] |
||
342 | ); |
||
343 | |||
344 | $content = $response->getContent(); |
||
345 | } else { |
||
346 | if (!empty($analytics)) { |
||
347 | $content = str_replace('</head>', $analytics."\n</head>", $content); |
||
348 | } |
||
349 | } |
||
350 | |||
351 | $dispatcher = $this->get('event_dispatcher'); |
||
352 | if ($dispatcher->hasListeners(PageEvents::PAGE_ON_DISPLAY)) { |
||
353 | $event = new PageDisplayEvent($content, $entity); |
||
354 | $dispatcher->dispatch(PageEvents::PAGE_ON_DISPLAY, $event); |
||
355 | $content = $event->getContent(); |
||
356 | } |
||
357 | |||
358 | return new Response($content); |
||
359 | } |
||
360 | |||
361 | /** |
||
362 | * @return Response |
||
363 | * |
||
364 | * @throws \Exception |
||
365 | */ |
||
366 | public function trackingImageAction() |
||
367 | { |
||
368 | /** @var \Mautic\PageBundle\Model\PageModel $model */ |
||
369 | $model = $this->getModel('page'); |
||
370 | $model->hitPage(null, $this->request); |
||
371 | |||
372 | return TrackingPixelHelper::getResponse($this->request); |
||
373 | } |
||
374 | |||
375 | /** |
||
376 | * @return JsonResponse |
||
377 | * |
||
378 | * @throws \Exception |
||
379 | */ |
||
380 | public function trackingAction() |
||
381 | { |
||
382 | if (!$this->get('mautic.security')->isAnonymous()) { |
||
383 | return new JsonResponse( |
||
384 | [ |
||
385 | 'success' => 0, |
||
386 | ] |
||
387 | ); |
||
388 | } |
||
389 | |||
390 | /** @var \Mautic\PageBundle\Model\PageModel $model */ |
||
391 | $model = $this->getModel('page'); |
||
392 | $model->hitPage(null, $this->request); |
||
393 | |||
394 | /** @var ContactTracker $contactTracker */ |
||
395 | $contactTracker = $this->get(ContactTracker::class); |
||
396 | |||
397 | $lead = $contactTracker->getContact(); |
||
398 | /** @var DeviceTrackingServiceInterface $trackedDevice */ |
||
399 | $trackedDevice = $this->get('mautic.lead.service.device_tracking_service')->getTrackedDevice(); |
||
400 | $trackingId = (null === $trackedDevice ? null : $trackedDevice->getTrackingId()); |
||
401 | |||
402 | /** @var TrackingHelper $trackingHelper */ |
||
403 | $trackingHelper = $this->get('mautic.page.helper.tracking'); |
||
404 | $sessionValue = $trackingHelper->getSession(true); |
||
405 | |||
406 | return new JsonResponse( |
||
407 | [ |
||
408 | 'success' => 1, |
||
409 | 'id' => ($lead) ? $lead->getId() : null, |
||
410 | 'sid' => $trackingId, |
||
411 | 'device_id' => $trackingId, |
||
412 | 'events' => $sessionValue, |
||
413 | ] |
||
414 | ); |
||
415 | } |
||
416 | |||
417 | /** |
||
418 | * @param $redirectId |
||
419 | * |
||
420 | * @return \Symfony\Component\HttpFoundation\RedirectResponse |
||
421 | * |
||
422 | * @throws \Exception |
||
423 | */ |
||
424 | public function redirectAction($redirectId) |
||
425 | { |
||
426 | $logger = $this->container->get('monolog.logger.mautic'); |
||
427 | |||
428 | $logger->debug('Attempting to load redirect with tracking_id of: '.$redirectId); |
||
429 | |||
430 | /** @var \Mautic\PageBundle\Model\RedirectModel $redirectModel */ |
||
431 | $redirectModel = $this->getModel('page.redirect'); |
||
432 | $redirect = $redirectModel->getRedirectById($redirectId); |
||
433 | |||
434 | $logger->debug('Executing Redirect: '.$redirect); |
||
435 | |||
436 | if (null === $redirect || !$redirect->isPublished(false)) { |
||
437 | $logger->debug('Redirect with tracking_id of '.$redirectId.' not found'); |
||
438 | |||
439 | $url = ($redirect) ? $redirect->getUrl() : 'n/a'; |
||
440 | |||
441 | throw $this->createNotFoundException($this->translator->trans('mautic.core.url.error.404', ['%url%' => $url])); |
||
442 | } |
||
443 | |||
444 | // Ensure the URL does not have encoded ampersands |
||
445 | $url = str_replace('&', '&', $redirect->getUrl()); |
||
446 | |||
447 | // Get query string |
||
448 | $query = $this->request->query->all(); |
||
449 | |||
450 | // Unset the clickthrough from the URL query |
||
451 | $ct = $query['ct']; |
||
452 | unset($query['ct']); |
||
453 | |||
454 | // Tak on anything left to the URL |
||
455 | if (count($query)) { |
||
456 | $url = UrlHelper::appendQueryToUrl($url, http_build_query($query)); |
||
457 | } |
||
458 | |||
459 | // If the IP address is not trackable, it means it came form a configured "do not track" IP or a "do not track" user agent |
||
460 | // This prevents simulated clicks from 3rd party services such as URL shorteners from simulating clicks |
||
461 | $ipAddress = $this->container->get('mautic.helper.ip_lookup')->getIpAddress(); |
||
462 | if ($ipAddress->isTrackable()) { |
||
463 | // Search replace lead fields in the URL |
||
464 | /** @var \Mautic\LeadBundle\Model\LeadModel $leadModel */ |
||
465 | $leadModel = $this->getModel('lead'); |
||
466 | |||
467 | /** @var PageModel $pageModel */ |
||
468 | $pageModel = $this->getModel('page'); |
||
469 | |||
470 | try { |
||
471 | $lead = $leadModel->getContactFromRequest(['ct' => $ct]); |
||
472 | $pageModel->hitPage($redirect, $this->request, 200, $lead); |
||
473 | } catch (InvalidDecodedStringException $e) { |
||
474 | // Invalid ct value so we must unset it |
||
475 | // and process the request without it |
||
476 | |||
477 | $logger->error(sprintf('Invalid clickthrough value: %s', $ct), ['exception' => $e]); |
||
478 | |||
479 | $this->request->request->set('ct', ''); |
||
480 | $this->request->query->set('ct', ''); |
||
481 | $lead = $leadModel->getContactFromRequest(); |
||
482 | $pageModel->hitPage($redirect, $this->request, 200, $lead); |
||
483 | } |
||
484 | |||
485 | /** @var PrimaryCompanyHelper $primaryCompanyHelper */ |
||
486 | $primaryCompanyHelper = $this->get('mautic.lead.helper.primary_company'); |
||
487 | $leadArray = ($lead) ? $primaryCompanyHelper->getProfileFieldsWithPrimaryCompany($lead) : []; |
||
488 | |||
489 | $url = TokenHelper::findLeadTokens($url, $leadArray, true); |
||
490 | } |
||
491 | |||
492 | $url = UrlHelper::sanitizeAbsoluteUrl($url); |
||
493 | |||
494 | if (!UrlHelper::isValidUrl($url)) { |
||
495 | throw $this->createNotFoundException($this->translator->trans('mautic.core.url.error.404', ['%url%' => $url])); |
||
496 | } |
||
497 | |||
498 | return $this->redirect($url); |
||
499 | } |
||
500 | |||
501 | /** |
||
502 | * PreProcess page slots for public view. |
||
503 | * |
||
504 | * @deprecated - to be removed in 3.0 |
||
505 | * |
||
506 | * @param array $slots |
||
507 | * @param Page $entity |
||
508 | */ |
||
509 | private function processSlots($slots, $entity) |
||
510 | { |
||
511 | /** @var \Mautic\CoreBundle\Templating\Helper\AssetsHelper $assetsHelper */ |
||
512 | $assetsHelper = $this->factory->getHelper('template.assets'); |
||
513 | /** @var \Mautic\CoreBundle\Templating\Helper\SlotsHelper $slotsHelper */ |
||
514 | $slotsHelper = $this->factory->getHelper('template.slots'); |
||
515 | |||
516 | $content = $entity->getContent(); |
||
517 | |||
518 | foreach ($slots as $slot => $slotConfig) { |
||
519 | // backward compatibility - if slotConfig array does not exist |
||
520 | if (is_numeric($slot)) { |
||
521 | $slot = $slotConfig; |
||
522 | $slotConfig = []; |
||
523 | } |
||
524 | |||
525 | if (isset($slotConfig['type']) && 'slideshow' == $slotConfig['type']) { |
||
526 | if (isset($content[$slot])) { |
||
527 | $options = json_decode($content[$slot], true); |
||
528 | } else { |
||
529 | $options = [ |
||
530 | 'width' => '100%', |
||
531 | 'height' => '250px', |
||
532 | 'background_color' => 'transparent', |
||
533 | 'arrow_navigation' => false, |
||
534 | 'dot_navigation' => true, |
||
535 | 'interval' => 5000, |
||
536 | 'pause' => 'hover', |
||
537 | 'wrap' => true, |
||
538 | 'keyboard' => true, |
||
539 | ]; |
||
540 | } |
||
541 | |||
542 | // Create sample slides for first time or if all slides were deleted |
||
543 | if (empty($options['slides'])) { |
||
544 | $options['slides'] = [ |
||
545 | [ |
||
546 | 'order' => 0, |
||
547 | 'background-image' => $assetsHelper->getUrl('media/images/mautic_logo_lb200.png'), |
||
548 | 'captionheader' => 'Caption 1', |
||
549 | ], |
||
550 | [ |
||
551 | 'order' => 1, |
||
552 | 'background-image' => $assetsHelper->getUrl('media/images/mautic_logo_db200.png'), |
||
553 | 'captionheader' => 'Caption 2', |
||
554 | ], |
||
555 | ]; |
||
556 | } |
||
557 | |||
558 | // Order slides |
||
559 | usort( |
||
560 | $options['slides'], |
||
561 | function ($a, $b) { |
||
562 | return strcmp($a['order'], $b['order']); |
||
563 | } |
||
564 | ); |
||
565 | |||
566 | $options['slot'] = $slot; |
||
567 | $options['public'] = true; |
||
568 | |||
569 | $renderingEngine = $this->container->get('templating')->getEngine('MauticPageBundle:Page:Slots/slideshow.html.php'); |
||
570 | $slotsHelper->set($slot, $renderingEngine->render('MauticPageBundle:Page:Slots/slideshow.html.php', $options)); |
||
571 | } elseif (isset($slotConfig['type']) && 'textarea' == $slotConfig['type']) { |
||
572 | $value = isset($content[$slot]) ? nl2br($content[$slot]) : ''; |
||
573 | $slotsHelper->set($slot, $value); |
||
574 | } else { |
||
575 | // Fallback for other types like html, text, textarea and all unknown |
||
576 | $value = isset($content[$slot]) ? $content[$slot] : ''; |
||
577 | $slotsHelper->set($slot, $value); |
||
578 | } |
||
579 | } |
||
580 | |||
581 | $parentVariant = $entity->getVariantParent(); |
||
582 | $title = (!empty($parentVariant)) ? $parentVariant->getTitle() : $entity->getTitle(); |
||
583 | $slotsHelper->set('pageTitle', $title); |
||
584 | } |
||
585 | |||
586 | /** |
||
587 | * Track video views. |
||
588 | */ |
||
589 | public function hitVideoAction() |
||
590 | { |
||
591 | // Only track XMLHttpRequests, because the hit should only come from there |
||
592 | if ($this->request->isXmlHttpRequest()) { |
||
593 | /** @var VideoModel $model */ |
||
594 | $model = $this->getModel('page.video'); |
||
595 | |||
596 | try { |
||
597 | $model->hitVideo($this->request); |
||
598 | } catch (\Exception $e) { |
||
599 | return new JsonResponse(['success' => false]); |
||
600 | } |
||
601 | |||
602 | return new JsonResponse(['success' => true]); |
||
603 | } |
||
604 | |||
605 | return new Response(); |
||
606 | } |
||
607 | |||
608 | /** |
||
609 | * Get the ID of the currently tracked Contact. |
||
610 | * |
||
611 | * @return JsonResponse |
||
612 | */ |
||
613 | public function getContactIdAction() |
||
614 | { |
||
615 | $data = []; |
||
616 | if ($this->get('mautic.security')->isAnonymous()) { |
||
617 | /** @var ContactTracker $contactTracker */ |
||
618 | $contactTracker = $this->get(ContactTracker::class); |
||
619 | |||
620 | $lead = $contactTracker->getContact(); |
||
621 | /** @var DeviceTrackingServiceInterface $trackedDevice */ |
||
622 | $trackedDevice = $this->get('mautic.lead.service.device_tracking_service')->getTrackedDevice(); |
||
623 | $trackingId = (null === $trackedDevice ? null : $trackedDevice->getTrackingId()); |
||
624 | $data = [ |
||
625 | 'id' => ($lead) ? $lead->getId() : null, |
||
626 | 'sid' => $trackingId, |
||
627 | 'device_id' => $trackingId, |
||
628 | ]; |
||
629 | } |
||
630 | |||
631 | return new JsonResponse($data); |
||
632 | } |
||
633 | } |
||
634 |