Completed
Push — 0.4 ( e232e8...87763b )
by Diego
05:27
created

MailchimpManager::searchMember()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 23
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 4

Importance

Changes 0
Metric Value
dl 0
loc 23
ccs 16
cts 16
cp 1
rs 8.7972
c 0
b 0
f 0
cc 4
eloc 12
nc 4
nop 1
crap 4
1
<?php namespace DiegoCaprioli\Larachimp\Services;
2
3
use DiegoCaprioli\Larachimp\Facades\LarachimpFacade;
4
use DiegoCaprioli\Larachimp\Models\LarachimpListMember;
5
use DiegoCaprioli\Larachimp\Services\Larachimp;
6
use DiegoCaprioli\Larachimp\Traits\BasicLogging;
7
use Illuminate\Contracts\Logging\Log;
8
9
class MailchimpManager
10
{
11
    /**
12
     * The ID of the Mailchimp list to use to subscribe and unsubscribe members.
13
     *
14
     * @var string
15
     */
16
    private $listId;
17
18
    /**
19
     * Make this class use a logger and it's basic methods
20
     */
21
    use BasicLogging;   
22
23
24
    /**
25
     * Returns a new MailchimpManager instance ready to use.
26
     *
27
     * @param \Illuminate\Contracts\Logging\Log $log
28
     */
29 5
    public function __construct(Log $log = null)
30
    {
31 5
        $this->log = $log;
32 5
        $this->listId = config('diegocaprioli.larachimp.larachimp.list_id');        
33 5
        LarachimpFacade::setLog($log);
34 5
    }
35
36
    /**
37
     * Verifies that the list_id corresponds to a valid list in the connected
38
     * Mailchimp account.
39
     */
40 5
    protected function verifyList()
41
    {        
42 5
        if (empty(config('diegocaprioli.larachimp.larachimp.apikey'))) {
43
            throw new \Exception('The Mailchimp API key is not properly set. Please verify the apikey configuration.');
44
        }
45
46 5
        $response = LarachimpFacade::request('GET', 'lists/' . $this->listId, [
47 5
            'query' => ['fields' => 'id,web_id,name'],
48 5
        ]);
49 5
        if (empty($response)) {
50
            throw new \Exception('The Mailchimp List does not exists. Please verify the list_id configuration.');
51
        }
52 5
    }
53
54
    /**
55
     * Returns the stdClass representing the Mailchimp List Member searched by
56
     * email exact match. Returns null if no match is found.
57
     * The returned stdClass has the fields as Mailchimp return for it's members
58
     * under the exact_matches.members entry.
59
     *
60
     * @param string $email The email of the Mailchim member to search for
61
     *
62
     * @return stdClass|null
63
     *
64
     * @see http://developer.mailchimp.com/documentation/mailchimp/reference/search-members/
65
     */
66 5
    public function searchMember($email)
67
    {
68 5
        $response = LarachimpFacade::request('GET', 'search-members', [
69
            'query' => [
70 5
                'query' => $email,
71 5
                'list_id' => $this->listId,
72 5
            ],
73 5
        ]);
74
75 5
        $member = null;
76 5
        if (!empty($response)) {
77 5
            if (isset($response->exact_matches)) {
78
                // Get the result. It should be an exact match
79 5
                if ($response->exact_matches->total_items == 1) {
80 5
                    $member = $response->exact_matches->members[0];
81 5
                }
82 5
            }
83 5
        }        
84
85 5
        $this->logInfo('Member Found = ' . var_export($member, true));
86
87 5
        return $member;
88
    }
89
90
    /**
91
     * Adds the $member to the Mailchimp List.
92
     *
93
     * @param LarachimpListMember $member The onbject isntance to add as a list member
94
     *
95
     * @return stdClass The Mailchimp member
96
     */
97 5
    public function addListMember(LarachimpListMember $member)
98
    {
99 5
        return LarachimpFacade::request('POST', 'lists/' . $this->listId . '/members', [
100 5
            'body' => json_encode([
101 5
                'email_address' => $member->getEmail(),
102 5
                'status' => $member->isSubscribedToMailchimpList() ? 'subscribed' : 'unsubscribed',
103 5
                'email_type' => 'html',
104 5
            ]),
105 5
        ]);
106
    }
107
108
    /**
109
     * Updates the subscription status of the list member.
110
     *
111
     * @param LarachimpListMember $member         The object instance that corresponds to the Mailchimp member
112
     * @param string              $subscriberHash The ID in Mailchimp for this subscriber
113
     *
114
     * @return stdClass The Mailchimp member
115
     */
116 1
    public function updateListMember(LarachimpListMember $member, $subscriberHash)
117
    {
118 1
        return LarachimpFacade::request('PATCH', 'lists/' . $this->listId . '/members/' . $subscriberHash, [
119 1
            'body' => json_encode([
120 1
                'status' => $member->isSubscribedToMailchimpList() ? 'subscribed' : 'unsubscribed',
121 1
        	]),
122 1
        ]);
123
    }
124
125
126
    /**
127
     * Removes the member from the mailchimp list, by email
128
     * 
129
     * @param  string $email The email to remove from the list
130
     */
131 5
    public function removeListMember($email)
132
    {
133
        // Get the member first from Mailchimp
134 5
        $member = $this->searchMember($email);
135 5
        if (empty($member)) {
136
            throw new \Exception('There\'s no Mailchimp member in the list with the email \'' . $email . '\'.');
137
        }
138
139 5
        LarachimpFacade::request('DELETE', 'lists/' . $this->listId . '/members/' . $member->id);
140 5
    }
141
142
143
    /**
144
     * Syncs the member to the Mailchimp List Member's data. Subscribes or
145
     * unsubscribes and adds new members if they don't exists yet.
146
     *
147
     * @param LarachimpListMember $member The object instance that corresponds to the Mailchimp member and should be synced
148
     * @return stdClass The Mailchimp member
149
     */
150 5
    public function syncMember(LarachimpListMember $member)
151
    {
152
        // Verify the list exists
153 5
        $this->verifyList();
154
155
        // Search the user by email in the list
156 5
        $mailchimpListMember = $this->searchMember($member->getEmail());
157
158 5
        if (empty($mailchimpListMember)) {
159
            // Add the user to the list
160 5
            $mailchimpListMember = $this->addListMember($member);
161 5
        } else {
162
            // Already exists, check if the subscription status should be changed
163 1
            $currentStatus = $member->isSubscribedToMailchimpList() ? 'subscribed' : 'unsubscribed';
164 1
            if ($mailchimpListMember->status != $currentStatus) {
165
                // Change status
166 1
                $mailchimpListMember = $this->updateListMember($member, $mailchimpListMember->id);
167 1
            }
168
        }
169
170 5
        return $mailchimpListMember;
171
    }
172
173
174
    /**
175
     * [updateMembersEmail description]
176
     * @param  LarachimpListMember  $member     The LarachimpListMember with the new email address
177
     * @param  string               $oldEmail   The old email address that the $member was registered with
178
     * @return stdClass                         The Mailchimp member
179
     */
180 2
    public function updateMembersEmail(LarachimpListMember $member, $oldEmail)
181
    {
182
183
        // Verify the list exists
184 2
        $this->verifyList();
185
186
        // Search the user using the oldEmail email in the list
187 2
        $oldListMember = $this->searchMember($oldEmail);
188 2
        if (empty($oldListMember)) {
189
            throw new \Exception('There\'s no Mailchimp member in the list with the email \'' . $oldEmail . '\'.');
190
        }
191
192
        // Add a new member with the new email:
193 2
        $newListMember = $this->syncMember($member);
194
195
        // Remove the old member
196 2
        $this->removeListMember($oldEmail);
197
198 2
        return $newListMember;
199
    }
200
201
}
202