/home/arranoyd/eventrify/wp-content/plugins/wpforms-mailchimp/v3/class-mailchimp.php
<?php
/**
* MailChimp integration.
*
* @since 1.1.0
*/
class WPForms_MailChimpv3 extends WPForms_Provider {
/**
* Account ID for current account.
*
* @since 1.1.0
*
* @var string
*/
public $account = false;
/**
* Initialize.
*
* @since 1.1.0
*/
public function init() {
$this->version = WPFORMS_MAILCHIMP_VERSION;
$this->name = 'MailChimp';
$this->slug = 'mailchimpv3';
$this->priority = 34;
$this->icon = WPFORMS_MAILCHIMP_URL . 'assets/images/addon-icon-mailchimp.png';
add_action( 'admin_notices', array( $this, 'upgrade_notice' ) );
}
/**
* Display upgrade notice for sites using the v2 API integration.
*
* @since 1.1.0
*/
public function upgrade_notice() {
// Only consider showing to admin users.
if ( ! is_super_admin() ) {
return;
}
// Only display if site has a v2 integration configured.
$providers = get_option( 'wpforms_providers' );
if ( empty( $providers['mailchimp'] ) ) {
return;
}
?>
<div class="notice notice-warning wpforms-mailchimp-update-notice">
<p>
<?php esc_html_e( 'Your forms are currently using an outdated MailChimp integration that is no longer supported. Please update your forms to use the new integration to avoid losing subscribers.', 'wpforms-mailchimp' ); ?>
<strong>
<a href="https://wpforms.com/new-announcing-an-important-mailchimp-addon-update/#update" target="_blank" rel="noopener noreferrer">
<?php esc_html_e( 'Click here for more details.', 'wpforms-mailchimp' ); ?>
</a>
</strong>
</p>
</div>
<?php
}
/**
* Process and submit entry to provider.
*
* @since 1.1.0
*
* @param array $fields WPForms form array of fields.
* @param array $entry
* @param array $form_data
* @param int $entry_id
*
* @throws \Exception If errors occurred.
*/
public function process_entry( $fields, $entry, $form_data, $entry_id = 0 ) {
// Only run if this form has connections for this provider.
if ( empty( $form_data['providers'][ $this->slug ] ) ) {
return;
}
/*
* Fire for each connection.
*/
foreach ( $form_data['providers'][ $this->slug ] as $connection ) :
// Before proceeding make sure required fields are configured.
if ( empty( $connection['fields']['EMAIL'] ) ) {
continue;
}
// Setup basic data.
$account_id = $connection['account_id'];
$list_id = $connection['list_id'];
$email_data = explode( '.', $connection['fields']['EMAIL'] );
$email_id = $email_data[0];
$double = isset( $connection['options']['doubleoptin'] );
$api = $this->api_connect( $account_id );
$ip = wpforms_get_ip();
$data = array(
'email_type' => 'html',
'status' => 'subscribed',
'status_if_new' => $double ? 'pending' : 'subscribed',
'ip_signup' => $ip,
'ip_opt' => $ip,
);
// Bail if there is any sort of issues with the API connection.
if ( is_wp_error( $api ) ) {
continue;
}
// Email is required.
if ( empty( $fields[ $email_id ]['value'] ) ) {
continue;
} else {
$data['email_address'] = strtolower( $fields[ $email_id ]['value'] );
}
// Check for conditional logic.
$pass = $this->process_conditionals( $fields, $entry, $form_data, $connection );
if ( ! $pass ) {
wpforms_log(
esc_html__( 'MailChimp Subscription stopped by conditional logic', 'wpforms-mailchimp' ),
$fields,
array(
'type' => array( 'provider', 'conditional_logic' ),
'parent' => $entry_id,
'form_id' => $form_data['id'],
)
);
continue;
}
/*
* Setup merge fields.
*/
foreach ( $connection['fields'] as $name => $merge_field ) {
// Don't include EMAIL merge fields.
if ( 'EMAIL' === $name ) {
continue;
}
// Check if merge vars are used.
if ( empty( $merge_field ) ) {
continue;
}
$merge_field = explode( '.', $merge_field );
$id = $merge_field[0]; // WPForms Field ID.
$key = ! empty( $merge_field[1] ) ? $merge_field[1] : 'value';
$type = ! empty( $merge_field[2] ) ? $merge_field[2] : 'text'; // MC merge field type.
// Check if mapped form field has a value.
if ( empty( $fields[ $id ][ $key ] ) ) {
continue;
}
$value = $fields[ $id ][ $key ];
// Special formatting for different types of data.
switch ( $type ) {
case 'phone':
if ( ! empty( $form_data['fields'][ $id ]['format'] ) && 'us' === $form_data['fields'][ $id ]['format'] ) {
$value = str_replace( ' ', '-', $value );
$value = str_replace( '(', '', $value );
$value = str_replace( ')', '', $value );
}
break;
case 'birthday':
if (
! empty( $form_data['fields'][ $id ]['format'] ) &&
'date' === $form_data['fields'][ $id ]['format']
) {
// To make use of all possible formats.
$date = DateTime::createFromFormat( $form_data['fields'][ $id ]['date_format'], $value );
$value = $date->format( 'm/d' );
if ( 'd/m/Y' === $form_data['fields'][ $id ]['date_format'] ) {
$value = $date->format( 'd/m' );
}
}
break;
}
$data['merge_fields'][ $name ] = $value;
} // End foreach( $connection['fields'] ).
/*
* Setup segments (groups).
*/
if ( ! empty( $connection['groups'] ) ) {
$s = array();
foreach ( $connection['groups'] as $id => $segments ) {
foreach ( $segments as $id => $segment ) {
$s[ $id ] = true;
}
}
if ( ! empty( $s ) ) {
$data['interests'] = $s;
}
}
/*
* Send to API
*/
$hash = md5( $data['email_address'] ); // In order to both insert or update, we have to PUT to the specific resource.
$res = $this->api->put( 'lists/' . $list_id . '/members/' . $hash, $data );
if ( false === $res || isset( $res['status'] ) && $res['status'] >= 300 ) {
$error_msg = ! empty( $res['detail'] ) ? $res['detail'] : esc_html__( 'Error creating subscription.', 'wpforms-mailchimp' );
wpforms_log(
esc_html__( 'MailChimp Subscription error', 'wpforms-mailchimp' ),
$error_msg,
array(
'type' => array( 'provider', 'error' ),
'parent' => $entry_id,
'form_id' => $form_data['id'],
)
);
}
endforeach; // End foreach( $form_data['providers'][ $this->slug ] ).
}
/************************************************************************
* API methods - these methods interact directly with the provider API. *
************************************************************************/
/**
* Authenticate with the API.
*
* @param array $data
* @param string $form_id
*
* @return mixed id or error object
*/
public function api_auth( $data = array(), $form_id = '' ) {
if ( ! class_exists( 'MailChimp_WPForms' ) ) {
require_once WPFORMS_MAILCHIMP_DIR . 'v3/vendor/MailChimp.php';
}
try {
$api = new MailChimp_WPForms( trim( $data['apikey'] ) );
} catch ( Exception $e ) {
return $this->error( $e->getMessage() );
}
$res = $api->get( '' );
if ( empty( $res['account_id'] ) ) {
$details = ! empty( $res['detail'] ) ? $res['detail'] : esc_html__( 'Could not verify API key', 'wpforms-mailchimp' );
wpforms_log(
esc_html__( 'MailChimp API error', 'wpforms-mailchimp' ),
$res,
array(
'type' => array( 'provider', 'error' ),
)
);
/* translators: %s - error details. */
return $this->error( sprintf( esc_html__( 'API auth error: %s', 'wpforms-mailchimp' ), $details ) );
}
$id = uniqid();
$providers = get_option( 'wpforms_providers', array() );
$providers[ $this->slug ][ $id ] = array(
'api' => trim( $data['apikey'] ),
'label' => sanitize_text_field( $data['label'] ),
'date' => time(),
);
update_option( 'wpforms_providers', $providers );
return $id;
}
/**
* Establish connection object to API.
*
* @since 1.1.0
*
* @param string $account_id
*
* @return mixed array or error object.
* @throws \Exception In case error occurred.
*/
public function api_connect( $account_id ) {
if ( ! class_exists( 'MailChimp_WPForms' ) ) {
require_once WPFORMS_MAILCHIMP_DIR . 'v3/vendor/MailChimp.php';
}
if ( ! empty( $this->api ) && $account_id === $this->account ) {
return $this->api;
} else {
$providers = get_option( 'wpforms_providers' );
if ( ! empty( $providers[ $this->slug ][ $account_id ]['api'] ) ) {
$this->account = $account_id;
$this->api = new MailChimp_WPForms( $providers[ $this->slug ][ $account_id ]['api'] );
return $this->api;
} else {
return $this->error( esc_html__( 'API connect error', 'wpforms-mailchimp' ) );
}
}
}
/**
* Retrieve provider account lists.
*
* @since 1.1.0
*
* @param string $connection_id
* @param string $account_id
*
* @return mixed array or error object.
* @throws \Exception In case error occurred.
*/
public function api_lists( $connection_id = '', $account_id = '' ) {
$this->api_connect( $account_id );
try {
$lists = $this->api->get( 'lists', array(
'count' => 500,
'fields' => 'lists.id,lists.name',
) );
if ( ! empty( $lists['lists'] ) ) {
$l = array();
foreach ( $lists['lists'] as $list ) {
if ( empty( $list['id'] ) ) {
continue;
}
$l[ $list['id'] ] = array(
'id' => $list['id'],
'name' => isset( $list['name'] ) ? trim( $list['name'] ) : esc_html__( 'Unknown List', 'wpforms-mailchimp' ),
);
}
return $l;
} else {
$error_msg = esc_html__( 'API list error: No lists', 'wpforms-mailchimp' );
return $this->error( $error_msg );
}
} catch ( Exception $e ) {
wpforms_log(
esc_html__( 'MailChimp API error', 'wpforms-mailchimp' ),
$e->getMessage(),
array(
'type' => array( 'provider', 'error' ),
)
);
/* translators: %s - error message. */
return $this->error( sprintf( esc_html__( 'API list error: %s', 'wpforms-mailchimp' ), $e->getMessage() ) );
}
}
/**
* Retrieve provider account list segments (groups).
*
* @since 1.1.0
*
* @param string $connection_id
* @param string $account_id
* @param string $list_id
*
* @return mixed array or error object
* @throws \Exception In case error occurred.
*/
public function api_groups( $connection_id = '', $account_id = '', $list_id = '' ) {
$this->api_connect( $account_id );
try {
$segments = $this->api->get( 'lists/' . $list_id . '/interest-categories', array(
'count' => 500,
'fields' => 'categories.id,categories.title',
) );
if ( ! empty( $segments['categories'] ) ) {
$s = array();
foreach ( $segments['categories'] as $segment ) {
if ( empty( $segment['id'] ) ) {
continue;
}
$s[ $segment['id'] ] = array(
'id' => $segment['id'],
'name' => isset( $segment['title'] ) ? trim( $segment['title'] ) : esc_html__( 'Unknown Segment', 'wpforms-mailchimp' ),
);
// Grab groups within the segment headings (now called Interest Categories).
$groups = $this->api->get( 'lists/' . $list_id . '/interest-categories/' . $segment['id'] . '/interests', array(
'count' => 500,
'fields' => 'interests.id,interests.name',
) );
if ( ! empty( $groups['interests'] ) ) {
$s[ $segment['id'] ]['groups'] = array();
foreach ( $groups['interests'] as $i => $group ) {
if ( empty( $group['id'] ) ) {
continue;
}
$s[ $segment['id'] ]['groups'][] = array(
'id' => $group['id'],
'name' => isset( $group['name'] ) ? trim( $group['name'] ) : esc_html__( 'Unknown Group', 'wpforms-mailchimp' ),
);
}
}
}
return $s;
} else {
$error_msg = esc_html__( 'API groups error: No groups', 'wpforms-mailchimp' );
return $this->error( $error_msg );
}
} catch ( Exception $e ) {
wpforms_log(
esc_html__( 'MailChimp API error', 'wpforms-mailchimp' ),
$e->getMessage(),
array(
'type' => array( 'provider', 'error' ),
)
);
/* translators: %s - error message. */
return $this->error( sprintf( esc_html__( 'API groups error: %s', 'wpforms-mailchimp' ), $e->getMessage() ) );
} // End try().
}
/**
* Retrieve provider account list fields.
*
* @since 1.1.0
*
* @param string $connection_id
* @param string $account_id
* @param string $list_id
*
* @return mixed array or error object
* @throws \Exception In case error occurred.
*/
public function api_fields( $connection_id = '', $account_id = '', $list_id = '' ) {
$this->api_connect( $account_id );
try {
$fields = $this->api->get( 'lists/' . $list_id . '/merge-fields', array(
'count' => 500,
) );
// Add email.
$f[0] = array(
'id' => 0,
'name' => esc_html__( 'Email Address', 'wpforms-mailchimp' ),
'req' => true,
'field_type' => 'email',
'tag' => 'EMAIL',
);
if ( ! empty( $fields['merge_fields'] ) ) {
foreach ( $fields['merge_fields'] as $field ) {
$f[ $field['merge_id'] ] = array(
'id' => $field['merge_id'],
'name' => isset( $field['name'] ) ? trim( $field['name'] ) : esc_html__( 'Unknown Merge Var', 'wpforms-mailchimp' ),
'req' => $field['required'] ? '1' : '',
'field_type' => $field['type'],
'tag' => $field['tag'],
);
}
}
return $f;
} catch ( Exception $e ) {
wpforms_log(
esc_html__( 'MailChimp API error', 'wpforms' ),
$e->getMessage(),
array(
'type' => array( 'provider', 'error' ),
)
);
/* translators: %s - error message. */
return $this->error( sprintf( esc_html__( 'API fields error: %s', 'wpforms-mailchimp' ), $e->getMessage() ) );
} // End try().
}
/*************************************************************************
* Output methods - these methods generally return HTML for the builder. *
*************************************************************************/
/**
* Provider account authorize fields HTML.
*
* @since 1.1.0
* @return string
*/
public function output_auth() {
$providers = get_option( 'wpforms_providers' );
$class = ! empty( $providers[ $this->slug ] ) ? 'hidden' : '';
$output = '<div class="wpforms-provider-account-add ' . $class . ' wpforms-connection-block">';
$output .= '<h4>' . esc_html__( 'Add New Account', 'wpforms-mailchimp' ) . '</h4>';
/* translators: %s - provider name. */
$output .= '<input type="text" data-name="apikey" placeholder="' . sprintf( esc_attr__( '%s API Key', 'wpforms-mailchimp' ), $this->name ) . '" class="wpforms-required">';
/* translators: %s - provider name. */
$output .= '<input type="text" data-name="label" placeholder="' . sprintf( esc_attr__( '%s Account Nickname', 'wpforms-mailchimp' ), $this->name ) . '" class="wpforms-required">';
$output .= '<button data-provider="' . esc_attr( $this->slug ) . '">' . esc_html__( 'Connect', 'wpforms-mailchimp' ) . '</button>';
$output .= '</div>';
return $output;
}
/**
* Provider account list options HTML.
*
* @since 1.1.0
*
* @param string $connection_id
* @param array $connection
*
* @return string
*/
public function output_options( $connection_id = '', $connection = array() ) {
if ( empty( $connection_id ) || empty( $connection['account_id'] ) || empty( $connection['list_id'] ) ) {
return '';
}
$output = '<div class="wpforms-provider-options wpforms-connection-block">';
$output .= '<h4>' . esc_html__( 'Options', 'wpforms-mailchimp' ) . '</h4>';
$output .= sprintf(
'<p><input id="%s_options_doubleoptin" type="checkbox" value="1" name="providers[%s][%s][options][doubleoptin]" %s><label for="%s_options_doubleoptin">%s</label></p>',
esc_attr( $connection_id ),
esc_attr( $this->slug ),
esc_attr( $connection_id ),
checked( ! empty( $connection['options']['doubleoptin'] ), true, false ),
esc_attr( $connection_id ),
esc_html__( 'Use double opt-in', 'wpforms-mailchimp' )
);
$output .= '</div>';
return $output;
}
/*************************************************************************
* Integrations tab methods - these methods relate to the settings page. *
*************************************************************************/
/**
* Form fields to add a new provider account.
*
* @since 1.1.0
*/
public function integrations_tab_new_form() {
/* translators: %s - provider name. */
echo '<input type="text" name="apikey" placeholder="' . sprintf( esc_attr__( '%s API Key', 'wpforms-mailchimp' ), $this->name ) . '">';
/* translators: %s - provider name. */
echo '<input type="text" name="label" placeholder="' . sprintf( esc_attr__( '%s Account Nickname', 'wpforms-mailchimp' ), $this->name ) . '">';
}
}
new WPForms_MailChimpv3;