Completed
Pull Request — master (#49)
by Eugene
02:37
created

MailgunEventRepository::getLastKnownSenderIp()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 23

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 0
Metric Value
dl 0
loc 23
ccs 0
cts 18
cp 0
rs 9.2408
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
178
                        $returnData['ip'] = $nextHeader[1];
179
                        $returnData['timestamp'] = $next['ts'];
180
                    }
181
                }
182
            }
183
        }
184
185
        return $returnData;
186
    }
187
188
    /**
189
     * Get a list of event fields that can be used for ordering results.
190
     *
191
     * @return array
192
     */
193
    public function getFieldsToOrderBy()
194
    {
195
        return array(
196
                'campaignId',
197
                'campaignName',
198
                'city',
199
                'clientName',
200
                'clientOs',
201
                'clientType',
202
                'country',
203
                'description',
204
                'deviceType',
205
                'domain',
206
                'error',
207
                'errorCode',
208
                'event',
209
                'ip',
210
                'mailingList',
211
                'messageHeaders',
212
                'messageId',
213
                'notification',
214
                'reason',
215
                'recipient',
216
                'region',
217
                'tag',
218
                'timestamp',
219
                'type',
220
                'userAgent',
221
                'url',
222
            );
223
    }
224
225
    /**
226
     * Get the most important events in the following priority
227
     * 1. Errors (rejected, failed)
228
     * 2. Warnings (complained, unsubscribed)
229
     * 3. Infos (accepted, delivered, opened, clicked, stored).
230
     *
231
     * @param int $count max number of events to fetch
232
     *
233
     * @return array of MailgunEvent
234
     */
235
    public function getImportantEvents($count)
236
    {
237
        $errors = $this->getEventsBySeverity(MailgunEvent::SEVERITY_ERROR, $count);
238
        $results = $errors;
239
240
        $getMoreCounter = $count - sizeof($errors);
241
242
        if ($getMoreCounter > 0) {
243
            $warnings = $this->getEventsBySeverity(MailgunEvent::SEVERITY_WARN, $count);
244
            $getMoreCounter = $getMoreCounter - sizeof($warnings);
245
            $results = array_merge($results, $warnings);
246
        }
247
248
        if ($getMoreCounter > 0) {
249
            $infos = $this->getEventsBySeverity(MailgunEvent::SEVERITY_INFO, $count);
250
            $results = array_merge($results, $infos);
251
        }
252
253
        return $results;
254
    }
255
256
    /**
257
     * Get events by severity/type.
258
     *
259
     * @param string $severity [info, warning, error]
260
     *
261
     * @return array of MailgunEvent
262
     */
263
    public function getEventsBySeverity($severity = MailgunEvent::SEVERITY_INFO, $maxResults = 0)
264
    {
265
        if (MailgunEvent::SEVERITY_INFO == $severity) {
266
            $criteria = "e.event = 'accepted' or e.event = 'delivered' or e.event = 'opened' or e.event = 'clicked' or e.event = 'stored'";
267
        } elseif (MailgunEvent::SEVERITY_WARN == $severity) {
268
            $criteria = "e.event = 'complained' or e.event = 'unsubscribed'";
269
        } elseif (MailgunEvent::SEVERITY_ERROR == $severity) {
270
            $criteria = "e.event = 'rejected' or e.event = 'failed' or e.event = 'dropped' or e.event = 'bounced'";
271
        } else {
272
            return null;
273
        }
274
275
        $qb = $this->createQueryBuilder('e')
276
            ->where($criteria)
277
            ->orderBy('e.timestamp ', 'desc');
278
279
        if ($maxResults > 0) {
280
            $qb->setMaxResults($maxResults);
281
        }
282
283
        $q = $qb->getQuery();
284
        $results = $q->execute();
285
286
        return $results;
287
    }
288
}
289