/wp-content/plugins/mailchimp-for-wp/includes/api/class-api.php
PHP | 578 lines | 294 code | 92 blank | 192 comment | 55 complexity | 2e1bc54c76038e5e8c20e701a175283d MD5 | raw file
- <?php
- /**
- * Takes care of requests to the Mailchimp API (version 2.0, deprecated)
- *
- * @access public
- * @uses WP_HTTP
- * @since 1.0
- * @deprecated 4.0
- */
- class MC4WP_API {
- /**
- * @var string The URL to the Mailchimp API
- */
- protected $api_url = 'https://api.mailchimp.com/2.0/';
- /**
- * @var string The API key to use
- */
- protected $api_key = '';
- /**
- * @var string The error message of the latest API request (if any)
- */
- protected $error_message = '';
- /**
- * @var int The error code of the last API request (if any)
- */
- protected $error_code = 0;
- /**
- * @var boolean Boolean indicating whether the user is connected with Mailchimp
- */
- protected $connected;
- /**
- * @var object The full response object of the latest API call
- */
- protected $last_response;
- /**
- * Constructor
- *
- * @param string $api_key
- */
- public function __construct( $api_key ) {
- $this->api_key = $api_key;
- $dash_position = strpos( $api_key, '-' );
- if ( $dash_position !== false ) {
- $this->api_url = 'https://' . substr( $api_key, $dash_position + 1 ) . '.api.mailchimp.com/2.0/';
- }
- }
- /**
- * Show an error message to administrators
- *
- * @param string $message
- *
- * @return bool
- */
- private function show_error( $message ) {
- if ( ! is_admin() || ! current_user_can( 'manage_options' ) ) {
- return false;
- }
- if ( ! function_exists( 'add_settings_error' ) ) {
- return false;
- }
- add_settings_error( 'mc4wp-api', 'mc4wp-api-error', $message, 'error' );
- return true;
- }
- /**
- * @param $message
- *
- * @return bool
- */
- private function show_connection_error( $message ) {
- $message .= '<br /><br />' . sprintf( '<a href="%s">' . __( 'Read more about common connectivity issues.', 'mailchimp-for-wp' ) . '</a>', 'https://www.mc4wp.com/kb/solving-connectivity-issues/#utm_source=wp-plugin&utm_medium=mailchimp-for-wp&utm_campaign=settings-notice' );
- return $this->show_error( $message );
- }
- /**
- * Pings the Mailchimp API to see if we're connected
- *
- * The result is cached to ensure a maximum of 1 API call per page load
- *
- * @return boolean
- */
- public function is_connected() {
- if ( is_bool( $this->connected ) ) {
- return $this->connected;
- }
- $result = $this->call( 'helper/ping' );
- $this->connected = false;
- if ( is_object( $result ) ) {
- // Msg key set? All good then!
- if ( ! empty( $result->msg ) ) {
- $this->connected = true;
- return true;
- }
- // Uh oh. We got an error back.
- if ( isset( $result->error ) ) {
- $this->show_error( 'Mailchimp Error: ' . $result->error );
- }
- }
- return $this->connected;
- }
- /**
- * Sends a subscription request to the Mailchimp API
- *
- * @param string $list_id The list id to subscribe to
- * @param string $email The email address to subscribe
- * @param array $merge_vars Array of extra merge variables
- * @param string $email_type The email type to send to this email address. Possible values are `html` and `text`.
- * @param boolean $double_optin Should this email be confirmed via double opt-in?
- * @param boolean $update_existing Update information if this email is already on list?
- * @param boolean $replace_interests Replace interest groupings, only if update_existing is true.
- * @param boolean $send_welcome Send a welcome e-mail, only if double_optin is false.
- *
- * @return boolean|string True if success, 'error' if error
- */
- 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 ) {
- $data = array(
- 'id' => $list_id,
- 'email' => array( 'email' => $email ),
- 'merge_vars' => $merge_vars,
- 'email_type' => $email_type,
- 'double_optin' => $double_optin,
- 'update_existing' => $update_existing,
- 'replace_interests' => $replace_interests,
- 'send_welcome' => $send_welcome,
- );
- $response = $this->call( 'lists/subscribe', $data );
- if ( is_object( $response ) && isset( $response->email ) ) {
- return true;
- }
- return false;
- }
- /**
- * Gets the Groupings for a given List
- * @param int $list_id
- * @return array|boolean
- */
- public function get_list_groupings( $list_id ) {
- $result = $this->call( 'lists/interest-groupings', array( 'id' => $list_id ) );
- if ( is_array( $result ) ) {
- return $result;
- }
- return false;
- }
- /**
- * @param array $list_ids Array of ID's of the lists to fetch. (optional)
- *
- * @return bool
- */
- public function get_lists( $list_ids = array() ) {
- $args = array(
- 'limit' => 100,
- 'sort_field' => 'web',
- 'sort_dir' => 'ASC',
- );
- // set filter if the $list_ids parameter was set
- if ( count( $list_ids ) > 0 ) {
- $args['filters'] = array(
- 'list_id' => implode( ',', $list_ids ),
- );
- }
- $result = $this->call( 'lists/list', $args );
- if ( is_object( $result ) && isset( $result->data ) ) {
- return $result->data;
- }
- return false;
- }
- /**
- * Get the lists an email address is subscribed to
- *
- * @param array|string $email
- *
- * @return array
- */
- public function get_lists_for_email( $email ) {
- if ( is_string( $email ) ) {
- $email = array(
- 'email' => $email,
- );
- }
- $result = $this->call( 'helper/lists-for-email', array( 'email' => $email ) );
- if ( ! is_array( $result ) ) {
- return array();
- }
- return $result;
- }
- /**
- * Get lists with their merge_vars for a given array of list id's
- * @param array $list_ids
- * @return array|bool
- */
- public function get_lists_with_merge_vars( $list_ids ) {
- $result = $this->call( 'lists/merge-vars', array( 'id' => $list_ids ) );
- if ( is_object( $result ) && isset( $result->data ) ) {
- return $result->data;
- }
- return false;
- }
- /**
- * Gets the member info for one or multiple emails on a list
- *
- * @param string $list_id
- * @param array $emails
- * @return array|bool
- */
- public function get_subscriber_info( $list_id, $emails ) {
- if ( is_string( $emails ) ) {
- $emails = array( $emails );
- }
- $result = $this->call(
- 'lists/member-info',
- array(
- 'id' => $list_id,
- 'emails' => $emails,
- )
- );
- if ( is_object( $result ) && isset( $result->data ) ) {
- return $result->data;
- }
- return false;
- }
- /**
- * Checks if an email address is on a given list
- *
- * @param string $list_id
- * @param string $email
- * @return bool
- */
- public function list_has_subscriber( $list_id, $email ) {
- $member_info = $this->get_subscriber_info( $list_id, array( array( 'email' => $email ) ) );
- if ( is_array( $member_info ) && isset( $member_info[0] ) ) {
- return ( $member_info[0]->status === 'subscribed' );
- }
- return false;
- }
- /**
- * @param string $list_id
- * @param array|string $email
- * @param array $merge_vars
- * @param string $email_type
- * @param bool $replace_interests
- *
- * @return bool
- */
- public function update_subscriber( $list_id, $email, $merge_vars = array(), $email_type = 'html', $replace_interests = false ) {
- // default to using email for updating
- if ( is_string( $email ) ) {
- $email = array(
- 'email' => $email,
- );
- }
- $result = $this->call(
- 'lists/update-member',
- array(
- 'id' => $list_id,
- 'email' => $email,
- 'merge_vars' => $merge_vars,
- 'email_type' => $email_type,
- 'replace_interests' => $replace_interests,
- )
- );
- if ( is_object( $result ) ) {
- if ( isset( $result->error ) ) {
- return false;
- } else {
- return true;
- }
- }
- return false;
- }
- /**
- * Unsubscribes the given email or luid from the given Mailchimp list
- *
- * @param string $list_id
- * @param array|string $struct
- * @param bool $delete_member
- * @param bool $send_goodbye
- * @param bool $send_notification
- *
- * @return bool
- */
- public function unsubscribe( $list_id, $struct, $send_goodbye = true, $send_notification = false, $delete_member = false ) {
- if ( ! is_array( $struct ) ) {
- // assume $struct is an email
- $struct = array(
- 'email' => $struct,
- );
- }
- $response = $this->call(
- 'lists/unsubscribe',
- array(
- 'id' => $list_id,
- 'email' => $struct,
- 'delete_member' => $delete_member,
- 'send_goodbye' => $send_goodbye,
- 'send_notify' => $send_notification,
- )
- );
- if ( is_object( $response ) ) {
- if ( isset( $response->complete ) && $response->complete ) {
- return true;
- }
- }
- return false;
- }
- /**
- * @see https://apidocs.mailchimp.com/api/2.0/ecomm/order-add.php
- *
- * @param array $order_data
- *
- * @return boolean
- */
- public function add_ecommerce_order( array $order_data ) {
- $response = $this->call( 'ecomm/order-add', array( 'order' => $order_data ) );
- if ( is_object( $response ) ) {
- // complete means success
- if ( isset( $response->complete ) && $response->complete ) {
- return true;
- }
- // if order was already added: great
- if ( isset( $response->code, $response->error ) && $response->code == 330 && strpos( $response->error, 'already been recorded' ) !== false ) {
- return true;
- }
- }
- return false;
- }
- /**
- * @see https://apidocs.mailchimp.com/api/2.0/ecomm/order-del.php
- *
- * @param string $store_id
- * @param string $order_id
- *
- * @return bool
- */
- public function delete_ecommerce_order( $store_id, $order_id ) {
- $data = array(
- 'store_id' => $store_id,
- 'order_id' => $order_id,
- );
- $response = $this->call( 'ecomm/order-del', $data );
- if ( is_object( $response ) ) {
- if ( isset( $response->complete ) && $response->complete ) {
- return true;
- }
- // Invalid order (order not existing). Good!
- if ( isset( $response->code ) && $response->code == 330 ) {
- return true;
- }
- }
- return false;
- }
- /**
- * Calls the Mailchimp API
- *
- * @uses WP_HTTP
- *
- * @param string $method
- * @param array $data
- *
- * @return object|bool
- */
- public function call( $method, array $data = array() ) {
- $this->empty_last_response();
- // do not make request when no api key was provided.
- if ( empty( $this->api_key ) ) {
- $this->error_message = 'Missing Mailchimp API key.';
- $this->error_code = 001;
- return false;
- }
- // do not make request if helper/ping failed already
- if ( $this->connected === false ) {
- return false;
- }
- $data['apikey'] = $this->api_key;
- $url = $this->api_url . $method . '.json';
- $request_args = array(
- 'body' => $data,
- 'timeout' => 10,
- 'headers' => $this->get_headers(),
- 'sslverify' => apply_filters( 'mc4wp_use_sslverify', true ),
- );
- $response = wp_remote_post( $url, $request_args );
- try {
- $response = $this->parse_response( $response );
- } catch ( Exception $e ) {
- $this->error_code = $e->getCode();
- $this->error_message = $e->getMessage();
- $this->show_connection_error( $e->getMessage() );
- return false;
- }
- // store response
- $this->last_response = $response;
- // store error (if any)
- if ( is_object( $response ) ) {
- if ( ! empty( $response->error ) ) {
- $this->error_message = $response->error;
- }
- // store error code (if any)
- if ( ! empty( $response->code ) ) {
- $this->error_code = (int) $response->code;
- }
- }
- return $response;
- }
- /**
- * Checks if an error occured in the most recent request
- * @return boolean
- */
- public function has_error() {
- return ( ! empty( $this->error_message ) );
- }
- /**
- * Gets the most recent error message
- * @return string
- */
- public function get_error_message() {
- return $this->error_message;
- }
- /**
- * Gets the most recent error code
- *
- * @return int
- */
- public function get_error_code() {
- return $this->error_code;
- }
- /**
- * Get the most recent response object
- *
- * @return object
- */
- public function get_last_response() {
- return $this->last_response;
- }
- /**
- * Empties all data from previous response
- */
- private function empty_last_response() {
- $this->last_response = null;
- $this->error_code = 0;
- $this->error_message = '';
- }
- /**
- * Get the request headers to send to the Mailchimp API
- *
- * @return array
- */
- private function get_headers() {
- global $wp_version;
- $headers = array(
- 'Accept' => 'application/json',
- 'User-Agent' => 'mc4wp/' . MC4WP_VERSION . '; WordPress/' . $wp_version . '; ' . get_bloginfo( 'url' ),
- );
- // Copy Accept-Language from browser headers
- if ( ! empty( $_SERVER['HTTP_ACCEPT_LANGUAGE'] ) ) {
- $headers['Accept-Language'] = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
- }
- return $headers;
- }
- /**
- * @param array|WP_Error $response
- * @return object
- * @throws Exception
- */
- private function parse_response( $response ) {
- if ( is_wp_error( $response ) ) {
- throw new Exception( 'Error connecting to Mailchimp. ' . $response->get_error_message(), (int) $response->get_error_code() );
- }
- // decode response body
- $body = wp_remote_retrieve_body( $response );
- $data = json_decode( $body );
- if ( ! is_null( $data ) ) {
- return $data;
- }
- $code = (int) wp_remote_retrieve_response_code( $response );
- $message = wp_remote_retrieve_response_message( $response );
- if ( $code !== 200 ) {
- $message = sprintf( 'The Mailchimp API server returned the following response: <em>%s %s</em>.', $code, $message );
- // check for Akamai firewall response
- if ( $code === 403 ) {
- preg_match( '/Reference (.*)/i', $body, $matches );
- if ( ! empty( $matches[1] ) ) {
- $message .= '</strong><br /><br />' . sprintf( 'This usually means that your server is blacklisted by Mailchimp\'s firewall. Please contact Mailchimp support with the following reference number: %s </strong>', $matches[1] );
- }
- }
- }
- throw new Exception( $message, $code );
- }
- }