/includes/api/class-yikes-inc-easy-mailchimp-api.php

https://github.com/yikesinc/yikes-inc-easy-mailchimp-extender · PHP · 383 lines · 114 code · 36 blank · 233 comment · 8 complexity · 5eb3036ccb17076b372b408bc1776a4b MD5 · raw file

  1. <?php
  2. /**
  3. * A class to handle requests to the Mailchimp API.
  4. *
  5. * @author Jeremy Pry
  6. * @since 6.3.0
  7. */
  8. class Yikes_Inc_Easy_Mailchimp_API {
  9. /**
  10. * The API key.
  11. *
  12. * @since 6.3.0
  13. * @var string
  14. */
  15. protected $api_key = '';
  16. /**
  17. * The URL for the API.
  18. *
  19. * @since 6.3.0
  20. * @var string
  21. */
  22. protected $api_url = '';
  23. /**
  24. * The API version.
  25. *
  26. * @since 6.3.0
  27. * @var string
  28. */
  29. protected $api_version = '';
  30. /**
  31. * The datacenter where the Mailchimp account is located.
  32. *
  33. * This is typically part of the API Key.
  34. *
  35. * @since 6.3.0
  36. * @var string
  37. */
  38. protected $datacenter = '';
  39. /**
  40. * Yikes_Inc_Easy_Mailchimp_API constructor.
  41. *
  42. * @since 6.3.0
  43. *
  44. * @param string $datacenter The datacenter string where the Mailchimp account is located.
  45. * @param string $api_key The base API key, without the datacenter appended.
  46. * @param string $api_version The API version to use.
  47. */
  48. public function __construct( $datacenter, $api_key, $api_version ) {
  49. $this->datacenter = $datacenter;
  50. $this->api_key = $api_key;
  51. $this->api_version = $api_version;
  52. $this->api_url = "https://{$this->datacenter}.api.mailchimp.com/{$this->api_version}";
  53. }
  54. /**
  55. * Send a DELETE request to the Mailchimp API.
  56. *
  57. * @author Jeremy Pry
  58. * @since 6.3.0
  59. *
  60. * @param string $path The relative path for the request.
  61. * @param array $headers Array of headers to send with the request.
  62. * @param array $params An array of additional parameters to pass to the request. See WP_Http::request().
  63. *
  64. * @return array|WP_Error
  65. */
  66. public function delete( $path = '', $headers = array(), $params = array() ) {
  67. return $this->send_request( $path, 'DELETE', $headers, $params );
  68. }
  69. /**
  70. * Send a GET request to the Mailchimp API.
  71. *
  72. * @author Jeremy Pry
  73. * @since 6.3.0
  74. *
  75. * @param string $path The relative path for the request.
  76. * @param array $headers Array of headers to send with the request.
  77. * @param array $params An array of additional parameters to pass to the request. See WP_Http::request().
  78. *
  79. * @return array|WP_Error
  80. */
  81. public function get( $path = '', $headers = array(), $params = array() ) {
  82. return $this->send_request( $path, 'GET', $headers, $params );
  83. }
  84. /**
  85. * Send a PATCH request to the Mailchimp API.
  86. *
  87. * @author Jeremy Pry
  88. * @since 6.3.0
  89. *
  90. * @param string $path The relative path for the request.
  91. * @param array $headers Array of headers to send with the request.
  92. * @param array $params An array of additional parameters to pass to the request. See WP_Http::request().
  93. *
  94. * @return array|WP_Error
  95. */
  96. public function patch( $path = '', $headers = array(), $params = array() ) {
  97. if ( ! isset( $params['body'] ) ) {
  98. return new WP_Error(
  99. 'yikesinc_eme_missing_body',
  100. sprintf(
  101. /* translators: %s refers to the request method. */
  102. __( '%s requests require a body as one of the parameters.', 'yikes-inc-easy-mailchimp-extender' ),
  103. 'PATCH'
  104. )
  105. );
  106. }
  107. return $this->send_request( $path, 'PATCH', $headers, $params );
  108. }
  109. /**
  110. * Send a POST request to the Mailchimp API.
  111. *
  112. * @author Jeremy Pry
  113. * @since 6.3.0
  114. *
  115. * @param string $path The relative path for the request.
  116. * @param array $headers Array of headers to send with the request.
  117. * @param array $params An array of additional parameters to pass to the request. See WP_Http::request().
  118. *
  119. * @return array|WP_Error
  120. */
  121. public function post( $path = '', $headers = array(), $params = array() ) {
  122. if ( ! isset( $params['body'] ) ) {
  123. return new WP_Error(
  124. 'yikesinc_eme_missing_body',
  125. sprintf(
  126. /* translators: %s refers to the request method. */
  127. __( '%s requests require a body as one of the parameters.', 'yikes-inc-easy-mailchimp-extender' ),
  128. 'POST'
  129. )
  130. );
  131. }
  132. return $this->send_request( $path, 'POST', $headers, $params );
  133. }
  134. /**
  135. * Send a PUT request to the Mailchimp API.
  136. *
  137. * @author Jeremy Pry
  138. * @since 6.3.0
  139. *
  140. * @param string $path The relative path for the request.
  141. * @param array $headers Array of headers to send with the request.
  142. * @param array $params An array of additional parameters to pass to the request. See WP_Http::request().
  143. *
  144. * @return array|WP_Error
  145. */
  146. public function put( $path = '', $headers = array(), $params = array() ) {
  147. if ( ! isset( $params['body'] ) ) {
  148. return new WP_Error(
  149. 'yikesinc_eme_missing_body',
  150. sprintf(
  151. /* translators: %s refers to the request method. */
  152. __( '%s requests require a body as one of the parameters.', 'yikes-inc-easy-mailchimp-extender' ),
  153. 'PUT'
  154. )
  155. );
  156. }
  157. return $this->send_request( $path, 'PUT', $headers, $params );
  158. }
  159. /**
  160. * Send a request to the Mailchimp API.
  161. *
  162. * @author Jeremy Pry
  163. * @since 6.3.0
  164. *
  165. * @param string $path The relative path for the request.
  166. * @param string $method The method to use for the request.
  167. * @param array $headers Array of headers to send with the request.
  168. * @param array $params An array of additional parameters to pass to the request. See WP_Http::request().
  169. *
  170. * @return array|WP_Error
  171. */
  172. protected function send_request( $path, $method, $headers = array(), $params = array() ) {
  173. $headers = apply_filters( 'yikesinc_eme_mailchimp_headers', $headers );
  174. // Remove leading slashes from $path, as we'll add that ourselves later.
  175. $path = ltrim( $path, '/' );
  176. $args = $this->build_request_args( $path, $method, $headers, $params );
  177. /**
  178. * Filter the URL used for a request to the Mailchimp API.
  179. *
  180. * @since 6.3.0
  181. *
  182. * @param string $url The URL to use.
  183. * @param string $path The relative path for the request.
  184. */
  185. $url = apply_filters( 'yikesinc_eme_api_url', sprintf( '%s/%s', $this->api_url, $path ), $path );
  186. return wp_remote_request( $url, $args );
  187. }
  188. /**
  189. * Get the user agent to use with a request to the API.
  190. *
  191. * @author Jeremy Pry
  192. * @since 6.3.0
  193. * @return string The user agent string.
  194. */
  195. protected function get_user_agent() {
  196. global $wp_version;
  197. $user_agent = 'WordPress/' . $wp_version . '; Yikes Easy Mailchimp Extender; ' . get_bloginfo( 'url' );
  198. /**
  199. * Filter the User Agent used in API requests.
  200. *
  201. * @since 6.3.0
  202. *
  203. * @param string $user_agent The user agent to send with API requests.
  204. */
  205. $user_agent = apply_filters( 'yikesinc_eme_api_user_agent', $user_agent );
  206. return $user_agent;
  207. }
  208. /**
  209. * Get the Auth Headers for an API requests.
  210. *
  211. * @author Jeremy Pry
  212. * @since 6.3.0
  213. * @return array The array of auth headers for an API request.
  214. */
  215. protected function get_auth_headers() {
  216. /*
  217. * According to the Mailchimp API docs, you can use any string you want, and the API
  218. * key as the password. We're just going to use "yikesmailchimp" as the user.
  219. */
  220. $user_pass = base64_encode( "yikesmailchimp:{$this->api_key}" );
  221. $auth_headers = array(
  222. 'Authorization' => "Basic {$user_pass}",
  223. );
  224. /**
  225. * Filter the Auth Headers used for an API request.
  226. *
  227. * @since 6.3.0
  228. *
  229. * @param array $auth_headers The array of auth headers for an API request.
  230. * @param string $api_version The version of the API being used.
  231. */
  232. return apply_filters( 'yikesinc_eme_api_auth_headers', $auth_headers, $this->api_version );
  233. }
  234. /**
  235. * Get a body array with authorization included.
  236. *
  237. * @author Jeremy Pry
  238. * @return array
  239. */
  240. protected function get_auth_body() {
  241. return array(
  242. 'apikey' => $this->api_key,
  243. );
  244. }
  245. /**
  246. * Build the arguments for the request.
  247. *
  248. * @author Jeremy Pry
  249. * @since 6.3.0
  250. *
  251. * @param string $path The relative path for the request.
  252. * @param string $method The method to use for the request.
  253. * @param array $headers Array of headers to send with the request.
  254. * @param array $params An array of additional parameters to pass to the request. See WP_Http::request().
  255. *
  256. * @return array
  257. */
  258. protected function build_request_args( $path, $method, $headers = array(), $params = array() ) {
  259. // Ensure our method is uppercase
  260. $method = strtoupper( $method );
  261. // Get the authorized array
  262. $authorized_args = $this->get_authorized_args();
  263. // If we have body data, maybe convert it to JSON.
  264. if ( isset( $params['body'] ) && ( is_array( $params['body'] ) || is_object( $params['body'] ) ) ) {
  265. $params['body'] = json_encode( wp_parse_args( $authorized_args['body'], $params['body'] ) );
  266. $headers['Content-Type'] = 'application/json';
  267. }
  268. // Combine the given headers and auth headers
  269. $headers = wp_parse_args( $authorized_args['headers'], $headers );
  270. /**
  271. * Filter the headers used for a request to the Mailchimp API.
  272. *
  273. * @since 6.3.0
  274. *
  275. * @param array $headers The array of headers to send with the request.
  276. * @param string $path The relative path for the request.
  277. * @param string $method The method used for the request.
  278. * @param array $params The array of additional parameters passed to the request.
  279. */
  280. $headers = apply_filters( 'yikesinc_eme_api_headers', $headers, $path, $method, $params );
  281. // Build the args for the request.
  282. $args = array(
  283. 'method' => $method,
  284. 'headers' => $headers,
  285. 'user-agent' => $this->get_user_agent(),
  286. /**
  287. * Filter the timeout used when sending an API request.
  288. *
  289. * @since 6.3.0
  290. *
  291. * @param int $timeout The number of seconds after which the request will time out.
  292. */
  293. 'timeout' => apply_filters( 'yikesinc_eme_api_timeout', 15 ),
  294. /**
  295. * Filter whether our requests should verify the SSL certificate.
  296. *
  297. * @since 6.3.0
  298. *
  299. * @param bool $sslverify
  300. */
  301. 'sslverify' => apply_filters( 'yikes-mailchimp-sslverify', true ),
  302. );
  303. /**
  304. * Filter the args used for a request to the Mailchimp API.
  305. *
  306. * @since 6.3.0
  307. *
  308. * @param array $args The arguments for the request.
  309. * @param string $path The relative path for the request.
  310. * @param string $method The method used for the request.
  311. * @param array $params The array of additional params passed to the request.
  312. */
  313. return apply_filters( 'yikesinc_eme_api_args', wp_parse_args( $params, $args ), $path, $method, $params );
  314. }
  315. /**
  316. * Get an authorized request based on the API version.
  317. *
  318. * @author Jeremy Pry
  319. * @since 6.3.0
  320. * @return array
  321. */
  322. protected function get_authorized_args() {
  323. $args = array(
  324. 'body' => array(),
  325. 'headers' => array(),
  326. );
  327. // Version 2.0 uses body authorization
  328. if ( version_compare( '3.0', $this->api_version, '>' ) ) {
  329. $args['body'] = $this->get_auth_body();
  330. }
  331. // Version 3.0 uses authorization headers.
  332. if ( version_compare( '3.0', $this->api_version, '<=' ) ) {
  333. $args['headers'] = $this->get_auth_headers();
  334. }
  335. return $args;
  336. }
  337. /**
  338. * Get the API version for this instance.
  339. *
  340. * @author Jeremy Pry
  341. * @since 6.3.0
  342. * @return string The API version.
  343. */
  344. public function get_version() {
  345. return $this->api_version;
  346. }
  347. }