Issues (3627)

bundles/CoreBundle/Controller/CommonController.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\CoreBundle\Controller;
13
14
use Mautic\CoreBundle\Factory\MauticFactory;
15
use Mautic\CoreBundle\Helper\CoreParametersHelper;
16
use Mautic\CoreBundle\Helper\DataExporterHelper;
17
use Mautic\CoreBundle\Helper\InputHelper;
18
use Mautic\CoreBundle\Helper\TrailingSlashHelper;
19
use Mautic\CoreBundle\Model\AbstractCommonModel;
20
use Mautic\CoreBundle\Service\FlashBag;
21
use Mautic\UserBundle\Entity\User;
22
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
23
use Symfony\Component\Debug\Exception\FlattenException;
24
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
25
use Symfony\Component\HttpFoundation\JsonResponse;
26
use Symfony\Component\HttpFoundation\RedirectResponse;
27
use Symfony\Component\HttpFoundation\Request;
28
use Symfony\Component\HttpFoundation\Response;
29
use Symfony\Component\HttpFoundation\StreamedResponse;
30
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
31
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
32
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
33
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
34
use Symfony\Component\HttpKernel\HttpKernelInterface;
35
use Symfony\Component\Translation\TranslatorInterface;
36
37
/**
38
 * Class CommonController.
39
 */
40
class CommonController extends Controller implements MauticController
41
{
42
    use FormThemeTrait;
43
44
    /**
45
     * @var MauticFactory
46
     */
47
    protected $factory;
48
49
    /**
50
     * @var \Symfony\Component\HttpFoundation\Request
51
     */
52
    protected $request;
53
54
    /**
55
     * @var User
56
     */
57
    protected $user;
58
59
    /**
60
     * @var CoreParametersHelper
61
     */
62
    protected $coreParametersHelper;
63
64
    /**
65
     * @var EventDispatcherInterface
66
     */
67
    protected $dispatcher;
68
69
    /**
70
     * @var TranslatorInterface
71
     */
72
    protected $translator;
73
74
    /**
75
     * @var FlashBag
76
     */
77
    private $flashBag;
78
79
    public function setRequest(Request $request)
80
    {
81
        $this->request = $request;
82
    }
83
84
    public function setFactory(MauticFactory $factory)
85
    {
86
        $this->factory = $factory;
87
    }
88
89
    public function setUser(User $user)
90
    {
91
        $this->user = $user;
92
    }
93
94
    public function setCoreParametersHelper(CoreParametersHelper $coreParametersHelper)
95
    {
96
        $this->coreParametersHelper = $coreParametersHelper;
97
    }
98
99
    public function setDispatcher(EventDispatcherInterface $dispatcher)
100
    {
101
        $this->dispatcher = $dispatcher;
102
    }
103
104
    public function setTranslator(TranslatorInterface $translator)
105
    {
106
        $this->translator = $translator;
107
    }
108
109
    public function setFlashBag(FlashBag $flashBag)
110
    {
111
        $this->flashBag = $flashBag;
112
    }
113
114
    public function initialize(FilterControllerEvent $event)
115
    {
116
    }
117
118
    /**
119
     * Check if a security level is granted.
120
     *
121
     * @param $level
122
     *
123
     * @return bool
124
     */
125
    protected function accessGranted($level)
126
    {
127
        return in_array($level, $this->getPermissions());
128
    }
129
130
    /**
131
     * Override this method in your controller
132
     * for easy access to the permissions.
133
     *
134
     * @return array
135
     */
136
    protected function getPermissions()
137
    {
138
        return [];
139
    }
140
141
    /**
142
     * Get a model instance from the service container.
143
     *
144
     * @param $modelNameKey
145
     *
146
     * @return AbstractCommonModel
147
     */
148
    protected function getModel($modelNameKey)
149
    {
150
        return $this->container->get('mautic.model.factory')->getModel($modelNameKey);
151
    }
152
153
    /**
154
     * Forwards the request to another controller and include the POST.
155
     *
156
     * @param string $controller The controller name (a string like BlogBundle:Post:index)
157
     * @param array  $request    An array of request parameters
158
     * @param array  $path       An array of path parameters
159
     * @param array  $query      An array of query parameters
160
     *
161
     * @return Response A Response instance
162
     */
163
    public function forwardWithPost($controller, array $request = [], array $path = [], array $query = [])
164
    {
165
        $path['_controller'] = $controller;
166
        $subRequest          = $this->container->get('request_stack')->getCurrentRequest()->duplicate($query, $request, $path);
167
168
        return $this->container->get('http_kernel')->handle($subRequest, HttpKernelInterface::SUB_REQUEST);
169
    }
170
171
    /**
172
     * Determines if ajax content should be returned or direct content (page refresh).
173
     *
174
     * @param array $args
175
     *
176
     * @return JsonResponse|Response
177
     */
178
    public function delegateView($args)
179
    {
180
        // Used for error handling
181
        defined('MAUTIC_DELEGATE_VIEW') || define('MAUTIC_DELEGATE_VIEW', 1);
182
183
        if (!is_array($args)) {
184
            $args = [
185
                'contentTemplate' => $args,
186
                'passthroughVars' => [
187
                    'mauticContent' => strtolower($this->request->get('bundle')),
188
                ],
189
            ];
190
        }
191
192
        if (!isset($args['viewParameters']['currentRoute']) && isset($args['passthroughVars']['route'])) {
193
            $args['viewParameters']['currentRoute'] = $args['passthroughVars']['route'];
194
        }
195
196
        if (!isset($args['passthroughVars']['inBuilder']) && $inBuilder = $this->request->get('inBuilder')) {
197
            $args['passthroughVars']['inBuilder'] = (bool) $inBuilder;
198
        }
199
200
        if (!isset($args['viewParameters']['mauticContent'])) {
201
            if (isset($args['passthroughVars']['mauticContent'])) {
202
                $mauticContent = $args['passthroughVars']['mauticContent'];
203
            } else {
204
                $mauticContent = strtolower($this->request->get('bundle'));
205
            }
206
            $args['viewParameters']['mauticContent'] = $mauticContent;
207
        }
208
209
        if ($this->request->isXmlHttpRequest() && !$this->request->get('ignoreAjax', false)) {
210
            return $this->ajaxAction($args);
211
        }
212
213
        $parameters = (isset($args['viewParameters'])) ? $args['viewParameters'] : [];
214
        $template   = $args['contentTemplate'];
215
216
        $code     = (isset($args['responseCode'])) ? $args['responseCode'] : 200;
217
        $response = new Response('', $code);
218
219
        return $this->render($template, $parameters, $response);
220
    }
221
222
    /**
223
     * Determines if a redirect response should be returned or a Json response directing the ajax call to force a page
224
     * refresh.
225
     *
226
     * @param $url
227
     *
228
     * @return JsonResponse|\Symfony\Component\HttpFoundation\RedirectResponse
229
     */
230
    public function delegateRedirect($url)
231
    {
232
        if ($this->request->isXmlHttpRequest()) {
233
            return new JsonResponse(['redirect' => $url]);
234
        } else {
235
            return $this->redirect($url);
236
        }
237
    }
238
239
    /**
240
     * Redirects URLs with trailing slashes in order to prevent 404s.
241
     *
242
     * @return \Symfony\Component\HttpFoundation\RedirectResponse
243
     */
244
    public function removeTrailingSlashAction(Request $request)
245
    {
246
        /** @var TrailingSlashHelper $trailingSlashHelper */
247
        $trailingSlashHelper = $this->get('mautic.helper.trailing_slash');
248
249
        return $this->redirect($trailingSlashHelper->getSafeRedirectUrl($request), 301);
250
    }
251
252
    /**
253
     * Redirects /s and /s/ to /s/dashboard.
254
     */
255
    public function redirectSecureRootAction()
256
    {
257
        return $this->redirect($this->generateUrl('mautic_dashboard_index'), 301);
258
    }
259
260
    /**
261
     * Redirects controller if not ajax or retrieves html output for ajax request.
262
     *
263
     * @param array $args [returnUrl, viewParameters, contentTemplate, passthroughVars, flashes, forwardController]
264
     *
265
     * @return JsonResponse|\Symfony\Component\HttpFoundation\RedirectResponse
266
     */
267
    public function postActionRedirect($args = [])
268
    {
269
        $returnUrl = array_key_exists('returnUrl', $args) ? $args['returnUrl'] : $this->generateUrl('mautic_dashboard_index');
270
        $flashes   = array_key_exists('flashes', $args) ? $args['flashes'] : [];
271
272
        //forward the controller by default
273
        $args['forwardController'] = (array_key_exists('forwardController', $args)) ? $args['forwardController'] : true;
274
275
        //set flashes
276
        if (!empty($flashes)) {
277
            foreach ($flashes as $flash) {
278
                $this->addFlash(
279
                    $flash['msg'],
280
                    !empty($flash['msgVars']) ? $flash['msgVars'] : [],
281
                    !empty($flash['type']) ? $flash['type'] : 'notice',
282
                    !empty($flash['domain']) ? $flash['domain'] : 'flashes'
283
                );
284
            }
285
        }
286
287
        if (isset($args['passthroughVars']['closeModal'])) {
288
            $args['passthroughVars']['updateMainContent'] = true;
289
        }
290
291
        if (!$this->request->isXmlHttpRequest() || !empty($args['ignoreAjax'])) {
292
            $code = (isset($args['responseCode'])) ? $args['responseCode'] : 302;
293
294
            return $this->redirect($returnUrl, $code);
295
        }
296
297
        //load by ajax
298
        return $this->ajaxAction($args);
299
    }
300
301
    /**
302
     * Generates html for ajax request.
303
     *
304
     * @param array $args [parameters, contentTemplate, passthroughVars, forwardController]
305
     *
306
     * @return JsonResponse
307
     */
308
    public function ajaxAction($args = [])
309
    {
310
        defined('MAUTIC_AJAX_VIEW') || define('MAUTIC_AJAX_VIEW', 1);
311
312
        $parameters      = array_key_exists('viewParameters', $args) ? $args['viewParameters'] : [];
313
        $contentTemplate = array_key_exists('contentTemplate', $args) ? $args['contentTemplate'] : '';
314
        $passthrough     = array_key_exists('passthroughVars', $args) ? $args['passthroughVars'] : [];
315
        $forward         = array_key_exists('forwardController', $args) ? $args['forwardController'] : false;
316
        $code            = array_key_exists('responseCode', $args) ? $args['responseCode'] : 200;
317
318
        /*
319
         * Return json response if this is a modal
320
         */
321
        if (!empty($passthrough['closeModal']) && empty($passthrough['updateModalContent']) && empty($passthrough['updateMainContent'])) {
322
            return new JsonResponse($passthrough);
323
        }
324
325
        //set the route to the returnUrl
326
        if (empty($passthrough['route']) && !empty($args['returnUrl'])) {
327
            $passthrough['route'] = $args['returnUrl'];
328
        }
329
330
        if (!empty($passthrough['route'])) {
331
            // Add the ajax route to the request so that the desired route is fed to plugins rather than the current request
332
            $baseUrl       = $this->request->getBaseUrl();
333
            $routePath     = str_replace($baseUrl, '', $passthrough['route']);
334
            $ajaxRouteName = false;
335
336
            try {
337
                $routeParams   = $this->get('router')->match($routePath);
338
                $ajaxRouteName = $routeParams['_route'];
339
340
                $this->request->attributes->set('ajaxRoute',
341
                    [
342
                        '_route'        => $ajaxRouteName,
343
                        '_route_params' => $routeParams,
344
                    ]
345
                );
346
            } catch (\Exception $e) {
347
                //do nothing
348
            }
349
350
            //breadcrumbs may fail as it will retrieve the crumb path for currently loaded URI so we must override
351
            $this->request->query->set('overrideRouteUri', $passthrough['route']);
352
            if ($ajaxRouteName) {
353
                if (isset($routeParams['objectAction'])) {
354
                    //action urls share same route name so tack on the action to differentiate
355
                    $ajaxRouteName .= "|{$routeParams['objectAction']}";
356
                }
357
                $this->request->query->set('overrideRouteName', $ajaxRouteName);
358
            }
359
        }
360
361
        //Ajax call so respond with json
362
        $newContent = '';
363
        if ($contentTemplate) {
364
            if ($forward) {
365
                //the content is from another controller action so we must retrieve the response from it instead of
366
                //directly parsing the template
367
                $query              = ['ignoreAjax' => true, 'request' => $this->request, 'subrequest' => true];
368
                $newContentResponse = $this->forward($contentTemplate, $parameters, $query);
369
                if ($newContentResponse instanceof RedirectResponse) {
370
                    $passthrough['redirect'] = $newContentResponse->getTargetUrl();
371
                    $passthrough['route']    = false;
372
                } else {
373
                    $newContent = $newContentResponse->getContent();
374
                }
375
            } else {
376
                $GLOBALS['MAUTIC_AJAX_DIRECT_RENDER'] = 1; // for error handling
377
                $newContent                           = $this->renderView($contentTemplate, $parameters);
378
379
                unset($GLOBALS['MAUTIC_AJAX_DIRECT_RENDER']);
380
            }
381
        }
382
383
        //there was a redirect within the controller leading to a double call of this function so just return the content
384
        //to prevent newContent from being json
385
        if ($this->request->get('ignoreAjax', false)) {
386
            return new Response($newContent, $code);
387
        }
388
389
        //render flashes
390
        $passthrough['flashes'] = $this->getFlashContent();
391
392
        if (!defined('MAUTIC_INSTALLER')) {
393
            // Prevent error in case installer is loaded via index_dev.php
394
            $passthrough['notifications'] = $this->getNotificationContent();
395
        }
396
397
        //render browser notifications
398
        $passthrough['browserNotifications'] = $this->get('session')->get('mautic.browser.notifications', []);
399
        $this->get('session')->set('mautic.browser.notifications', []);
400
401
        $tmpl = (isset($parameters['tmpl'])) ? $parameters['tmpl'] : $this->request->get('tmpl', 'index');
402
        if ('index' == $tmpl) {
403
            $updatedContent = [];
404
            if (!empty($newContent)) {
405
                $updatedContent['newContent'] = $newContent;
406
            }
407
408
            $dataArray = array_merge(
409
                $passthrough,
410
                $updatedContent
411
            );
412
        } else {
413
            //just retrieve the content
414
            $dataArray = array_merge(
415
                $passthrough,
416
                ['newContent' => $newContent]
417
            );
418
        }
419
420
        if ($newContent instanceof Response) {
421
            $response = $newContent;
422
        } else {
423
            $response = new JsonResponse($dataArray, $code);
424
        }
425
426
        return $response;
427
    }
428
429
    /**
430
     * Get's the content of error page.
431
     *
432
     * @return Response
433
     */
434
    public function renderException(\Exception $e)
435
    {
436
        $exception  = FlattenException::create($e, $e->getCode(), $this->request->headers->all());
437
        $parameters = ['request' => $this->request, 'exception' => $exception];
438
        $query      = ['ignoreAjax' => true, 'request' => $this->request, 'subrequest' => true];
439
440
        return $this->forward('MauticCoreBundle:Exception:show', $parameters, $query);
441
    }
442
443
    /**
444
     * Executes an action defined in route.
445
     *
446
     * @param string $objectAction
447
     * @param int    $objectId
448
     * @param int    $objectSubId
449
     * @param string $objectModel
450
     *
451
     * @return array|JsonResponse|\Symfony\Component\HttpFoundation\RedirectResponse
452
     */
453
    public function executeAction($objectAction, $objectId = 0, $objectSubId = 0, $objectModel = '')
454
    {
455
        if (method_exists($this, "{$objectAction}Action")) {
456
            return $this->{"{$objectAction}Action"}($objectId, $objectModel);
457
        }
458
459
        return $this->notFound();
460
    }
461
462
    /**
463
     * Generates access denied message.
464
     *
465
     * @param bool   $batch Flag if a batch action is being performed
466
     * @param string $msg   Message that is logged
467
     *
468
     * @return JsonResponse|\Symfony\Component\HttpFoundation\RedirectResponse|array
469
     *
470
     * @throws AccessDeniedHttpException
471
     */
472
    public function accessDenied($batch = false, $msg = 'mautic.core.url.error.401')
473
    {
474
        $anonymous = $this->get('mautic.security')->isAnonymous();
475
476
        if ($anonymous || !$batch) {
477
            throw new AccessDeniedHttpException($this->translator->trans($msg, ['%url%' => $this->request->getRequestUri()]));
478
        }
479
480
        if ($batch) {
0 ignored issues
show
The condition $batch is always true.
Loading history...
481
            return [
482
                'type' => 'error',
483
                'msg'  => $this->translator->trans('mautic.core.error.accessdenied', [], 'flashes'),
484
            ];
485
        }
486
    }
487
488
    /**
489
     * Generate 404 not found message.
490
     *
491
     * @param string $msg
492
     *
493
     * @return Response
494
     */
495
    public function notFound($msg = 'mautic.core.url.error.404')
496
    {
497
        return $this->renderException(
498
            new NotFoundHttpException(
499
                $this->translator->trans($msg,
500
                    [
501
                        '%url%' => $this->request->getRequestUri(),
502
                    ]
503
                )
504
            )
505
        );
506
    }
507
508
    /**
509
     * Returns a json encoded access denied error for modal windows.
510
     *
511
     * @param string $msg
512
     *
513
     * @return JsonResponse
514
     */
515
    public function modalAccessDenied($msg = 'mautic.core.error.accessdenied')
516
    {
517
        return new JsonResponse([
518
            'error' => $this->translator->trans($msg, [], 'flashes'),
519
        ]);
520
    }
521
522
    /**
523
     * Updates list filters, order, limit.
524
     *
525
     * @param null $name
526
     */
527
    protected function setListFilters($name = null)
528
    {
529
        $session = $this->get('session');
530
531
        if (null === $name) {
532
            $name = InputHelper::clean($this->request->query->get('name'));
533
        }
534
        $name = 'mautic.'.$name;
535
536
        if ($this->request->query->has('orderby')) {
537
            $orderBy = InputHelper::clean($this->request->query->get('orderby'), true);
538
            $dir     = $session->get("$name.orderbydir", 'ASC');
539
            $dir     = ('ASC' == $dir) ? 'DESC' : 'ASC';
540
            $session->set("$name.orderby", $orderBy);
541
            $session->set("$name.orderbydir", $dir);
542
        }
543
544
        if ($this->request->query->has('limit')) {
545
            $limit = (int) $this->request->query->get('limit');
546
            $session->set("$name.limit", $limit);
547
        }
548
549
        if ($this->request->query->has('filterby')) {
550
            $filter  = InputHelper::clean($this->request->query->get('filterby'), true);
551
            $value   = InputHelper::clean($this->request->query->get('value'), true);
552
            $filters = $session->get("$name.filters", []);
553
554
            if ('' == $value) {
555
                if (isset($filters[$filter])) {
556
                    unset($filters[$filter]);
557
                }
558
            } else {
559
                $filters[$filter] = [
560
                    'column' => $filter,
561
                    'expr'   => 'like',
562
                    'value'  => $value,
563
                    'strict' => false,
564
                ];
565
            }
566
567
            $session->set("$name.filters", $filters);
568
        }
569
    }
570
571
    /**
572
     * Renders flashes' HTML.
573
     *
574
     * @return string
575
     */
576
    protected function getFlashContent()
577
    {
578
        return $this->renderView('MauticCoreBundle:Notification:flash_messages.html.php');
579
    }
580
581
    /**
582
     * Renders notification info for ajax.
583
     *
584
     * @param Request $request
585
     *
586
     * @return array
587
     */
588
    protected function getNotificationContent(Request $request = null)
589
    {
590
        if (null == $request) {
591
            $request = $this->request;
592
        }
593
594
        $afterId = $request->get('mauticLastNotificationId', null);
595
596
        /** @var \Mautic\CoreBundle\Model\NotificationModel $model */
597
        $model = $this->getModel('core.notification');
598
599
        list($notifications, $showNewIndicator, $updateMessage) = $model->getNotificationContent($afterId, false, 200);
600
601
        $lastNotification = reset($notifications);
602
603
        return [
604
            'content' => ($notifications || $updateMessage) ? $this->renderView('MauticCoreBundle:Notification:notification_messages.html.php', [
605
                'notifications' => $notifications,
606
                'updateMessage' => $updateMessage,
607
            ]) : '',
608
            'lastId'              => (!empty($lastNotification)) ? $lastNotification['id'] : $afterId,
609
            'hasNewNotifications' => $showNewIndicator,
610
            'updateAvailable'     => (!empty($updateMessage)),
611
        ];
612
    }
613
614
    /**
615
     * @param           $message
616
     * @param null      $type
617
     * @param bool|true $isRead
618
     * @param null      $header
619
     * @param null      $iconClass
620
     *
621
     * @deprecated Will be removed in Mautic 3.0 as unused.
622
     */
623
    public function addNotification($message, $type = null, $isRead = true, $header = null, $iconClass = null, \DateTime $datetime = null)
624
    {
625
        /** @var \Mautic\CoreBundle\Model\NotificationModel $notificationModel */
626
        $notificationModel = $this->getModel('core.notification');
627
        $notificationModel->addNotification($message, $type, $isRead, $header, $iconClass, $datetime);
628
    }
629
630
    /**
631
     * @param string      $message
632
     * @param array|null  $messageVars
633
     * @param string|null $level
634
     * @param string|null $domain
635
     * @param bool|null   $addNotification
636
     *
637
     * @deprecated Will be removed in Mautic 3.0. Use CommonController::flashBag->addFlash() instead.
638
     */
639
    public function addFlash($message, $messageVars = [], $level = FlashBag::LEVEL_NOTICE, $domain = 'flashes', $addNotification = false)
640
    {
641
        $this->flashBag->add($message, $messageVars, $level, $domain, $addNotification);
642
    }
643
644
    /**
645
     * @param        $message
646
     * @param array  $messageVars
647
     * @param string $domain
648
     * @param null   $title
649
     * @param null   $icon
650
     * @param bool   $addNotification
651
     * @param string $type
652
     *
653
     * @deprecated Will be removed in Mautic 3.0 as unused
654
     */
655
    public function addBrowserNotification($message, $messageVars = [], $domain = 'flashes', $title = null, $icon = null, $addNotification = true, $type = 'notice')
656
    {
657
        if (null == $domain) {
658
            $domain = 'flashes';
659
        }
660
661
        $translator = $this->translator;
662
663
        if (false === $domain) {
664
            //message is already translated
665
            $translatedMessage = $message;
666
        } else {
667
            if (isset($messageVars['pluralCount'])) {
668
                $translatedMessage = $translator->transChoice($message, $messageVars['pluralCount'], $messageVars, $domain);
669
            } else {
670
                $translatedMessage = $translator->trans($message, $messageVars, $domain);
671
            }
672
        }
673
674
        if (null !== $title) {
675
            $title = $translator->trans($title);
676
        } else {
677
            $title = 'Mautic';
678
        }
679
680
        if (null == $icon) {
681
            $icon = 'media/images/favicon.ico';
682
        }
683
684
        if (0 !== strpos($icon, 'http')) {
685
            $assetHelper = $this->factory->getHelper('template.assets');
686
            $icon        = $assetHelper->getUrl($icon, null, null, true);
687
        }
688
689
        $session                = $this->get('session');
690
        $browserNotifications   = $session->get('mautic.browser.notifications', []);
691
        $browserNotifications[] = [
692
            'message' => $translatedMessage,
693
            'title'   => $title,
694
            'icon'    => $icon,
695
        ];
696
697
        $session->set('mautic.browser.notifications', $browserNotifications);
698
699
        if (!defined('MAUTIC_INSTALLER') && $addNotification) {
700
            switch ($type) {
701
                case 'warning':
702
                    $iconClass = 'text-warning fa-exclamation-triangle';
703
                    break;
704
                case 'error':
705
                    $iconClass = 'text-danger fa-exclamation-circle';
706
                    break;
707
                case 'notice':
708
                    $iconClass = 'fa-info-circle';
709
                    // no break
710
                default:
711
                    break;
712
            }
713
714
            //If the user has not interacted with the browser for the last 30 seconds, consider the message unread
715
            $lastActive = $this->request->get('mauticUserLastActive', 0);
716
            $isRead     = $lastActive > 30 ? 0 : 1;
717
718
            $this->addNotification($translatedMessage, null, $isRead, null, $iconClass);
719
        }
720
    }
721
722
    /**
723
     * @param array|\Iterator $toExport
724
     * @param                 $type
725
     * @param                 $filename
726
     *
727
     * @return StreamedResponse
728
     */
729
    public function exportResultsAs($toExport, $type, $filename)
730
    {
731
        /** @var \Mautic\CoreBundle\Helper\ExportHelper */
732
        $exportHelper = $this->get('mautic.helper.export');
733
734
        if (!in_array($type, $exportHelper->getSupportedExportTypes())) {
735
            throw new BadRequestHttpException($this->translator->trans('mautic.error.invalid.export.type', ['%type%' => $type]));
736
        }
737
738
        $dateFormat = $this->coreParametersHelper->get('date_format_dateonly');
739
        $dateFormat = str_replace('--', '-', preg_replace('/[^a-zA-Z]/', '-', $dateFormat));
740
        $filename   = strtolower($filename.'_'.((new \DateTime())->format($dateFormat)).'.'.$type);
741
742
        return $exportHelper->exportDataAs($toExport, $type, $filename);
743
    }
744
745
    /**
746
     * Standard function to generate an array of data via any model's "getEntities" method.
747
     *
748
     * Overwrite in your controller if required.
749
     *
750
     * @param int|null $start
751
     *
752
     * @return array
753
     */
754
    protected function getDataForExport(AbstractCommonModel $model, array $args, callable $resultsCallback = null, $start = 0)
755
    {
756
        $data = new DataExporterHelper();
757
758
        return $data->getDataForExport($start, $model, $args, $resultsCallback);
759
    }
760
}
761