1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace DrewM\MailChimp; |
4
|
|
|
|
5
|
|
|
/** |
6
|
|
|
* Super-simple, minimum abstraction MailChimp API v3 wrapper |
7
|
|
|
* MailChimp API v3: http://developer.mailchimp.com |
8
|
|
|
* This wrapper: https://github.com/drewm/mailchimp-api |
9
|
|
|
* |
10
|
|
|
* @author Drew McLellan <[email protected]> |
11
|
|
|
* @version 2.0.7 |
12
|
|
|
*/ |
13
|
|
|
class MailChimp |
14
|
|
|
{ |
15
|
|
|
private $api_key; |
16
|
|
|
private $api_endpoint = 'https://<dc>.api.mailchimp.com/3.0'; |
17
|
|
|
|
18
|
|
|
/* SSL Verification |
19
|
|
|
Read before disabling: |
20
|
|
|
http://snippets.webaware.com.au/howto/stop-turning-off-curlopt_ssl_verifypeer-and-fix-your-php-config/ |
21
|
|
|
*/ |
22
|
|
|
public $verify_ssl = true; |
23
|
|
|
|
24
|
|
|
private $last_error = ''; |
25
|
|
|
private $last_response = array(); |
26
|
|
|
|
27
|
|
|
/** |
28
|
|
|
* Create a new instance |
29
|
|
|
* @param string $api_key Your MailChimp API key |
30
|
|
|
*/ |
31
|
|
|
public function __construct($api_key) |
32
|
|
|
{ |
33
|
|
|
$this->api_key = $api_key; |
34
|
|
|
|
35
|
|
|
list(, $datacentre) = explode('-', $this->api_key); |
36
|
|
|
$this->api_endpoint = str_replace('<dc>', $datacentre, $this->api_endpoint); |
37
|
|
|
|
38
|
|
|
$this->last_response = array('headers'=>null, 'body'=>null); |
39
|
|
|
} |
40
|
|
|
|
41
|
|
|
/** |
42
|
|
|
* Convert an email address into a 'subscriber hash' for identifying the subscriber in a method URL |
43
|
|
|
* @param string $email The subscriber's email address |
44
|
|
|
* @return string Hashed version of the input |
45
|
|
|
*/ |
46
|
|
|
public function subscriberHash($email) |
47
|
|
|
{ |
48
|
|
|
return md5(strtolower($email)); |
49
|
|
|
} |
50
|
|
|
|
51
|
|
|
/** |
52
|
|
|
* Get the last error returned by either the network transport, or by the API. |
53
|
|
|
* If something didn't work, this should contain the string describing the problem. |
54
|
|
|
* @return array|false describing the error |
55
|
|
|
*/ |
56
|
|
|
public function getLastError() |
57
|
|
|
{ |
58
|
|
|
if ($this->last_error) return $this->last_error; |
59
|
|
|
return false; |
60
|
|
|
} |
61
|
|
|
|
62
|
|
|
/** |
63
|
|
|
* Get an array containing the HTTP headers and the body of the API response. |
64
|
|
|
* @return array Assoc array with keys 'headers' and 'body' |
65
|
|
|
*/ |
66
|
|
|
public function getLastResponse() |
67
|
|
|
{ |
68
|
|
|
return $this->last_response; |
69
|
|
|
} |
70
|
|
|
|
71
|
|
|
/** |
72
|
|
|
* Make an HTTP DELETE request - for deleting data |
73
|
|
|
* @param string URL of the API request method |
74
|
|
|
* @param array Assoc array of arguments (if any) |
75
|
|
|
* @param int Timeout limit for request in seconds |
76
|
|
|
* @return array|false Assoc array of API response, decoded from JSON |
77
|
|
|
*/ |
78
|
|
|
public function delete($method, $args=array(), $timeout=10) |
79
|
|
|
{ |
80
|
|
|
return $this->makeRequest('delete', $method, $args, $timeout); |
81
|
|
|
} |
82
|
|
|
|
83
|
|
|
/** |
84
|
|
|
* Make an HTTP GET request - for retrieving data |
85
|
|
|
* @param string URL of the API request method |
86
|
|
|
* @param array Assoc array of arguments (usually your data) |
87
|
|
|
* @param int Timeout limit for request in seconds |
88
|
|
|
* @return array|false Assoc array of API response, decoded from JSON |
89
|
|
|
*/ |
90
|
|
|
public function get($method, $args=array(), $timeout=10) |
91
|
|
|
{ |
92
|
|
|
return $this->makeRequest('get', $method, $args, $timeout); |
93
|
|
|
} |
94
|
|
|
|
95
|
|
|
/** |
96
|
|
|
* Make an HTTP PATCH request - for performing partial updates |
97
|
|
|
* @param string URL of the API request method |
98
|
|
|
* @param array Assoc array of arguments (usually your data) |
99
|
|
|
* @param int Timeout limit for request in seconds |
100
|
|
|
* @return array|false Assoc array of API response, decoded from JSON |
101
|
|
|
*/ |
102
|
|
|
public function patch($method, $args=array(), $timeout=10) |
103
|
|
|
{ |
104
|
|
|
return $this->makeRequest('patch', $method, $args, $timeout); |
105
|
|
|
} |
106
|
|
|
|
107
|
|
|
/** |
108
|
|
|
* Make an HTTP POST request - for creating and updating items |
109
|
|
|
* @param string URL of the API request method |
110
|
|
|
* @param array Assoc array of arguments (usually your data) |
111
|
|
|
* @param int Timeout limit for request in seconds |
112
|
|
|
* @return array|false Assoc array of API response, decoded from JSON |
113
|
|
|
*/ |
114
|
|
|
public function post($method, $args=array(), $timeout=10) |
115
|
|
|
{ |
116
|
|
|
return $this->makeRequest('post', $method, $args, $timeout); |
117
|
|
|
} |
118
|
|
|
|
119
|
|
|
/** |
120
|
|
|
* Make an HTTP PUT request - for creating new items |
121
|
|
|
* @param string URL of the API request method |
122
|
|
|
* @param array Assoc array of arguments (usually your data) |
123
|
|
|
* @param int Timeout limit for request in seconds |
124
|
|
|
* @return array|false Assoc array of API response, decoded from JSON |
125
|
|
|
*/ |
126
|
|
|
public function put($method, $args=array(), $timeout=10) |
127
|
|
|
{ |
128
|
|
|
return $this->makeRequest('put', $method, $args, $timeout); |
129
|
|
|
} |
130
|
|
|
|
131
|
|
|
/** |
132
|
|
|
* Performs the underlying HTTP request. Not very exciting |
133
|
|
|
* @param string $http_verb The HTTP verb to use: get, post, put, patch, delete |
134
|
|
|
* @param string $method The API method to be called |
135
|
|
|
* @param array $args Assoc array of parameters to be passed |
136
|
|
|
* @return array|false Assoc array of decoded result |
137
|
|
|
*/ |
138
|
|
|
private function makeRequest($http_verb, $method, $args=array(), $timeout=10) |
139
|
|
|
{ |
140
|
|
|
$url = $this->api_endpoint.'/'.$method; |
141
|
|
|
|
142
|
|
|
$this->last_error = ''; |
143
|
|
|
$response = array('headers'=>null, 'body'=>null); |
144
|
|
|
$this->last_response = $response; |
145
|
|
|
|
146
|
|
|
if (function_exists('curl_init') && function_exists('curl_setopt')) { |
147
|
|
|
$ch = curl_init(); |
148
|
|
|
curl_setopt($ch, CURLOPT_URL, $url); |
149
|
|
|
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept: application/vnd.api+json', |
150
|
|
|
'Content-Type: application/vnd.api+json', |
151
|
|
|
'Authorization: apikey '.$this->api_key)); |
152
|
|
|
curl_setopt($ch, CURLOPT_USERAGENT, 'DrewM/MailChimp-API/3.0 (github.com/drewm/mailchimp-api)'); |
153
|
|
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); |
154
|
|
|
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); |
155
|
|
|
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, $this->verify_ssl); |
156
|
|
|
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); |
157
|
|
|
curl_setopt($ch, CURLOPT_ENCODING, ''); |
158
|
|
|
|
159
|
|
|
switch($http_verb) { |
160
|
|
View Code Duplication |
case 'post': |
|
|
|
|
161
|
|
|
curl_setopt($ch, CURLOPT_POST, true); |
162
|
|
|
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($args)); |
163
|
|
|
break; |
164
|
|
|
|
165
|
|
|
case 'get': |
166
|
|
|
$query = http_build_query($args); |
167
|
|
|
curl_setopt($ch, CURLOPT_URL, $url.'?'.$query); |
168
|
|
|
break; |
169
|
|
|
|
170
|
|
|
case 'delete': |
171
|
|
|
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE'); |
172
|
|
|
break; |
173
|
|
|
|
174
|
|
View Code Duplication |
case 'patch': |
|
|
|
|
175
|
|
|
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PATCH'); |
176
|
|
|
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($args)); |
177
|
|
|
break; |
178
|
|
|
|
179
|
|
View Code Duplication |
case 'put': |
|
|
|
|
180
|
|
|
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT'); |
181
|
|
|
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($args)); |
182
|
|
|
break; |
183
|
|
|
} |
184
|
|
|
|
185
|
|
|
$response['body'] = curl_exec($ch); |
186
|
|
|
$response['headers'] = curl_getinfo($ch); |
187
|
|
|
|
188
|
|
|
if ($response['body'] === false) { |
189
|
|
|
$this->last_error = curl_error($ch); |
190
|
|
|
} |
191
|
|
|
|
192
|
|
|
curl_close($ch); |
193
|
|
|
} else { |
194
|
|
|
throw new \Exception("cURL support is required, but can't be found."); |
195
|
|
|
} |
196
|
|
|
|
197
|
|
|
return $this->formatResponse($response); |
198
|
|
|
} |
199
|
|
|
|
200
|
|
|
private function formatResponse($response) |
201
|
|
|
{ |
202
|
|
|
$this->last_response = $response; |
203
|
|
|
|
204
|
|
|
if (!empty($response['body'])) { |
205
|
|
|
|
206
|
|
|
$d = json_decode($response['body'], true); |
207
|
|
|
|
208
|
|
|
if (isset($d['status']) && $d['status']!='200' && isset($d['detail'])) { |
209
|
|
|
$this->last_error = sprintf('%d: %s', $d['status'], $d['detail']); |
210
|
|
|
} |
211
|
|
|
|
212
|
|
|
return $d; |
213
|
|
|
} |
214
|
|
|
|
215
|
|
|
return false; |
216
|
|
|
} |
217
|
|
|
} |
218
|
|
|
|
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.