Issues (3627)

EventListener/CampaignSubscriber.php (1 issue)

1
<?php
2
3
/*
4
 * @copyright   2016 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\NotificationBundle\EventListener;
13
14
use Mautic\CampaignBundle\CampaignEvents;
15
use Mautic\CampaignBundle\Event\CampaignBuilderEvent;
16
use Mautic\CampaignBundle\Event\CampaignExecutionEvent;
17
use Mautic\CoreBundle\Event\TokenReplacementEvent;
18
use Mautic\LeadBundle\Entity\DoNotContact;
19
use Mautic\LeadBundle\Model\DoNotContact as DoNotContactModel;
20
use Mautic\NotificationBundle\Api\AbstractNotificationApi;
21
use Mautic\NotificationBundle\Event\NotificationSendEvent;
22
use Mautic\NotificationBundle\Form\Type\MobileNotificationSendType;
23
use Mautic\NotificationBundle\Form\Type\NotificationSendType;
24
use Mautic\NotificationBundle\Model\NotificationModel;
25
use Mautic\NotificationBundle\NotificationEvents;
26
use Mautic\PluginBundle\Helper\IntegrationHelper;
27
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
28
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
29
30
class CampaignSubscriber implements EventSubscriberInterface
31
{
32
    /**
33
     * @var NotificationModel
34
     */
35
    private $notificationModel;
36
37
    /**
38
     * @var AbstractNotificationApi
39
     */
40
    private $notificationApi;
41
42
    /**
43
     * @var IntegrationHelper
44
     */
45
    private $integrationHelper;
46
47
    /**
48
     * @var EventDispatcherInterface
49
     */
50
    private $dispatcher;
51
52
    /**
53
     * @var DoNotContactModel
54
     */
55
    private $doNotContact;
56
57
    public function __construct(
58
        IntegrationHelper $integrationHelper,
59
        NotificationModel $notificationModel,
60
        AbstractNotificationApi $notificationApi,
61
        EventDispatcherInterface $dispatcher,
62
        DoNotContactModel $doNotContact
63
    ) {
64
        $this->integrationHelper = $integrationHelper;
65
        $this->notificationModel = $notificationModel;
66
        $this->notificationApi   = $notificationApi;
67
        $this->dispatcher        = $dispatcher;
68
        $this->doNotContact      = $doNotContact;
69
    }
70
71
    /**
72
     * {@inheritdoc}
73
     */
74
    public static function getSubscribedEvents()
75
    {
76
        return [
77
            CampaignEvents::CAMPAIGN_ON_BUILD              => ['onCampaignBuild', 0],
78
            NotificationEvents::ON_CAMPAIGN_TRIGGER_ACTION => ['onCampaignTriggerAction', 0],
79
        ];
80
    }
81
82
    public function onCampaignBuild(CampaignBuilderEvent $event)
83
    {
84
        $integration = $this->integrationHelper->getIntegrationObject('OneSignal');
85
86
        if (!$integration || false === $integration->getIntegrationSettings()->getIsPublished()) {
87
            return;
88
        }
89
90
        $features = $integration->getSupportedFeatures();
91
92
        if (in_array('mobile', $features)) {
93
            $event->addAction(
94
                'notification.send_mobile_notification',
95
                [
96
                    'label'            => 'mautic.notification.campaign.send_mobile_notification',
97
                    'description'      => 'mautic.notification.campaign.send_mobile_notification.tooltip',
98
                    'eventName'        => NotificationEvents::ON_CAMPAIGN_TRIGGER_ACTION,
99
                    'formType'         => MobileNotificationSendType::class,
100
                    'formTypeOptions'  => ['update_select' => 'campaignevent_properties_notification'],
101
                    'formTheme'        => 'MauticNotificationBundle:FormTheme\NotificationSendList',
102
                    'timelineTemplate' => 'MauticNotificationBundle:SubscribedEvents\Timeline:index.html.php',
103
                    'channel'          => 'mobile_notification',
104
                    'channelIdField'   => 'mobile_notification',
105
                ]
106
            );
107
        }
108
109
        $event->addAction(
110
            'notification.send_notification',
111
            [
112
                'label'            => 'mautic.notification.campaign.send_notification',
113
                'description'      => 'mautic.notification.campaign.send_notification.tooltip',
114
                'eventName'        => NotificationEvents::ON_CAMPAIGN_TRIGGER_ACTION,
115
                'formType'         => NotificationSendType::class,
116
                'formTypeOptions'  => ['update_select' => 'campaignevent_properties_notification'],
117
                'formTheme'        => 'MauticNotificationBundle:FormTheme\NotificationSendList',
118
                'timelineTemplate' => 'MauticNotificationBundle:SubscribedEvents\Timeline:index.html.php',
119
                'channel'          => 'notification',
120
                'channelIdField'   => 'notification',
121
            ]
122
        );
123
    }
124
125
    /**
126
     * @return CampaignExecutionEvent
127
     */
128
    public function onCampaignTriggerAction(CampaignExecutionEvent $event)
129
    {
130
        $lead = $event->getLead();
131
132
        if (DoNotContact::IS_CONTACTABLE !== $this->doNotContact->isContactable($lead, 'notification')) {
133
            return $event->setFailed('mautic.notification.campaign.failed.not_contactable');
134
        }
135
136
        $notificationId = (int) $event->getConfig()['notification'];
137
138
        /** @var \Mautic\NotificationBundle\Entity\Notification $notification */
139
        $notification = $this->notificationModel->getEntity($notificationId);
140
141
        if ($notification->getId() !== $notificationId) {
142
            return $event->setFailed('mautic.notification.campaign.failed.missing_entity');
143
        }
144
145
        if (!$notification->getIsPublished()) {
146
            return $event->setFailed('mautic.notification.campaign.failed.unpublished');
147
        }
148
149
        // If lead has subscribed on multiple devices, get all of them.
150
        /** @var \Mautic\NotificationBundle\Entity\PushID[] $pushIDs */
151
        $pushIDs = $lead->getPushIDs();
152
153
        $playerID = [];
154
155
        foreach ($pushIDs as $pushID) {
156
            // Skip non-mobile PushIDs if this is a mobile event
157
            if ($event->checkContext('notification.send_mobile_notification') && false == $pushID->isMobile()) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
158
                continue;
159
            }
160
161
            // Skip mobile PushIDs if this is a non-mobile event
162
            if ($event->checkContext('notification.send_notification') && true == $pushID->isMobile()) {
163
                continue;
164
            }
165
166
            $playerID[] = $pushID->getPushID();
167
        }
168
169
        if (empty($playerID)) {
170
            return $event->setFailed('mautic.notification.campaign.failed.not_subscribed');
171
        }
172
173
        if ($url = $notification->getUrl()) {
174
            $url = $this->notificationApi->convertToTrackedUrl(
175
                $url,
176
                [
177
                    'notification' => $notification->getId(),
178
                    'lead'         => $lead->getId(),
179
                ],
180
                $notification
181
            );
182
        }
183
184
        /** @var TokenReplacementEvent $tokenEvent */
185
        $tokenEvent = $this->dispatcher->dispatch(
186
            NotificationEvents::TOKEN_REPLACEMENT,
187
            new TokenReplacementEvent(
188
                $notification->getMessage(),
189
                $lead,
190
                ['channel' => ['notification', $notification->getId()]]
191
            )
192
        );
193
194
        /** @var NotificationSendEvent $sendEvent */
195
        $sendEvent = $this->dispatcher->dispatch(
196
            NotificationEvents::NOTIFICATION_ON_SEND,
197
            new NotificationSendEvent($tokenEvent->getContent(), $notification->getHeading(), $lead)
198
        );
199
200
        // prevent rewrite notification entity
201
        $sendNotification = clone $notification;
202
        $sendNotification->setUrl($url);
203
        $sendNotification->setMessage($sendEvent->getMessage());
204
        $sendNotification->setHeading($sendEvent->getHeading());
205
206
        $response = $this->notificationApi->sendNotification(
207
            $playerID,
208
            $sendNotification
209
        );
210
211
        $event->setChannel('notification', $notification->getId());
212
213
        // If for some reason the call failed, tell mautic to try again by return false
214
        if (200 !== $response->code) {
215
            return $event->setResult(false);
216
        }
217
218
        $this->notificationModel->createStatEntry($notification, $lead, 'campaign.event', $event->getEvent()['id']);
219
        $this->notificationModel->getRepository()->upCount($notificationId);
220
221
        $result = [
222
            'status'  => 'mautic.notification.timeline.status.delivered',
223
            'type'    => 'mautic.notification.notification',
224
            'id'      => $notification->getId(),
225
            'name'    => $notification->getName(),
226
            'heading' => $sendEvent->getHeading(),
227
            'content' => $sendEvent->getMessage(),
228
        ];
229
230
        $event->setResult($result);
231
    }
232
}
233