Completed
Push — master ( fd16d9...770ec9 )
by Dominik
04:32 queued 03:29
created

MailgunEventRepository::getLastKnownSenderIpData()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 26

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 0
Metric Value
dl 0
loc 26
ccs 0
cts 17
cp 0
rs 9.1928
c 0
b 0
f 0
cc 5
nc 5
nop 0
crap 30
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
        $result = $this->getEventsQuery($criteria)->getQuery()->execute();
20
21
        return sizeof($result);
22
    }
23
24
    /**
25
     * Get MailgunEvent that match the search criteria.
26
     *
27
     * @param $criteria
28
     * @param $orderBy
29
     * @param $limit
30
     * @param $offset
31
     *
32
     * @return mixed
33
     */
34
    public function getEvents($criteria, $orderBy, $limit, $offset)
35
    {
36
        $qb = $this->getEventsQuery($criteria);
37
        $orderField = key($orderBy);
38
        $orderDirection = $orderBy[$orderField];
39
        $qb->orderBy('e.'.$orderField, $orderDirection);
40
        if (-1 != $limit) {
41
            $qb->setMaxResults($limit);
42
            $qb->setFirstResult($offset);
43
        }
44
45
        $result = $qb->getQuery()->execute();
46
47
        return $result;
48
    }
49
50
    /**
51
     * @param array $criteria
52
     *
53
     * @return QueryBuilder
54
     */
55
    private function getEventsQuery($criteria)
56
    {
57
        $lookForUnopened = array_key_exists('eventType', $criteria) && 'unopened' == $criteria['eventType'];
58
        if ($lookForUnopened) {
59
            unset($criteria['eventType']);
60
        }
61
62
        $qb = $this->createQueryBuilder('e');
63
        if (array_key_exists('domain', $criteria) && '' != $criteria['domain']) {
64
            $qb->andWhere('e.domain = :domain')
65
                ->setParameter('domain', $criteria['domain']);
66
        }
67
68 View Code Duplication
        if (array_key_exists('recipient', $criteria) && '' != $criteria['recipient']) {
69
            $qb->andWhere('e.recipient like :recipient')
70
                ->setParameter('recipient', '%'.$criteria['recipient'].'%');
71
        }
72
73
        if (array_key_exists('eventType', $criteria) && 'all' != $criteria['eventType']) {
74
            $qb->andWhere('e.event = :eventType')
75
                ->setParameter('eventType', $criteria['eventType']);
76
        }
77
78 View Code Duplication
        if (array_key_exists('search', $criteria) && '' != $criteria['search']) {
79
            $qb->andWhere('(e.messageHeaders like :search OR e.description like :search OR e.notification like :search OR e.reason like :search OR e.errorCode like :search OR e.ip like :search OR e.error 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)')
80
                ->setParameter('search', '%'.$criteria['search'].'%');
81
        }
82
83
        if ($lookForUnopened) {
84
            $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'))");
85
        }
86
87
        return $qb;
88
    }
89
90
    /**
91
     * Get distinct list of types of events.
92
     *
93
     * @return array of string
94
     */
95 View Code Duplication
    public function getEventTypes()
96
    {
97
        $q = $this->getEntityManager()->createQueryBuilder()
98
            ->select('e.event as event')
99
            ->from($this->getEntityName(), 'e')
100
            ->distinct()
101
            ->orderBy('e.event ', 'asc')
102
            ->getQuery();
103
        $result = array();
104
        foreach ($q->execute() as $next) {
105
            $result[] = $next['event'];
106
        }
107
108
        return $result;
109
    }
110
111
    /**
112
     * Get distinct list of email domains.
113
     *
114
     * @return array of string
115
     */
116 View Code Duplication
    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 View Code Duplication
    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