MC4WP_API

Takes care of requests to the MailChimp API.

Defined (1)

The class is defined in the following location(s).

/includes/class-api.php  
  1. class MC4WP_API { 
  2.  
  3. /** 
  4. * @var string 
  5. */ 
  6. private $api_url = 'https://api.mailchimp.com/2.0/'; 
  7.  
  8. /** 
  9. * @var string 
  10. */ 
  11. private $api_key = ''; 
  12.  
  13. /** 
  14. * @var string 
  15. */ 
  16. protected $error_message = ''; 
  17.  
  18. /** 
  19. * @var int 
  20. */ 
  21. protected $error_code = 0; 
  22.  
  23. /** 
  24. * @var boolean 
  25. */ 
  26. private $connected = null; 
  27.  
  28. /** 
  29. * @var object The full response object of the latest API call 
  30. */ 
  31. private $last_response; 
  32.  
  33. /** 
  34. * Constructor 
  35. * @param string $api_key MailChimp API key 
  36. */ 
  37. public function __construct( $api_key ) { 
  38. $this->api_key = $api_key; 
  39.  
  40. $dash_position = strpos( $api_key, '-' ); 
  41. if( $dash_position !== false ) { 
  42. $this->api_url = 'https://' . substr( $api_key, $dash_position + 1 ) . '.api.mailchimp.com/2.0/'; 
  43.  
  44. /** 
  45. * Show an error message to administrators 
  46. * @param string $message 
  47. * @return bool 
  48. */ 
  49. private function show_error( $message ) { 
  50.  
  51. if( ! is_admin() || ! current_user_can( 'manage_options' ) ) { 
  52. return false; 
  53.  
  54. if( ! function_exists( 'add_settings_error' ) ) { 
  55. return false; 
  56.  
  57. add_settings_error( 'mc4wp-api', 'mc4wp-api-error', $message, 'error' ); 
  58. return true; 
  59.  
  60. /** 
  61. * Pings the MailChimp API 
  62. * Will store its result to ensure a maximum of 1 ping per page load 
  63. * @return boolean 
  64. */ 
  65. public function is_connected() { 
  66. if( $this->connected === null ) { 
  67.  
  68. $this->connected = false; 
  69. $result = $this->call( 'helper/ping' ); 
  70.  
  71. if( $result !== false ) { 
  72. if( isset( $result->msg ) && $result->msg === "Everything's Chimpy!" ) { 
  73. $this->connected = true; 
  74. } elseif( isset( $result->error ) ) { 
  75. $this->show_error( 'MailChimp Error: ' . $result->error ); 
  76.  
  77.  
  78. return $this->connected; 
  79.  
  80. /** 
  81. * Sends a subscription request to the MailChimp API 
  82. * @param string $list_id 
  83. * @param string $email 
  84. * @param array $merge_vars 
  85. * @param string $email_type 
  86. * @param boolean $double_optin 
  87. * @param boolean $update_existing 
  88. * @param boolean $replace_interests 
  89. * @param boolean $send_welcome 
  90. * @return boolean Successful? 
  91. */ 
  92. public function subscribe( $list_id, $email, array $merge_vars = array(), $email_type = 'html', $double_optin = true, $update_existing = false, $replace_interests = true, $send_welcome = false ) { 
  93. $data = array( 
  94. 'id' => $list_id,  
  95. 'email' => array( 'email' => $email),  
  96. 'merge_vars' => $merge_vars,  
  97. 'email_type' => $email_type,  
  98. 'double_optin' => $double_optin,  
  99. 'update_existing' => $update_existing,  
  100. 'replace_interests' => $replace_interests,  
  101. 'send_welcome' => $send_welcome,  
  102. ); 
  103.  
  104. $response = $this->call( 'lists/subscribe', $data ); 
  105.  
  106. if( is_object( $response ) && isset( $response->email ) ) { 
  107. return true; 
  108.  
  109. return false; 
  110.  
  111. /** 
  112. * Gets the Groupings for a given List 
  113. * @param string $list_id 
  114. * @return array|boolean 
  115. */ 
  116. public function get_list_groupings( $list_id ) { 
  117. $result = $this->call( 'lists/interest-groupings', array( 'id' => $list_id ) ); 
  118.  
  119. if( is_array( $result ) ) { 
  120. return $result; 
  121.  
  122. return false; 
  123.  
  124. /** 
  125. * @param array $list_ids Array of ID's of the lists to fetch. (optional) 
  126. * @return array|bool 
  127. */ 
  128. public function get_lists( $list_ids = array() ) { 
  129. $args = array( 
  130. 'limit' => 100,  
  131. 'sort_field' => 'web',  
  132. 'sort_dir' => 'ASC',  
  133. ); 
  134.  
  135. // set filter if the $list_ids parameter was set 
  136. if( count( $list_ids ) > 0 ) { 
  137. $args['filters'] = array( 
  138. 'list_id' => implode( ', ', $list_ids ),  
  139. ); 
  140.  
  141. $result = $this->call( 'lists/list', $args ); 
  142.  
  143. if( is_object( $result ) && isset( $result->data ) ) { 
  144. return $result->data; 
  145.  
  146. return false; 
  147.  
  148. /** 
  149. * Get lists with their merge_vars for a given array of list id's 
  150. * @param array $list_ids 
  151. * @return array|boolean 
  152. */ 
  153. public function get_lists_with_merge_vars( $list_ids ) { 
  154. $result = $this->call( 'lists/merge-vars', array('id' => $list_ids ) ); 
  155.  
  156. if( is_object( $result ) && isset( $result->data ) ) { 
  157. return $result->data; 
  158.  
  159. return false; 
  160.  
  161. /** 
  162. * Gets the member info for one or multiple emails on a list 
  163. * @param string $list_id 
  164. * @param array $emails 
  165. * @return array|bool 
  166. */ 
  167. public function get_subscriber_info( $list_id, $emails ) { 
  168. $result = $this->call( 'lists/member-info', array( 
  169. 'id' => $list_id,  
  170. 'emails' => $emails,  
  171. ); 
  172.  
  173. if( is_object( $result ) && isset( $result->data ) ) { 
  174. return $result->data; 
  175.  
  176. return false; 
  177.  
  178. /** 
  179. * @param $list_id 
  180. * @param array|string $email 
  181. * @param array $merge_vars 
  182. * @param string $email_type 
  183. * @param bool $replace_interests 
  184. * @return bool 
  185. */ 
  186. public function update_subscriber( $list_id, $email, $merge_vars = array(), $email_type = 'html', $replace_interests = false ) { 
  187.  
  188. // default to using email for updating 
  189. if( ! is_array( $email ) ) { 
  190. $email = array( 
  191. 'email' => $email,  
  192. ); 
  193.  
  194. $result = $this->call( 'lists/update-member', array( 
  195. 'id' => $list_id,  
  196. 'email' => $email,  
  197. 'merge_vars' => $merge_vars,  
  198. 'email_type' => $email_type,  
  199. 'replace_interests' => $replace_interests,  
  200. ); 
  201.  
  202. if( is_object( $result ) ) { 
  203.  
  204. if( isset( $result->error ) ) { 
  205. return false; 
  206. } else { 
  207. return true; 
  208.  
  209.  
  210. return false; 
  211.  
  212. /** 
  213. * Checks if an email address is on a given list 
  214. * @param string $list_id 
  215. * @param string $email 
  216. * @return boolean 
  217. */ 
  218. public function list_has_subscriber( $list_id, $email ) { 
  219. $member_info = $this->get_subscriber_info( $list_id, array( array( 'email' => $email ) ) ); 
  220.  
  221. if( is_array( $member_info ) && isset( $member_info[0] ) ) { 
  222. return ( $member_info[0]->status === 'subscribed' ); 
  223.  
  224. return false; 
  225.  
  226. /** 
  227. * Unsubscribes the given email or luid from the given MailChimp list 
  228. * @param string $list_id 
  229. * @param array|string $struct 
  230. * @param bool $delete_member 
  231. * @param bool $send_goodbye 
  232. * @param bool $send_notification 
  233. * @return bool 
  234. */ 
  235. public function unsubscribe( $list_id, $struct, $send_goodbye = true, $send_notification = false, $delete_member = false ) { 
  236.  
  237. if( ! is_array( $struct ) ) { 
  238. // assume $struct is an email 
  239. $struct = array( 
  240. 'email' => $struct,  
  241. ); 
  242.  
  243. $response = $this->call( 'lists/unsubscribe', array( 
  244. 'id' => $list_id,  
  245. 'email' => $struct,  
  246. 'delete_member' => $delete_member,  
  247. 'send_goodbye' => $send_goodbye,  
  248. 'send_notify' => $send_notification,  
  249. ); 
  250.  
  251. if( is_object( $response ) ) { 
  252. if ( isset( $response->complete ) && $response->complete ) { 
  253. return true; 
  254.  
  255. return false; 
  256.  
  257. /** 
  258. * Calls the MailChimp API 
  259. * @uses WP_HTTP 
  260. * @param string $method 
  261. * @param array $data 
  262. * @return object 
  263. */ 
  264. public function call( $method, array $data = array() ) { 
  265.  
  266. $this->empty_last_response(); 
  267.  
  268. // do not make request when no api key was provided. 
  269. if( empty( $this->api_key ) ) { 
  270. return false; 
  271.  
  272. $data['apikey'] = $this->api_key; 
  273. $url = $this->api_url . $method . '.json'; 
  274.  
  275. $response = wp_remote_post( $url, array( 
  276. 'body' => $data,  
  277. 'timeout' => 10,  
  278. 'headers' => $this->get_headers() 
  279. ); 
  280.  
  281. // test for wp errors 
  282. if( is_wp_error( $response ) ) { 
  283. // show error message to admins 
  284. $this->show_error( 'HTTP Error: ' . $response->get_error_message() ); 
  285. return false; 
  286.  
  287. // dirty fix for older WP versions 
  288. if( $method === 'helper/ping' && is_array( $response ) && isset( $response['headers']['content-length'] ) && (int) $response['headers']['content-length'] === 44 ) { 
  289. return (object) array( 
  290. 'msg' => "Everything's Chimpy!",  
  291. ); 
  292.  
  293. $body = wp_remote_retrieve_body( $response ); 
  294. $response = json_decode( $body ); 
  295.  
  296. // store response 
  297. if( is_object( $response ) ) { 
  298. $this->last_response = $response; 
  299.  
  300. if( isset( $response->error ) ) { 
  301. $this->error_message = $response->error; 
  302.  
  303. if( isset( $response->code ) ) { 
  304. $this->error_code = (int) $response->code; 
  305.  
  306. return $response; 
  307.  
  308. /** 
  309. * Checks if an error occurred in the most recent API request 
  310. * @return bool 
  311. */ 
  312. public function has_error() { 
  313. return ( ! empty( $this->error_message ) ); 
  314.  
  315. /** 
  316. * Get the most recent error message 
  317. * @return string 
  318. */ 
  319. public function get_error_message() { 
  320. return $this->error_message; 
  321.  
  322. /** 
  323. * Gets the most recent error code 
  324. * @return int 
  325. */ 
  326. public function get_error_code() { 
  327. return $this->error_code; 
  328.  
  329. /** 
  330. * Get the most recent response object 
  331. * @return object 
  332. */ 
  333. public function get_last_response() { 
  334. return $this->last_response; 
  335.  
  336. /** 
  337. * Empties all data from previous response 
  338. */ 
  339. private function empty_last_response() { 
  340. $this->last_response = null; 
  341. $this->error_code = 0; 
  342. $this->error_message = ''; 
  343.  
  344. /** 
  345. * Get the request headers to send to the MailChimp API 
  346. * @return array 
  347. */ 
  348. private function get_headers() { 
  349.  
  350. $headers = array( 
  351. 'Accept-Encoding' => '' 
  352. ); 
  353.  
  354. // Copy Accept-Language from browser headers 
  355. if( isset( $_SERVER['HTTP_ACCEPT_LANGUAGE'] ) ) { 
  356. $headers['Accept-Language'] = $_SERVER['HTTP_ACCEPT_LANGUAGE']; 
  357.  
  358. return $headers; 
  359.