Issues (3627)

CampaignBundle/Controller/CampaignController.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\CampaignBundle\Controller;
13
14
use Mautic\CampaignBundle\Entity\Campaign;
15
use Mautic\CampaignBundle\Entity\Event;
16
use Mautic\CampaignBundle\Entity\LeadEventLogRepository;
17
use Mautic\CampaignBundle\EventCollector\EventCollector;
18
use Mautic\CampaignBundle\EventListener\CampaignActionJumpToEventSubscriber;
19
use Mautic\CampaignBundle\Model\CampaignModel;
20
use Mautic\CampaignBundle\Model\EventModel;
21
use Mautic\CoreBundle\Controller\AbstractStandardFormController;
22
use Mautic\CoreBundle\Form\Type\DateRangeType;
23
use Mautic\LeadBundle\Controller\EntityContactsTrait;
24
use Symfony\Component\Form\Form;
25
use Symfony\Component\Form\FormError;
26
use Symfony\Component\HttpFoundation\JsonResponse;
27
use Symfony\Component\HttpFoundation\Response;
28
29
class CampaignController extends AbstractStandardFormController
30
{
31
    use EntityContactsTrait;
32
33
    /**
34
     * @var array
35
     */
36
    protected $addedSources = [];
37
38
    /**
39
     * @var array
40
     */
41
    protected $campaignEvents = [];
42
43
    /**
44
     * @var array
45
     */
46
    protected $campaignSources = [];
47
48
    /**
49
     * @var array
50
     */
51
    protected $connections = [];
52
53
    /**
54
     * @var array
55
     */
56
    protected $deletedEvents = [];
57
58
    /**
59
     * @var array
60
     */
61
    protected $deletedSources = [];
62
63
    /**
64
     * @var array
65
     */
66
    protected $listFilters = [];
67
68
    /**
69
     * @var array
70
     */
71
    protected $modifiedEvents = [];
72
73
    protected $sessionId;
74
75
    /**
76
     * @return array
77
     */
78
    protected function getPermissions()
79
    {
80
        //set some permissions
81
        return (array) $this->get('mautic.security')->isGranted(
82
            [
83
                'campaign:campaigns:viewown',
84
                'campaign:campaigns:viewother',
85
                'campaign:campaigns:create',
86
                'campaign:campaigns:editown',
87
                'campaign:campaigns:editother',
88
                'campaign:campaigns:cloneown',
89
                'campaign:campaigns:cloneother',
90
                'campaign:campaigns:deleteown',
91
                'campaign:campaigns:deleteother',
92
                'campaign:campaigns:publishown',
93
                'campaign:campaigns:publishother',
94
            ],
95
            'RETURN_ARRAY'
96
        );
97
    }
98
99
    /**
100
     * Deletes a group of entities.
101
     *
102
     * @return \Symfony\Component\HttpFoundation\JsonResponse|\Symfony\Component\HttpFoundation\RedirectResponse
103
     */
104
    public function batchDeleteAction()
105
    {
106
        return $this->batchDeleteStandard();
107
    }
108
109
    /**
110
     * Clone an entity.
111
     *
112
     * @param $objectId
113
     *
114
     * @return JsonResponse|\Symfony\Component\HttpFoundation\RedirectResponse|Response
115
     */
116
    public function cloneAction($objectId)
117
    {
118
        return $this->cloneStandard($objectId);
119
    }
120
121
    /**
122
     * @param     $objectId
123
     * @param int $page
124
     *
125
     * @return JsonResponse|\Symfony\Component\HttpFoundation\RedirectResponse|Response
126
     */
127
    public function contactsAction($objectId, $page = 1)
128
    {
129
        return $this->generateContactsGrid(
130
            $objectId,
131
            $page,
132
            'campaign:campaigns:view',
133
            'campaign',
134
            'campaign_leads',
135
            null,
136
            'campaign_id',
137
            ['manually_removed' => 0]
138
        );
139
    }
140
141
    /**
142
     * Deletes the entity.
143
     *
144
     * @param $objectId
145
     *
146
     * @return \Symfony\Component\HttpFoundation\JsonResponse|\Symfony\Component\HttpFoundation\RedirectResponse
147
     */
148
    public function deleteAction($objectId)
149
    {
150
        return $this->deleteStandard($objectId);
151
    }
152
153
    /**
154
     * @param      $objectId
155
     * @param bool $ignorePost
156
     *
157
     * @return JsonResponse|\Symfony\Component\HttpFoundation\RedirectResponse|Response
158
     */
159
    public function editAction($objectId, $ignorePost = false)
160
    {
161
        return $this->editStandard($objectId, $ignorePost);
162
    }
163
164
    /**
165
     * @param int $page
166
     *
167
     * @return JsonResponse|\Symfony\Component\HttpFoundation\Response
168
     */
169
    public function indexAction($page = null)
170
    {
171
        return $this->indexStandard($page);
172
    }
173
174
    /**
175
     * Generates new form and processes post data.
176
     *
177
     * @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
178
     */
179
    public function newAction()
180
    {
181
        return $this->newStandard();
182
    }
183
184
    /**
185
     * View a specific campaign.
186
     *
187
     * @param $objectId
188
     *
189
     * @return \Symfony\Component\HttpFoundation\JsonResponse|\Symfony\Component\HttpFoundation\Response
190
     */
191
    public function viewAction($objectId)
192
    {
193
        return $this->viewStandard($objectId, $this->getModelName(), null, null, 'campaign');
194
    }
195
196
    /**
197
     * @param Campaign $campaign
198
     * @param Campaign $oldCampaign
199
     */
200
    protected function afterEntityClone($campaign, $oldCampaign)
201
    {
202
        $tempId   = 'mautic_'.sha1(uniqid(mt_rand(), true));
203
        $objectId = $oldCampaign->getId();
204
205
        // Get the events that need to be duplicated as well
206
        $events = $oldCampaign->getEvents()->toArray();
207
208
        $campaign->setIsPublished(false);
209
210
        // Clone the campaign's events
211
        /** @var Event $event */
212
        foreach ($events as $event) {
213
            $tempEventId = 'new'.$event->getId();
214
215
            $clone = clone $event;
216
            $clone->nullId();
217
            $clone->setCampaign($campaign);
218
            $clone->setTempId($tempEventId);
219
220
            // Just wipe out the parent as it'll be generated when the cloned entity is saved
221
            $clone->setParent(null);
222
223
            if (CampaignActionJumpToEventSubscriber::EVENT_NAME === $clone->getType()) {
224
                // Update properties to point to the new temp ID
225
                $properties                = $clone->getProperties();
226
                $properties['jumpToEvent'] = 'new'.$properties['jumpToEvent'];
227
228
                $clone->setProperties($properties);
229
            }
230
231
            $campaign->addEvent($tempEventId, $clone);
232
        }
233
234
        // Update canvas settings with new event ids
235
        $canvasSettings = $campaign->getCanvasSettings();
236
        if (isset($canvasSettings['nodes'])) {
237
            foreach ($canvasSettings['nodes'] as &$node) {
238
                // Only events and not lead sources
239
                if (is_numeric($node['id'])) {
240
                    $node['id'] = 'new'.$node['id'];
241
                }
242
            }
243
        }
244
245
        if (isset($canvasSettings['connections'])) {
246
            foreach ($canvasSettings['connections'] as &$c) {
247
                // Only events and not lead sources
248
                if (is_numeric($c['sourceId'])) {
249
                    $c['sourceId'] = 'new'.$c['sourceId'];
250
                }
251
252
                // Only events and not lead sources
253
                if (is_numeric($c['targetId'])) {
254
                    $c['targetId'] = 'new'.$c['targetId'];
255
                }
256
            }
257
        }
258
259
        // Simulate edit
260
        $campaign->setCanvasSettings($canvasSettings);
261
        $this->setSessionCanvasSettings($tempId, $canvasSettings);
262
        $tempId = $this->getCampaignSessionId($campaign, 'clone', $tempId);
263
264
        $campaignSources = $this->getCampaignModel()->getLeadSources($objectId);
265
        $this->prepareCampaignSourcesForEdit($tempId, $campaignSources);
266
    }
267
268
    /**
269
     * @param      $entity
270
     * @param      $action
271
     * @param null $persistConnections
272
     */
273
    protected function afterEntitySave($entity, Form $form, $action, $persistConnections = null)
274
    {
275
        if ($persistConnections) {
0 ignored issues
show
$persistConnections is of type null, thus it always evaluated to false.
Loading history...
276
            // Update canvas settings with new event IDs then save
277
            $this->connections = $this->getCampaignModel()->setCanvasSettings($entity, $this->connections);
278
        } else {
279
            // Just update and add to entity
280
            $this->connections = $this->getCampaignModel()->setCanvasSettings($entity, $this->connections, false, $this->modifiedEvents);
281
        }
282
    }
283
284
    /**
285
     * @param      $isValid
286
     * @param      $entity
287
     * @param      $action
288
     * @param bool $isClone
289
     */
290
    protected function afterFormProcessed($isValid, $entity, Form $form, $action, $isClone = false)
291
    {
292
        if (!$isValid) {
293
            // Add the canvas settings to the entity to be able to rebuild it
294
            $this->afterEntitySave($entity, $form, $action, false);
295
        } else {
296
            $this->clearSessionComponents($this->sessionId);
297
            $this->sessionId = $entity->getId();
298
        }
299
    }
300
301
    /**
302
     * @param      $entity
303
     * @param      $action
304
     * @param      $isPost
305
     * @param null $objectId
306
     * @param bool $isClone
307
     */
308
    protected function beforeFormProcessed($entity, Form $form, $action, $isPost, $objectId = null, $isClone = false)
309
    {
310
        $sessionId = $this->getCampaignSessionId($entity, $action, $objectId);
311
        //set added/updated events
312
        list($this->modifiedEvents, $this->deletedEvents, $this->campaignEvents) = $this->getSessionEvents($sessionId);
313
314
        //set added/updated sources
315
        list($this->addedSources, $this->deletedSources, $campaignSources) = $this->getSessionSources($sessionId, $isClone);
316
        $this->connections                                                 = $this->getSessionCanvasSettings($sessionId);
317
318
        if ($isPost) {
319
            $this->getCampaignModel()->setCanvasSettings($entity, $this->connections, false, $this->modifiedEvents);
320
            $this->prepareCampaignSourcesForEdit($sessionId, $campaignSources, true);
321
        } else {
322
            if (!$isClone) {
323
                //clear out existing fields in case the form was refreshed, browser closed, etc
324
                $this->clearSessionComponents($sessionId);
325
                $this->modifiedEvents = $this->campaignSources = [];
326
327
                if ($entity->getId()) {
328
                    $campaignSources = $this->getCampaignModel()->getLeadSources($entity->getId());
329
                    $this->prepareCampaignSourcesForEdit($sessionId, $campaignSources);
330
331
                    $this->setSessionCanvasSettings($sessionId, $entity->getCanvasSettings());
332
                }
333
            }
334
335
            $this->deletedEvents = [];
336
337
            $form->get('sessionId')->setData($sessionId);
338
339
            $this->prepareCampaignEventsForEdit($entity, $sessionId, $isClone);
340
        }
341
    }
342
343
    /**
344
     * @param Campaign $entity
345
     * @param          $action
346
     * @param null     $objectId
347
     * @param bool     $isClone
348
     *
349
     * @return bool
350
     */
351
    protected function beforeEntitySave($entity, Form $form, $action, $objectId = null, $isClone = false)
352
    {
353
        if (empty($this->campaignEvents)) {
354
            //set the error
355
            $form->addError(
356
                new FormError(
357
                    $this->get('translator')->trans('mautic.campaign.form.events.notempty', [], 'validators')
358
                )
359
            );
360
361
            return false;
362
        }
363
364
        if (empty($this->campaignSources['lists']) && empty($this->campaignSources['forms'])) {
365
            //set the error
366
            $form->addError(
367
                new FormError(
368
                    $this->get('translator')->trans('mautic.campaign.form.sources.notempty', [], 'validators')
369
                )
370
            );
371
372
            return false;
373
        }
374
375
        if ($isClone) {
376
            list($this->addedSources, $this->deletedSources, $campaignSources) = $this->getSessionSources($objectId, $isClone);
377
            $this->getCampaignModel()->setLeadSources($entity, $campaignSources, []);
378
            // If this is a clone, we need to save the entity first to properly build the events, sources and canvas settings
379
            $this->getCampaignModel()->getRepository()->saveEntity($entity);
380
            // Set as new so that timestamps are still hydrated
381
            $entity->setNew();
382
            $this->sessionId = $entity->getId();
383
        }
384
385
        // Set lead sources
386
        $this->getCampaignModel()->setLeadSources($entity, $this->addedSources, $this->deletedSources);
387
388
        // Build and set Event entities
389
        $this->getCampaignModel()->setEvents($entity, $this->campaignEvents, $this->connections, $this->deletedEvents);
390
391
        if ('edit' === $action && null !== $this->connections) {
392
            if (!empty($this->deletedEvents)) {
393
                /** @var EventModel $eventModel */
394
                $eventModel = $this->getModel('campaign.event');
395
                $eventModel->deleteEvents($entity->getEvents()->toArray(), $this->deletedEvents);
396
            }
397
        }
398
399
        return true;
400
    }
401
402
    /**
403
     * Clear field and events from the session.
404
     *
405
     * @param $id
406
     */
407
    protected function clearSessionComponents($id)
408
    {
409
        $session = $this->get('session');
410
        $session->remove('mautic.campaign.'.$id.'.events.modified');
411
        $session->remove('mautic.campaign.'.$id.'.events.deleted');
412
        $session->remove('mautic.campaign.'.$id.'.events.canvassettings');
413
        $session->remove('mautic.campaign.'.$id.'.leadsources.current');
414
        $session->remove('mautic.campaign.'.$id.'.leadsources.modified');
415
        $session->remove('mautic.campaign.'.$id.'.leadsources.deleted');
416
    }
417
418
    /**
419
     * @return CampaignModel
420
     */
421
    protected function getCampaignModel()
422
    {
423
        /** @var CampaignModel $model */
424
        $model = $this->getModel($this->getModelName());
425
426
        return $model;
427
    }
428
429
    /**
430
     * @param      $action
431
     * @param null $objectId
432
     *
433
     * @return int|string|null
434
     */
435
    protected function getCampaignSessionId(Campaign $campaign, $action, $objectId = null)
436
    {
437
        if (isset($this->sessionId)) {
438
            return $this->sessionId;
439
        }
440
441
        if ($objectId) {
0 ignored issues
show
$objectId is of type null, thus it always evaluated to false.
Loading history...
442
            $sessionId = $objectId;
443
        } elseif ('new' === $action && empty($sessionId)) {
444
            $sessionId = 'mautic_'.sha1(uniqid(mt_rand(), true));
445
            if ($this->request->request->has('campaign')) {
446
                $campaign  = $this->request->request->get('campaign', []);
447
                $sessionId = $campaign['sessionId'] ?? $sessionId;
448
            }
449
        } elseif ('edit' === $action) {
450
            $sessionId = $campaign->getId();
451
        }
452
453
        $this->sessionId = $sessionId;
454
455
        return $sessionId;
456
    }
457
458
    /**
459
     * @return string
460
     */
461
    protected function getControllerBase()
462
    {
463
        return 'MauticCampaignBundle:Campaign';
464
    }
465
466
    /**
467
     * @param $start
468
     * @param $limit
469
     * @param $filter
470
     * @param $orderBy
471
     * @param $orderByDir
472
     */
473
    protected function getIndexItems($start, $limit, $filter, $orderBy, $orderByDir, array $args = [])
474
    {
475
        $session        = $this->get('session');
476
        $currentFilters = $session->get('mautic.campaign.list_filters', []);
477
        $updatedFilters = $this->request->get('filters', false);
478
479
        $sourceLists = $this->getCampaignModel()->getSourceLists();
480
        $listFilters = [
481
            'filters' => [
482
                'placeholder' => $this->get('translator')->trans('mautic.campaign.filter.placeholder'),
483
                'multiple'    => true,
484
                'groups'      => [
485
                    'mautic.campaign.leadsource.form' => [
486
                        'options' => $sourceLists['forms'],
487
                        'prefix'  => 'form',
488
                    ],
489
                    'mautic.campaign.leadsource.list' => [
490
                        'options' => $sourceLists['lists'],
491
                        'prefix'  => 'list',
492
                    ],
493
                ],
494
            ],
495
        ];
496
497
        if ($updatedFilters) {
498
            // Filters have been updated
499
500
            // Parse the selected values
501
            $newFilters     = [];
502
            $updatedFilters = json_decode($updatedFilters, true);
503
504
            if ($updatedFilters) {
505
                foreach ($updatedFilters as $updatedFilter) {
506
                    list($clmn, $fltr) = explode(':', $updatedFilter);
507
508
                    $newFilters[$clmn][] = $fltr;
509
                }
510
511
                $currentFilters = $newFilters;
512
            } else {
513
                $currentFilters = [];
514
            }
515
        }
516
        $session->set('mautic.campaign.list_filters', $currentFilters);
517
518
        $joinLists = $joinForms = false;
519
        if (!empty($currentFilters)) {
520
            $listIds = $catIds = [];
521
            foreach ($currentFilters as $type => $typeFilters) {
522
                $listFilters['filters']['groups']['mautic.campaign.leadsource.'.$type]['values'] = $typeFilters;
523
524
                foreach ($typeFilters as $fltr) {
525
                    if ('list' == $type) {
526
                        $listIds[] = (int) $fltr;
527
                    } else {
528
                        $formIds[] = (int) $fltr;
529
                    }
530
                }
531
            }
532
533
            if (!empty($listIds)) {
534
                $joinLists         = true;
535
                $filter['force'][] = ['column' => 'l.id', 'expr' => 'in', 'value' => $listIds];
536
            }
537
538
            if (!empty($formIds)) {
539
                $joinForms         = true;
540
                $filter['force'][] = ['column' => 'f.id', 'expr' => 'in', 'value' => $formIds];
541
            }
542
        }
543
544
        // Store for customizeViewArguments
545
        $this->listFilters = $listFilters;
546
547
        return parent::getIndexItems(
548
            $start,
549
            $limit,
550
            $filter,
551
            $orderBy,
552
            $orderByDir,
553
            [
554
                'joinLists' => $joinLists,
555
                'joinForms' => $joinForms,
556
            ]
557
        );
558
    }
559
560
    /**
561
     * @return string
562
     */
563
    protected function getModelName()
564
    {
565
        return 'campaign';
566
    }
567
568
    /**
569
     * @param $action
570
     *
571
     * @return array
572
     */
573
    protected function getPostActionRedirectArguments(array $args, $action)
574
    {
575
        switch ($action) {
576
            case 'new':
577
            case 'edit':
578
                if (!empty($args['entity'])) {
579
                    $sessionId = $this->getCampaignSessionId($args['entity'], $action);
580
                    $this->clearSessionComponents($sessionId);
581
                }
582
                break;
583
        }
584
585
        return $args;
586
    }
587
588
    /**
589
     * Get events from session.
590
     *
591
     * @param $id
592
     *
593
     * @return array
594
     */
595
    protected function getSessionEvents($id)
596
    {
597
        $session = $this->get('session');
598
599
        $modifiedEvents = $session->get('mautic.campaign.'.$id.'.events.modified', []);
600
        $deletedEvents  = $session->get('mautic.campaign.'.$id.'.events.deleted', []);
601
602
        $events = array_diff_key($modifiedEvents, array_flip($deletedEvents));
603
604
        return [$modifiedEvents, $deletedEvents, $events];
605
    }
606
607
    /**
608
     * Get events from session.
609
     *
610
     * @param $id
611
     * @param $isClone
612
     *
613
     * @return array
614
     */
615
    protected function getSessionSources($id, $isClone = false)
616
    {
617
        $session = $this->get('session');
618
619
        $campaignSources = $session->get('mautic.campaign.'.$id.'.leadsources.current', []);
620
        $modifiedSources = $session->get('mautic.campaign.'.$id.'.leadsources.modified', []);
621
622
        if ($campaignSources === $modifiedSources) {
623
            if ($isClone) {
624
                // Clone hasn't saved the sources yet so return the current list as added
625
                return [$campaignSources, [], $campaignSources];
626
            } else {
627
                return [[], [], $campaignSources];
628
            }
629
        }
630
631
        // Deleted sources
632
        $deletedSources = [];
633
        foreach ($campaignSources as $type => $sources) {
634
            if (isset($modifiedSources[$type])) {
635
                $deletedSources[$type] = array_diff_key($sources, $modifiedSources[$type]);
636
            } else {
637
                $deletedSources[$type] = $sources;
638
            }
639
        }
640
641
        // Added sources
642
        $addedSources = [];
643
        foreach ($modifiedSources as $type => $sources) {
644
            if (isset($campaignSources[$type])) {
645
                $addedSources[$type] = array_diff_key($sources, $campaignSources[$type]);
646
            } else {
647
                $addedSources[$type] = $sources;
648
            }
649
        }
650
651
        return [$addedSources, $deletedSources, $modifiedSources];
652
    }
653
654
    /**
655
     * @param $action
656
     *
657
     * @return array
658
     */
659
    protected function getViewArguments(array $args, $action)
660
    {
661
        /** @var EventCollector $eventCollector */
662
        $eventCollector = $this->get('mautic.campaign.event_collector');
663
664
        switch ($action) {
665
            case 'index':
666
                $args['viewParameters']['filters'] = $this->listFilters;
667
                break;
668
            case 'view':
669
                /** @var Campaign $entity */
670
                $entity   = $args['entity'];
671
                $objectId = $args['objectId'];
672
                // Init the date range filter form
673
                $dateRangeValues = $this->request->get('daterange', []);
674
                $action          = $this->generateUrl('mautic_campaign_action', ['objectAction' => 'view', 'objectId' => $objectId]);
675
                $dateRangeForm   = $this->get('form.factory')->create(DateRangeType::class, $dateRangeValues, ['action' => $action]);
676
677
                /** @var LeadEventLogRepository $eventLogRepo */
678
                $eventLogRepo             = $this->getDoctrine()->getManager()->getRepository('MauticCampaignBundle:LeadEventLog');
679
                $events                   = $this->getCampaignModel()->getEventRepository()->getCampaignEvents($entity->getId());
680
                $leadCount                = $this->getCampaignModel()->getRepository()->getCampaignLeadCount($entity->getId());
681
                $campaignLogCounts        = $eventLogRepo->getCampaignLogCounts($entity->getId(), false, false, true);
682
                $pendingCampaignLogCounts = $eventLogRepo->getCampaignLogCounts($entity->getId(), false, false);
683
                $sortedEvents             = [
684
                    'decision'  => [],
685
                    'action'    => [],
686
                    'condition' => [],
687
                ];
688
                foreach ($events as &$event) {
689
                    $event['logCount']           =
690
                    $event['logCountForPending'] =
691
                    $event['percent']            =
692
                    $event['yesPercent']         =
693
                    $event['noPercent']          = 0;
694
                    $event['leadCount']          = $leadCount;
695
696
                    if (isset($campaignLogCounts[$event['id']])) {
697
                        $event['logCount']           = array_sum($campaignLogCounts[$event['id']]);
698
                        $event['logCountForPending'] = isset($pendingCampaignLogCounts[$event['id']]) ? array_sum($pendingCampaignLogCounts[$event['id']]) : 0;
699
700
                        $pending  = $event['leadCount'] - $event['logCountForPending'];
701
                        $totalYes = $campaignLogCounts[$event['id']][1];
702
                        $totalNo  = $campaignLogCounts[$event['id']][0];
703
                        $total    = $totalYes + $totalNo + $pending;
704
                        if ($leadCount) {
705
                            $event['percent']    = round(($event['logCount'] / $total) * 100, 1);
706
                            $event['yesPercent'] = round(($campaignLogCounts[$event['id']][1] / $total) * 100, 1);
707
                            $event['noPercent']  = round(($campaignLogCounts[$event['id']][0] / $total) * 100, 1);
708
                        }
709
                    }
710
                }
711
712
                // rewrite stats data from parent condition if exist
713
                foreach ($events as &$event) {
714
                    if (!empty($event['decisionPath']) && !empty($event['parent_id']) && isset($events[$event['parent_id']])) {
715
                        $parentEvent                 = $events[$event['parent_id']];
716
                        $event['logCountForPending'] = $parentEvent['logCountForPending'];
717
                        $event['percent']            = $parentEvent['percent'];
718
                        $event['yesPercent']         = $parentEvent['yesPercent'];
719
                        $event['noPercent']          = $parentEvent['noPercent'];
720
                        if ('yes' == $event['decisionPath']) {
721
                            $event['noPercent'] = 0;
722
                        } else {
723
                            $event['yesPercent'] = 0;
724
                        }
725
                    }
726
                    $sortedEvents[$event['eventType']][] = $event;
727
                }
728
729
                $stats = $this->getCampaignModel()->getCampaignMetricsLineChartData(
730
                    null,
731
                    new \DateTime($dateRangeForm->get('date_from')->getData()),
732
                    new \DateTime($dateRangeForm->get('date_to')->getData()),
733
                    null,
734
                    ['campaign_id' => $objectId]
735
                );
736
737
                $campaignSources = $this->getCampaignModel()->getSourceLists();
738
739
                $this->prepareCampaignSourcesForEdit($objectId, $campaignSources, true);
740
                $this->prepareCampaignEventsForEdit($entity, $objectId, true);
741
742
                $args['viewParameters'] = array_merge(
743
                    $args['viewParameters'],
744
                    [
745
                        'campaign'        => $entity,
746
                        'stats'           => $stats,
747
                        'events'          => $sortedEvents,
748
                        'eventSettings'   => $eventCollector->getEventsArray(),
749
                        'sources'         => $this->getCampaignModel()->getLeadSources($entity),
750
                        'dateRangeForm'   => $dateRangeForm->createView(),
751
                        'campaignSources' => $this->campaignSources,
752
                        'campaignEvents'  => $events,
753
                        'campaignLeads'   => $this->forward(
754
                            'MauticCampaignBundle:Campaign:contacts',
755
                            [
756
                                'objectId'   => $entity->getId(),
757
                                'page'       => $this->get('session')->get('mautic.campaign.contact.page', 1),
758
                                'ignoreAjax' => true,
759
                            ]
760
                        )->getContent(),
761
                    ]
762
                );
763
                break;
764
765
            case 'new':
766
            case 'edit':
767
                $args['viewParameters'] = array_merge(
768
                    $args['viewParameters'],
769
                    [
770
                        'eventSettings'   => $eventCollector->getEventsArray(),
771
                        'campaignEvents'  => $this->campaignEvents,
772
                        'campaignSources' => $this->campaignSources,
773
                        'deletedEvents'   => $this->deletedEvents,
774
                    ]
775
                );
776
                break;
777
        }
778
779
        return $args;
780
    }
781
782
    /**
783
     * @param      $entity
784
     * @param      $objectId
785
     * @param bool $isClone
786
     *
787
     * @return array
788
     */
789
    protected function prepareCampaignEventsForEdit($entity, $objectId, $isClone = false)
790
    {
791
        //load existing events into session
792
        $campaignEvents = [];
793
794
        $existingEvents = $entity->getEvents()->toArray();
795
        $translator     = $this->get('translator');
796
        $dateHelper     = $this->get('mautic.helper.template.date');
797
        foreach ($existingEvents as $e) {
798
            $event = $e->convertToArray();
799
800
            if ($isClone) {
801
                $id          = $e->getTempId();
802
                $event['id'] = $id;
803
            } else {
804
                $id = $e->getId();
805
            }
806
807
            unset($event['campaign']);
808
            unset($event['children']);
809
            unset($event['parent']);
810
            unset($event['log']);
811
812
            $label = false;
813
            switch ($event['triggerMode']) {
814
                case 'interval':
815
                    $label = $translator->trans(
816
                        'mautic.campaign.connection.trigger.interval.label'.('no' == $event['decisionPath'] ? '_inaction' : ''),
817
                        [
818
                            '%number%' => $event['triggerInterval'],
819
                            '%unit%'   => $translator->transChoice(
820
                                'mautic.campaign.event.intervalunit.'.$event['triggerIntervalUnit'],
821
                                $event['triggerInterval']
822
                            ),
823
                        ]
824
                    );
825
                    break;
826
                case 'date':
827
                    $label = $translator->trans(
828
                        'mautic.campaign.connection.trigger.date.label'.('no' == $event['decisionPath'] ? '_inaction' : ''),
829
                        [
830
                            '%full%' => $dateHelper->toFull($event['triggerDate']),
831
                            '%time%' => $dateHelper->toTime($event['triggerDate']),
832
                            '%date%' => $dateHelper->toShort($event['triggerDate']),
833
                        ]
834
                    );
835
                    break;
836
            }
837
            if ($label) {
838
                $event['label'] = $label;
839
            }
840
841
            $campaignEvents[$id] = $event;
842
        }
843
844
        $this->modifiedEvents = $this->campaignEvents = $campaignEvents;
845
        $this->get('session')->set('mautic.campaign.'.$objectId.'.events.modified', $campaignEvents);
846
    }
847
848
    /**
849
     * @param $objectId
850
     * @param $campaignSources
851
     */
852
    protected function prepareCampaignSourcesForEdit($objectId, $campaignSources, $isPost = false)
853
    {
854
        $this->campaignSources = [];
855
        if (is_array($campaignSources)) {
856
            foreach ($campaignSources as $type => $sources) {
857
                if (!empty($sources)) {
858
                    $sourceList                   = $this->getModel('campaign')->getSourceLists($type);
859
                    $this->campaignSources[$type] = [
860
                        'sourceType' => $type,
861
                        'campaignId' => $objectId,
862
                        'names'      => implode(', ', array_intersect_key($sourceList, $sources)),
863
                    ];
864
                }
865
            }
866
        }
867
868
        if (!$isPost) {
869
            $session = $this->get('session');
870
            $session->set('mautic.campaign.'.$objectId.'.leadsources.current', $campaignSources);
871
            $session->set('mautic.campaign.'.$objectId.'.leadsources.modified', $campaignSources);
872
        }
873
    }
874
875
    /**
876
     * @param $sessionId
877
     * @param $canvasSettings
878
     */
879
    protected function setSessionCanvasSettings($sessionId, $canvasSettings)
880
    {
881
        $this->get('session')->set('mautic.campaign.'.$sessionId.'.events.canvassettings', $canvasSettings);
882
    }
883
884
    /**
885
     * @param $sessionId
886
     *
887
     * @return mixed
888
     */
889
    protected function getSessionCanvasSettings($sessionId)
890
    {
891
        return $this->get('session')->get('mautic.campaign.'.$sessionId.'.events.canvassettings');
892
    }
893
}
894