Issues (3627)

NotificationBundle/Model/NotificationModel.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\Model;
13
14
use Doctrine\DBAL\Query\QueryBuilder;
15
use Mautic\CoreBundle\Helper\Chart\ChartQuery;
16
use Mautic\CoreBundle\Helper\Chart\LineChart;
17
use Mautic\CoreBundle\Model\AjaxLookupModelInterface;
18
use Mautic\CoreBundle\Model\FormModel;
19
use Mautic\LeadBundle\Entity\Lead;
20
use Mautic\NotificationBundle\Entity\Notification;
21
use Mautic\NotificationBundle\Entity\Stat;
22
use Mautic\NotificationBundle\Event\NotificationEvent;
23
use Mautic\NotificationBundle\Form\Type\MobileNotificationType;
24
use Mautic\NotificationBundle\Form\Type\NotificationType;
25
use Mautic\NotificationBundle\NotificationEvents;
26
use Mautic\PageBundle\Model\TrackableModel;
27
use Symfony\Component\EventDispatcher\Event;
28
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
29
30
/**
31
 * Class NotificationModel
32
 * {@inheritdoc}
33
 */
34
class NotificationModel extends FormModel implements AjaxLookupModelInterface
35
{
36
    /**
37
     * @var TrackableModel
38
     */
39
    protected $pageTrackableModel;
40
41
    /**
42
     * NotificationModel constructor.
43
     */
44
    public function __construct(TrackableModel $pageTrackableModel)
45
    {
46
        $this->pageTrackableModel = $pageTrackableModel;
47
    }
48
49
    /**
50
     * {@inheritdoc}
51
     *
52
     * @return \Mautic\NotificationBundle\Entity\NotificationRepository
53
     */
54
    public function getRepository()
55
    {
56
        return $this->em->getRepository('MauticNotificationBundle:Notification');
57
    }
58
59
    /**
60
     * @return \Mautic\NotificationBundle\Entity\StatRepository
61
     */
62
    public function getStatRepository()
63
    {
64
        return $this->em->getRepository('MauticNotificationBundle:Stat');
65
    }
66
67
    /**
68
     * {@inheritdoc}
69
     */
70
    public function getPermissionBase()
71
    {
72
        return 'notification:notifications';
73
    }
74
75
    /**
76
     * Save an array of entities.
77
     *
78
     * @param  $entities
79
     * @param  $unlock
80
     *
81
     * @return array
82
     */
83
    public function saveEntities($entities, $unlock = true)
84
    {
85
        //iterate over the results so the events are dispatched on each delete
86
        $batchSize = 20;
87
        $i         = 0;
88
        foreach ($entities as $entity) {
89
            $isNew = ($entity->getId()) ? false : true;
90
91
            //set some defaults
92
            $this->setTimestamps($entity, $isNew, $unlock);
93
94
            if ($dispatchEvent = $entity instanceof Notification) {
95
                $event = $this->dispatchEvent('pre_save', $entity, $isNew);
96
            }
97
98
            $this->getRepository()->saveEntity($entity, false);
99
100
            if ($dispatchEvent) {
101
                $this->dispatchEvent('post_save', $entity, $isNew, $event);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $event does not seem to be defined for all execution paths leading up to this point.
Loading history...
102
            }
103
104
            if (0 === ++$i % $batchSize) {
105
                $this->em->flush();
106
            }
107
        }
108
        $this->em->flush();
109
    }
110
111
    /**
112
     * {@inheritdoc}
113
     *
114
     * @param       $entity
115
     * @param       $formFactory
116
     * @param null  $action
117
     * @param array $options
118
     *
119
     * @return mixed
120
     *
121
     * @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
122
     * @throws MethodNotAllowedHttpException
123
     */
124
    public function createForm($entity, $formFactory, $action = null, $options = [])
125
    {
126
        if (!$entity instanceof Notification) {
127
            throw new MethodNotAllowedHttpException(['Notification']);
128
        }
129
        if (!empty($action)) {
130
            $options['action'] = $action;
131
        }
132
133
        $type = false !== strpos($action, 'mobile_') ? MobileNotificationType::class : NotificationType::class;
134
135
        return $formFactory->create($type, $entity, $options);
136
    }
137
138
    /**
139
     * Get a specific entity or generate a new one if id is empty.
140
     *
141
     * @param $id
142
     *
143
     * @return Notification|null
144
     */
145
    public function getEntity($id = null)
146
    {
147
        if (null === $id) {
148
            $entity = new Notification();
149
        } else {
150
            $entity = parent::getEntity($id);
151
        }
152
153
        return $entity;
154
    }
155
156
    /**
157
     * @param string $source
158
     * @param int    $sourceId
159
     */
160
    public function createStatEntry(Notification $notification, Lead $lead, $source = null, $sourceId = null)
161
    {
162
        $stat = new Stat();
163
        $stat->setDateSent(new \DateTime());
164
        $stat->setLead($lead);
165
        $stat->setNotification($notification);
166
        $stat->setSource($source);
167
        $stat->setSourceId($sourceId);
168
169
        $this->getStatRepository()->saveEntity($stat);
170
    }
171
172
    /**
173
     * {@inheritdoc}
174
     *
175
     * @param $action
176
     * @param $event
177
     * @param $entity
178
     * @param $isNew
179
     *
180
     * @throws \Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException
181
     */
182
    protected function dispatchEvent($action, &$entity, $isNew = false, Event $event = null)
183
    {
184
        if (!$entity instanceof Notification) {
185
            throw new MethodNotAllowedHttpException(['Notification']);
186
        }
187
188
        switch ($action) {
189
            case 'pre_save':
190
                $name = NotificationEvents::NOTIFICATION_PRE_SAVE;
191
                break;
192
            case 'post_save':
193
                $name = NotificationEvents::NOTIFICATION_POST_SAVE;
194
                break;
195
            case 'pre_delete':
196
                $name = NotificationEvents::NOTIFICATION_PRE_DELETE;
197
                break;
198
            case 'post_delete':
199
                $name = NotificationEvents::NOTIFICATION_POST_DELETE;
200
                break;
201
            default:
202
                return;
203
        }
204
205
        if ($this->dispatcher->hasListeners($name)) {
206
            if (empty($event)) {
207
                $event = new NotificationEvent($entity, $isNew);
208
                $event->setEntityManager($this->em);
209
            }
210
211
            $this->dispatcher->dispatch($name, $event);
212
213
            return $event;
214
        } else {
215
            return;
216
        }
217
    }
218
219
    /**
220
     * Joins the page table and limits created_by to currently logged in user.
221
     */
222
    public function limitQueryToCreator(QueryBuilder &$q)
223
    {
224
        $q->join('t', MAUTIC_TABLE_PREFIX.'push_notifications', 'p', 'p.id = t.notification_id')
225
            ->andWhere('p.created_by = :userId')
226
            ->setParameter('userId', $this->userHelper->getUser()->getId());
227
    }
228
229
    /**
230
     * Get line chart data of hits.
231
     *
232
     * @param char   $unit          {@link php.net/manual/en/function.date.php#refsect1-function.date-parameters}
233
     * @param string $dateFormat
234
     * @param array  $filter
235
     * @param bool   $canViewOthers
236
     *
237
     * @return array
238
     */
239
    public function getHitsLineChartData($unit, \DateTime $dateFrom, \DateTime $dateTo, $dateFormat = null, $filter = [], $canViewOthers = true)
240
    {
241
        $flag = null;
242
243
        if (isset($filter['flag'])) {
244
            $flag = $filter['flag'];
245
            unset($filter['flag']);
246
        }
247
248
        $chart = new LineChart($unit, $dateFrom, $dateTo, $dateFormat);
249
        $query = new ChartQuery($this->em->getConnection(), $dateFrom, $dateTo);
250
251
        if (!$flag || 'total_and_unique' === $flag) {
252
            $q = $query->prepareTimeDataQuery('push_notification_stats', 'date_sent', $filter);
253
254
            if (!$canViewOthers) {
255
                $this->limitQueryToCreator($q);
256
            }
257
258
            $data = $query->loadAndBuildTimeData($q);
259
            $chart->setDataset($this->translator->trans('mautic.notification.show.total.sent'), $data);
260
        }
261
262
        return $chart->render();
263
    }
264
265
    /**
266
     * @param $idHash
267
     *
268
     * @return Stat
269
     */
270
    public function getNotificationStatus($idHash)
271
    {
272
        return $this->getStatRepository()->getNotificationStatus($idHash);
273
    }
274
275
    /**
276
     * Search for an notification stat by notification and lead IDs.
277
     *
278
     * @param $notificationId
279
     * @param $leadId
280
     *
281
     * @return array
282
     */
283
    public function getNotificationStatByLeadId($notificationId, $leadId)
284
    {
285
        return $this->getStatRepository()->findBy(
286
            [
287
                'notification' => (int) $notificationId,
288
                'lead'         => (int) $leadId,
289
            ],
290
            ['dateSent' => 'DESC']
291
        );
292
    }
293
294
    /**
295
     * Get an array of tracked links.
296
     *
297
     * @param $notificationId
298
     *
299
     * @return array
300
     */
301
    public function getNotificationClickStats($notificationId)
302
    {
303
        return $this->pageTrackableModel->getTrackableList('notification', $notificationId);
304
    }
305
306
    /**
307
     * @param        $type
308
     * @param string $filter
309
     * @param int    $limit
310
     * @param int    $start
311
     * @param array  $options
312
     *
313
     * @return array
314
     */
315
    public function getLookupResults($type, $filter = '', $limit = 10, $start = 0, $options = [])
316
    {
317
        $results = [];
318
        switch ($type) {
319
            case 'notification':
320
                $entities = $this->getRepository()->getNotificationList(
321
                    $filter,
322
                    $limit,
323
                    $start,
324
                    $this->security->isGranted($this->getPermissionBase().':viewother'),
325
                    isset($options['notification_type']) ? $options['notification_type'] : null
326
                );
327
328
                foreach ($entities as $entity) {
329
                    $results[$entity['language']][$entity['id']] = $entity['name'];
330
                }
331
332
                //sort by language
333
                ksort($results);
334
335
                break;
336
            case 'mobile_notification':
337
                $entities = $this->getRepository()->getMobileNotificationList(
338
                    $filter,
339
                    $limit,
340
                    $start,
341
                    $this->security->isGranted($this->getPermissionBase().':viewother'),
342
                    isset($options['notification_type']) ? $options['notification_type'] : null
343
                );
344
345
                foreach ($entities as $entity) {
346
                    $results[$entity['language']][$entity['id']] = $entity['name'];
347
                }
348
349
                //sort by language
350
                ksort($results);
351
352
                break;
353
        }
354
355
        return $results;
356
    }
357
}
358