Issues (3627)

bundles/LeadBundle/Controller/ListController.php (2 issues)

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\LeadBundle\Controller;
13
14
use Doctrine\ORM\EntityNotFoundException;
15
use Mautic\CoreBundle\Controller\FormController;
16
use Mautic\CoreBundle\Form\Type\DateRangeType;
17
use Mautic\CoreBundle\Helper\InputHelper;
18
use Mautic\LeadBundle\Entity\LeadList;
19
use Mautic\LeadBundle\Model\LeadModel;
20
use Mautic\LeadBundle\Model\ListModel;
21
use Symfony\Component\Form\FormInterface;
22
use Symfony\Component\HttpFoundation\JsonResponse;
23
use Symfony\Component\HttpFoundation\RedirectResponse;
24
use Symfony\Component\HttpFoundation\Response;
25
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
26
use Symfony\Component\Translation\TranslatorInterface;
27
28
class ListController extends FormController
29
{
30
    use EntityContactsTrait;
31
32
    /**
33
     * Generate's default list view.
34
     *
35
     * @param int $page
36
     *
37
     * @return JsonResponse | Response
38
     */
39
    public function indexAction($page = 1)
40
    {
41
        /** @var ListModel $model */
42
        $model   = $this->getModel('lead.list');
43
        $session = $this->get('session');
44
45
        //set some permissions
46
        $permissions = $this->get('mautic.security')->isGranted([
47
            'lead:leads:viewown',
48
            'lead:leads:viewother',
49
            'lead:lists:viewother',
50
            'lead:lists:editother',
51
            'lead:lists:deleteother',
52
        ], 'RETURN_ARRAY');
53
54
        //Lists can be managed by anyone who has access to leads
55
        if (!$permissions['lead:leads:viewown'] && !$permissions['lead:leads:viewother']) {
56
            return $this->accessDenied();
57
        }
58
59
        $this->setListFilters();
60
61
        //set limits
62
        $limit = $session->get('mautic.segment.limit', $this->coreParametersHelper->get('default_pagelimit'));
63
        $start = (1 === $page) ? 0 : (($page - 1) * $limit);
64
        if ($start < 0) {
65
            $start = 0;
66
        }
67
68
        $search = $this->request->get('search', $session->get('mautic.segment.filter', ''));
69
        $session->set('mautic.segment.filter', $search);
70
71
        //do some default filtering
72
        $orderBy    = $session->get('mautic.segment.orderby', 'l.name');
73
        $orderByDir = $session->get('mautic.segment.orderbydir', 'ASC');
74
75
        $filter = [
76
            'string' => $search,
77
        ];
78
79
        $tmpl = $this->request->isXmlHttpRequest() ? $this->request->get('tmpl', 'index') : 'index';
80
81
        if (!$permissions['lead:lists:viewother']) {
82
            $translator      = $this->get('translator');
83
            $mine            = $translator->trans('mautic.core.searchcommand.ismine');
84
            $global          = $translator->trans('mautic.lead.list.searchcommand.isglobal');
85
            $filter['force'] = "($mine or $global)";
86
        }
87
88
        $items = $model->getEntities(
89
            [
90
                'start'      => $start,
91
                'limit'      => $limit,
92
                'filter'     => $filter,
93
                'orderBy'    => $orderBy,
94
                'orderByDir' => $orderByDir,
95
            ]);
96
97
        $count = count($items);
98
99
        if ($count && $count < ($start + 1)) {
100
            //the number of entities are now less then the current page so redirect to the last page
101
            if (1 === $count) {
102
                $lastPage = 1;
103
            } else {
104
                $lastPage = (ceil($count / $limit)) ?: 1;
105
            }
106
            $session->set('mautic.segment.page', $lastPage);
107
            $returnUrl = $this->generateUrl('mautic_segment_index', ['page' => $lastPage]);
108
109
            return $this->postActionRedirect([
110
                'returnUrl'      => $returnUrl,
111
                'viewParameters' => [
112
                    'page' => $lastPage,
113
                    'tmpl' => $tmpl,
114
                ],
115
                'contentTemplate' => 'MauticLeadBundle:List:index',
116
                'passthroughVars' => [
117
                    'activeLink'    => '#mautic_segment_index',
118
                    'mauticContent' => 'leadlist',
119
                ],
120
            ]);
121
        }
122
123
        //set what page currently on so that we can return here after form submission/cancellation
124
        $session->set('mautic.segment.page', $page);
125
126
        $listIds    = array_keys($items->getIterator()->getArrayCopy());
127
        $leadCounts = (!empty($listIds)) ? $model->getRepository()->getLeadCount($listIds) : [];
128
129
        $parameters = [
130
            'items'       => $items,
131
            'leadCounts'  => $leadCounts,
132
            'page'        => $page,
133
            'limit'       => $limit,
134
            'permissions' => $permissions,
135
            'security'    => $this->get('mautic.security'),
136
            'tmpl'        => $tmpl,
137
            'currentUser' => $this->user,
138
            'searchValue' => $search,
139
        ];
140
141
        return $this->delegateView([
142
            'viewParameters'  => $parameters,
143
            'contentTemplate' => 'MauticLeadBundle:List:list.html.php',
144
            'passthroughVars' => [
145
                'activeLink'    => '#mautic_segment_index',
146
                'route'         => $this->generateUrl('mautic_segment_index', ['page' => $page]),
147
                'mauticContent' => 'leadlist',
148
            ],
149
        ]);
150
    }
151
152
    /**
153
     * Generate's new form and processes post data.
154
     *
155
     * @return JsonResponse | RedirectResponse | Response
156
     */
157
    public function newAction()
158
    {
159
        if (!$this->get('mautic.security')->isGranted('lead:leads:viewown')) {
160
            return $this->accessDenied();
161
        }
162
163
        //retrieve the entity
164
        $list = new LeadList();
165
        /** @var ListModel $model */
166
        $model = $this->getModel('lead.list');
167
        //set the page we came from
168
        $page = $this->get('session')->get('mautic.segment.page', 1);
169
        //set the return URL for post actions
170
        $returnUrl = $this->generateUrl('mautic_segment_index', ['page' => $page]);
171
        $action    = $this->generateUrl('mautic_segment_action', ['objectAction' => 'new']);
172
173
        //get the user form factory
174
        $form = $model->createForm($list, $this->get('form.factory'), $action);
175
176
        ///Check for a submitted form and process it
177
        if ('POST' == $this->request->getMethod()) {
178
            $valid = false;
179
            if (!$cancelled = $this->isFormCancelled($form)) {
180
                if ($valid = $this->isFormValid($form)) {
181
                    //form is valid so process the data
182
                    $model->saveEntity($list);
183
184
                    $this->addFlash('mautic.core.notice.created', [
0 ignored issues
show
Deprecated Code introduced by
The function Mautic\CoreBundle\Contro...nController::addFlash() has been deprecated: Will be removed in Mautic 3.0. Use CommonController::flashBag->addFlash() instead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

184
                    /** @scrutinizer ignore-deprecated */ $this->addFlash('mautic.core.notice.created', [

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
185
                        '%name%'      => $list->getName().' ('.$list->getAlias().')',
186
                        '%menu_link%' => 'mautic_segment_index',
187
                        '%url%'       => $this->generateUrl('mautic_segment_action', [
188
                            'objectAction' => 'edit',
189
                            'objectId'     => $list->getId(),
190
                        ]),
191
                    ]);
192
                }
193
            }
194
195
            if ($cancelled || ($valid && $form->get('buttons')->get('save')->isClicked())) {
196
                return $this->postActionRedirect([
197
                    'returnUrl'       => $returnUrl,
198
                    'viewParameters'  => ['page' => $page],
199
                    'contentTemplate' => 'MauticLeadBundle:List:index',
200
                    'passthroughVars' => [
201
                        'activeLink'    => '#mautic_segment_index',
202
                        'mauticContent' => 'leadlist',
203
                    ],
204
                ]);
205
            } elseif ($valid && !$cancelled) {
206
                return $this->editAction($list->getId(), true);
207
            }
208
        }
209
210
        return $this->delegateView([
211
            'viewParameters' => [
212
                'form' => $this->setFormTheme($form, 'MauticLeadBundle:List:form.html.php', 'MauticLeadBundle:FormTheme\Filter'),
213
            ],
214
            'contentTemplate' => 'MauticLeadBundle:List:form.html.php',
215
            'passthroughVars' => [
216
                'activeLink'    => '#mautic_segment_index',
217
                'route'         => $this->generateUrl('mautic_segment_action', ['objectAction' => 'new']),
218
                'mauticContent' => 'leadlist',
219
            ],
220
        ]);
221
    }
222
223
    /**
224
     * Generate's clone form and processes post data.
225
     *
226
     * @param int  $objectId
227
     * @param bool $ignorePost
228
     *
229
     * @return Response
230
     */
231
    public function cloneAction($objectId, $ignorePost = false)
232
    {
233
        $postActionVars = $this->getPostActionVars();
234
235
        try {
236
            $segment = $this->getSegment($objectId);
237
238
            return $this->createSegmentModifyResponse(
239
                clone $segment,
240
                $postActionVars,
241
                $this->generateUrl('mautic_segment_action', ['objectAction' => 'clone', 'objectId' => $objectId]),
242
                $ignorePost
243
            );
244
        } catch (AccessDeniedException $exception) {
245
            return $this->accessDenied();
246
        } catch (EntityNotFoundException $exception) {
247
            return $this->postActionRedirect(
248
                array_merge($postActionVars, [
249
                    'flashes' => [
250
                        [
251
                            'type'    => 'error',
252
                            'msg'     => 'mautic.lead.list.error.notfound',
253
                            'msgVars' => ['%id%' => $objectId],
254
                        ],
255
                    ],
256
                ])
257
            );
258
        }
259
    }
260
261
    /**
262
     * Generate's edit form and processes post data.
263
     *
264
     * @param int  $objectId
265
     * @param bool $ignorePost
266
     *
267
     * @return Response
268
     */
269
    public function editAction($objectId, $ignorePost = false)
270
    {
271
        $postActionVars = $this->getPostActionVars($objectId);
272
273
        try {
274
            $segment = $this->getSegment($objectId);
275
276
            return $this->createSegmentModifyResponse(
277
                $segment,
278
                $postActionVars,
279
                $this->generateUrl('mautic_segment_action', ['objectAction' => 'edit', 'objectId' => $objectId]),
280
                $ignorePost
281
            );
282
        } catch (AccessDeniedException $exception) {
283
            return $this->accessDenied();
284
        } catch (EntityNotFoundException $exception) {
285
            return $this->postActionRedirect(
286
                array_merge($postActionVars, [
287
                    'flashes' => [
288
                        [
289
                            'type'    => 'error',
290
                            'msg'     => 'mautic.lead.list.error.notfound',
291
                            'msgVars' => ['%id%' => $objectId],
292
                        ],
293
                    ],
294
                ])
295
            );
296
        }
297
    }
298
299
    /**
300
     * Create modifying response for segments - edit/clone.
301
     *
302
     * @param string $action
303
     * @param bool   $ignorePost
304
     *
305
     * @return Response
306
     */
307
    private function createSegmentModifyResponse(LeadList $segment, array $postActionVars, $action, $ignorePost)
308
    {
309
        /** @var ListModel $segmentModel */
310
        $segmentModel = $this->getModel('lead.list');
311
312
        if ($segmentModel->isLocked($segment)) {
313
            return $this->isLocked($postActionVars, $segment, 'lead.list');
314
        }
315
316
        /** @var FormInterface $form */
317
        $form = $segmentModel->createForm($segment, $this->get('form.factory'), $action);
318
319
        ///Check for a submitted form and process it
320
        if (!$ignorePost && 'POST' == $this->request->getMethod()) {
321
            if (!$cancelled = $this->isFormCancelled($form)) {
322
                if ($this->isFormValid($form)) {
323
                    //form is valid so process the data
324
                    $segmentModel->saveEntity($segment, $form->get('buttons')->get('save')->isClicked());
325
326
                    $this->addFlash('mautic.core.notice.updated', [
0 ignored issues
show
Deprecated Code introduced by
The function Mautic\CoreBundle\Contro...nController::addFlash() has been deprecated: Will be removed in Mautic 3.0. Use CommonController::flashBag->addFlash() instead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

326
                    /** @scrutinizer ignore-deprecated */ $this->addFlash('mautic.core.notice.updated', [

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
327
                        '%name%'      => $segment->getName().' ('.$segment->getAlias().')',
328
                        '%menu_link%' => 'mautic_segment_index',
329
                        '%url%'       => $this->generateUrl('mautic_segment_action', [
330
                            'objectAction' => 'edit',
331
                            'objectId'     => $segment->getId(),
332
                        ]),
333
                    ]);
334
335
                    if ($form->get('buttons')->get('apply')->isClicked()) {
336
                        $contentTemplate                     = 'MauticLeadBundle:List:form.html.php';
337
                        $postActionVars['contentTemplate']   = $contentTemplate;
338
                        $postActionVars['forwardController'] = false;
339
                        $postActionVars['returnUrl']         = $this->generateUrl('mautic_segment_action', [
340
                            'objectAction' => 'edit',
341
                            'objectId'     => $segment->getId(),
342
                        ]);
343
344
                        // Re-create the form once more with the fresh segment and action.
345
                        // The alias was empty on redirect after cloning.
346
                        $editAction = $this->generateUrl('mautic_segment_action', ['objectAction' => 'edit', 'objectId' => $segment->getId()]);
347
                        $form       = $segmentModel->createForm($segment, $this->get('form.factory'), $editAction);
348
349
                        $postActionVars['viewParameters'] = [
350
                            'objectAction' => 'edit',
351
                            'objectId'     => $segment->getId(),
352
                            'form'         => $this->setFormTheme($form, $contentTemplate, 'MauticLeadBundle:FormTheme\Filter'),
353
                        ];
354
355
                        return $this->postActionRedirect($postActionVars);
356
                    } else {
357
                        return $this->viewAction($segment->getId());
358
                    }
359
                }
360
            } else {
361
                //unlock the entity
362
                $segmentModel->unlockEntity($segment);
363
            }
364
365
            if ($cancelled) {
366
                return $this->postActionRedirect($postActionVars);
367
            }
368
        } else {
369
            //lock the entity
370
            $segmentModel->lockEntity($segment);
371
        }
372
373
        return $this->delegateView([
374
            'viewParameters' => [
375
                'form'          => $this->setFormTheme($form, 'MauticLeadBundle:List:form.html.php', 'MauticLeadBundle:FormTheme\Filter'),
376
                'currentListId' => $segment->getId(),
377
            ],
378
            'contentTemplate' => 'MauticLeadBundle:List:form.html.php',
379
            'passthroughVars' => [
380
                'activeLink'    => '#mautic_segment_index',
381
                'route'         => $action,
382
                'mauticContent' => 'leadlist',
383
            ],
384
        ]);
385
    }
386
387
    /**
388
     * Return segment if exists and user has access.
389
     *
390
     * @param int $segmentId
391
     *
392
     * @return LeadList
393
     *
394
     * @throws EntityNotFoundException
395
     * @throws AccessDeniedException
396
     */
397
    private function getSegment($segmentId)
398
    {
399
        /** @var LeadList $segment */
400
        $segment = $this->getModel('lead.list')->getEntity($segmentId);
401
402
        // Check if exists
403
        if (!$segment instanceof LeadList) {
404
            throw new EntityNotFoundException(sprintf('Segment with id %d not found.', $segmentId));
405
        }
406
407
        if (!$this->get('mautic.security')->hasEntityAccess(
408
            true, 'lead:lists:editother', $segment->getCreatedBy()
409
        )) {
410
            throw new AccessDeniedException(sprintf('User has not access on segment with id %d', $segmentId));
411
        }
412
413
        return $segment;
414
    }
415
416
    /**
417
     * Get variables for POST action.
418
     *
419
     * @param null $objectId
420
     *
421
     * @return array
422
     */
423
    private function getPostActionVars($objectId = null)
424
    {
425
        //set the return URL
426
        if ($objectId) {
427
            $returnUrl       = $this->generateUrl('mautic_segment_action', ['objectAction' => 'view', 'objectId'=> $objectId]);
428
            $viewParameters  = ['objectAction' => 'view', 'objectId'=> $objectId];
429
            $contentTemplate = 'MauticLeadBundle:List:view';
430
        } else {
431
            //set the page we came from
432
            $page            = $this->get('session')->get('mautic.segment.page', 1);
433
            $returnUrl       = $this->generateUrl('mautic_segment_index', ['page' => $page]);
434
            $viewParameters  = ['page' => $page];
435
            $contentTemplate = 'MauticLeadBundle:List:index';
436
        }
437
438
        return [
439
            'returnUrl'       => $returnUrl,
440
            'viewParameters'  => $viewParameters,
441
            'contentTemplate' => $contentTemplate,
442
            'passthroughVars' => [
443
                'activeLink'    => '#mautic_segment_index',
444
                'mauticContent' => 'leadlist',
445
            ],
446
        ];
447
    }
448
449
    /**
450
     * Delete a list.
451
     *
452
     * @param $objectId
453
     *
454
     * @return JsonResponse | RedirectResponse
455
     */
456
    public function deleteAction($objectId)
457
    {
458
        /** @var ListModel $model */
459
        $model     = $this->getModel('lead.list');
460
        $page      = $this->get('session')->get('mautic.segment.page', 1);
461
        $returnUrl = $this->generateUrl('mautic_segment_index', ['page' => $page]);
462
        $flashes   = [];
463
464
        $postActionVars = [
465
            'returnUrl'       => $returnUrl,
466
            'viewParameters'  => ['page' => $page],
467
            'contentTemplate' => 'MauticLeadBundle:List:index',
468
            'passthroughVars' => [
469
                'activeLink'    => '#mautic_segment_index',
470
                'mauticContent' => 'lead',
471
            ],
472
        ];
473
474
        $dependents = $model->getSegmentsWithDependenciesOnSegment($objectId);
475
476
        if (!empty($dependents)) {
477
            $flashes[] = [
478
                    'type'    => 'error',
479
                    'msg'     => 'mautic.lead.list.error.cannot.delete',
480
                    'msgVars' => ['%segments%' => implode(', ', $dependents)],
481
                ];
482
483
            return $this->postActionRedirect(
484
                array_merge($postActionVars, [
485
                    'flashes' => $flashes,
486
                ])
487
            );
488
        }
489
490
        if ('POST' == $this->request->getMethod()) {
491
            /** @var ListModel $model */
492
            $model = $this->getModel('lead.list');
493
            $list  = $model->getEntity($objectId);
494
495
            if (null === $list) {
496
                $flashes[] = [
497
                    'type'    => 'error',
498
                    'msg'     => 'mautic.lead.list.error.notfound',
499
                    'msgVars' => ['%id%' => $objectId],
500
                ];
501
            } elseif (!$this->get('mautic.security')->hasEntityAccess(
502
                true, 'lead:lists:deleteother', $list->getCreatedBy()
503
            )
504
            ) {
505
                return $this->accessDenied();
506
            } elseif ($model->isLocked($list)) {
507
                return $this->isLocked($postActionVars, $list, 'lead.list');
508
            }
509
510
            $model->deleteEntity($list);
511
512
            $flashes[] = [
513
                'type'    => 'notice',
514
                'msg'     => 'mautic.core.notice.deleted',
515
                'msgVars' => [
516
                    '%name%' => $list->getName(),
517
                    '%id%'   => $objectId,
518
                ],
519
            ];
520
        } //else don't do anything
521
522
        return $this->postActionRedirect(
523
            array_merge($postActionVars, [
524
                'flashes' => $flashes,
525
            ])
526
        );
527
    }
528
529
    /**
530
     * Deletes a group of entities.
531
     *
532
     * @return JsonResponse | RedirectResponse
533
     */
534
    public function batchDeleteAction()
535
    {
536
        $page      = $this->get('session')->get('mautic.segment.page', 1);
537
        $returnUrl = $this->generateUrl('mautic_segment_index', ['page' => $page]);
538
        $flashes   = [];
539
540
        $postActionVars = [
541
            'returnUrl'       => $returnUrl,
542
            'viewParameters'  => ['page' => $page],
543
            'contentTemplate' => 'MauticLeadBundle:List:index',
544
            'passthroughVars' => [
545
                'activeLink'    => '#mautic_segment_index',
546
                'mauticContent' => 'lead',
547
            ],
548
        ];
549
550
        if ('POST' == $this->request->getMethod()) {
551
            /** @var ListModel $model */
552
            $model           = $this->getModel('lead.list');
553
            $ids             = json_decode($this->request->query->get('ids', '{}'));
554
            $canNotBeDeleted = $model->canNotBeDeleted($ids);
555
556
            if (!empty($canNotBeDeleted)) {
557
                $flashes[] = [
558
                    'type'    => 'error',
559
                    'msg'     => 'mautic.lead.list.error.cannot.delete.batch',
560
                    'msgVars' => ['%segments%' => implode(', ', $canNotBeDeleted)],
561
                ];
562
            }
563
564
            $toBeDeleted = array_diff($ids, array_keys($canNotBeDeleted));
565
            $deleteIds   = [];
566
567
            // Loop over the IDs to perform access checks pre-delete
568
            foreach ($toBeDeleted as $objectId) {
569
                $entity = $model->getEntity($objectId);
570
571
                if (null === $entity) {
572
                    $flashes[] = [
573
                        'type'    => 'error',
574
                        'msg'     => 'mautic.lead.list.error.notfound',
575
                        'msgVars' => ['%id%' => $objectId],
576
                    ];
577
                } elseif (!$this->get('mautic.security')->hasEntityAccess(
578
                    true, 'lead:lists:deleteother', $entity->getCreatedBy()
579
                )) {
580
                    $flashes[] = $this->accessDenied(true);
581
                } elseif ($model->isLocked($entity)) {
582
                    $flashes[] = $this->isLocked($postActionVars, $entity, 'lead.list', true);
583
                } else {
584
                    $deleteIds[] = $objectId;
585
                }
586
            }
587
588
            // Delete everything we are able to
589
            if (!empty($deleteIds)) {
590
                $entities = $model->deleteEntities($deleteIds);
591
592
                $flashes[] = [
593
                    'type'    => 'notice',
594
                    'msg'     => 'mautic.lead.list.notice.batch_deleted',
595
                    'msgVars' => [
596
                        '%count%' => count($entities),
597
                    ],
598
                ];
599
            }
600
        } //else don't do anything
601
602
        return $this->postActionRedirect(
603
            array_merge($postActionVars, [
604
                'flashes' => $flashes,
605
            ])
606
        );
607
    }
608
609
    /**
610
     * @param $objectId
611
     *
612
     * @return JsonResponse | RedirectResponse
613
     */
614
    public function removeLeadAction($objectId)
615
    {
616
        return $this->changeList($objectId, 'remove');
617
    }
618
619
    /**
620
     * @param $objectId
621
     *
622
     * @return JsonResponse | RedirectResponse
623
     */
624
    public function addLeadAction($objectId)
625
    {
626
        return $this->changeList($objectId, 'add');
627
    }
628
629
    /**
630
     * @param $listId
631
     * @param $action
632
     *
633
     * @return array | JsonResponse | RedirectResponse
634
     */
635
    protected function changeList($listId, $action)
636
    {
637
        $page      = $this->get('session')->get('mautic.lead.page', 1);
638
        $returnUrl = $this->generateUrl('mautic_contact_index', ['page' => $page]);
639
        $flashes   = [];
640
641
        $postActionVars = [
642
            'returnUrl'       => $returnUrl,
643
            'viewParameters'  => ['page' => $page],
644
            'contentTemplate' => 'MauticLeadBundle:Lead:index',
645
            'passthroughVars' => [
646
                'activeLink'    => '#mautic_contact_index',
647
                'mauticContent' => 'lead',
648
            ],
649
        ];
650
651
        $leadId = $this->request->get('leadId');
652
        if (!empty($leadId) && 'POST' == $this->request->getMethod()) {
653
            /** @var ListModel $model */
654
            $model = $this->getModel('lead.list');
655
            /** @var LeadList $list */
656
            $list = $model->getEntity($listId);
657
            /** @var LeadModel $leadModel */
658
            $leadModel = $this->getModel('lead');
659
            $lead      = $leadModel->getEntity($leadId);
660
661
            if (null === $lead) {
662
                $flashes[] = [
663
                    'type'    => 'error',
664
                    'msg'     => 'mautic.lead.lead.error.notfound',
665
                    'msgVars' => ['%id%' => $listId],
666
                ];
667
            } elseif (!$this->get('mautic.security')->hasEntityAccess(
668
                'lead:leads:editown', 'lead:leads:editother', $lead->getPermissionUser()
669
            )) {
670
                return $this->accessDenied();
671
            } elseif (null === $list) {
672
                $flashes[] = [
673
                    'type'    => 'error',
674
                    'msg'     => 'mautic.lead.list.error.notfound',
675
                    'msgVars' => ['%id%' => $list->getId()],
676
                ];
677
            } elseif (!$list->isGlobal() && !$this->get('mautic.security')->hasEntityAccess(
678
                    true, 'lead:lists:viewother', $list->getCreatedBy()
679
                )) {
680
                return $this->accessDenied();
681
            } elseif ($model->isLocked($lead)) {
682
                return $this->isLocked($postActionVars, $lead, 'lead');
683
            } else {
684
                $function = ('remove' == $action) ? 'removeLead' : 'addLead';
685
                $model->$function($lead, $list, true);
686
687
                $identifier = $this->get('translator')->trans($lead->getPrimaryIdentifier());
688
                $flashes[]  = [
689
                    'type' => 'notice',
690
                    'msg'  => ('remove' == $action) ? 'mautic.lead.lead.notice.removedfromlists' :
691
                        'mautic.lead.lead.notice.addedtolists',
692
                    'msgVars' => [
693
                        '%name%' => $identifier,
694
                        '%id%'   => $leadId,
695
                        '%list%' => $list->getName(),
696
                        '%url%'  => $this->generateUrl('mautic_contact_action', [
697
                            'objectAction' => 'edit',
698
                            'objectId'     => $leadId,
699
                        ]),
700
                    ],
701
                ];
702
            }
703
        } //else don't do anything
704
705
        return $this->postActionRedirect(
706
            array_merge($postActionVars, [
707
                'flashes' => $flashes,
708
            ])
709
        );
710
    }
711
712
    /**
713
     * Loads a specific form into the detailed panel.
714
     *
715
     * @param $objectId
716
     *
717
     * @return \Symfony\Component\HttpFoundation\JsonResponse|\Symfony\Component\HttpFoundation\Response
718
     */
719
    public function viewAction($objectId)
720
    {
721
        /** @var \Mautic\LeadBundle\Model\ListModel $model */
722
        $model    = $this->getModel('lead.list');
723
        $security = $this->get('mautic.security');
724
725
        /** @var LeadList $list */
726
        $list = $model->getEntity($objectId);
727
        //set the page we came from
728
        $page = $this->get('session')->get('mautic.segment.page', 1);
729
730
        if ('POST' === $this->request->getMethod() && $this->request->request->has('includeEvents')) {
731
            $filters = [
732
                'includeEvents' => InputHelper::clean($this->request->get('includeEvents', [])),
733
            ];
734
            $this->get('session')->set('mautic.segment.filters', $filters);
735
        } else {
736
            $filters = [];
737
        }
738
739
        if (null === $list) {
740
            //set the return URL
741
            $returnUrl = $this->generateUrl('mautic_segment_index', ['page' => $page]);
742
743
            return $this->postActionRedirect([
744
                'returnUrl'       => $returnUrl,
745
                'viewParameters'  => ['page' => $page],
746
                'contentTemplate' => 'MauticLeadBundle:List:index',
747
                'passthroughVars' => [
748
                    'activeLink'    => '#mautic_segment_index',
749
                    'mauticContent' => 'list',
750
                ],
751
                'flashes' => [
752
                    [
753
                        'type'    => 'error',
754
                        'msg'     => 'mautic.list.error.notfound',
755
                        'msgVars' => ['%id%' => $objectId],
756
                    ],
757
                ],
758
            ]);
759
        } elseif (!$this->get('mautic.security')->hasEntityAccess(
760
            'lead:leads:viewown',
761
            'lead:lists:viewother',
762
            $list->getCreatedBy()
763
        )
764
        ) {
765
            return $this->accessDenied();
766
        }
767
        /** @var TranslatorInterface $translator */
768
        $translator = $this->get('translator');
769
        /** @var ListModel $listModel */
770
        $listModel                    = $this->getModel('lead.list');
771
        $dateRangeValues              = $this->request->get('daterange', []);
772
        $action                       = $this->generateUrl('mautic_segment_action', ['objectAction' => 'view', 'objectId' => $objectId]);
773
        $dateRangeForm                = $this->get('form.factory')->create(DateRangeType::class, $dateRangeValues, ['action' => $action]);
774
        $segmentContactsLineChartData = $listModel->getSegmentContactsLineChartData(
775
            null,
776
            new \DateTime($dateRangeForm->get('date_from')->getData()),
777
            new \DateTime($dateRangeForm->get('date_to')->getData()),
778
            null,
779
            [
780
                'leadlist_id'   => [
781
                    'value'            => $objectId,
782
                    'list_column_name' => 't.lead_id',
783
                ],
784
                't.leadlist_id' => $objectId,
785
            ]
786
        );
787
788
        return $this->delegateView([
789
            'returnUrl'      => $this->generateUrl('mautic_segment_action', ['objectAction' => 'view', 'objectId' => $list->getId()]),
790
            'viewParameters' => [
791
                'usageStats'     => $this->get('mautic.lead.segment.stat.dependencies')->getChannelsIds($list->getId()),
792
                'campaignStats'  => $this->get('mautic.lead.segment.stat.campaign.share')->getCampaignList($list->getId()),
793
                'stats'          => $segmentContactsLineChartData,
794
                'list'           => $list,
795
                'segmentCount'   => $listModel->getRepository()->getLeadCount($list->getId()),
796
                'permissions'    => $security->isGranted([
797
                    'lead:leads:editown',
798
                    'lead:lists:viewother',
799
                    'lead:lists:editother',
800
                    'lead:lists:deleteother',
801
                ], 'RETURN_ARRAY'),
802
                'security'      => $security,
803
                'dateRangeForm' => $dateRangeForm->createView(),
804
                'events'        => [
805
                    'filters' => $filters,
806
                    'types'   => [
807
                        'manually_added'   => $translator->trans('mautic.segment.contact.manually.added'),
808
                        'manually_removed' => $translator->trans('mautic.segment.contact.manually.removed'),
809
                        'filter_added'     => $translator->trans('mautic.segment.contact.filter.added'),
810
                    ],
811
                ],
812
                'contacts' => $this->forward(
813
                    'MauticLeadBundle:List:contacts',
814
                    [
815
                        'objectId'   => $list->getId(),
816
                        'page'       => $this->get('session')->get('mautic.segment.contact.page', 1),
817
                        'ignoreAjax' => true,
818
                        'filters'    => $filters,
819
                    ]
820
                )->getContent(),
821
            ],
822
            'contentTemplate' => 'MauticLeadBundle:List:details.html.php',
823
            'passthroughVars' => [
824
                'activeLink'    => '#mautic_segment_index',
825
                'mauticContent' => 'list',
826
            ],
827
        ]);
828
    }
829
830
    /**
831
     * @param     $objectId
832
     * @param int $page
833
     *
834
     * @return JsonResponse|\Symfony\Component\HttpFoundation\RedirectResponse|Response
835
     */
836
    public function contactsAction($objectId, $page = 1)
837
    {
838
        $manuallyRemoved = 0;
839
        $listFilters     = ['manually_removed' => $manuallyRemoved];
840
        if ('POST' === $this->request->getMethod() && $this->request->request->has('includeEvents')) {
841
            $filters = [
842
                'includeEvents' => InputHelper::clean($this->request->get('includeEvents', [])),
843
            ];
844
            $this->get('session')->set('mautic.segment.filters', $filters);
845
        } else {
846
            $filters = [];
847
        }
848
849
        if (!empty($filters)) {
850
            if (isset($filters['includeEvents']) && in_array('manually_added', $filters['includeEvents'])) {
851
                $listFilters = array_merge($listFilters, ['manually_added' => 1]);
852
            }
853
            if (isset($filters['includeEvents']) && in_array('manually_removed', $filters['includeEvents'])) {
854
                $listFilters = array_merge($listFilters, ['manually_removed' => 1]);
855
            }
856
            if (isset($filters['includeEvents']) && in_array('filter_added', $filters['includeEvents'])) {
857
                $listFilters = array_merge($listFilters, ['manually_added' => 0]);
858
            }
859
        }
860
861
        return $this->generateContactsGrid(
862
            $objectId,
863
            $page,
864
            ['lead:leads:viewother', 'lead:leads:viewown'],
865
            'segment',
866
            'lead_lists_leads',
867
            null,
868
            'leadlist_id',
869
            $listFilters
870
        );
871
    }
872
}
873