Current File : /home/aventura/www/site/wp-content/plugins/mailchimp-for-wp/includes/class-mailchimp.php |
<?php
/**
* Class MC4WP_MailChimp
*
* @access private
* @ignore
*/
class MC4WP_MailChimp {
/**
* @var string
*/
public $error_code = '';
/**
* @var string
*/
public $error_message = '';
/**
*
* Sends a subscription request to the MailChimp API
*
* @param string $list_id The list id to subscribe to
* @param string $email_address The email address to subscribe
* @param array $args
* @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.
*
* @return object
*/
public function list_subscribe( $list_id, $email_address, array $args = array(), $update_existing = false, $replace_interests = true ) {
$this->reset_error();
$default_args = array(
'status' => 'pending',
'email_address' => $email_address,
'interests' => array(),
'merge_fields' => array(),
);
$already_on_list = false;
// setup default args
$args = $args + $default_args;
// first, check if subscriber is already on the given list
try {
$existing_member_data = $this->get_api()->get_list_member( $list_id, $email_address );
if( $existing_member_data->status === 'subscribed' ) {
$already_on_list = true;
// if we're not supposed to update, bail.
if( ! $update_existing ) {
$this->error_code = 214;
$this->error_message = 'That subscriber already exists.';
return null;
}
$args['status'] = 'subscribed';
// this key only exists if list actually has interests
if( isset( $existing_member_data->interests ) ) {
$existing_interests = (array) $existing_member_data->interests;
// if replace, assume all existing interests disabled
if( $replace_interests ) {
$existing_interests = array_fill_keys( array_keys( $existing_interests ), false );
}
// TODO: Use array_replace here (PHP 5.3+)
$new_interests = $args['interests'];
$args['interests'] = $existing_interests;
foreach( $new_interests as $interest_id => $interest_status ) {
$args['interests']["{$interest_id}"] = $interest_status;
}
}
} else if( $args['status'] === 'pending' && $existing_member_data->status === 'pending' ) {
// if status is "pending", delete & then re-subscribe
// this ensures that a new double opt-in email is send out
$this->get_api()->delete_list_member( $list_id, $email_address );
}
} catch( MC4WP_API_Resource_Not_Found_Exception $e ) {
// subscriber does not exist (not an issue in this case)
} catch( MC4WP_API_Exception $e ) {
// other errors.
$this->error_code = $e->getCode();
$this->error_message = $e;
return null;
}
try {
$data = $this->get_api()->add_list_member( $list_id, $args );
} catch ( MC4WP_API_Exception $e ) {
$this->error_code = $e->getCode();
$this->error_message = $e;
return null;
}
$data->was_already_on_list = $already_on_list;
return $data;
}
/**
* Changes the subscriber status to "unsubscribed"
*
* @param string $list_id
* @param string $email_address
*
* @return boolean
*/
public function list_unsubscribe( $list_id, $email_address ) {
$this->reset_error();
try {
$this->get_api()->update_list_member( $list_id, $email_address, array( 'status' => 'unsubscribed' ) );
} catch( MC4WP_API_Resource_Not_Found_Exception $e ) {
// if email wasn't even on the list: great.
return true;
} catch( MC4WP_API_Exception $e ) {
$this->error_code = $e->getCode();
$this->error_message = $e;
return false;
}
return true;
}
/**
* Deletes the subscriber from the given list.
*
* @param string $list_id
* @param string $email_address
*
* @return boolean
*/
public function list_unsubscribe_delete( $list_id, $email_address ) {
$this->reset_error();
try {
$this->get_api()->delete_list_member( $list_id, $email_address );
} catch( MC4WP_API_Resource_Not_Found_Exception $e ) {
// if email wasn't even on the list: great.
return true;
} catch( MC4WP_API_Exception $e ) {
$this->error_code = $e->getCode();
$this->error_message = $e;
return false;
}
return true;
}
/**
* Checks if an email address is on a given list with status "subscribed"
*
* @param string $list_id
* @param string $email_address
*
* @return boolean
*/
public function list_has_subscriber( $list_id, $email_address ) {
try{
$data = $this->get_api()->get_list_member( $list_id, $email_address );
} catch( MC4WP_API_Resource_Not_Found_Exception $e ) {
return false;
}
return ! empty( $data->id ) && $data->status === 'subscribed';
}
/**
* Empty the Lists cache
*/
public function empty_cache() {
global $wpdb;
delete_option( 'mc4wp_mailchimp_list_ids' );
$wpdb->query( "DELETE FROM {$wpdb->options} WHERE option_name LIKE 'mc4wp_mailchimp_list_%'" );
delete_transient( 'mc4wp_list_counts' );
}
/**
* Get MailChimp lists from cache.
*
* @param boolean deprecated parameter.
* @return array
*/
public function get_cached_lists() {
return $this->get_lists( false );
}
/**
* Get a specific MailChimp list from local DB.
*
* @param string $list_id
* @return MC4WP_MailChimp_List
*/
public function get_cached_list( $list_id ) {
return $this->get_list( $list_id, false );
}
/**
* Get MailChimp lists, from cache or remote API.
*
* @param boolean $force Whether to force a result by hitting MailChimp API
* @return array
*/
public function get_lists( $force = true ) {
// first, get all list id's
$list_ids = $this->get_list_ids( $force );
// then, fill $lists array with individual list details
$lists = array();
foreach( $list_ids as $list_id ) {
$list = $this->get_list( $list_id, $force );
$lists["{$list_id}"] = $list;
}
return $lists;
}
/**
* @param string $list_id
*
* @return MC4WP_MailChimp_List
*/
private function fetch_list( $list_id ) {
try{
$list_data = $this->get_api()->get_list( $list_id, array( 'fields' => 'id,name,stats,web_id,campaign_defaults.from_name,campaign_defaults.from_email' ) );
// create local object
$list = new MC4WP_MailChimp_List( $list_data->id, $list_data->name );
$list->subscriber_count = $list_data->stats->member_count;
$list->web_id = $list_data->web_id;
$list->campaign_defaults = $list_data->campaign_defaults;
// get merge fields (if any)
if( $list_data->stats->merge_field_count > 0 ) {
$field_data = $this->get_api()->get_list_merge_fields( $list->id, array( 'count' => 100, 'fields' => 'merge_fields.name,merge_fields.tag,merge_fields.type,merge_fields.required,merge_fields.default_value,merge_fields.options,merge_fields.public' ) );
// hydrate data into object
foreach( $field_data as $data ) {
$object = MC4WP_MailChimp_Merge_Field::from_data( $data );
$list->merge_fields[] = $object;
}
}
// get interest categories
$interest_categories_data = $this->get_api()->get_list_interest_categories( $list->id, array( 'count' => 100, 'fields' => 'categories.id,categories.title,categories.type' ) );
foreach( $interest_categories_data as $interest_category_data ) {
$interest_category = MC4WP_MailChimp_Interest_Category::from_data( $interest_category_data );
// fetch groups for this interest
$interests_data = $this->get_api()->get_list_interest_category_interests( $list->id, $interest_category->id, array( 'count' => 100, 'fields' => 'interests.id,interests.name') );
foreach( $interests_data as $interest_data ) {
$interest_category->interests[ (string) $interest_data->id ] = $interest_data->name;
}
$list->interest_categories[] = $interest_category;
}
} catch( MC4WP_API_Exception $e ) {
return null;
}
// save in option
update_option( 'mc4wp_mailchimp_list_' . $list_id, $list, false );
return $list;
}
/**
* Get MailChimp list ID's
*
* @param bool $force Force result by hitting MailChimp API
* @return array
*/
public function get_list_ids( $force = false ) {
$list_ids = (array) get_option( 'mc4wp_mailchimp_list_ids', array() );
if( empty( $list_ids ) && $force ) {
$list_ids = $this->fetch_list_ids();
}
return $list_ids;
}
/**
* @return array
*/
public function fetch_list_ids() {
try{
$lists_data = $this->get_api()->get_lists( array( 'count' => 200, 'fields' => 'lists.id' ) );
} catch( MC4WP_API_Exception $e ) {
return array();
}
$list_ids = wp_list_pluck( $lists_data, 'id' );
// store list id's
update_option( 'mc4wp_mailchimp_list_ids', $list_ids, false );
return $list_ids;
}
/**
* Fetch list ID's + lists from MailChimp.
*
* @return bool
*/
public function fetch_lists() {
// try to increase time limit as this can take a while
@set_time_limit(300);
$list_ids = $this->fetch_list_ids();
// randomize array order
shuffle( $list_ids );
// fetch individual list details
foreach ( $list_ids as $list_id ) {
$list = $this->fetch_list( $list_id );
}
return ! empty( $list_ids );
}
/**
* Get a given MailChimp list
*
* @param string $list_id
* @param bool $force Whether to force a result by hitting remote API
* @return MC4WP_MailChimp_List
*/
public function get_list( $list_id, $force = false ) {
$list = get_option( 'mc4wp_mailchimp_list_' . $list_id );
if( empty( $list ) && $force ) {
$list = $this->fetch_list( $list_id );
}
if( empty( $list ) ) {
return new MC4WP_MailChimp_List( $list_id, 'Unknown List' );
}
return $list;
}
/**
* Get an array of list_id => number of subscribers
*
* @return array
*/
public function get_subscriber_counts() {
// get from transient
$list_counts = get_transient( 'mc4wp_list_counts' );
if( is_array( $list_counts ) ) {
return $list_counts;
}
// transient not valid, fetch from API
try {
$lists = $this->get_api()->get_lists( array( 'count' => 100, 'fields' => 'lists.id,lists.stats' ) );
} catch( MC4WP_API_Exception $e ) {
return array();
}
$list_counts = array();
// we got a valid response
foreach ( $lists as $list ) {
$list_counts["{$list->id}"] = $list->stats->member_count;
}
$seconds = 3600;
/**
* Filters the cache time for MailChimp lists configuration, in seconds. Defaults to 3600 seconds (1 hour).
*
* @since 2.0
* @param int $seconds
*/
$transient_lifetime = (int) apply_filters( 'mc4wp_lists_count_cache_time', $seconds );
set_transient( 'mc4wp_list_counts', $list_counts, $transient_lifetime );
// bail
return $list_counts;
}
/**
* Returns number of subscribers on given lists.
*
* @param array|string $list_ids Array of list ID's, or single string.
* @return int Total # subscribers for given lists.
*/
public function get_subscriber_count( $list_ids ) {
// make sure we're getting an array
if( ! is_array( $list_ids ) ) {
$list_ids = array( $list_ids );
}
// if we got an empty array, return 0
if( empty( $list_ids ) ) {
return 0;
}
// get total number of subscribers for all lists
$counts = $this->get_subscriber_counts();
// start calculating subscribers count for all given list ID's combined
$count = 0;
foreach ( $list_ids as $id ) {
$count += ( isset( $counts["{$id}"] ) ) ? $counts["{$id}"] : 0;
}
/**
* Filters the total subscriber_count for the given List ID's.
*
* @since 2.0
* @param string $count
* @param array $list_ids
*/
return apply_filters( 'mc4wp_subscriber_count', $count, $list_ids );
}
/**
* Resets error properties.
*/
public function reset_error() {
$this->error_message = '';
$this->error_code = '';
}
/**
* @return bool
*/
public function has_error() {
return ! empty( $this->error_code );
}
/**
* @return string
*/
public function get_error_message() {
return $this->error_message;
}
/**
* @return string
*/
public function get_error_code() {
return $this->error_code;
}
/**
* @return MC4WP_API_v3
*/
private function get_api() {
return mc4wp( 'api' );
}
}