Completed
Push — master ( 1a9a95...4ed083 )
by Gaël
10:07
created

MailchimpDriver   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 224
Duplicated Lines 12.5 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 0
Metric Value
dl 28
loc 224
c 0
b 0
f 0
wmc 21
lcom 1
cbo 4
rs 10

14 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A subscribe() 14 14 2
A subscribeOrUpdate() 14 14 2
A addMember() 0 6 1
A getMembers() 0 6 1
A getMember() 0 6 1
A hasMember() 0 14 3
A isSubscribed() 0 14 3
A unsubscribe() 0 14 2
A delete() 0 8 1
A getLastError() 0 4 1
A getApi() 0 4 1
A getSubscriberHash() 0 4 1
A getSubscriptionOptions() 0 12 1

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 DansMaCulotte\Newsletter\Drivers;
4
5
use DrewM\MailChimp\MailChimp;
6
use DansMaCulotte\Newsletter\Exceptions\ApiError;
7
use DansMaCulotte\Newsletter\Exceptions\InvalidNewsletterList;
8
use DansMaCulotte\Newsletter\NewsletterListCollection;
9
10
class MailchimpDriver implements Driver
11
{
12
    /** @var MailChimp */
13
    public $client;
14
15
    /** @var NewsletterListCollection */
16
    public $lists;
17
18
    /**
19
     * MailchimpDriver constructor.
20
     * @param array $credentials
21
     * @param array $config
22
     * @throws InvalidNewsletterList
23
     */
24
    public function __construct(array $credentials, array $config)
25
    {
26
        $this->client = new Mailchimp($credentials['apiKey']);
27
        $this->lists = NewsletterListCollection::createFromConfig($config);
28
    }
29
30
31
    /**
32
     * @param string $email
33
     * @param array $options
34
     * @param string $listName
35
     * @return array|false
36
     * @throws ApiError
37
     * @throws InvalidNewsletterList
38
     */
39 View Code Duplication
    public function subscribe(string $email, array $options = [], string $listName = '')
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
40
    {
41
        $list = $this->lists->findByName($listName);
42
43
        $options = $this->getSubscriptionOptions($email, $options);
44
45
        $response = $this->client->post("lists/{$list->getId()}/members", $options);
46
47
        if (! $this->client->success()) {
48
            throw ApiError::responseError($this->client->getLastError(), 'mailchimp');
0 ignored issues
show
Security Bug introduced by
It seems like $this->client->getLastError() targeting DrewM\MailChimp\MailChimp::getLastError() can also be of type false; however, DansMaCulotte\Newsletter...iError::responseError() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
49
        }
50
51
        return $response;
52
    }
53
54
55
    /**
56
     * @param string $email
57
     * @param array $options
58
     * @param string $listName
59
     * @return array|bool|false
60
     * @throws ApiError
61
     * @throws InvalidNewsletterList
62
     */
63 View Code Duplication
    public function subscribeOrUpdate(string $email, array $options = [], string $listName = '')
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
64
    {
65
        $list = $this->lists->findByName($listName);
66
67
        $options = $this->getSubscriptionOptions($email, $options);
68
69
        $response = $this->client->put("lists/{$list->getId()}/members/{$this->getSubscriberHash($email)}", $options);
70
71
        if (! $this->client->success()) {
72
            throw ApiError::responseError($this->client->getLastError(), 'mailchimp');
0 ignored issues
show
Security Bug introduced by
It seems like $this->client->getLastError() targeting DrewM\MailChimp\MailChimp::getLastError() can also be of type false; however, DansMaCulotte\Newsletter...iError::responseError() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
73
        }
74
75
        return $response;
76
    }
77
78
    public function addMember(string $email, array $options = [], string $listName = '')
79
    {
80
        return $this->subscribe($email, array_merge([
81
            'status' => 'unsubscribed',
82
        ], $options), $listName);
83
    }
84
85
    /**
86
     * @param string $listName
87
     * @param array $parameters
88
     * @return array|false
89
     * @throws InvalidNewsletterList
90
     */
91
    public function getMembers(string $listName = '', array $parameters = [])
92
    {
93
        $list = $this->lists->findByName($listName);
94
95
        return $this->client->get("lists/{$list->getId()}/members", $parameters);
96
    }
97
98
    /**
99
     * @param string $email
100
     * @param string $listName
101
     * @return array|false
102
     * @throws InvalidNewsletterList
103
     */
104
    public function getMember(string $email, string $listName = '')
105
    {
106
        $list = $this->lists->findByName($listName);
107
108
        return $this->client->get("lists/{$list->getId()}/members/{$this->getSubscriberHash($email)}");
109
    }
110
111
    /**
112
     * @param string $email
113
     * @param string $listName
114
     * @return bool
115
     * @throws InvalidNewsletterList
116
     */
117
    public function hasMember(string $email, string $listName = ''): bool
118
    {
119
        $response = $this->getMember($email, $listName);
120
121
        if (! isset($response['email_address'])) {
122
            return false;
123
        }
124
125
        if (strtolower($response['email_address']) !== strtolower($email)) {
126
            return false;
127
        }
128
129
        return true;
130
    }
131
132
    /**
133
     * @param string $email
134
     * @param string $listName
135
     * @return bool
136
     * @throws InvalidNewsletterList
137
     */
138
    public function isSubscribed(string $email, string $listName = ''): bool
139
    {
140
        $response = $this->getMember($email, $listName);
141
142
        if (! isset($response)) {
143
            return false;
144
        }
145
146
        if ($response['status'] !== 'subscribed') {
147
            return false;
148
        }
149
150
        return true;
151
    }
152
153
    /**
154
     * @param string $email
155
     * @param string $listName
156
     * @return array|false
157
     * @throws ApiError
158
     * @throws InvalidNewsletterList
159
     */
160
    public function unsubscribe(string $email, string $listName = '')
161
    {
162
        $list = $this->lists->findByName($listName);
163
164
        $response = $this->client->patch("lists/{$list->getId()}/members/{$this->getSubscriberHash($email)}", [
165
            'status' => 'unsubscribed',
166
        ]);
167
168
        if (! $this->client->success()) {
169
            throw ApiError::responseError($this->client->getLastError(), 'mailchimp');
0 ignored issues
show
Security Bug introduced by
It seems like $this->client->getLastError() targeting DrewM\MailChimp\MailChimp::getLastError() can also be of type false; however, DansMaCulotte\Newsletter...iError::responseError() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
170
        }
171
172
        return $response;
173
    }
174
175
176
    /**
177
     * @param string $email
178
     * @param string $listName
179
     * @return array|false
180
     * @throws InvalidNewsletterList
181
     */
182
    public function delete(string $email, string $listName = '')
183
    {
184
        $list = $this->lists->findByName($listName);
185
186
        $response = $this->client->delete("lists/{$list->getId()}/members/{$this->getSubscriberHash($email)}");
187
188
        return $response;
189
    }
190
191
    /**
192
     * @return string|false
193
     */
194
    public function getLastError()
195
    {
196
        return $this->client->getLastError();
197
    }
198
199
    /**
200
     * @return MailChimp
201
     */
202
    public function getApi(): MailChimp
203
    {
204
        return $this->client;
205
    }
206
207
    /**
208
     * @param string $email
209
     * @return string
210
     */
211
    protected function getSubscriberHash(string $email): string
212
    {
213
        return $this->client->subscriberHash($email);
214
    }
215
216
    /**
217
     * @param string $email
218
     * @param array $options
219
     * @return array
220
     */
221
    protected function getSubscriptionOptions(string $email, array $options): array
222
    {
223
        $defaultOptions = [
224
            'email_address' => $email,
225
            'status' => 'subscribed',
226
            'email_type' => 'html',
227
        ];
228
229
        $options = array_merge($defaultOptions, $options);
230
231
        return $options;
232
    }
233
}
234