Completed
Push — staging ( 68fed3...485a71 )
by Evan
04:30
created

Yikes_Inc_Easy_MailChimp_API::put()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 14
Code Lines 8

Duplication

Lines 14
Ratio 100 %

Importance

Changes 0
Metric Value
cc 3
eloc 8
nc 2
nop 3
dl 14
loc 14
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * A class to handle requests to the MailChimp API.
5
 *
6
 * @author Jeremy Pry
7
 * @since  %VERSION%
8
 */
9
class Yikes_Inc_Easy_MailChimp_API {
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
10
11
	/**
12
	 * The API key.
13
	 *
14
	 * @since %VERSION%
15
	 * @var string
16
	 */
17
	protected $api_key = '';
18
19
	/**
20
	 * The URL for the API.
21
	 *
22
	 * @since %VERSION%
23
	 * @var string
24
	 */
25
	protected $api_url = '';
26
27
	/**
28
	 * The API version.
29
	 *
30
	 * @since %VERSION%
31
	 * @var string
32
	 */
33
	protected $api_version = '';
34
35
	/**
36
	 * The datacenter where the MailChimp account is located.
37
	 *
38
	 * This is typically part of the API Key.
39
	 *
40
	 * @since %VERSION%
41
	 * @var string
42
	 */
43
	protected $datacenter = '';
44
45
	/**
46
	 * Yikes_Inc_Easy_MailChimp_API constructor.
47
	 *
48
	 * @since %VERSION%
49
	 *
50
	 * @param string $datacenter  The datacenter string where the MailChimp account is located.
51
	 * @param string $api_key     The base API key, without the datacenter appended.
52
	 * @param string $api_version The API version to use.
53
	 */
54
	public function __construct( $datacenter, $api_key, $api_version ) {
55
		$this->datacenter  = $datacenter;
56
		$this->api_key     = $api_key;
57
		$this->api_version = $api_version;
58
		$this->api_url     = "https://{$this->datacenter}.api.mailchimp.com/{$this->api_version}";
59
	}
60
61
	/**
62
	 * Send a DELETE request to the MailChimp API.
63
	 *
64
	 * @author Jeremy Pry
65
	 * @since  %VERSION%
66
	 *
67
	 * @param string $path    The relative path for the request.
68
	 * @param array  $headers Array of headers to send with the request.
69
	 * @param array  $params  An array of additional parameters to pass to the request. See WP_Http::request().
70
	 *
71
	 * @return array|WP_Error
72
	 */
73
	public function delete( $path = '', $headers = array(), $params = array() ) {
74
		return $this->send_request( $path, 'DELETE', $headers, $params );
75
	}
76
77
	/**
78
	 * Send a GET request to the MailChimp API.
79
	 *
80
	 * @author Jeremy Pry
81
	 * @since  %VERSION%
82
	 *
83
	 * @param string $path    The relative path for the request.
84
	 * @param array  $headers Array of headers to send with the request.
85
	 * @param array  $params  An array of additional parameters to pass to the request. See WP_Http::request().
86
	 *
87
	 * @return array|WP_Error
88
	 */
89
	public function get( $path = '', $headers = array(), $params = array() ) {
90
		return $this->send_request( $path, 'GET', $headers, $params );
91
	}
92
93
	/**
94
	 * Send a PATCH request to the MailChimp API.
95
	 *
96
	 * @author Jeremy Pry
97
	 * @since  %VERSION%
98
	 *
99
	 * @param string $path    The relative path for the request.
100
	 * @param array  $headers Array of headers to send with the request.
101
	 * @param array  $params  An array of additional parameters to pass to the request. See WP_Http::request().
102
	 *
103
	 * @return array|WP_Error
104
	 */
105 View Code Duplication
	public function patch( $path = '', $headers = array(), $params = array() ) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
106
		if ( ! isset( $params['body'] ) || empty( $params['body'] ) ) {
107
			return new WP_Error(
108
				'yikesinc_eme_missing_body',
109
				sprintf(
110
					/* translators: %s refers to the request method. */
111
					__( '%s requests require a body as one of the parameters.', 'yikes-inc-easy-mailchimp-extender' ),
112
					'PATCH'
113
				)
114
			);
115
		}
116
117
		return $this->send_request( $path, 'PATCH', $headers, $params );
118
	}
119
120
	/**
121
	 * Send a POST request to the MailChimp API.
122
	 *
123
	 * @author Jeremy Pry
124
	 * @since  %VERSION%
125
	 *
126
	 * @param string $path    The relative path for the request.
127
	 * @param array  $headers Array of headers to send with the request.
128
	 * @param array  $params  An array of additional parameters to pass to the request. See WP_Http::request().
129
	 *
130
	 * @return array|WP_Error
131
	 */
132 View Code Duplication
	public function post( $path = '', $headers = array(), $params = array() ) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
133
		if ( ! isset( $params['body'] ) || empty( $params['body'] ) ) {
134
			return new WP_Error(
135
				'yikesinc_eme_missing_body',
136
				sprintf(
137
					/* translators: %s refers to the request method. */
138
					__( '%s requests require a body as one of the parameters.', 'yikes-inc-easy-mailchimp-extender' ),
139
					'POST'
140
				)
141
			);
142
		}
143
144
		return $this->send_request( $path, 'POST', $headers, $params );
145
	}
146
147
	/**
148
	 * Send a PUT request to the MailChimp API.
149
	 *
150
	 * @author Jeremy Pry
151
	 * @since  %VERSION%
152
	 *
153
	 * @param string $path    The relative path for the request.
154
	 * @param array  $headers Array of headers to send with the request.
155
	 * @param array  $params  An array of additional parameters to pass to the request. See WP_Http::request().
156
	 *
157
	 * @return array|WP_Error
158
	 */
159 View Code Duplication
	public function put( $path = '', $headers = array(), $params = array() ) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
160
		if ( ! isset( $params['body'] ) || empty( $params['body'] ) ) {
161
			return new WP_Error(
162
				'yikesinc_eme_missing_body',
163
				sprintf(
164
					/* translators: %s refers to the request method. */
165
					__( '%s requests require a body as one of the parameters.', 'yikes-inc-easy-mailchimp-extender' ),
166
					'PUT'
167
				)
168
			);
169
		}
170
171
		return $this->send_request( $path, 'PUT', $headers, $params );
172
	}
173
174
	/**
175
	 * Send a request to the MailChimp API.
176
	 *
177
	 * @author Jeremy Pry
178
	 * @since  %VERSION%
179
	 *
180
	 * @param string $path    The relative path for the request.
181
	 * @param string $method  The method to use for the request.
182
	 * @param array  $headers Array of headers to send with the request.
183
	 * @param array  $params  An array of additional parameters to pass to the request. See WP_Http::request().
184
	 *
185
	 * @return array|WP_Error
186
	 */
187
	protected function send_request( $path, $method, $headers = array(), $params = array() ) {
188
189
		// Remove leading slashes from $path, as we'll add that ourselves later.
190
		$path = ltrim( $path, '/' );
191
192
		$args = $this->build_request_args( $path, $method, $headers, $params );
193
194
		/**
195
		 * Filter the URL used for a request to the MailChimp API.
196
		 *
197
		 * @since %VERSION%
198
		 *
199
		 * @param string $url  The URL to use.
200
		 * @param string $path The relative path for the request.
201
		 */
202
		$url = apply_filters( 'yikesinc_eme_api_url', sprintf( '%s/%s', $this->api_url, $path ), $path );
203
204
		return wp_remote_request( $url, $args );
205
	}
206
207
	/**
208
	 * Get the user agent to use with a request to the API.
209
	 *
210
	 * @author Jeremy Pry
211
	 * @since  %VERSION%
212
	 * @return string The user agent string.
213
	 */
214
	protected function get_user_agent() {
215
		global $wp_version;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
216
217
		$user_agent = 'WordPress/' . $wp_version . '; Yikes Easy MailChimp Extender; ' . get_bloginfo( 'url' );
218
		/**
219
		 * Filter the User Agent used in API requests.
220
		 *
221
		 * @since %VERSION%
222
		 *
223
		 * @param string $user_agent The user agent to send with API requests.
224
		 */
225
		$user_agent = apply_filters( 'yikesinc_eme_api_user_agent', $user_agent );
226
227
		return $user_agent;
228
	}
229
230
	/**
231
	 * Get the Auth Headers for an API requests.
232
	 *
233
	 * @author Jeremy Pry
234
	 * @since  %VERSION%
235
	 * @return array The array of auth headers for an API request.
236
	 */
237
	protected function get_auth_headers() {
238
		/*
239
		 * According to the MailChimp API docs, you can use any string you want, and the API
240
		 * key as the password. We're just going to use "yikesmailchimp" as the user.
241
		 */
242
		$user_pass    = base64_encode( "yikesmailchimp:{$this->api_key}" );
243
		$auth_headers = array(
244
			'Authorization' => "Basic {$user_pass}",
245
		);
246
247
		/**
248
		 * Filter the Auth Headers used for an API request.
249
		 *
250
		 * @since %VERSION%
251
		 *
252
		 * @param array  $auth_headers The array of auth headers for an API request.
253
		 * @param string $api_version  The version of the API being used.
254
		 */
255
		return apply_filters( 'yikesinc_eme_api_auth_headers', $auth_headers, $this->api_version );
256
	}
257
258
	/**
259
	 * Get a body array with authorization included.
260
	 *
261
	 * @author Jeremy Pry
262
	 * @return array
263
	 */
264
	protected function get_auth_body() {
265
		return array(
266
			'apikey' => $this->api_key,
267
		);
268
	}
269
270
	/**
271
	 * Build the arguments for the request.
272
	 *
273
	 * @author Jeremy Pry
274
	 * @since %VERSION%
275
	 *
276
	 * @param string $path    The relative path for the request.
277
	 * @param string $method  The method to use for the request.
278
	 * @param array  $headers Array of headers to send with the request.
279
	 * @param array  $params  An array of additional parameters to pass to the request. See WP_Http::request().
280
	 *
281
	 * @return array
282
	 */
283
	protected function build_request_args( $path, $method, $headers = array(), $params = array() ) {
284
		// Ensure our method is uppercase
285
		$method = strtoupper( $method );
286
287
		// Get the authorized array
288
		$authorized_args = $this->get_authorized_args();
289
290
		// If we have body data, maybe convert it to JSON.
291
		if ( isset( $params['body'] ) && ( is_array( $params['body'] ) || is_object( $params['body'] ) ) ) {
292
			$params['body']          = json_encode( wp_parse_args( $authorized_args['body'], $params['body'] ) );
293
			$headers['Content-Type'] = 'application/json';
294
		}
295
296
		// Combine the given headers and auth headers
297
		$headers = wp_parse_args( $authorized_args['headers'], $headers );
298
		/**
299
		 * Filter the headers used for a request to the MailChimp API.
300
		 *
301
		 * @since %VERSION%
302
		 *
303
		 * @param array  $headers The array of headers to send with the request.
304
		 * @param string $path    The relative path for the request.
305
		 * @param string $method  The method used for the request.
306
		 * @param array  $params  The array of additional parameters passed to the request.
307
		 */
308
		$headers = apply_filters( 'yikesinc_eme_api_headers', $headers, $path, $method, $params );
309
310
		// Build the args for the request.
311
		$args = array(
312
			'method'     => $method,
313
			'headers'    => $headers,
314
			'user-agent' => $this->get_user_agent(),
315
			/**
316
			 * Filter the timeout used when sending an API request.
317
			 *
318
			 * @since %VERSION%
319
			 *
320
			 * @param int $timeout The number of seconds after which the request will time out.
321
			 */
322
			'timeout'    => apply_filters( 'yikesinc_eme_api_timeout', 15 ),
323
			/**
324
			 * Filter whether our requests should verify the SSL certificate.
325
			 *
326
			 * @since %VERSION%
327
			 *
328
			 * @param bool $sslverify
329
			 */
330
			'sslverify'  => apply_filters( 'yikes-mailchimp-sslverify', true ),
331
		);
332
333
		/**
334
		 * Filter the args used for a request to the MailChimp API.
335
		 *
336
		 * @since %VERSION%
337
		 *
338
		 * @param array  $args   The arguments for the request.
339
		 * @param string $path   The relative path for the request.
340
		 * @param string $method The method used for the request.
341
		 * @param array  $params The array of additional params passed to the request.
342
		 */
343
		return apply_filters( 'yikesinc_eme_api_args', wp_parse_args( $params, $args ), $path, $method, $params );
344
	}
345
346
	/**
347
	 * Get an authorized request based on the API version.
348
	 *
349
	 * @author Jeremy Pry
350
	 * @since %VERSION%
351
	 * @return array
352
	 */
353
	protected function get_authorized_args() {
354
		$args = array(
355
			'body'    => array(),
356
			'headers' => array(),
357
		);
358
359
		// Version 2.0 uses body authorization
360
		if ( version_compare( '3.0', $this->api_version, '>' ) ) {
361
			$args['body'] = $this->get_auth_body();
362
		}
363
364
		// Version 3.0 uses authorization headers.
365
		if ( version_compare( '3.0', $this->api_version, '<=' ) ) {
366
			$args['headers'] = $this->get_auth_headers();
367
		}
368
369
		return $args;
370
	}
371
372
	/**
373
	 * Get the API version for this instance.
374
	 *
375
	 * @author Jeremy Pry
376
	 * @since %VERSION%
377
	 * @return string The API version.
378
	 */
379
	public function get_version() {
380
		return $this->api_version;
381
	}
382
}
383