MailChimp::addList()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 17
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 2.0017

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 11
c 1
b 0
f 0
nc 2
nop 2
dl 0
loc 17
ccs 12
cts 13
cp 0.9231
crap 2.0017
rs 9.9
1
<?php
2
3
4
namespace MailMarketing\Drivers;
5
6
use Illuminate\Support\Arr;
7
use MailMarketing\Entities\MailchimpResponse;
8
use MailMarketing\Entities\ResponseInterface;
9
use MailMarketing\MailMarketingException;
10
11
/**
12
 * @see https://mailchimp.com/developer/api/
13
 */
14
class MailChimp implements MailMarketingInterface
15
{
16
    protected \DrewM\MailChimp\MailChimp $client;
17
18
    protected array $config = [];
19
20 18
    public function __construct(array $config)
21
    {
22 18
        if (!($config['key'] ?? false)) {
23 1
            throw new \InvalidArgumentException('MailChimp API key not present');
24
        }
25
26 17
        $this->client = new \DrewM\MailChimp\MailChimp($config['key']);
27 17
        unset($config['key']);
28
29 17
        $this->config = $config;
30
    }
31
32 7
    public function setClient(\DrewM\MailChimp\MailChimp $client): static
33
    {
34 7
        $this->client = $client;
35
36 7
        return $this;
37
    }
38
39
    /**
40
     * @inheritDoc
41
     */
42 1
    public function client(?string $type = null): mixed
43
    {
44 1
        return $this->client;
45
    }
46
47
    /**
48
     * @inheritDoc
49
     */
50 1
    public function addList(string $name, array $data = []): ResponseInterface
51
    {
52 1
        $listConfig = Arr::get($this->config, 'list', []);
53 1
        if (!is_array($listConfig)) {
54
            $listConfig = [];
55
        }
56
        
57 1
        $config = array_merge($listConfig, $data);
58 1
        $params = [
59 1
            'name'                => $name,
60 1
            'contact'             => Arr::get($config, 'contact'),
61 1
            'permission_reminder' => Arr::get($config, 'permission_reminder'),
62 1
            'campaign_defaults'   => Arr::get($config, 'campaign_defaults'),
63 1
            'email_type_option'   => Arr::get($config, 'email_type_option'),
64 1
        ];
65
66 1
        return MailchimpResponse::init($this->client->post('lists', $params));
67
    }
68
69
    /**
70
     * @inheritDoc
71
     */
72 1
    public function addMembersToList($listId, $members, array $data = []): ResponseInterface
73
    {
74 1
        $batch = $this->client->new_batch();
75
76 1
        foreach ($members as $member) {
77 1
            $email = Arr::get($member, 'email');
78 1
            $batch->put(
79 1
                $listId . '__' . Arr::get($member, 'id'),
80 1
                "lists/$listId/members/" . $this->client::subscriberHash($email),
81 1
                [
82 1
                    'email_address'         => $email,
83 1
                    'status'                => 'subscribed',
84 1
                    'skip_merge_validation' => true,
85 1
                    'merge_fields'          => [
86 1
                        'FNAME'   => Arr::get($member, 'first_name', ''),
87 1
                        'LNAME'   => Arr::get($member, 'last_name', ''),
88 1
                        'PHONE'   => Arr::get($member, 'phone', ''),
89 1
                        'ADDRESS' => Arr::get($member, 'address', ''),
90 1
                    ],
91 1
                ]
92 1
            );
93
        }
94
95 1
        return MailchimpResponse::init($batch->execute());
96
    }
97
98
    /**
99
     * @inheritDoc
100
     */
101 2
    public function addMemberToList($listId, $member, array $data = []): ResponseInterface
102
    {
103 2
        $email = Arr::get($member, 'email');
104 2
        if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
105 1
            throw new MailMarketingException("Email '{$email}' not valid");
106
        }
107 1
        $response = $this->client->put(
108 1
            "lists/$listId/members/" . $this->client::subscriberHash($email),
109 1
            [
110 1
                'email_address'         => $email,
111 1
                'status_if_new'         => 'subscribed',
112 1
                'status'                => 'subscribed',
113 1
                'skip_merge_validation' => false,
114 1
                'merge_fields'          => [
115 1
                    'FNAME'   => Arr::get($member, 'first_name', ''),
116 1
                    'LNAME'   => Arr::get($member, 'last_name', ''),
117 1
                    'PHONE'   => Arr::get($member, 'phone', ''),
118 1
                    'ADDRESS' => Arr::get($member, 'address', ''),
119 1
                ],
120 1
            ]
121 1
        );
122
123 1
        return MailchimpResponse::init($response);
124
    }
125
126
    /**
127
     * @inheritDoc
128
     */
129 2
    public function removeMemberFromList($listId, $member, array $data = []): ResponseInterface
130
    {
131 2
        $email = Arr::get($member, 'email');
132 2
        if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
133 1
            throw new MailMarketingException("Email '{$email}' not valid");
134
        }
135 1
        $response = $this->client->patch(
136 1
            "lists/$listId/members/" . $this->client::subscriberHash($email),
137 1
            [
138 1
                'email_address'         => $email,
139 1
                'status'                => 'unsubscribed',
140 1
                'skip_merge_validation' => false,
141 1
                'merge_fields'          => [
142 1
                    'FNAME'   => Arr::get($member, 'first_name', ''),
143 1
                    'LNAME'   => Arr::get($member, 'last_name', ''),
144 1
                    'PHONE'   => Arr::get($member, 'phone', ''),
145 1
                    'ADDRESS' => Arr::get($member, 'address', ''),
146 1
                ],
147 1
            ]
148 1
        );
149
150 1
        return MailchimpResponse::init($response);
151
    }
152
153
    /**
154
     * @inheritDoc
155
     */
156 1
    public function getMemberInfoForList($listId, string $email): ResponseInterface
157
    {
158 1
        $response = $this->client->get("lists/{$listId}/members/{$this->client::subscriberHash($email)}");
159
160 1
        return MailchimpResponse::init($response);
161
    }
162
163
    /**
164
     * @inheritDoc
165
     */
166 1
    public function manageMemberTags($listId, string $email, array $tags): ResponseInterface
167
    {
168 1
        $tags = $this->formatTagsBeforeSend($tags);
169
170 1
        $response = false;
171 1
        if (count($tags) > 0) {
172 1
            $response = $this->client->post(
173 1
                "lists/{$listId}/members/{$this->client::subscriberHash($email)}/tags",
174 1
                [
175 1
                    'tags' => $tags,
176 1
                ]
177 1
            );
178
        }
179
180 1
        return MailchimpResponse::init($response);
181
    }
182
183
    /**
184
     * @inheritDoc
185
     */
186 1
    public function getMemberTags($listId, string $email): ResponseInterface
187
    {
188 1
        $response = $this->client->get("lists/{$listId}/members/{$this->client::subscriberHash($email)}/tags");
189
190 1
        return MailchimpResponse::init($response);
191
    }
192
193
    /**
194
     * @param array $tags
195
     * $tags can be:
196
     * ['tag1', 'tag2', 'tag3']
197
     * ['tag1' => true, 'tag2' => false, 'tag3' => true]
198
     * [['name' => 'tag1'], ['name' => 'tag2', 'status' => 'inactive'], ['name' => 'tag3', 'status' => 'active']]
199
     * or combination of these examples
200
     *
201
     * @return array
202
     */
203 5
    protected function formatTagsBeforeSend(array $tags): array
204
    {
205 5
        return array_filter(array_map(function ($key, $tag) {
206
            // ['tag1' => true, 'tag2' => false, 'tag3' => true]
207 5
            if (is_string($key) && is_bool($tag)) {
208 1
                return [
209 1
                    'name'   => $key,
210 1
                    'status' => $tag ? 'active' : 'inactive',
211 1
                ];
212
            }
213
214
            // ['tag1', 'tag2', 'tag3']
215 4
            if (is_string($tag)) {
216 3
                return [
217 3
                    'name'   => $tag,
218 3
                    'status' => 'active',
219 3
                ];
220
            }
221
222
            // [['name' => 'tag1'], ['name' => 'tag2', 'status' => 'inactive'], ['name' => 'tag3', 'status' => 'active']]
223 3
            if (is_array($tag) && key_exists('name', $tag)) {
224 2
                return $tag;
225
            }
226
227 1
            return null;
228 5
        }, array_keys($tags), $tags));
229
    }
230
}
231