Completed
Push — master ( 4a101c...616cb7 )
by Drew
02:52
created

MailChimp::attachRequestPayload()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 2
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.8
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
                case 'post':
161
                    curl_setopt($ch, CURLOPT_POST, true);
162
                    $this->attachRequestPayload($ch, $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
                case 'patch':
175
                    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PATCH');
176
                    $this->attachRequestPayload($ch, $args);
177
                    break;
178
                
179
                case 'put':
180
                    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
181
                    $this->attachRequestPayload($ch, $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
    /**
201
     * Encode the data and attach it to the request
202
     * @param   resource    cURL session handle, used by reference
203
     * @param   array       Assoc array of data to attach
204
     */
205
    private function attachRequestPayload(&$ch, $data)
206
    {
207
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data)); 
208
    }
209
210
    private function formatResponse($response)
211
    {
212
        $this->last_response = $response;
213
214
        if (!empty($response['body'])) {
215
216
            $d = json_decode($response['body'], true);
217
            
218
            if (isset($d['status']) && $d['status']!='200' && isset($d['detail'])) {
219
                $this->last_error = sprintf('%d: %s', $d['status'], $d['detail']);
220
            }
221
            
222
            return $d;
223
        }
224
225
        return false;
226
    }
227
}
228