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

MailgunEventRepository   A

Complexity

Total Complexity 35

Size/Duplication

Total Lines 273
Duplicated Lines 20.15 %

Coupling/Cohesion

Components 2
Dependencies 4

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 35
lcom 2
cbo 4
dl 55
loc 273
ccs 0
cts 113
cp 0
rs 9.6
c 0
b 0
f 0

10 Methods

Rating   Name   Duplication   Size   Complexity  
A getEventCount() 0 6 1
A getEvents() 0 15 2
C getEventsQuery() 8 34 12
A getEventTypes() 15 15 2
A getDomains() 16 16 2
A getRecipients() 16 16 2
A getLastKnownSenderIpData() 0 26 5
A getFieldsToOrderBy() 0 31 1
A getImportantEvents() 0 20 3
A getEventsBySeverity() 0 25 5

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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