Completed
Push — master ( f9691c...4f8ea6 )
by Gaël
14:13
created

MailchimpDriver::addMember()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
c 0
b 0
f 0
rs 10
cc 1
nc 1
nop 3
1
<?php
2
3
namespace DansMaCulotte\Newsletter\Drivers;
4
5
use DrewM\MailChimp\MailChimp;
6
use Exception;
7
use DansMaCulotte\Newsletter\Exceptions\ApiError;
8
use DansMaCulotte\Newsletter\Exceptions\InvalidNewsletterList;
9
use DansMaCulotte\Newsletter\NewsletterListCollection;
10
11
class MailchimpDriver implements Driver
12
{
13
    /** @var MailChimp */
14
    public $client;
15
16
    /** @var NewsletterListCollection */
17
    public $lists;
18
19
    /**
20
     * MailchimpDriver constructor.
21
     * @param array $credentials
22
     * @param array $config
23
     * @throws InvalidNewsletterList
24
     */
25
    public function __construct(array $credentials, array $config)
26
    {
27
        $this->client = new Mailchimp($credentials['apiKey']);
28
        $this->lists = NewsletterListCollection::createFromConfig($config);
29
    }
30
31
32
    /**
33
     * @param string $email
34
     * @param array $options
35
     * @param string $listName
36
     * @return array|false
37
     * @throws ApiError
38
     * @throws InvalidNewsletterList
39
     */
40 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...
41
    {
42
        $list = $this->lists->findByName($listName);
43
44
        $options = $this->getSubscriptionOptions($email, $options);
45
46
        $response = $this->client->post("lists/{$list->getId()}/members", $options);
47
48
        if (! $this->client->success()) {
49
            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...
50
        }
51
52
        return $response;
53
    }
54
55
56
    /**
57
     * @param string $email
58
     * @param array $options
59
     * @param string $listName
60
     * @return array|bool|false
61
     * @throws ApiError
62
     * @throws InvalidNewsletterList
63
     */
64 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...
65
    {
66
        $list = $this->lists->findByName($listName);
67
68
        $options = $this->getSubscriptionOptions($email, $options);
69
70
        $response = $this->client->put("lists/{$list->getId()}/members/{$this->getSubscriberHash($email)}", $options);
71
72
        if (! $this->client->success()) {
73
            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...
74
        }
75
76
        return $response;
77
    }
78
79
    public function addMember(string $email, array $options = [], string $listName = '')
80
    {
81
        return $this->subscribe($email, array_merge([
82
            'status' => 'unsubscribed',
83
        ], $options), $listName);
84
    }
85
86
    /**
87
     * @param string $listName
88
     * @param array $parameters
89
     * @return array|false
90
     * @throws InvalidNewsletterList
91
     */
92
    public function getMembers(string $listName = '', array $parameters = [])
93
    {
94
        $list = $this->lists->findByName($listName);
95
96
        return $this->client->get("lists/{$list->getId()}/members", $parameters);
97
    }
98
99
    /**
100
     * @param string $email
101
     * @param string $listName
102
     * @return array|false
103
     * @throws InvalidNewsletterList
104
     */
105
    public function getMember(string $email, string $listName = '')
106
    {
107
        $list = $this->lists->findByName($listName);
108
109
        return $this->client->get("lists/{$list->getId()}/members/{$this->getSubscriberHash($email)}");
110
    }
111
112
    /**
113
     * @param string $email
114
     * @param string $listName
115
     * @return bool
116
     * @throws InvalidNewsletterList
117
     */
118
    public function hasMember(string $email, string $listName = ''): bool
119
    {
120
        $response = $this->getMember($email, $listName);
121
122
        if (! isset($response['email_address'])) {
123
            return false;
124
        }
125
126
        if (strtolower($response['email_address']) !== strtolower($email)) {
127
            return false;
128
        }
129
130
        return true;
131
    }
132
133
    /**
134
     * @param string $email
135
     * @param string $listName
136
     * @return bool
137
     * @throws InvalidNewsletterList
138
     */
139
    public function isSubscribed(string $email, string $listName = ''): bool
140
    {
141
        $response = $this->getMember($email, $listName);
142
143
        if (! isset($response)) {
144
            return false;
145
        }
146
147
        if ($response['status'] !== 'subscribed') {
148
            return false;
149
        }
150
151
        return true;
152
    }
153
154
    /**
155
     * @param string $email
156
     * @param string $listName
157
     * @return array|false
158
     * @throws ApiError
159
     * @throws InvalidNewsletterList
160
     */
161
    public function unsubscribe(string $email, string $listName = '')
162
    {
163
        $list = $this->lists->findByName($listName);
164
165
        $response = $this->client->patch("lists/{$list->getId()}/members/{$this->getSubscriberHash($email)}", [
166
            'status' => 'unsubscribed',
167
        ]);
168
169
        if (! $this->client->success()) {
170
            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...
171
        }
172
173
        return $response;
174
    }
175
176
177
    /**
178
     * @param string $email
179
     * @param string $listName
180
     * @return array|false
181
     * @throws InvalidNewsletterList
182
     */
183
    public function delete(string $email, string $listName = '')
184
    {
185
        $list = $this->lists->findByName($listName);
186
187
        $response = $this->client->delete("lists/{$list->getId()}/members/{$this->getSubscriberHash($email)}");
188
189
        return $response;
190
    }
191
192
    /**
193
     * @return MailChimp
194
     */
195
    public function getApi(): MailChimp
196
    {
197
        return $this->client;
198
    }
199
200
    /**
201
     * @param string $email
202
     * @return string
203
     */
204
    protected function getSubscriberHash(string $email): string
205
    {
206
        return $this->client->subscriberHash($email);
207
    }
208
209
    /**
210
     * @param string $email
211
     * @param array $options
212
     * @return array
213
     */
214
    protected function getSubscriptionOptions(string $email, array $options): array
215
    {
216
        $defaultOptions = [
217
            'email_address' => $email,
218
            'status' => 'subscribed',
219
            'email_type' => 'html',
220
        ];
221
222
        $options = array_merge($defaultOptions, $options);
223
224
        return $options;
225
    }
226
}
227