MailgunEventRepository::getEventsQuery()   C
last analyzed

Complexity

Conditions 12
Paths 128

Size

Total Lines 33
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 156

Importance

Changes 0
Metric Value
cc 12
eloc 19
c 0
b 0
f 0
nc 128
nop 1
dl 0
loc 33
ccs 0
cts 20
cp 0
crap 156
rs 6.7333

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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