Skip to content

Commit 8f9737c

Browse files
authored
Merge pull request #108 from thinkshout/oauth-with-api-key
Adds new Mailchimp class for handling OAuth authentication
2 parents b402bd6 + 196e437 commit 8f9737c

File tree

2 files changed

+345
-0
lines changed

2 files changed

+345
-0
lines changed

README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,23 @@ if (!empty($response) && isset($response->lists)) {
7474
}
7575
```
7676

77+
### API Key vs OAuth Access Token
78+
79+
If you need to connect to Mailchimp using an OAuth generated access token, modify your calls to use the Mailchimp2 class as follows.
80+
81+
```php
82+
<?php
83+
// Replace calls like this:
84+
$api_key = 'YOUR_API_KEY';
85+
$mailchimp = new Mailchimp\Mailchimp($api_key);
86+
87+
// With this:
88+
$access_token = 'YOUR_ACCESS_TOKEN';
89+
$data_center = 'YOUR_DATA_CENTER'; // ex. us-10
90+
$mailchimp = new Mailchimp\Mailchimp2($access_token, $data_center);
91+
92+
```
93+
7794
## Testing
7895

7996
This library includes a [PHPUnit](https://phpunit.de/) test suite.

src/Mailchimp2.php

Lines changed: 328 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,328 @@
1+
<?php
2+
3+
namespace Mailchimp;
4+
5+
use Mailchimp\http\MailchimpCurlHttpClient;
6+
use Mailchimp\http\MailchimpGuzzleHttpClient;
7+
use Mailchimp\http\MailchimpHttpClientInterface;
8+
9+
/**
10+
* Mailchimp library with access token authentication.
11+
*
12+
* @package Mailchimp
13+
*/
14+
class Mailchimp2 {
15+
16+
const VERSION = '2.0.0';
17+
const DEFAULT_DATA_CENTER = 'us1';
18+
19+
const ERROR_CODE_BAD_REQUEST = 'BadRequest';
20+
const ERROR_CODE_INVALID_ACTION = 'InvalidAction';
21+
const ERROR_CODE_INVALID_RESOURCE = 'InvalidResource';
22+
const ERROR_CODE_JSON_PARSE_ERROR = 'JSONParseError';
23+
const ERROR_CODE_API_KEY_MISSING = 'APIKeyMissing';
24+
const ERROR_CODE_API_KEY_INVALID = 'APIKeyInvalid';
25+
const ERROR_CODE_FORBIDDEN = 'Forbidden';
26+
const ERROR_CODE_USER_DISABLED = 'UserDisabled';
27+
const ERROR_CODE_WRONG_DATACENTER = 'WrongDatacenter';
28+
const ERROR_CODE_RESOURCE_NOT_FOUND = 'ResourceNotFound';
29+
const ERROR_CODE_METHOD_NOT_ALLOWED = 'MethodNotAllowed';
30+
const ERROR_CODE_RESOURCE_NESTING_TOO_DEEP = 'ResourceNestingTooDeep';
31+
const ERROR_CODE_INVALID_METHOD_OVERRIDE = 'InvalidMethodOverride';
32+
const ERROR_CODE_REQUESTED_FIELDS_INVALID = 'RequestedFieldsInvalid';
33+
const ERROR_CODE_TOO_MANY_REQUESTS = 'TooManyRequests';
34+
const ERROR_CODE_INTERNAL_SERVER_ERROR = 'InternalServerError';
35+
const ERROR_CODE_COMPLIANCE_RELATED = 'ComplianceRelated';
36+
37+
/**
38+
* API version.
39+
*
40+
* @var string $version
41+
*/
42+
public $version = self::VERSION;
43+
44+
/**
45+
* The HTTP client.
46+
*
47+
* @var MailchimpHttpClientInterface $client
48+
*/
49+
protected $client;
50+
51+
/**
52+
* The REST API endpoint.
53+
*
54+
* @var string $endpoint
55+
*/
56+
protected $endpoint = 'https://us1.api.mailchimp.com/3.0';
57+
58+
/**
59+
* The Mailchimp Access token to authenticate with.
60+
*
61+
* @var string $access_token
62+
*/
63+
private $access_token;
64+
65+
/**
66+
* The Mailchimp API username to authenticate with.
67+
*
68+
* @var string $api_user
69+
*/
70+
private $api_user;
71+
72+
/**
73+
* A Mailchimp API error code to return with every API response.
74+
*
75+
* Used for testing / debugging error handling.
76+
* See ERROR_CODE_* constants.
77+
*
78+
* @var string $debug_error_code
79+
*/
80+
private $debug_error_code;
81+
82+
/**
83+
* Array of pending batch operations.
84+
*
85+
* @var array $batch_operations
86+
*
87+
* @see http://developer.mailchimp.com/documentation/mailchimp/reference/batches/#create-post_batches
88+
*/
89+
private $batch_operations;
90+
91+
/**
92+
* Mailchimp constructor.
93+
*
94+
* @param string $access_token
95+
* The Mailchimp Access token.
96+
* @param string $data_center
97+
* The Mailchimp data center associated with the account.
98+
* @param string $api_user
99+
* The Mailchimp API username.
100+
* @param array $http_options
101+
* HTTP client options.
102+
* @param MailchimpHttpClientInterface $client
103+
* Optional custom HTTP client. $http_options are ignored if this is set.
104+
*/
105+
public function __construct($access_token, $data_center, $api_user = 'OAuth', $http_options = [], MailchimpHttpClientInterface $client = NULL) {
106+
$this->access_token = $access_token;
107+
$this->api_user = $api_user;
108+
$this->endpoint = str_replace(Mailchimp::DEFAULT_DATA_CENTER, $data_center, $this->endpoint);
109+
110+
if (!empty($client)) {
111+
$this->client = $client;
112+
}
113+
else {
114+
$this->client = $this->getDefaultHttpClient($http_options);
115+
}
116+
}
117+
118+
/**
119+
* Sets a custom HTTP client to be used for all API requests.
120+
*
121+
* @param \Mailchimp\http\MailchimpHttpClientInterface $client
122+
* The HTTP client.
123+
*/
124+
public function setClient(MailchimpHttpClientInterface $client) {
125+
$this->client = $client;
126+
}
127+
128+
/**
129+
* Sets a Mailchimp error code to be returned by all requests.
130+
*
131+
* Used to test and debug error handling.
132+
*
133+
* @param string $error_code
134+
* The Mailchimp error code.
135+
*/
136+
public function setDebugErrorCode($error_code) {
137+
$this->debug_error_code = $error_code;
138+
}
139+
140+
/**
141+
* Gets Mailchimp account information for the authenticated account.
142+
*
143+
* @param array $parameters
144+
* Associative array of optional request parameters.
145+
*
146+
* @return object
147+
*
148+
* @see http://developer.mailchimp.com/documentation/mailchimp/reference/root/#read-get_root
149+
*/
150+
public function getAccount($parameters = []) {
151+
return $this->request('GET', '/', NULL, $parameters);
152+
}
153+
154+
/**
155+
* Processes all pending batch operations.
156+
*
157+
* @throws MailchimpAPIException
158+
*
159+
* @see http://developer.mailchimp.com/documentation/mailchimp/reference/batches/#create-post_batches
160+
*/
161+
public function processBatchOperations() {
162+
$parameters = [
163+
'operations' => $this->batch_operations,
164+
];
165+
166+
try {
167+
$response = $this->request('POST', '/batches', NULL, $parameters);
168+
169+
// Reset batch operations.
170+
$this->batch_operations = [];
171+
172+
return $response;
173+
174+
}
175+
catch (MailchimpAPIException $e) {
176+
$message = 'Failed to process batch operations: ' . $e->getMessage();
177+
throw new MailchimpAPIException($message, $e->getCode(), $e);
178+
}
179+
}
180+
181+
/**
182+
* Gets the status of a batch request.
183+
*
184+
* @param string $batch_id
185+
* The ID of the batch operation.
186+
*
187+
* @return object
188+
*
189+
* @see http://developer.mailchimp.com/documentation/mailchimp/reference/batches/#read-get_batches_batch_id
190+
*/
191+
public function getBatchOperation($batch_id) {
192+
$tokens = [
193+
'batch_id' => $batch_id,
194+
];
195+
196+
return $this->request('GET', '/batches/{batch_id}', $tokens);
197+
}
198+
199+
/**
200+
* Adds a pending batch operation.
201+
*
202+
* @param string $method
203+
* The HTTP method.
204+
* @param string $path
205+
* The request path, relative to the API endpoint.
206+
* @param array $parameters
207+
* Associative array of optional request parameters.
208+
*
209+
* @return object
210+
* The new batch operation object.
211+
*
212+
* @throws MailchimpAPIException
213+
*
214+
* @see http://developer.mailchimp.com/documentation/mailchimp/reference/batches/#create-post_batches
215+
*/
216+
protected function addBatchOperation($method, $path, $parameters = []) {
217+
if (empty($method) || empty($path)) {
218+
throw new MailchimpAPIException('Cannot add batch operation without a method and path.');
219+
}
220+
221+
$op = (object) [
222+
'method' => $method,
223+
'path' => $path,
224+
];
225+
226+
if (!empty($parameters)) {
227+
if ($method == 'GET') {
228+
$op->params = (object) $parameters;
229+
}
230+
else {
231+
$op->body = json_encode($parameters);
232+
}
233+
}
234+
235+
if (empty($this->batch_operations)) {
236+
$this->batch_operations = [];
237+
}
238+
239+
$this->batch_operations[] = $op;
240+
241+
return $op;
242+
}
243+
244+
/**
245+
* Makes a request to the Mailchimp API.
246+
*
247+
* @param string $method
248+
* The REST method to use when making the request.
249+
* @param string $path
250+
* The API path to request.
251+
* @param array $tokens
252+
* Associative array of tokens and values to replace in the path.
253+
* @param array $parameters
254+
* Associative array of parameters to send in the request body.
255+
* @param bool $batch
256+
* TRUE if this request should be added to pending batch operations.
257+
* @param bool $returnAssoc
258+
* TRUE to return Mailchimp API response as an associative array.
259+
*
260+
* @return mixed
261+
* Object or Array if $returnAssoc is TRUE.
262+
*
263+
* @throws MailchimpAPIException
264+
*/
265+
public function request($method, $path, $tokens = NULL, $parameters = [], $batch = FALSE, $returnAssoc = FALSE) {
266+
if (!empty($tokens)) {
267+
foreach ($tokens as $key => $value) {
268+
$path = str_replace('{' . $key . '}', $value, $path);
269+
}
270+
}
271+
272+
if ($batch) {
273+
return $this->addBatchOperation($method, $path, $parameters);
274+
}
275+
276+
// Set default request options with auth header.
277+
$options = [
278+
'headers' => [
279+
'Authorization' => $this->api_user . ' ' . $this->access_token,
280+
],
281+
];
282+
283+
// Add trigger error header if a debug error code has been set.
284+
if (!empty($this->debug_error_code)) {
285+
$options['headers']['X-Trigger-Error'] = $this->debug_error_code;
286+
}
287+
288+
return $this->client->handleRequest($method, $this->endpoint . $path, $options, $parameters, $returnAssoc);
289+
}
290+
291+
/**
292+
* Instantiates a default HTTP client based on the local environment.
293+
*
294+
* @param array $http_options
295+
* HTTP client options.
296+
*
297+
* @return MailchimpHttpClientInterface
298+
* The HTTP client.
299+
*/
300+
private function getDefaultHttpClient($http_options) {
301+
// Process HTTP options.
302+
// Handle deprecated 'timeout' argument.
303+
if (is_int($http_options)) {
304+
$http_options = [
305+
'timeout' => $http_options,
306+
];
307+
}
308+
309+
// Default timeout is 10 seconds.
310+
$http_options += [
311+
'timeout' => 10,
312+
];
313+
314+
$client = NULL;
315+
316+
// Use cURL HTTP client if PHP version is below 5.5.0.
317+
// Use Guzzle client otherwise.
318+
if (version_compare(phpversion(), '5.5.0', '<')) {
319+
$client = new MailchimpCurlHttpClient($http_options);
320+
}
321+
else {
322+
$client = new MailchimpGuzzleHttpClient($http_options);
323+
}
324+
325+
return $client;
326+
}
327+
328+
}

0 commit comments

Comments
 (0)