Completed
Push — master ( 6f1f11...46af25 )
by Gaël
01:59
created

MailchimpDriver::isSubscribed()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 14
c 0
b 0
f 0
rs 9.7998
cc 3
nc 3
nop 2
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
    /**
80
     * @param string $listName
81
     * @param array $parameters
82
     * @return array|false
83
     * @throws InvalidNewsletterList
84
     */
85
    public function getMembers(string $listName = '', array $parameters = [])
86
    {
87
        $list = $this->lists->findByName($listName);
88
89
        return $this->client->get("lists/{$list->getId()}/members", $parameters);
90
    }
91
92
    /**
93
     * @param string $email
94
     * @param string $listName
95
     * @return array|false
96
     * @throws InvalidNewsletterList
97
     */
98
    public function getMember(string $email, string $listName = '')
99
    {
100
        $list = $this->lists->findByName($listName);
101
102
        return $this->client->get("lists/{$list->getId()}/members/{$this->getSubscriberHash($email)}");
103
    }
104
105
    /**
106
     * @param string $email
107
     * @param string $listName
108
     * @return bool
109
     * @throws InvalidNewsletterList
110
     */
111
    public function hasMember(string $email, string $listName = ''): bool
112
    {
113
        $response = $this->getMember($email, $listName);
114
115
        if (! isset($response['email_address'])) {
116
            return false;
117
        }
118
119
        if (strtolower($response['email_address']) != strtolower($email)) {
120
            return false;
121
        }
122
123
        return true;
124
    }
125
126
    /**
127
     * @param string $email
128
     * @param string $listName
129
     * @return bool
130
     * @throws InvalidNewsletterList
131
     */
132
    public function isSubscribed(string $email, string $listName = ''): bool
133
    {
134
        $response = $this->getMember($email, $listName);
135
136
        if (! isset($response)) {
137
            return false;
138
        }
139
140
        if ($response['status'] != 'subscribed') {
141
            return false;
142
        }
143
144
        return true;
145
    }
146
147
    /**
148
     * @param string $email
149
     * @param string $listName
150
     * @return array|false
151
     * @throws ApiError
152
     * @throws InvalidNewsletterList
153
     */
154
    public function unsubscribe(string $email, string $listName = '')
155
    {
156
        $list = $this->lists->findByName($listName);
157
158
        $response = $this->client->patch("lists/{$list->getId()}/members/{$this->getSubscriberHash($email)}", [
159
            'status' => 'unsubscribed',
160
        ]);
161
162
        if (! $this->client->success()) {
163
            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...
164
        }
165
166
        return $response;
167
    }
168
169
170
    /**
171
     * @param string $email
172
     * @param string $listName
173
     * @return array|false
174
     * @throws InvalidNewsletterList
175
     */
176
    public function delete(string $email, string $listName = '')
177
    {
178
        $list = $this->lists->findByName($listName);
179
180
        $response = $this->client->delete("lists/{$list->getId()}/members/{$this->getSubscriberHash($email)}");
181
182
        return $response;
183
    }
184
185
    /**
186
     * @return MailChimp
187
     */
188
    public function getApi(): MailChimp
189
    {
190
        return $this->client;
191
    }
192
193
    /**
194
     * @param string $email
195
     * @return string
196
     */
197
    protected function getSubscriberHash(string $email): string
198
    {
199
        return $this->client->subscriberHash($email);
200
    }
201
202
    /**
203
     * @param string $email
204
     * @param array $options
205
     * @return array
206
     */
207
    protected function getSubscriptionOptions(string $email, array $options): array
208
    {
209
        $defaultOptions = [
210
            'email_address' => $email,
211
            'status' => 'subscribed',
212
            'email_type' => 'html',
213
        ];
214
215
        $options = array_merge($defaultOptions, $options);
216
217
        return $options;
218
    }
219
}
220