MailgunEventRepository::getLastKnownSenderIpData()   A
last analyzed

Complexity

Conditions 5
Paths 5

Size

Total Lines 25
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 0
Metric Value
cc 5
eloc 16
c 0
b 0
f 0
nc 5
nop 0
dl 0
loc 25
ccs 0
cts 17
cp 0
crap 30
rs 9.4222
1
<?php
2
3
namespace Azine\MailgunWebhooksBundle\Entity\Repositories;
4
5
use Azine\MailgunWebhooksBundle\Entity\MailgunEvent;
6
use Doctrine\ORM\EntityRepository;
7
use Doctrine\ORM\QueryBuilder;
8
9
/**
10
 * MailgunEventRepository.
11
 *
12
 * This class was generated by the Doctrine ORM. Add your own custom
13
 * repository methods below.
14
 */
15
class MailgunEventRepository extends EntityRepository
16
{
17
    public function getEventCount($criteria)
18
    {
19
        return $this->getEventsQuery($criteria)->select('count(e.id)')->getQuery()->getSingleScalarResult();
20
    }
21
22
    /**
23
     * Get MailgunEvent that match the search criteria.
24
     *
25
     * @param $criteria
26
     * @param $orderBy
27
     * @param $limit
28
     * @param $offset
29
     *
30
     * @return mixed
31
     */
32
    public function getEvents($criteria, $orderBy, $limit, $offset)
33
    {
34
        $qb = $this->getEventsQuery($criteria);
35
        $orderField = key($orderBy);
36
        $orderDirection = $orderBy[$orderField];
37
        $qb->orderBy('e.'.$orderField, $orderDirection);
38
        if (-1 != $limit) {
39
            $qb->setMaxResults($limit);
40
            $qb->setFirstResult($offset);
41
        }
42
43
        $result = $qb->getQuery()->execute();
44
45
        return $result;
46
    }
47
48
    /**
49
     * @param array $criteria
50
     *
51
     * @return QueryBuilder
52
     */
53
    private function getEventsQuery($criteria)
54
    {
55
        $lookForUnopened = array_key_exists('eventType', $criteria) && 'unopened' == $criteria['eventType'];
56
        if ($lookForUnopened) {
57
            unset($criteria['eventType']);
58
        }
59
60
        $qb = $this->createQueryBuilder('e');
61
        if (array_key_exists('domain', $criteria) && '' != $criteria['domain']) {
62
            $qb->andWhere('e.domain = :domain')
63
                ->setParameter('domain', $criteria['domain']);
64
        }
65
66
        if (array_key_exists('recipient', $criteria) && '' != $criteria['recipient']) {
67
            $qb->andWhere('e.recipient like :recipient')
68
                ->setParameter('recipient', '%'.$criteria['recipient'].'%');
69
        }
70
71
        if (array_key_exists('eventType', $criteria) && 'all' != $criteria['eventType']) {
72
            $qb->andWhere('e.event = :eventType')
73
                ->setParameter('eventType', $criteria['eventType']);
74
        }
75
76
        if (array_key_exists('search', $criteria) && '' != $criteria['search']) {
77
            $qb->andWhere('(e.messageHeaders like :search OR e.description like :search OR e.reason like :search OR e.ip like :search OR e.country like :search OR e.city like :search OR e.campaignId like :search OR e.campaignName like :search OR e.clientName like :search OR e.clientOs like :search OR e.clientType like :search OR e.deviceType like :search OR e.mailingList like :search OR e.messageId like :search OR e.tag like :search OR e.userAgent like :search OR e.url like :search)')
78
                ->setParameter('search', '%'.$criteria['search'].'%');
79
        }
80
81
        if ($lookForUnopened) {
82
            $qb->andWhere("NOT EXISTS (SELECT o.id FROM AzineMailgunWebhooksBundle:MailgunEvent o WHERE o.messageId like e.messageId AND o.event in ('opened', 'clicked', 'unsubscribed', 'complained'))");
83
        }
84
85
        return $qb;
86
    }
87
88
    /**
89
     * Get distinct list of types of events.
90
     *
91
     * @return array of string
92
     */
93
    public function getEventTypes()
94
    {
95
        $q = $this->getEntityManager()->createQueryBuilder()
96
            ->select('e.event as event')
97
            ->from($this->getEntityName(), 'e')
98
            ->distinct()
99
            ->orderBy('e.event ', 'asc')
100
            ->getQuery();
101
        $result = array();
102
        foreach ($q->execute() as $next) {
103
            $result[] = $next['event'];
104
        }
105
106
        $result[] = 'all';
107
108
        return $result;
109
    }
110
111
    /**
112
     * Get distinct list of email domains.
113
     *
114
     * @return array of string
115
     */
116
    public function getDomains()
117
    {
118
        $q = $this->getEntityManager()->createQueryBuilder()
119
            ->select('e.domain as domain')
120
            ->from($this->getEntityName(), 'e')
121
            ->distinct()
122
            ->orderBy('e.domain ', 'asc')
123
            ->getQuery();
124
125
        $result = array();
126
        foreach ($q->execute() as $next) {
127
            $result[] = $next['domain'];
128
        }
129
130
        return $result;
131
    }
132
133
    /**
134
     * Get distinct list of email recipients.
135
     *
136
     * @return array of string
137
     */
138
    public function getRecipients()
139
    {
140
        $q = $this->getEntityManager()->createQueryBuilder()
141
            ->select('e.recipient as recipient')
142
            ->from($this->getEntityName(), 'e')
143
            ->distinct()
144
            ->orderBy('e.recipient ', 'asc')
145
            ->getQuery();
146
147
        $result = array();
148
        foreach ($q->execute() as $next) {
149
            $result[] = $next['recipient'];
150
        }
151
152
        return $result;
153
    }
154
155
    /**
156
     * Get last known sender IP based on stored events list.
157
     *
158
     * @return array|null
159
     */
160
    public function getLastKnownSenderIpData()
161
    {
162
        $q = $this->getEntityManager()->createQueryBuilder()
163
            ->select('e.messageHeaders as mh, e.timestamp as ts')
164
            ->from($this->getEntityName(), 'e')
165
            ->orderBy('e.timestamp', 'desc')
166
            ->where('e.event IN (:events)')
167
            ->setParameter('events', array('opened', 'delivered', 'bounced', 'dropped', 'complained'))
168
            ->setMaxResults(50)
169
            ->getQuery();
170
171
        $returnData = null;
172
173
        foreach ($q->execute() as $next) {
174
            if ($next['mh']) {
175
                foreach ($next['mh'] as $nextHeader) {
176
                    if ('X-Mailgun-Sending-Ip' == $nextHeader[0]) {
177
                        $returnData['ip'] = $nextHeader[1];
178
                        $returnData['timestamp'] = $next['ts'];
179
                    }
180
                }
181
            }
182
        }
183
184
        return $returnData;
185
    }
186
187
    /**
188
     * Get a list of event fields that can be used for ordering results.
189
     *
190
     * @return array
191
     */
192
    public function getFieldsToOrderBy()
193
    {
194
        return array(
195
                'campaignId',
196
                'campaignName',
197
                'city',
198
                'clientName',
199
                'clientOs',
200
                'clientType',
201
                'country',
202
                'description',
203
                'deviceType',
204
                'domain',
205
                'error',
206
                'errorCode',
207
                'event',
208
                'ip',
209
                'mailingList',
210
                'messageHeaders',
211
                'messageId',
212
                'notification',
213
                'reason',
214
                'recipient',
215
                'region',
216
                'tag',
217
                'timestamp',
218
                'type',
219
                'userAgent',
220
                'url',
221
            );
222
    }
223
224
    /**
225
     * Get the most important events in the following priority
226
     * 1. Errors (rejected, failed)
227
     * 2. Warnings (complained, unsubscribed)
228
     * 3. Infos (accepted, delivered, opened, clicked, stored).
229
     *
230
     * @param int $count max number of events to fetch
231
     *
232
     * @return array of MailgunEvent
233
     */
234
    public function getImportantEvents($count)
235
    {
236
        $errors = $this->getEventsBySeverity(MailgunEvent::SEVERITY_ERROR, $count);
237
        $results = $errors;
238
239
        $getMoreCounter = $count - sizeof($errors);
240
241
        if ($getMoreCounter > 0) {
242
            $warnings = $this->getEventsBySeverity(MailgunEvent::SEVERITY_WARN, $count);
243
            $getMoreCounter = $getMoreCounter - sizeof($warnings);
244
            $results = array_merge($results, $warnings);
245
        }
246
247
        if ($getMoreCounter > 0) {
248
            $infos = $this->getEventsBySeverity(MailgunEvent::SEVERITY_INFO, $count);
249
            $results = array_merge($results, $infos);
250
        }
251
252
        return $results;
253
    }
254
255
    /**
256
     * Get events by severity/type.
257
     *
258
     * @param string $severity [info, warning, error]
259
     *
260
     * @return array of MailgunEvent
261
     */
262
    public function getEventsBySeverity($severity = MailgunEvent::SEVERITY_INFO, $maxResults = 0)
263
    {
264
        if (MailgunEvent::SEVERITY_INFO == $severity) {
265
            $criteria = "e.event = 'accepted' or e.event = 'delivered' or e.event = 'opened' or e.event = 'clicked' or e.event = 'stored'";
266
        } elseif (MailgunEvent::SEVERITY_WARN == $severity) {
267
            $criteria = "e.event = 'complained' or e.event = 'unsubscribed'";
268
        } elseif (MailgunEvent::SEVERITY_ERROR == $severity) {
269
            $criteria = "e.event = 'rejected' or e.event = 'failed' or e.event = 'dropped' or e.event = 'bounced'";
270
        } else {
271
            return null;
272
        }
273
274
        $qb = $this->createQueryBuilder('e')
275
            ->where($criteria)
276
            ->orderBy('e.timestamp ', 'desc');
277
278
        if ($maxResults > 0) {
279
            $qb->setMaxResults($maxResults);
280
        }
281
282
        $q = $qb->getQuery();
283
        $results = $q->execute();
284
285
        return $results;
286
    }
287
}
288