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