MailchimpDriver::getMember()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
c 0
b 0
f 0
nc 1
nop 2
dl 0
loc 5
rs 10
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
    public function subscribe(string $email, array $options = [], string $listName = '')
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
Bug introduced by
It seems like $this->client->getLastError() can also be of type false; however, parameter $error of DansMaCulotte\Newsletter...iError::responseError() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

48
            throw ApiError::responseError(/** @scrutinizer ignore-type */ $this->client->getLastError(), 'mailchimp');
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
    public function subscribeOrUpdate(string $email, array $options = [], string $listName = '')
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
Bug introduced by
It seems like $this->client->getLastError() can also be of type false; however, parameter $error of DansMaCulotte\Newsletter...iError::responseError() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

72
            throw ApiError::responseError(/** @scrutinizer ignore-type */ $this->client->getLastError(), 'mailchimp');
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
Bug introduced by
It seems like $this->client->getLastError() can also be of type false; however, parameter $error of DansMaCulotte\Newsletter...iError::responseError() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

169
            throw ApiError::responseError(/** @scrutinizer ignore-type */ $this->client->getLastError(), 'mailchimp');
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