version 4.13.0
This commit is contained in:
316
core/components/api/email/ActiveCampaign.php
Normal file
316
core/components/api/email/ActiveCampaign.php
Normal file
@ -0,0 +1,316 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Wrapper for ActiveCampaign's API.
|
||||
*
|
||||
* @since 1.1.0
|
||||
*
|
||||
* @package ET\Core\API\Email
|
||||
*/
|
||||
class ET_Core_API_Email_ActiveCampaign extends ET_Core_API_Email_Provider {
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $name = 'ActiveCampaign';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $slug = 'activecampaign';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $uses_oauth = false;
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $custom_fields_scope = 'account';
|
||||
|
||||
protected function _fetch_custom_fields( $list_id = '', $list = array() ) {
|
||||
// These general / default fields are static (it can not be edited or deleted in the ActiveCampaign dashboard) and not returned by the rest API,
|
||||
// so just add it here as the default custom fields for ActiveCampaign.
|
||||
$fields = array(
|
||||
'%phone%' => array(
|
||||
'field_id' => '%phone%',
|
||||
'hidden' => false,
|
||||
'name' => 'Phone',
|
||||
'type' => 'input',
|
||||
),
|
||||
'%customer_acct_name%' => array(
|
||||
'field_id' => '%customer_acct_name%',
|
||||
'hidden' => false,
|
||||
'name' => 'Account',
|
||||
'type' => 'input',
|
||||
),
|
||||
);
|
||||
|
||||
foreach ( $list['fields'] as $field ) {
|
||||
$field = $this->transform_data_to_our_format( $field, 'custom_field' );
|
||||
$field_id = $field['field_id'];
|
||||
$type = $field['type'];
|
||||
|
||||
$field['type'] = self::$_->array_get( $this->data_keys, "custom_field_type.{$type}", 'text' );
|
||||
|
||||
if ( isset( $field['options'] ) ) {
|
||||
$options = array();
|
||||
|
||||
foreach ( $field['options'] as $option ) {
|
||||
$option = $this->transform_data_to_our_format( $option, 'custom_field_option' );
|
||||
$id = $option['id'];
|
||||
|
||||
$options[ $id ] = $option['name'];
|
||||
}
|
||||
|
||||
$field['options'] = $options;
|
||||
}
|
||||
|
||||
$fields[ $field_id ] = $field;
|
||||
}
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
protected function _process_custom_fields( $args ) {
|
||||
if ( ! isset( $args['custom_fields'] ) ) {
|
||||
return $args;
|
||||
}
|
||||
|
||||
$fields = $args['custom_fields'];
|
||||
|
||||
unset( $args['custom_fields'] );
|
||||
|
||||
foreach ( $fields as $field_id => $value ) {
|
||||
if ( is_array( $value ) && $value ) {
|
||||
// This is a multiple choice field (eg. checkbox, radio, select)
|
||||
$value = array_values( $value );
|
||||
|
||||
if ( 'checkbox' === $this->data['custom_fields'][ $field_id ]['type'] ) {
|
||||
$value = implode( '||', $value );
|
||||
$value = "||{$value}||";
|
||||
} else {
|
||||
$value = array_pop( $value );
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the custom field is an ActiveCampaign general field,
|
||||
// it should be posted as dedicated param instead of `field[{$field_id},0]` param.
|
||||
if ( preg_match( '/%(.*)%/', $field_id, $matches ) ) {
|
||||
self::$_->array_set( $args, $matches[1], $value );
|
||||
} else {
|
||||
self::$_->array_set( $args, "field[{$field_id},0]", $value );
|
||||
}
|
||||
}
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requests URL for the account assigned to this class instance.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function _get_requests_url() {
|
||||
$base_url = untrailingslashit( $this->data['api_url'] );
|
||||
|
||||
return "{$base_url}/admin/api.php";
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function get_account_fields() {
|
||||
return array(
|
||||
'api_key' => array(
|
||||
'label' => esc_html__( 'API Key', 'et_core' ),
|
||||
),
|
||||
'api_url' => array(
|
||||
'label' => esc_html__( 'API URL', 'et_core' ),
|
||||
'apply_password_mask' => false,
|
||||
),
|
||||
'form_id' => array(
|
||||
'label' => esc_html__( 'Form ID', 'et_core' ),
|
||||
'not_required' => true,
|
||||
'apply_password_mask' => false,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function get_data_keymap( $keymap = array() ) {
|
||||
$keymap = array(
|
||||
'list' => array(
|
||||
'list_id' => 'id',
|
||||
'name' => 'name',
|
||||
'subscribers_count' => 'subscriber_count',
|
||||
),
|
||||
'subscriber' => array(
|
||||
'email' => 'email',
|
||||
'last_name' => 'last_name',
|
||||
'name' => 'first_name',
|
||||
'custom_fields' => 'custom_fields',
|
||||
),
|
||||
'error' => array(
|
||||
'error_message' => 'result_message',
|
||||
),
|
||||
'custom_field' => array(
|
||||
'field_id' => 'id',
|
||||
'name' => 'title',
|
||||
'type' => 'type',
|
||||
'hidden' => '!visible',
|
||||
'options' => 'options',
|
||||
),
|
||||
'custom_field_option' => array(
|
||||
'id' => 'value',
|
||||
'name' => 'name',
|
||||
),
|
||||
'custom_field_type' => array(
|
||||
// Us <=> Them
|
||||
'checkbox' => 'checkbox',
|
||||
'radio' => 'radio',
|
||||
'textarea' => 'textarea',
|
||||
'hidden' => 'hidden',
|
||||
// Us => Them
|
||||
'select' => 'dropdown',
|
||||
'input' => 'text',
|
||||
// Them => Us
|
||||
'dropdown' => 'select',
|
||||
'text' => 'input',
|
||||
),
|
||||
);
|
||||
|
||||
return parent::get_data_keymap( $keymap );
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function fetch_subscriber_lists() {
|
||||
if ( empty( $this->data['api_key'] ) || empty( $this->data['api_url'] ) ) {
|
||||
return $this->API_KEY_REQUIRED;
|
||||
}
|
||||
|
||||
$query_args = array(
|
||||
'api_key' => $this->data['api_key'],
|
||||
'api_action' => 'list_list',
|
||||
'api_output' => 'json',
|
||||
'ids' => 'all',
|
||||
'full' => '1',
|
||||
'global_fields' => '1',
|
||||
);
|
||||
|
||||
$request_url = add_query_arg( $query_args, $this->_get_requests_url() );
|
||||
$request_url = esc_url_raw( $request_url, array( 'https' ) );
|
||||
|
||||
$this->prepare_request( $request_url );
|
||||
$this->request->HEADERS['Content-Type'] = 'application/x-www-form-urlencoded';
|
||||
|
||||
parent::fetch_subscriber_lists();
|
||||
|
||||
if ( $this->response->ERROR ) {
|
||||
return $this->get_error_message();
|
||||
}
|
||||
|
||||
$lists = array();
|
||||
|
||||
foreach ( $this->response->DATA as $key => $list_data ) {
|
||||
if ( ! is_numeric( $key ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( ! empty( $list_data ) ) {
|
||||
$lists[] = $list_data;
|
||||
}
|
||||
}
|
||||
|
||||
$this->data['lists'] = $this->_process_subscriber_lists( $lists );
|
||||
$this->data['custom_fields'] = $this->_fetch_custom_fields( '', array_shift( $this->response->DATA ) );
|
||||
$this->data['is_authorized'] = 'true';
|
||||
|
||||
$this->save_data();
|
||||
|
||||
et_debug($this->data);
|
||||
|
||||
return 'success';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get ActiveCampaign subscriber info by email.
|
||||
*
|
||||
* @param string $email
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_subscriber( $email ) {
|
||||
$query_args = array(
|
||||
'api_key' => $this->data['api_key'],
|
||||
'api_action' => 'subscriber_view_email',
|
||||
'api_output' => 'json',
|
||||
'email' => $email,
|
||||
);
|
||||
|
||||
// Build request URL. This action only accept GET method.
|
||||
$request_url = add_query_arg( $query_args, $this->_get_requests_url() );
|
||||
$request_url = esc_url_raw( $request_url, array( 'https' ) );
|
||||
|
||||
// Prepare and send the request.
|
||||
$this->prepare_request( $request_url );
|
||||
$this->request->HEADERS['Content-Type'] = 'application/x-www-form-urlencoded';
|
||||
$this->make_remote_request();
|
||||
|
||||
// Ensure no error happen and it's included in one of the lists.
|
||||
$list_id = self::$_->array_get( $this->response->DATA, 'listid', false );
|
||||
$result_code = self::$_->array_get( $this->response->DATA, 'result_code', false );
|
||||
if ( $this->response->ERROR || ! $list_id || ! $result_code ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->response->DATA;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function subscribe( $args, $url= '' ) {
|
||||
// Ensure to skip subscribe action if current email already subscribed.
|
||||
$subscriber_data = $this->get_subscriber( $args['email'] );
|
||||
$subscriber_lists = self::$_->array_get( $subscriber_data, 'lists', array() );
|
||||
$subscriber_list = self::$_->array_get( $subscriber_lists, $args['list_id'], false );
|
||||
if ( $subscriber_list ) {
|
||||
return 'success';
|
||||
}
|
||||
|
||||
$list_id_key = 'p[' . $args['list_id'] . ']';
|
||||
$status_key = 'status[' . $args['list_id'] . ']';
|
||||
$responders_key = 'instantresponders[' . $args['list_id'] . ']';
|
||||
$list_id = $args['list_id'];
|
||||
|
||||
$args = $this->transform_data_to_provider_format( $args, 'subscriber', array( 'list_id' ) );
|
||||
$args = $this->_process_custom_fields( $args );
|
||||
|
||||
$query_args = array(
|
||||
'api_key' => $this->data['api_key'],
|
||||
'api_action' => 'contact_sync',
|
||||
'api_output' => 'json',
|
||||
);
|
||||
|
||||
$url = esc_url_raw( add_query_arg( $query_args, $this->_get_requests_url() ) );
|
||||
|
||||
$args[ $list_id_key ] = $list_id;
|
||||
$args[ $status_key ] = 1;
|
||||
$args[ $responders_key ] = 1;
|
||||
|
||||
if ( ! empty( $this->data['form_id'] ) ) {
|
||||
$args['form'] = (int) $this->data['form_id'];
|
||||
}
|
||||
|
||||
$this->prepare_request( $url, 'POST', false, $args );
|
||||
$this->request->HEADERS['Content-Type'] = 'application/x-www-form-urlencoded';
|
||||
|
||||
return parent::subscribe( $args, $url );
|
||||
}
|
||||
}
|
255
core/components/api/email/Aweber.php
Normal file
255
core/components/api/email/Aweber.php
Normal file
@ -0,0 +1,255 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Wrapper for Aweber's API.
|
||||
*
|
||||
* @since 1.1.0
|
||||
*
|
||||
* @package ET\Core\API\Email
|
||||
*/
|
||||
class ET_Core_API_Email_Aweber extends ET_Core_API_Email_Provider {
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $ACCESS_TOKEN_URL = 'https://auth.aweber.com/1.0/oauth/access_token';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $AUTHORIZATION_URL = 'https://auth.aweber.com/1.0/oauth/authorize';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $REQUEST_TOKEN_URL = 'https://auth.aweber.com/1.0/oauth/request_token';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $BASE_URL = 'https://api.aweber.com/1.0';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $accounts_url;
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $name = 'Aweber';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $name_field_only = true;
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $slug = 'aweber';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $oauth_version = '1.0a';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $uses_oauth = true;
|
||||
|
||||
/**
|
||||
* ET_Core_API_Email_Aweber constructor.
|
||||
*
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function __construct( $owner, $account_name = '', $api_key = '' ) {
|
||||
parent::__construct( $owner, $account_name, $api_key );
|
||||
$this->accounts_url = "{$this->BASE_URL}/accounts";
|
||||
}
|
||||
|
||||
protected function _fetch_custom_fields( $list_id = '', $list = array() ) {
|
||||
$this->prepare_request( $list['custom_fields_collection_link'] );
|
||||
|
||||
return parent::_fetch_custom_fields( $list_id, $list );
|
||||
}
|
||||
|
||||
protected function _get_lists_collection_url() {
|
||||
$this->prepare_request( $this->accounts_url );
|
||||
$this->make_remote_request();
|
||||
$url = '';
|
||||
|
||||
if ( ! $this->response->ERROR && ! empty( $this->response->DATA['entries'][0]['lists_collection_link'] ) ) {
|
||||
$url = $this->response->DATA['entries'][0]['lists_collection_link'];
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
protected static function _parse_ID( $ID ) {
|
||||
$values = explode( '|', $ID );
|
||||
|
||||
return ( count( $values ) === 6 ) ? $values : null;
|
||||
}
|
||||
|
||||
protected function _process_custom_fields( $args ) {
|
||||
if ( ! isset( $args['custom_fields'] ) ) {
|
||||
return $args;
|
||||
}
|
||||
|
||||
$fields = $args['custom_fields'];
|
||||
|
||||
unset( $args['custom_fields'] );
|
||||
|
||||
foreach ( $fields as $field_id => $value ) {
|
||||
if ( is_array( $value ) && $value ) {
|
||||
// This is a multiple choice field (eg. checkbox, radio, select)
|
||||
$value = array_values( $value );
|
||||
|
||||
if ( count( $value ) > 1 ) {
|
||||
$value = implode( ',', $value );
|
||||
} else {
|
||||
$value = array_pop( $value );
|
||||
}
|
||||
}
|
||||
|
||||
$list_id = $args['list_id'];
|
||||
$field_name = self::$_->array_get( $this->data, "lists.{$list_id}.custom_fields.{$field_id}.name" );
|
||||
|
||||
self::$_->array_set( $args, "custom_fields.{$field_name}", $value );
|
||||
}
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses the app's authorization code to get an access token
|
||||
*/
|
||||
public function authenticate() {
|
||||
if ( empty( $this->data['api_key'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$key_parts = self::_parse_ID( $this->data['api_key'] );
|
||||
|
||||
if ( null === $key_parts ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
list( $consumer_key, $consumer_secret, $request_token, $request_secret, $verifier ) = $key_parts;
|
||||
|
||||
if ( ! $verifier ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->data['consumer_key'] = $consumer_key;
|
||||
$this->data['consumer_secret'] = $consumer_secret;
|
||||
$this->data['access_key'] = $request_token;
|
||||
$this->data['access_secret'] = $request_secret;
|
||||
$this->oauth_verifier = $verifier;
|
||||
|
||||
// AWeber returns oauth access key in url query format :face_with_rolling_eyes:
|
||||
$this->http->expects_json = false;
|
||||
|
||||
return parent::authenticate();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function get_account_fields() {
|
||||
return array(
|
||||
'api_key' => array(
|
||||
'label' => esc_html__( 'Authorization Code', 'et_core' ),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function get_error_message() {
|
||||
$error_message = parent::get_error_message();
|
||||
|
||||
return preg_replace('/https.*/m', '', $error_message );
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function get_data_keymap( $keymap = array() ) {
|
||||
$keymap = array(
|
||||
'list' => array(
|
||||
'list_id' => 'id',
|
||||
'name' => 'name',
|
||||
'subscribers_count' => 'total_subscribers',
|
||||
),
|
||||
'subscriber' => array(
|
||||
'name' => 'name',
|
||||
'email' => 'email',
|
||||
'ad_tracking' => 'ad_tracking',
|
||||
'custom_fields' => 'custom_fields',
|
||||
),
|
||||
'error' => array(
|
||||
'error_message' => 'error.message',
|
||||
),
|
||||
'custom_field' => array(
|
||||
'field_id' => 'id',
|
||||
'name' => 'name',
|
||||
),
|
||||
);
|
||||
|
||||
return parent::get_data_keymap( $keymap );
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function fetch_subscriber_lists() {
|
||||
$needs_to_authenticate = ! $this->is_authenticated() || ! $this->_initialize_oauth_helper();
|
||||
|
||||
if ( $needs_to_authenticate && ! $this->authenticate() ) {
|
||||
if ( empty( $this->response->DATA ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$this->response->DATA = json_decode( $this->response->DATA, true );
|
||||
return $this->get_error_message();
|
||||
}
|
||||
|
||||
$this->http->expects_json = true;
|
||||
$this->LISTS_URL = $this->_get_lists_collection_url();
|
||||
|
||||
if ( empty( $this->LISTS_URL ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$this->response_data_key = 'entries';
|
||||
|
||||
return parent::fetch_subscriber_lists();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function subscribe( $args, $url = '' ) {
|
||||
$lists_url = $this->_get_lists_collection_url();
|
||||
$url = "{$lists_url}/{$args['list_id']}/subscribers";
|
||||
$ip_address = 'true' === self::$_->array_get( $args, 'ip_address', 'true' );
|
||||
|
||||
$params = $this->_process_custom_fields( $args );
|
||||
$params = $this->transform_data_to_provider_format( $params, 'subscriber' );
|
||||
$params = array_merge( $params, array(
|
||||
'ws.op' => 'create',
|
||||
'ip_address' => $ip_address ? et_core_get_ip_address() : '0.0.0.0',
|
||||
'misc_notes' => $this->SUBSCRIBED_VIA,
|
||||
) );
|
||||
|
||||
// There is a bug in AWeber some characters not encoded properly on AWeber side when sending data in x-www-form-urlencoded format so use json instead
|
||||
$this->prepare_request( $url, 'POST', false, $params, true );
|
||||
$this->request->HEADERS['Content-Type'] = 'application/json';
|
||||
|
||||
return parent::subscribe( $params, $url );
|
||||
}
|
||||
}
|
271
core/components/api/email/CampaignMonitor.php
Normal file
271
core/components/api/email/CampaignMonitor.php
Normal file
@ -0,0 +1,271 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Wrapper for Campaign Monitor's API.
|
||||
*
|
||||
* @since 1.1.0
|
||||
*
|
||||
* @package ET\Core\API\Email
|
||||
*/
|
||||
class ET_Core_API_Email_CampaignMonitor extends ET_Core_API_Email_Provider {
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $BASE_URL = 'https://api.createsend.com/api/v3.1';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $http_auth = array(
|
||||
'username' => 'api_key',
|
||||
'password' => '-',
|
||||
);
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $name = 'CampaignMonitor';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $name_field_only = true;
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $slug = 'campaign_monitor';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @internal If true, oauth endpoints properties must also be defined.
|
||||
*/
|
||||
public $uses_oauth = false;
|
||||
|
||||
public function __construct( $owner, $account_name, $api_key = '' ) {
|
||||
parent::__construct( $owner, $account_name, $api_key );
|
||||
|
||||
$this->http_auth['password'] = $owner;
|
||||
}
|
||||
|
||||
protected function _fetch_custom_fields( $list_id = '', $list = array() ) {
|
||||
$this->prepare_request( "{$this->BASE_URL}/lists/{$list_id}/customfields.json" );
|
||||
$this->make_remote_request();
|
||||
|
||||
$result = array();
|
||||
|
||||
if ( $this->response->ERROR ) {
|
||||
et_debug( $this->get_error_message() );
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
foreach ( $this->response->DATA as &$custom_field ) {
|
||||
$custom_field = $this->transform_data_to_our_format( $custom_field, 'custom_field' );
|
||||
$custom_field['field_id'] = ltrim( rtrim( $custom_field['field_id'], ']' ), '[' );
|
||||
}
|
||||
|
||||
$fields = array();
|
||||
|
||||
foreach ( $this->response->DATA as $field ) {
|
||||
$field_id = $field['field_id'];
|
||||
$type = self::$_->array_get( $field, 'type', 'any' );
|
||||
|
||||
$field['type'] = self::$_->array_get( $this->data_keys, "custom_field_type.{$type}", 'any' );
|
||||
|
||||
$fields[ $field_id ] = $field;
|
||||
}
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
protected function _get_clients() {
|
||||
$url = "{$this->BASE_URL}/clients.json";
|
||||
|
||||
$this->prepare_request( $url );
|
||||
$this->make_remote_request();
|
||||
|
||||
if ( $this->response->ERROR ) {
|
||||
return $this->get_error_message();
|
||||
}
|
||||
|
||||
return (array) $this->response->DATA;
|
||||
}
|
||||
|
||||
protected function _get_subscriber_counts() {
|
||||
$subscriber_lists = $this->_process_subscriber_lists( $this->response->DATA );
|
||||
$with_counts = array();
|
||||
|
||||
foreach ( $subscriber_lists as $subscriber_list ) {
|
||||
$list_id = $subscriber_list['list_id'];
|
||||
$with_counts[ $list_id ] = $subscriber_list;
|
||||
$url = "{$this->BASE_URL}/lists/{$list_id}/stats.json";
|
||||
|
||||
$this->prepare_request( $url );
|
||||
$this->make_remote_request();
|
||||
|
||||
if ( $this->response->ERROR ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( isset( $this->response->DATA['TotalActiveSubscribers'] ) ) {
|
||||
$with_counts[ $list_id ]['subscribers_count'] = $this->response->DATA['TotalActiveSubscribers'];
|
||||
} else {
|
||||
$with_counts[ $list_id ]['subscribers_count'] = 0;
|
||||
}
|
||||
|
||||
usleep( 500000 ); // 0.5 seconds
|
||||
}
|
||||
|
||||
return $with_counts;
|
||||
}
|
||||
|
||||
protected function _process_custom_fields( $args ) {
|
||||
if ( ! isset( $args['custom_fields'] ) ) {
|
||||
return $args;
|
||||
}
|
||||
|
||||
$fields_unprocessed = $args['custom_fields'];
|
||||
|
||||
unset( $args['custom_fields'] );
|
||||
|
||||
$fields = array();
|
||||
|
||||
foreach ( $fields_unprocessed as $field_id => $value ) {
|
||||
if ( is_array( $value ) && $value ) {
|
||||
// This is a multiple choice field (eg. checkbox)
|
||||
foreach ( $value as $selected_option ) {
|
||||
$fields[] = array(
|
||||
'Key' => $field_id,
|
||||
'Value' => $selected_option,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$fields[] = array(
|
||||
'Key' => $field_id,
|
||||
'Value' => $value,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$args['CustomFields'] = $fields;
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function get_account_fields() {
|
||||
return array(
|
||||
'api_key' => array(
|
||||
'label' => esc_html__( 'API Key', 'et_core' ),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function get_data_keymap( $keymap = array() ) {
|
||||
$keymap = array(
|
||||
'list' => array(
|
||||
'list_id' => 'ListID',
|
||||
'name' => 'Name',
|
||||
'subscribers_count' => 'TotalActiveSubscribers',
|
||||
),
|
||||
'subscriber' => array(
|
||||
'name' => 'Name',
|
||||
'email' => 'EmailAddress',
|
||||
'custom_fields' => 'custom_fields',
|
||||
),
|
||||
'error' => array(
|
||||
'error_message' => 'Message',
|
||||
),
|
||||
'custom_field' => array(
|
||||
'field_id' => 'Key',
|
||||
'name' => 'FieldName',
|
||||
'type' => 'DataType',
|
||||
'options' => 'FieldOptions',
|
||||
),
|
||||
'custom_field_type' => array(
|
||||
// Us => Them
|
||||
'input' => 'Text',
|
||||
'select' => 'MultiSelectOne',
|
||||
'checkbox' => 'MultiSelectMany',
|
||||
// Them => Us
|
||||
'Text' => 'input',
|
||||
'Number' => 'input',
|
||||
'Date' => 'input',
|
||||
'MultiSelectOne' => 'select',
|
||||
'MultiSelectMany' => 'checkbox',
|
||||
),
|
||||
);
|
||||
|
||||
return parent::get_data_keymap( $keymap );
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function fetch_subscriber_lists() {
|
||||
if ( empty( $this->data['api_key'] ) ) {
|
||||
return $this->API_KEY_REQUIRED;
|
||||
}
|
||||
|
||||
$clients = $this->_get_clients();
|
||||
$lists = array();
|
||||
|
||||
if ( ! is_array( $clients ) ) {
|
||||
// Request failed with an error, return the error message.
|
||||
return $clients;
|
||||
}
|
||||
|
||||
foreach ( $clients as $client_info ) {
|
||||
if ( empty( $client_info['ClientID'] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$url = "{$this->BASE_URL}/clients/{$client_info['ClientID']}/lists.json";
|
||||
|
||||
$this->prepare_request( $url );
|
||||
|
||||
parent::fetch_subscriber_lists();
|
||||
|
||||
if ( $this->response->ERROR ) {
|
||||
return $this->get_error_message();
|
||||
}
|
||||
|
||||
if ( isset( $this->response->DATA ) ) {
|
||||
$with_counts = $this->_get_subscriber_counts();
|
||||
$lists = $lists + $with_counts;
|
||||
$this->data['is_authorized'] = true;
|
||||
|
||||
$this->save_data();
|
||||
}
|
||||
}
|
||||
|
||||
if ( empty( $this->data['lists'] ) || ! empty( $lists ) ) {
|
||||
$this->data['lists'] = $lists;
|
||||
$this->save_data();
|
||||
}
|
||||
|
||||
return $this->is_authenticated() ? 'success' : $this->FAILURE_MESSAGE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function subscribe( $args, $url = '' ) {
|
||||
$url = "{$this->BASE_URL}/subscribers/{$args['list_id']}.json";
|
||||
$params = $this->transform_data_to_provider_format( $args, 'subscriber' );
|
||||
$params = $this->_process_custom_fields( $params );
|
||||
|
||||
$params['CustomFields'][] = array( 'Key' => 'Note', 'Value' => $this->SUBSCRIBED_VIA );
|
||||
|
||||
$this->prepare_request( $url, 'POST', false, $params, true );
|
||||
|
||||
return parent::subscribe( $params, $url );
|
||||
}
|
||||
}
|
255
core/components/api/email/ConstantContact.php
Normal file
255
core/components/api/email/ConstantContact.php
Normal file
@ -0,0 +1,255 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Wrapper for ConstantContact's API.
|
||||
*
|
||||
* @since 3.0.75
|
||||
*
|
||||
* @package ET\Core\API\Email
|
||||
*/
|
||||
class ET_Core_API_Email_ConstantContact extends ET_Core_API_Email_Provider {
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $BASE_URL = 'https://api.constantcontact.com/v2';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $LISTS_URL = 'https://api.constantcontact.com/v2/lists';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $SUBSCRIBE_URL = 'https://api.constantcontact.com/v2/contacts';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $SUBSCRIBERS_URL = 'https://api.constantcontact.com/v2/contacts';
|
||||
|
||||
protected $_subscriber;
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $custom_fields_scope = 'account';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $name = 'ConstantContact';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $slug = 'constant_contact';
|
||||
|
||||
/**
|
||||
* ET_Core_API_Email_ConstantContact constructor.
|
||||
*
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function __construct( $owner = '', $account_name = '', $api_key = '' ) {
|
||||
parent::__construct( $owner, $account_name, $api_key );
|
||||
|
||||
$this->_maybe_set_custom_headers();
|
||||
}
|
||||
|
||||
protected function _create_subscriber_data_array( $args ) {
|
||||
return $this->transform_data_to_provider_format( $args, 'subscriber' );
|
||||
}
|
||||
|
||||
protected function _fetch_custom_fields( $list_id = '', $list = array() ) {
|
||||
$fields = array();
|
||||
|
||||
foreach ( range( 1, 15 ) as $i ) {
|
||||
$fields["custom_field_{$i}"] = array(
|
||||
'field_id' => "custom_field_{$i}",
|
||||
'name' => "custom_field_{$i}",
|
||||
'type' => 'any',
|
||||
);
|
||||
}
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
protected function _get_list_from_subscriber( $subscriber, $list_id ) {
|
||||
if ( ! isset( $subscriber['lists'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ( $subscriber['lists'] as &$list ) {
|
||||
if ( $list['id'] === $list_id ) {
|
||||
return $list;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function _maybe_set_custom_headers() {
|
||||
if ( empty( $this->custom_headers ) && isset( $this->data['token'] ) ) {
|
||||
$this->custom_headers = array(
|
||||
'Authorization' => 'Bearer ' . sanitize_text_field( $this->data['token'] ),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
protected function _process_custom_fields( $args ) {
|
||||
if ( ! isset( $args['custom_fields'] ) ) {
|
||||
return $args;
|
||||
}
|
||||
|
||||
$fields = $args['custom_fields'];
|
||||
$processed_fields = array();
|
||||
|
||||
unset( $args['custom_fields'], $this->_subscriber['custom_fields_unprocessed'] );
|
||||
|
||||
foreach ( $fields as $field_id => $value ) {
|
||||
if ( is_array( $value ) && $value ) {
|
||||
// This is a multiple choice field (eg. checkbox, radio, select)
|
||||
$value = array_values( $value );
|
||||
|
||||
if ( count( $value ) > 1 ) {
|
||||
$value = implode( ',', $value );
|
||||
} else {
|
||||
$value = array_pop( $value );
|
||||
}
|
||||
}
|
||||
|
||||
$processed_fields[] = array(
|
||||
'name' => $field_id,
|
||||
'value' => $value,
|
||||
);
|
||||
}
|
||||
|
||||
if ( isset( $this->_subscriber['custom_fields'] ) ) {
|
||||
$processed_fields = array_merge( $processed_fields, $this->_subscriber['custom_fields'] );
|
||||
}
|
||||
|
||||
$this->_subscriber['custom_fields'] = array_unique( $processed_fields, SORT_REGULAR );
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function get_account_fields() {
|
||||
return array(
|
||||
'api_key' => array(
|
||||
'label' => esc_html__( 'API Key', 'et_core' ),
|
||||
),
|
||||
'token' => array(
|
||||
'label' => esc_html__( 'Access Token', 'et_core' ),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function get_data_keymap( $keymap = array() ) {
|
||||
$keymap = array(
|
||||
'list' => array(
|
||||
'list_id' => 'id',
|
||||
'name' => 'name',
|
||||
'subscribers_count' => 'contact_count',
|
||||
),
|
||||
'subscriber' => array(
|
||||
'name' => 'first_name',
|
||||
'last_name' => 'last_name',
|
||||
'email' => 'email_addresses.[0].email_address',
|
||||
'list_id' => 'lists.[0].id',
|
||||
'custom_fields' => 'custom_fields_unprocessed',
|
||||
),
|
||||
'error' => array(
|
||||
'error_message' => '[0].error_message',
|
||||
),
|
||||
'custom_field' => array(
|
||||
'field_id' => 'name',
|
||||
'name' => 'name',
|
||||
),
|
||||
);
|
||||
|
||||
return parent::get_data_keymap( $keymap );
|
||||
}
|
||||
|
||||
public function get_subscriber( $email ) {
|
||||
$url = add_query_arg( 'email', $email, $this->SUBSCRIBERS_URL );
|
||||
|
||||
$this->prepare_request( $url, 'GET', false );
|
||||
$this->make_remote_request();
|
||||
|
||||
if ( $this->response->ERROR || ! isset( $this->response->DATA['results'] ) ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
return $this->response->DATA['results'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function fetch_subscriber_lists() {
|
||||
if ( empty( $this->data['api_key'] ) || empty( $this->data['token'] ) ) {
|
||||
return $this->API_KEY_REQUIRED;
|
||||
}
|
||||
|
||||
$this->_maybe_set_custom_headers();
|
||||
|
||||
$this->response_data_key = false;
|
||||
|
||||
$this->LISTS_URL = add_query_arg( 'api_key', $this->data['api_key'], $this->LISTS_URL );
|
||||
|
||||
return parent::fetch_subscriber_lists();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function subscribe( $args, $url = '' ) {
|
||||
$this->SUBSCRIBERS_URL = add_query_arg( 'api_key', $this->data['api_key'], $this->SUBSCRIBERS_URL );
|
||||
$result = null;
|
||||
$args['list_id'] = (string) $args['list_id'];
|
||||
|
||||
$subscriber = $this->get_subscriber( $args['email'] );
|
||||
$subscriber = $subscriber ? $subscriber[0] : $subscriber;
|
||||
|
||||
$query_args = array( 'api_key' => $this->data['api_key'], 'action_by' => 'ACTION_BY_VISITOR' );
|
||||
|
||||
if ( $subscriber ) {
|
||||
if ( $list = $this->_get_list_from_subscriber( $subscriber, $args['list_id'] ) ) {
|
||||
$result = 'success';
|
||||
} else {
|
||||
$subscriber['lists'][] = array( 'id' => $args['list_id'] );
|
||||
|
||||
$this->_subscriber = &$subscriber;
|
||||
|
||||
$args = $this->_process_custom_fields( $args );
|
||||
|
||||
$url = add_query_arg( $query_args, "{$this->SUBSCRIBE_URL}/{$subscriber['id']}" );
|
||||
|
||||
$this->prepare_request( $url, 'PUT', false, $subscriber, true );
|
||||
}
|
||||
|
||||
} else {
|
||||
$url = add_query_arg( $query_args, $this->SUBSCRIBE_URL );
|
||||
$subscriber = $this->_create_subscriber_data_array( $args );
|
||||
|
||||
$this->_subscriber = &$subscriber;
|
||||
|
||||
$args = $this->_process_custom_fields( $args );
|
||||
|
||||
$this->prepare_request( $url, 'POST', false, $subscriber, true );
|
||||
}
|
||||
|
||||
if ( 'success' !== $result ) {
|
||||
$result = parent::subscribe( $args, $this->SUBSCRIBE_URL );
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
224
core/components/api/email/ConvertKit.php
Normal file
224
core/components/api/email/ConvertKit.php
Normal file
@ -0,0 +1,224 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Wrapper for ConvertKit's API.
|
||||
*
|
||||
* @since 1.1.0
|
||||
*
|
||||
* @package ET\Core\API\Email
|
||||
*/
|
||||
class ET_Core_API_Email_ConvertKit extends ET_Core_API_Email_Provider {
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $BASE_URL = 'https://api.convertkit.com/v3';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $custom_fields_scope = 'account';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $name = 'ConvertKit';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $name_field_only = true;
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $slug = 'convertkit';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $uses_oauth = false;
|
||||
|
||||
/**
|
||||
* ET_Core_API_Email_ConvertKit constructor.
|
||||
*
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function __construct( $owner, $account_name = '', $api_key = '' ) {
|
||||
parent::__construct( $owner, $account_name, $api_key );
|
||||
|
||||
// ConvertKit doesn't have "lists". They have "forms" so we use "forms" as if they were "lists".
|
||||
$this->LISTS_URL = "{$this->BASE_URL}/forms";
|
||||
}
|
||||
|
||||
protected function _fetch_custom_fields( $list_id = '', $list = array() ) {
|
||||
$this->response_data_key = 'custom_fields';
|
||||
|
||||
$this->prepare_request( $this->_generate_url_for_request( "{$this->BASE_URL}/custom_fields" ) );
|
||||
|
||||
return parent::_fetch_custom_fields( $list_id, $list );
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the URL for adding subscribers.
|
||||
*
|
||||
* @param $list_id
|
||||
*
|
||||
* @since 1.1.0
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function _get_subscribe_url( $list_id ) {
|
||||
return "{$this->LISTS_URL}/{$list_id}/subscribe";
|
||||
}
|
||||
|
||||
protected function _get_subscriber_counts( $forms ) {
|
||||
$result = array();
|
||||
|
||||
foreach ( (array) $forms as $form_info ) {
|
||||
$url = $this->_generate_url_for_request( "{$this->LISTS_URL}/{$form_info['id']}/subscriptions", true );
|
||||
|
||||
$this->prepare_request( $url );
|
||||
$this->make_remote_request();
|
||||
|
||||
if ( $this->response->ERROR || ! isset( $this->response->DATA['total_subscriptions'] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$form_info['total_subscriptions'] = $this->response->DATA['total_subscriptions'];
|
||||
|
||||
$result[] = $form_info;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds default args for all API requests to given url.
|
||||
*
|
||||
* @since 1.1.0
|
||||
*
|
||||
* @param string $url
|
||||
* @param bool $with_secret
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function _generate_url_for_request( $url, $with_secret = false ) {
|
||||
$key = $with_secret ? $this->data['api_secret'] : $this->data['api_key'];
|
||||
$key_type = $with_secret ? 'api_secret' : 'api_key';
|
||||
|
||||
return esc_url_raw( add_query_arg( $key_type, $key, $url ) );
|
||||
}
|
||||
|
||||
protected function _process_custom_fields( $args ) {
|
||||
if ( ! isset( $args['custom_fields'] ) ) {
|
||||
return $args;
|
||||
}
|
||||
|
||||
$fields = $args['custom_fields'];
|
||||
|
||||
unset( $args['custom_fields'] );
|
||||
|
||||
foreach ( $fields as $field_id => $value ) {
|
||||
if ( is_array( $value ) && $value ) {
|
||||
// This is a multiple choice field (eg. checkbox, radio, select)
|
||||
$value = array_values( $value );
|
||||
|
||||
if ( count( $value ) > 1 ) {
|
||||
$value = implode( ',', $value );
|
||||
} else {
|
||||
$value = array_pop( $value );
|
||||
}
|
||||
}
|
||||
|
||||
self::$_->array_set( $args, "fields.{$field_id}", $value );
|
||||
}
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function get_account_fields() {
|
||||
return array(
|
||||
'api_key' => array(
|
||||
'label' => esc_html__( 'API Key', 'et_core' ),
|
||||
),
|
||||
'api_secret' => array(
|
||||
'label' => esc_html__( 'API Secret', 'et_core' ),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function get_data_keymap( $keymap = array() ) {
|
||||
$keymap = array(
|
||||
'list' => array(
|
||||
'list_id' => 'id',
|
||||
'name' => 'name',
|
||||
'subscribers_count' => 'total_subscriptions',
|
||||
),
|
||||
'subscriber' => array(
|
||||
'email' => 'email',
|
||||
'name' => 'first_name',
|
||||
'custom_fields' => 'custom_fields',
|
||||
),
|
||||
'error' => array(
|
||||
'error_message' => 'message',
|
||||
),
|
||||
'custom_field' => array(
|
||||
'field_id' => 'key',
|
||||
'name' => 'label',
|
||||
),
|
||||
);
|
||||
|
||||
return parent::get_data_keymap( $keymap );
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function fetch_subscriber_lists() {
|
||||
if ( empty( $this->data['api_key'] ) ) {
|
||||
return $this->API_KEY_REQUIRED;
|
||||
}
|
||||
|
||||
$url = $this->_generate_url_for_request( $this->LISTS_URL );
|
||||
$result = 'success';
|
||||
|
||||
$this->response_data_key = '';
|
||||
|
||||
$this->prepare_request( $url );
|
||||
parent::fetch_subscriber_lists();
|
||||
|
||||
if ( ! $this->response->ERROR && ! empty( $this->response->DATA['forms'] ) ) {
|
||||
$with_subscriber_counts = $this->_get_subscriber_counts( $this->response->DATA['forms'] );
|
||||
$this->data['lists'] = $this->_process_subscriber_lists( $with_subscriber_counts );
|
||||
$this->data['is_authorized'] = 'true';
|
||||
$this->data['custom_fields'] = $this->_fetch_custom_fields( '', array_shift( $this->response->DATA['forms'] ) );
|
||||
|
||||
$this->save_data();
|
||||
} else if ( $this->response->ERROR ) {
|
||||
$result = $this->get_error_message();
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function subscribe( $args, $url = '' ) {
|
||||
$url = $this->_generate_url_for_request( $this->_get_subscribe_url( $args['list_id'] ) );
|
||||
$params = $this->transform_data_to_provider_format( $args, 'subscriber' );
|
||||
$params = $this->_process_custom_fields( $params );
|
||||
$params['fields']['notes'] = $this->SUBSCRIBED_VIA;
|
||||
|
||||
$this->prepare_request( $url, 'POST', false, $params );
|
||||
|
||||
return parent::subscribe( $params, $url );
|
||||
}
|
||||
}
|
167
core/components/api/email/Emma.php
Normal file
167
core/components/api/email/Emma.php
Normal file
@ -0,0 +1,167 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Wrapper for Emma's API.
|
||||
*
|
||||
* @since 1.1.0
|
||||
*
|
||||
* @package ET\Core\API\Email
|
||||
*/
|
||||
class ET_Core_API_Email_Emma extends ET_Core_API_Email_Provider {
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $BASE_URL = 'https://api.e2ma.net';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $custom_fields_scope = 'account';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $http_auth = array(
|
||||
'username' => 'api_key',
|
||||
'password' => 'private_api_key',
|
||||
);
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $name = 'Emma';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $slug = 'emma';
|
||||
|
||||
protected function _fetch_custom_fields( $list_id = '', $list = array() ) {
|
||||
$this->response_data_key = false;
|
||||
|
||||
$this->prepare_request( $this->_get_custom_fields_url() );
|
||||
|
||||
return parent::_fetch_custom_fields( $list_id, $list );
|
||||
}
|
||||
|
||||
protected function _get_custom_fields_url() {
|
||||
return "https://api.e2ma.net/{$this->data['user_id']}/fields?group_types=all";
|
||||
}
|
||||
|
||||
protected function _get_lists_url() {
|
||||
return "https://api.e2ma.net/{$this->data['user_id']}/groups?group_types=all";
|
||||
}
|
||||
|
||||
protected function _get_subscribe_url() {
|
||||
return "https://api.e2ma.net/{$this->data['user_id']}/members/signup";
|
||||
}
|
||||
|
||||
protected function _process_custom_fields( $args ) {
|
||||
if ( ! isset( $args['custom_fields'] ) ) {
|
||||
return $args;
|
||||
}
|
||||
|
||||
$fields = $args['custom_fields'];
|
||||
|
||||
unset( $args['custom_fields'] );
|
||||
|
||||
foreach ( $fields as $field_id => $value ) {
|
||||
if ( is_array( $value ) && $value ) {
|
||||
// This is a multiple choice field (eg. checkbox, radio, select)
|
||||
$value = array_values( $value );
|
||||
}
|
||||
|
||||
self::$_->array_set( $args, "fields.{$field_id}", $value );
|
||||
}
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function get_account_fields() {
|
||||
return array(
|
||||
'api_key' => array(
|
||||
'label' => esc_html__( 'Public API Key', 'et_core' ),
|
||||
),
|
||||
'private_api_key' => array(
|
||||
'label' => esc_html__( 'Private API Key', 'et_core' ),
|
||||
),
|
||||
'user_id' => array(
|
||||
'label' => esc_html__( 'Account ID', 'et_core' ),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function get_data_keymap( $keymap = array() ) {
|
||||
$keymap = array(
|
||||
'list' => array(
|
||||
'name' => 'group_name',
|
||||
'list_id' => 'member_group_id',
|
||||
'subscribers_count' => 'active_count',
|
||||
),
|
||||
'subscriber' => array(
|
||||
'email' => 'email',
|
||||
'name' => 'fields.first_name',
|
||||
'last_name' => 'fields.last_name',
|
||||
'list_id' => '@group_ids',
|
||||
'custom_fields' => 'custom_fields',
|
||||
),
|
||||
'custom_field' => array(
|
||||
'field_id' => 'shortcut_name',
|
||||
'name' => 'display_name',
|
||||
'options' => 'options',
|
||||
'type' => 'widget_type',
|
||||
),
|
||||
'custom_field_type' => array(
|
||||
// Us <=> Them
|
||||
'radio' => 'radio',
|
||||
// Us => Them
|
||||
'select' => 'select one',
|
||||
'text' => 'long',
|
||||
'checkbox' => 'check_multiple',
|
||||
// Them => Us
|
||||
'text' => 'input',
|
||||
'long' => 'text',
|
||||
'check_multiple' => 'checkbox',
|
||||
'select one' => 'select',
|
||||
),
|
||||
);
|
||||
|
||||
return parent::get_data_keymap( $keymap );
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function fetch_subscriber_lists() {
|
||||
if ( empty( $this->data['api_key'] ) ) {
|
||||
return $this->API_KEY_REQUIRED;
|
||||
}
|
||||
|
||||
$this->LISTS_URL = $this->_get_lists_url();
|
||||
$this->response_data_key = false;
|
||||
|
||||
return parent::fetch_subscriber_lists();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function subscribe( $args, $url = '' ) {
|
||||
$url = $this->_get_subscribe_url();
|
||||
$this->response_data_key = 'member_id';
|
||||
|
||||
$args = $this->transform_data_to_provider_format( $args, 'subscriber' );
|
||||
$args = $this->_process_custom_fields( $args );
|
||||
|
||||
$this->prepare_request( $url, 'POST', false, $args, true );
|
||||
|
||||
return parent::subscribe( $args, $url );
|
||||
}
|
||||
}
|
172
core/components/api/email/Feedblitz.php
Normal file
172
core/components/api/email/Feedblitz.php
Normal file
@ -0,0 +1,172 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Wrapper for Feedblitz's API.
|
||||
*
|
||||
* @since 1.1.0
|
||||
*
|
||||
* @package ET\Core\API\Email
|
||||
*/
|
||||
class ET_Core_API_Email_Feedblitz extends ET_Core_API_Email_Provider {
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $BASE_URL = 'https://www.feedblitz.com';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $LISTS_URL = 'https://www.feedblitz.com/f.api/syndications';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $SUBSCRIBE_URL = 'https://www.feedblitz.com/f';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $custom_fields = 'dynamic';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $custom_fields_scope = 'account';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $name = 'Feedblitz';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $slug = 'feedblitz';
|
||||
|
||||
protected function _process_custom_fields( $args ) {
|
||||
if ( ! isset( $args['custom_fields'] ) ) {
|
||||
return $args;
|
||||
}
|
||||
|
||||
$fields = $args['custom_fields'];
|
||||
|
||||
unset( $args['custom_fields'] );
|
||||
|
||||
foreach ( $fields as $field_id => $value ) {
|
||||
if ( is_array( $value ) && $value ) {
|
||||
// This is a multiple choice field (eg. checkbox, radio, select)
|
||||
$value = array_values( $value );
|
||||
|
||||
if ( count( $value ) > 1 ) {
|
||||
$value = implode( ',', $value );
|
||||
} else {
|
||||
$value = array_pop( $value );
|
||||
}
|
||||
}
|
||||
|
||||
self::$_->array_set( $args, $field_id, rawurlencode( $value ) );
|
||||
}
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function get_account_fields() {
|
||||
return array(
|
||||
'api_key' => array(
|
||||
'label' => esc_html__( 'API Key', 'et_core' ),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function get_data_keymap( $keymap = array() ) {
|
||||
$keymap = array(
|
||||
'list' => array(
|
||||
'list_id' => 'id',
|
||||
'name' => 'name',
|
||||
'subscribers_count' => 'subscribersummary.subscribers',
|
||||
),
|
||||
'subscriber' => array(
|
||||
'list_id' => 'listid',
|
||||
'email' => 'email',
|
||||
'name' => 'FirstName',
|
||||
'last_name' => 'LastName',
|
||||
'custom_fields' => 'custom_fields',
|
||||
),
|
||||
'error' => array(
|
||||
'error_message' => 'rsp.err.@attributes.msg',
|
||||
)
|
||||
);
|
||||
|
||||
return parent::get_data_keymap( $keymap );
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function fetch_subscriber_lists() {
|
||||
if ( empty( $this->data['api_key'] ) ) {
|
||||
return $this->API_KEY_REQUIRED;
|
||||
}
|
||||
|
||||
$this->http->expects_json = false;
|
||||
$this->response_data_key = false;
|
||||
$this->LISTS_URL = add_query_arg( 'key', $this->data['api_key'], $this->LISTS_URL );
|
||||
|
||||
parent::fetch_subscriber_lists();
|
||||
|
||||
$response = $this->data_utils->process_xmlrpc_response( $this->response->DATA, true );
|
||||
$response = $this->data_utils->xml_to_array( $response );
|
||||
|
||||
if ( $this->response->ERROR || ! empty( $response['rsp']['err']['@attributes']['msg'] ) ) {
|
||||
return $this->get_error_message();
|
||||
}
|
||||
|
||||
$this->data['lists'] = $this->_process_subscriber_lists( $response['syndications']['syndication'] );
|
||||
$this->data['is_authorized'] = true;
|
||||
|
||||
$this->save_data();
|
||||
|
||||
return 'success';
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function subscribe( $args, $url = '' ) {
|
||||
$query_args = array(
|
||||
'email' => rawurlencode( $args['email'] ),
|
||||
'name' => empty( $args['name'] ) ? '' : rawurlencode( $args['name'] ),
|
||||
'last_name' => empty( $args['last_name'] ) ? '' : rawurlencode( $args['last_name'] ),
|
||||
'custom_fields' => $args['custom_fields'],
|
||||
'list_id' => $args['list_id'],
|
||||
);
|
||||
|
||||
$query = $this->transform_data_to_provider_format( $query_args, 'subscriber' );
|
||||
$query = $this->_process_custom_fields( $query );
|
||||
$query['key'] = rawurlencode( $this->data['api_key'] );
|
||||
$url = add_query_arg( $query, "{$this->SUBSCRIBE_URL}?SimpleApiSubscribe" );
|
||||
|
||||
$this->prepare_request( $url, 'GET', false, null, false, false );
|
||||
$this->make_remote_request();
|
||||
|
||||
$response = $this->data_utils->process_xmlrpc_response( $this->response->DATA, true );
|
||||
$response = $this->data_utils->xml_to_array( $response );
|
||||
|
||||
if ( $this->response->ERROR || ! empty( $response['rsp']['err']['@attributes']['msg'] ) ) {
|
||||
return $this->get_error_message();
|
||||
}
|
||||
|
||||
if ( ! empty( $response['rsp']['success']['@attributes']['msg'] ) ) {
|
||||
return $response['rsp']['success']['@attributes']['msg'];
|
||||
}
|
||||
|
||||
return 'success';
|
||||
}
|
||||
}
|
436
core/components/api/email/Fields.php
Normal file
436
core/components/api/email/Fields.php
Normal file
@ -0,0 +1,436 @@
|
||||
<?php
|
||||
|
||||
|
||||
class ET_Core_API_Email_Fields {
|
||||
|
||||
/**
|
||||
* @var ET_Core_Data_Utils
|
||||
*/
|
||||
protected static $_;
|
||||
|
||||
protected static $_any_custom_field_type_support;
|
||||
protected static $_predefined_custom_field_support;
|
||||
|
||||
/**
|
||||
* @var ET_Core_API_Email_Providers
|
||||
*/
|
||||
protected static $_providers;
|
||||
|
||||
public static $owner;
|
||||
|
||||
protected static function _custom_field_definitions() {
|
||||
$readonly_dependency = 'builder' === self::$owner ? 'parentModule:provider' : 'email_provider';
|
||||
$custom_fields_support = array_keys( self::$_providers->names_by_slug( 'all', 'custom_fields' ) );
|
||||
$custom_fields_data = self::$_providers->custom_fields_data();
|
||||
$fields = array();
|
||||
|
||||
if ( 'bloom' === self::$owner ) {
|
||||
$fields = array(
|
||||
'use_custom_fields' => array(
|
||||
'label' => esc_html__( 'Use Custom Fields', 'et_core' ),
|
||||
'type' => 'yes_no_button',
|
||||
'options' => array(
|
||||
'on' => esc_html__( 'Yes', 'et_core' ),
|
||||
'off' => esc_html__( 'No', 'et_core' ),
|
||||
),
|
||||
'default' => 'off',
|
||||
'show_if' => array(
|
||||
'email_provider' => $custom_fields_support,
|
||||
),
|
||||
'allow_dynamic' => array_keys( self::$_providers->names_by_slug( 'all', 'dynamic_custom_fields' ) ),
|
||||
'description' => esc_html__( 'Enable this option to use custom fields in your opt-in form.', 'et_core' ),
|
||||
),
|
||||
'custom_fields' => array(
|
||||
'type' => 'sortable_list',
|
||||
'label' => '',
|
||||
'default' => '[]',
|
||||
),
|
||||
'editing_field' => array(
|
||||
'type' => 'skip',
|
||||
'default' => 'off',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
foreach ( $custom_fields_data as $provider => $accounts ) {
|
||||
foreach ( $accounts as $account => $lists ) {
|
||||
$account_name = str_replace( ' ', '', strtolower( $account ) );
|
||||
$key = "predefined_field_{$provider}_{$account_name}";
|
||||
|
||||
if ( isset( $lists['custom_fields'] ) ) {
|
||||
// Custom fields are per account
|
||||
$fields[ $key ] = self::_predefined_custom_field_select( $lists['custom_fields'], $provider, $account );
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ( $lists as $list_id => $custom_fields ) {
|
||||
// Custom fields are per list
|
||||
$key = "predefined_field_{$provider}_{$account_name}_{$list_id}";
|
||||
$fields[ $key ] = self::_predefined_custom_field_select( $custom_fields, $provider, $account, $list_id );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$labels = array(
|
||||
'link_url' => esc_html__( 'Link URL', 'et_core' ),
|
||||
'link_text' => esc_html__( 'Link Text', 'et_core' ),
|
||||
'link_cancel' => esc_html__( 'Discard Changes', 'et_core' ),
|
||||
'link_save' => esc_html__( 'Save Changes', 'et_core' ),
|
||||
'link_settings' => esc_html__( 'Option Link', 'et_core' ),
|
||||
);
|
||||
|
||||
$fields = array_merge( $fields, array(
|
||||
'predefined_field' => array(
|
||||
'type' => 'skip',
|
||||
'default' => 'none',
|
||||
),
|
||||
'field_id' => array(
|
||||
'label' => esc_html__( 'ID', 'et_core' ),
|
||||
'type' => 'text',
|
||||
'default' => '', // <--- Intentional
|
||||
'description' => esc_html__( 'Define a unique ID for this field. You should use only English characters without special characters or spaces.', 'et_core' ),
|
||||
'toggle_slug' => 'main_content',
|
||||
'readonly_if' => array(
|
||||
$readonly_dependency => self::$_predefined_custom_field_support,
|
||||
),
|
||||
),
|
||||
'field_title' => array(
|
||||
'label' => esc_html__( 'Name', 'et_core' ),
|
||||
'type' => 'text',
|
||||
'description' => esc_html__( 'Set the label that will appear above this field in the opt-in form.', 'et_core' ),
|
||||
'toggle_slug' => 'main_content',
|
||||
'readonly_if' => array(
|
||||
$readonly_dependency => self::$_predefined_custom_field_support,
|
||||
),
|
||||
'readonly_if_not' => array(
|
||||
$readonly_dependency => array( 'getresponse', 'sendinblue', 'constant_contact', 'fluentcrm' ),
|
||||
),
|
||||
),
|
||||
'field_type' => array(
|
||||
'label' => esc_html__( 'Type', 'et_core' ),
|
||||
'type' => 'select',
|
||||
'default' => 'none',
|
||||
'option_category' => 'basic_option',
|
||||
'options' => array(
|
||||
'none' => esc_html__( 'Choose a field type...', 'et_core' ),
|
||||
'input' => esc_html__( 'Input Field', 'et_core' ),
|
||||
'email' => esc_html__( 'Email Field', 'et_core' ),
|
||||
'text' => esc_html__( 'Textarea', 'et_core' ),
|
||||
'checkbox' => esc_html__( 'Checkboxes', 'et_core' ),
|
||||
'radio' => esc_html__( 'Radio Buttons', 'et_core' ),
|
||||
'select' => esc_html__( 'Select Dropdown', 'et_core' ),
|
||||
),
|
||||
'description' => esc_html__( 'Choose the type of field', 'et_core' ),
|
||||
'toggle_slug' => 'field_options',
|
||||
'readonly_if' => array(
|
||||
$readonly_dependency => self::$_predefined_custom_field_support,
|
||||
),
|
||||
'readonly_if_not' => array(
|
||||
$readonly_dependency => self::$_any_custom_field_type_support,
|
||||
),
|
||||
),
|
||||
'checkbox_checked' => array(
|
||||
'label' => esc_html__( 'Checked By Default', 'et_core' ),
|
||||
'description' => esc_html__( 'If enabled, the check mark will be automatically selected for the visitor. They can still deselect it.', 'et_core' ),
|
||||
'type' => 'hidden',
|
||||
'option_category' => 'layout',
|
||||
'default' => 'off',
|
||||
'toggle_slug' => 'field_options',
|
||||
'show_if' => array(
|
||||
'field_type' => 'checkbox',
|
||||
),
|
||||
),
|
||||
'checkbox_options' => array(
|
||||
'label' => esc_html__( 'Options', 'et_core' ),
|
||||
'type' => 'sortable_list',
|
||||
'checkbox' => true,
|
||||
'option_category' => 'basic_option',
|
||||
'toggle_slug' => 'field_options',
|
||||
'readonly_if' => array(
|
||||
$readonly_dependency => self::$_predefined_custom_field_support,
|
||||
),
|
||||
'readonly_if_not' => array(
|
||||
$readonly_dependency => self::$_any_custom_field_type_support,
|
||||
),
|
||||
'show_if' => array(
|
||||
'field_type' => 'checkbox',
|
||||
),
|
||||
'right_actions' => 'move|link|copy|delete',
|
||||
'right_actions_readonly' => 'move|link',
|
||||
'labels' => $labels,
|
||||
),
|
||||
'radio_options' => array(
|
||||
'label' => esc_html__( 'Options', 'et_core' ),
|
||||
'type' => 'sortable_list',
|
||||
'radio' => true,
|
||||
'option_category' => 'basic_option',
|
||||
'toggle_slug' => 'field_options',
|
||||
'readonly_if' => array(
|
||||
$readonly_dependency => self::$_predefined_custom_field_support,
|
||||
),
|
||||
'readonly_if_not' => array(
|
||||
$readonly_dependency => self::$_any_custom_field_type_support,
|
||||
),
|
||||
'show_if' => array(
|
||||
'field_type' => 'radio',
|
||||
),
|
||||
'right_actions' => 'move|link|copy|delete',
|
||||
'right_actions_readonly' => 'move|link',
|
||||
'labels' => $labels,
|
||||
),
|
||||
'select_options' => array(
|
||||
'label' => esc_html__( 'Options', 'et_core' ),
|
||||
'type' => 'sortable_list',
|
||||
'option_category' => 'basic_option',
|
||||
'toggle_slug' => 'field_options',
|
||||
'readonly_if' => array(
|
||||
$readonly_dependency => self::$_predefined_custom_field_support,
|
||||
),
|
||||
'readonly_if_not' => array(
|
||||
$readonly_dependency => self::$_any_custom_field_type_support,
|
||||
),
|
||||
'show_if' => array(
|
||||
'field_type' => 'select',
|
||||
),
|
||||
'right_actions' => 'move|copy|delete',
|
||||
'right_actions_readonly' => 'move',
|
||||
),
|
||||
'min_length' => array(
|
||||
'label' => esc_html__( 'Minimum Length', 'et_core' ),
|
||||
'description' => esc_html__( 'Leave at 0 to remove restriction', 'et_core' ),
|
||||
'type' => 'range',
|
||||
'default' => '0',
|
||||
'unitless' => true,
|
||||
'range_settings' => array(
|
||||
'min' => '0',
|
||||
'max' => '255',
|
||||
'step' => '1',
|
||||
),
|
||||
'option_category' => 'basic_option',
|
||||
'toggle_slug' => 'field_options',
|
||||
'show_if' => array(
|
||||
'field_type' => 'input',
|
||||
),
|
||||
),
|
||||
'max_length' => array(
|
||||
'label' => esc_html__( 'Maximum Length', 'et_core' ),
|
||||
'description' => esc_html__( 'Leave at 0 to remove restriction', 'et_core' ),
|
||||
'type' => 'range',
|
||||
'default' => '0',
|
||||
'unitless' => true,
|
||||
'range_settings' => array(
|
||||
'min' => '0',
|
||||
'max' => '255',
|
||||
'step' => '1',
|
||||
),
|
||||
'option_category' => 'basic_option',
|
||||
'toggle_slug' => 'field_options',
|
||||
'show_if' => array(
|
||||
'field_type' => 'input',
|
||||
),
|
||||
),
|
||||
'allowed_symbols' => array(
|
||||
'label' => esc_html__( 'Allowed Symbols', 'et_core' ),
|
||||
'description' => esc_html__( 'You can validate certain types of information by disallowing certain symbols. Symbols added here will prevent the form from being submitted if added by the user.', 'et_core' ),
|
||||
'type' => 'select',
|
||||
'default' => 'all',
|
||||
'options' => array(
|
||||
'all' => esc_html__( 'All', 'et_core' ),
|
||||
'letters' => esc_html__( 'Letters Only (A-Z)', 'et_core' ),
|
||||
'numbers' => esc_html__( 'Numbers Only (0-9)', 'et_core' ),
|
||||
'alphanumeric' => esc_html__( 'Alphanumeric Only (A-Z, 0-9)', 'et_core' ),
|
||||
),
|
||||
'option_category' => 'basic_option',
|
||||
'toggle_slug' => 'field_options',
|
||||
'show_if' => array(
|
||||
'field_type' => 'input',
|
||||
),
|
||||
),
|
||||
'required_mark' => array(
|
||||
'label' => esc_html__( 'Required Field', 'et_core' ),
|
||||
'type' => 'yes_no_button',
|
||||
'option_category' => 'configuration',
|
||||
'default' => 'on',
|
||||
'options' => array(
|
||||
'on' => esc_html__( 'Yes', 'et_core' ),
|
||||
'off' => esc_html__( 'No', 'et_core' ),
|
||||
),
|
||||
'description' => esc_html__( 'Define whether the field should be required or optional', 'et_core' ),
|
||||
'toggle_slug' => 'field_options',
|
||||
'show_if_not' => array(
|
||||
'email_provider' => 'getresponse',
|
||||
),
|
||||
),
|
||||
'hidden' => array(
|
||||
'label' => esc_html__( 'Hidden Field', 'et_core' ),
|
||||
'type' => 'yes_no_button',
|
||||
'option_category' => 'configuration',
|
||||
'default' => 'off',
|
||||
'options' => array(
|
||||
'on' => esc_html__( 'Yes', 'et_core' ),
|
||||
'off' => esc_html__( 'No', 'et_core' ),
|
||||
),
|
||||
'description' => esc_html__( 'Define whether or not the field should be visible.', 'et_core' ),
|
||||
'toggle_slug' => 'field_options',
|
||||
'readonly_if' => array(
|
||||
$readonly_dependency => self::$_predefined_custom_field_support,
|
||||
),
|
||||
'readonly_if_not' => array(
|
||||
$readonly_dependency => self::$_any_custom_field_type_support,
|
||||
),
|
||||
),
|
||||
'fullwidth_field' => array(
|
||||
'label' => esc_html__( 'Make Fullwidth', 'et_core' ),
|
||||
'type' => 'yes_no_button',
|
||||
'option_category' => 'layout',
|
||||
'options' => array(
|
||||
'on' => esc_html__( 'Yes', 'et_core' ),
|
||||
'off' => esc_html__( 'No', 'et_core' ),
|
||||
),
|
||||
'tab_slug' => 'advanced',
|
||||
'toggle_slug' => 'layout',
|
||||
'description' => esc_html__( 'If enabled, the field will take 100% of the width of the form, otherwise it will take 50%', 'et_core' ),
|
||||
'default' => array( 'parent:layout', array(
|
||||
'left_right' => 'on',
|
||||
'right_left' => 'on',
|
||||
'top_bottom' => 'off',
|
||||
'bottom_top' => 'off',
|
||||
)),
|
||||
),
|
||||
) );
|
||||
|
||||
if ( 'builder' === self::$owner ) {
|
||||
$fields = array_merge( $fields, array(
|
||||
'field_background_color' => array(
|
||||
'label' => esc_html__( 'Field Background Color', 'et_core' ),
|
||||
'description' => esc_html__( "Pick a color to fill the module's input fields.", 'et_core' ),
|
||||
'type' => 'color-alpha',
|
||||
'custom_color' => true,
|
||||
'toggle_slug' => 'form_field',
|
||||
'tab_slug' => 'advanced',
|
||||
),
|
||||
'conditional_logic' => array(
|
||||
'label' => esc_html__( 'Enable', 'et_core' ),
|
||||
'type' => 'yes_no_button',
|
||||
'option_category' => 'layout',
|
||||
'default' => 'off',
|
||||
'options' => array(
|
||||
'on' => esc_html__( 'Yes', 'et_core' ),
|
||||
'off' => esc_html__( 'No', 'et_core' ),
|
||||
),
|
||||
'description' => et_get_safe_localization( __( "Enabling conditional logic makes this field only visible when any or all of the rules below are fulfilled<br><strong>Note:</strong> Only fields with an unique and non-empty field ID can be used", 'et_core' ) ),
|
||||
'toggle_slug' => 'conditional_logic',
|
||||
),
|
||||
'conditional_logic_relation' => array(
|
||||
'label' => esc_html__( 'Relation', 'et_core' ),
|
||||
'type' => 'yes_no_button',
|
||||
'option_category' => 'layout',
|
||||
'options' => array(
|
||||
'on' => esc_html__( 'All', 'et_core' ),
|
||||
'off' => esc_html__( 'Any', 'et_core' ),
|
||||
),
|
||||
'default' => 'off',
|
||||
'button_options' => array(
|
||||
'button_type' => 'equal',
|
||||
),
|
||||
'description' => esc_html__( 'Choose whether any or all of the rules should be fulfilled', 'et_core' ),
|
||||
'toggle_slug' => 'conditional_logic',
|
||||
'show_if' => array(
|
||||
'conditional_logic' => 'on',
|
||||
),
|
||||
),
|
||||
'conditional_logic_rules' => array(
|
||||
'label' => esc_html__( 'Rules', 'et_core' ),
|
||||
'description' => esc_html__( 'Conditional logic rules can be used to hide and display different input fields conditionally based on how the visitor has interacted with different inputs.', 'et_core' ),
|
||||
'type' => 'conditional_logic',
|
||||
'option_category' => 'layout',
|
||||
'depends_show_if' => 'on',
|
||||
'toggle_slug' => 'conditional_logic',
|
||||
'show_if' => array(
|
||||
'conditional_logic' => 'on',
|
||||
),
|
||||
),
|
||||
) );
|
||||
}
|
||||
|
||||
if ( 'bloom' === self::$owner ) {
|
||||
foreach ( $fields as $field_slug => &$field ) {
|
||||
if ( 'use_custom_fields' !== $field_slug ) {
|
||||
self::$_->array_set( $field, 'show_if.use_custom_fields', 'on' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
protected static function _predefined_custom_field_select( $custom_fields, $provider, $account_name, $list_id = '' ) {
|
||||
$is_builder = 'builder' === self::$owner;
|
||||
$is_bloom = 'bloom' === self::$owner;
|
||||
$dependency = $is_builder ? 'parentModule:provider' : 'email_provider';
|
||||
$show_if = array(
|
||||
$dependency => $provider,
|
||||
);
|
||||
|
||||
if ( $is_bloom ) {
|
||||
$show_if['account_name'] = $account_name;
|
||||
}
|
||||
|
||||
if ( $list_id && $is_builder ) {
|
||||
$dependency = "parentModule:{$provider}_list";
|
||||
$show_if[ $dependency ] = "{$account_name}|{$list_id}";
|
||||
} else if ( $list_id && $is_bloom ) {
|
||||
$show_if['email_list'] = (string) $list_id;
|
||||
}
|
||||
|
||||
$options = array( 'none' => esc_html__( 'Choose a field...', 'et_core' ) );
|
||||
|
||||
foreach ( $custom_fields as $field ) {
|
||||
$field_id = isset( $field['group_id'] ) ? $field['group_id'] : $field['field_id'];
|
||||
$options[ $field_id ] = $field['name'];
|
||||
}
|
||||
|
||||
return array(
|
||||
'label' => esc_html__( 'Field', 'et_core' ),
|
||||
'type' => 'select',
|
||||
'options' => $options,
|
||||
'order' => array_keys( $options ),
|
||||
'show_if' => $show_if,
|
||||
'toggle_slug' => 'main_content',
|
||||
'default' => 'none',
|
||||
'description' => esc_html__( 'Choose a custom field. Custom fields must be defined in your email provider account.', 'et_core' ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get field definitions
|
||||
*
|
||||
* @since 3.10
|
||||
*
|
||||
* @param string $type Accepts 'custom_field'
|
||||
* @param string $for Accepts 'builder', 'bloom'
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_definitions( $for, $type = 'custom_field' ) {
|
||||
self::$owner = $for;
|
||||
$fields = array();
|
||||
|
||||
if ( 'custom_field' === $type ) {
|
||||
$fields = self::_custom_field_definitions();
|
||||
}
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
public static function initialize() {
|
||||
self::$_ = ET_Core_Data_Utils::instance();
|
||||
self::$_providers = ET_Core_API_Email_Providers::instance();
|
||||
|
||||
self::$_predefined_custom_field_support = array_keys( self::$_providers->names_by_slug( 'all', 'predefined_custom_fields' ) );
|
||||
self::$_any_custom_field_type_support = self::$_providers->names_by_slug( 'all', 'any_custom_field_type' );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ET_Core_API_Email_Fields::initialize();
|
338
core/components/api/email/FluentCRM.php
Normal file
338
core/components/api/email/FluentCRM.php
Normal file
@ -0,0 +1,338 @@
|
||||
<?php
|
||||
/**
|
||||
* ET_Core_API_Email_FluentCRM class file.
|
||||
*
|
||||
* @class ET_Core_API_Email_FluentCRM
|
||||
* @package ET\Core\API\Email
|
||||
*/
|
||||
|
||||
// phpcs:disable Squiz.Commenting.VariableComment.MissingVar -- All the class level variables here inherit parent inline documentation. Please check ET_Core_API_Email_Provider or ET_Core_API_Service class.
|
||||
// phpcs:disable Squiz.Commenting.FunctionComment.MissingParamTag -- Almost all the methods here inherit parent inline documentation. Please check ET_Core_API_Email_Provider or ET_Core_API_Service class.
|
||||
|
||||
/**
|
||||
* Wrapper for FluentCRM's API.
|
||||
*
|
||||
* @since 4.9.1
|
||||
*
|
||||
* @package ET\Core\API\Email
|
||||
*/
|
||||
class ET_Core_API_Email_FluentCRM extends ET_Core_API_Email_Provider {
|
||||
|
||||
/**
|
||||
* Warning message text if the required plugin doesn't exist.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
public static $PLUGIN_REQUIRED; // phpcs:ignore ET.Sniffs.ValidVariableName.PropertyNotSnakeCase -- Widely used on all email provider classes.
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public $name = 'FluentCRM';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public $slug = 'fluentcrm';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public $custom_fields = 'predefined';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public $custom_fields_scope = 'account';
|
||||
|
||||
/**
|
||||
* ET_Core_API_Email_FluentCRM constructor.
|
||||
*/
|
||||
public function __construct( $owner = '', $account_name = '', $api_key = '' ) {
|
||||
parent::__construct( $owner, $account_name, $api_key );
|
||||
|
||||
if ( null === self::$PLUGIN_REQUIRED ) { // phpcs:ignore ET.Sniffs.ValidVariableName.UsedPropertyNotSnakeCase -- Widely used on all email provider classes.
|
||||
self::$PLUGIN_REQUIRED = esc_html__( 'FluentCRM plugin is either not installed or not activated.', 'et_core' ); // phpcs:ignore ET.Sniffs.ValidVariableName.UsedPropertyNotSnakeCase -- Widely used on all email provider classes.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get_data_keymap( $keymap = array() ) {
|
||||
$keymap = array(
|
||||
'list' => array(
|
||||
'list_id' => 'id',
|
||||
'name' => 'title',
|
||||
),
|
||||
'subscriber' => array(
|
||||
'email' => 'email',
|
||||
'last_name' => 'last_name',
|
||||
'name' => 'first_name',
|
||||
'custom_fields' => 'custom_fields',
|
||||
),
|
||||
'custom_field' => array(
|
||||
'field_id' => 'slug',
|
||||
'name' => 'label',
|
||||
'type' => 'type',
|
||||
'hidden' => 'hidden',
|
||||
'options' => 'options',
|
||||
),
|
||||
'custom_field_option' => array(
|
||||
'id' => 'value',
|
||||
'name' => 'value',
|
||||
),
|
||||
'custom_field_type' => array(
|
||||
// Us <=> Them.
|
||||
'radio' => 'radio',
|
||||
'checkbox' => 'checkbox',
|
||||
// Us => Them.
|
||||
'input' => 'text',
|
||||
'select' => 'select-one',
|
||||
// Them => Us.
|
||||
'text' => 'input',
|
||||
'number' => 'input',
|
||||
'date' => 'input',
|
||||
'date_time' => 'input',
|
||||
'select-one' => 'select',
|
||||
'select-multi' => 'checkbox',
|
||||
),
|
||||
);
|
||||
|
||||
return parent::get_data_keymap( $keymap );
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* FluentCRM is self hosted and all the fields can be managed on the plugin itself.
|
||||
*/
|
||||
protected function _fetch_custom_fields( $list_id = '', $list = array() ) {
|
||||
|
||||
static $processed = null;
|
||||
|
||||
if ( is_null( $processed ) ) {
|
||||
// A. Default custom fields.
|
||||
$processed = array(
|
||||
'address_line_1' => array(
|
||||
'field_id' => 'address_line_1',
|
||||
'name' => __( 'Address Line 1', 'et_builder' ),
|
||||
'type' => 'input',
|
||||
'hidden' => false,
|
||||
),
|
||||
'address_line_2' => array(
|
||||
'field_id' => 'address_line_2',
|
||||
'name' => __( 'Address Line 2', 'et_builder' ),
|
||||
'type' => 'input',
|
||||
'hidden' => false,
|
||||
),
|
||||
'postal_code' => array(
|
||||
'field_id' => 'postal_code',
|
||||
'name' => __( 'Postal Code', 'et_builder' ),
|
||||
'type' => 'input',
|
||||
'hidden' => false,
|
||||
),
|
||||
'city' => array(
|
||||
'field_id' => 'city',
|
||||
'name' => __( 'City', 'et_builder' ),
|
||||
'type' => 'input',
|
||||
'hidden' => false,
|
||||
),
|
||||
'state' => array(
|
||||
'field_id' => 'state',
|
||||
'name' => __( 'State', 'et_builder' ),
|
||||
'type' => 'input',
|
||||
'hidden' => false,
|
||||
),
|
||||
'country' => array(
|
||||
'field_id' => 'country',
|
||||
'name' => __( 'Country', 'et_builder' ),
|
||||
'type' => 'input',
|
||||
'hidden' => false,
|
||||
),
|
||||
'phone' => array(
|
||||
'field_id' => 'phone',
|
||||
'name' => __( 'Phone', 'et_builder' ),
|
||||
'type' => 'input',
|
||||
'hidden' => false,
|
||||
),
|
||||
'status' => array(
|
||||
'field_id' => 'status',
|
||||
'name' => __( 'Enable Double Optin', 'et_builder' ),
|
||||
'type' => 'input',
|
||||
'required_mark' => 'off',
|
||||
'default' => 'pending',
|
||||
'hidden' => true,
|
||||
),
|
||||
);
|
||||
|
||||
// B. Contact custom fields.
|
||||
$contact_custom_fields = fluentcrm_get_option( 'contact_custom_fields', array() );
|
||||
|
||||
if ( ! empty( $contact_custom_fields ) ) {
|
||||
foreach ( $contact_custom_fields as $field ) {
|
||||
// 1. Transform field data to fit our format.
|
||||
$field = $this->transform_data_to_our_format( $field, 'custom_field' );
|
||||
$field_id = $field['field_id'];
|
||||
$type = $field['type'];
|
||||
|
||||
// 2. Transform field type to fit our supported field type.
|
||||
$field['type'] = self::$_->array_get( $this->data_keys, "custom_field_type.{$type}", 'any' );
|
||||
|
||||
if ( 'select-multi' === $type ) {
|
||||
$field['type_origin'] = $type;
|
||||
}
|
||||
|
||||
// 3. Transform `options` data to fit our format (`id` => `name`).
|
||||
if ( ! empty( $field['options'] ) ) {
|
||||
$options = array();
|
||||
|
||||
foreach ( $field['options'] as $option ) {
|
||||
$option = array( 'value' => $option );
|
||||
$option = $this->transform_data_to_our_format( $option, 'custom_field_option' );
|
||||
|
||||
$options[ $option['id'] ] = $option['name'];
|
||||
}
|
||||
|
||||
$field['options'] = $options;
|
||||
}
|
||||
|
||||
$processed[ $field_id ] = $field;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $processed;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* FluentCRM is self hosted and all the fields can be managed on the plugin itself.
|
||||
*/
|
||||
public function get_account_fields() {
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* FluentCRM is self hosted and all the lists can be managed on the plugin itself.
|
||||
*/
|
||||
public function fetch_subscriber_lists() {
|
||||
if ( ! defined( 'FLUENTCRM' ) ) {
|
||||
return self::$PLUGIN_REQUIRED; // phpcs:ignore ET.Sniffs.ValidVariableName.UsedPropertyNotSnakeCase -- Widely used on all email provider classes.
|
||||
}
|
||||
|
||||
$list_tags = array();
|
||||
|
||||
// Lists.
|
||||
$lists = FluentCrmApi( 'lists' )->all();
|
||||
|
||||
foreach ( $lists as $list ) {
|
||||
$list_tags[ 'list_' . $list->id ] = array(
|
||||
'list_id' => 'list_' . $list->id,
|
||||
'name' => 'List: ' . $list->title,
|
||||
'subscribers_count' => 0,
|
||||
);
|
||||
}
|
||||
|
||||
// Tags.
|
||||
$tags = FluentCrmApi( 'tags' )->all();
|
||||
|
||||
foreach ( $tags as $tag ) {
|
||||
$list_tags[ 'tags_' . $tag->id ] = array(
|
||||
'list_id' => 'tags_' . $tag->id,
|
||||
'name' => 'Tag: ' . $tag->title,
|
||||
'subscribers_count' => 0,
|
||||
);
|
||||
}
|
||||
|
||||
// Combine both of lists and tags because there is no other way to display both
|
||||
// with different fields.
|
||||
$this->data['lists'] = $list_tags;
|
||||
$this->data['custom_fields'] = $this->_fetch_custom_fields( '', array() );
|
||||
$this->data['is_authorized'] = true;
|
||||
|
||||
$this->save_data();
|
||||
|
||||
return 'success';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function _process_custom_fields( $args ) {
|
||||
if ( ! empty( $args['custom_fields'] ) ) {
|
||||
$custom_fields = $args['custom_fields'];
|
||||
|
||||
foreach ( $custom_fields as $field_id => $field_value ) {
|
||||
if ( $field_value ) {
|
||||
$field_type = self::$_->array_get( $this->data['custom_fields'][ $field_id ], 'type' );
|
||||
$field_type_origin = self::$_->array_get( $this->data['custom_fields'][ $field_id ], 'type_origin' );
|
||||
|
||||
// Transform `checkbox` value into string separated by comma i.e. 'val1,val2'.
|
||||
// However, if the field type origin is `select-multi`, we have to use array
|
||||
// values instead.
|
||||
if ( 'checkbox' === $field_type ) {
|
||||
$field_value = 'select-multi' === $field_type_origin ? array_values( $field_value ) : implode( ',', $field_value );
|
||||
}
|
||||
|
||||
$args[ $field_id ] = $field_value;
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $custom_fields['status'] ) ) {
|
||||
$args['status'] = 'pending';
|
||||
}
|
||||
|
||||
unset( $args['custom_fields'] );
|
||||
}
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function subscribe( $args, $url = '' ) {
|
||||
if ( ! defined( 'FLUENTCRM' ) ) {
|
||||
ET_Core_Logger::error( self::$PLUGIN_REQUIRED ); // phpcs:ignore ET.Sniffs.ValidVariableName.UsedPropertyNotSnakeCase -- Widely used on all email provider classes.
|
||||
return esc_html__( 'An error occurred. Please try again later.', 'et_core' );
|
||||
}
|
||||
|
||||
$contact = $this->transform_data_to_provider_format( $args, 'subscriber' );
|
||||
$contact = $this->_process_custom_fields( $contact );
|
||||
|
||||
// IP Address.
|
||||
$ip_address = 'true' === self::$_->array_get( $args, 'ip_address', 'true' ) ? et_core_get_ip_address() : '';
|
||||
$contact['ip_address'] = $ip_address;
|
||||
|
||||
// Name.
|
||||
if ( empty( $contact['last_name'] ) ) {
|
||||
$contact['full_name'] = $contact['first_name'];
|
||||
unset( $contact['first_name'] );
|
||||
unset( $contact['last_name'] );
|
||||
}
|
||||
|
||||
// List or Tag.
|
||||
$list_or_tag_id = $args['list_id'];
|
||||
|
||||
if ( false === strpos( $list_or_tag_id, 'tags_' ) ) {
|
||||
$contact['lists'] = array( intval( str_replace( 'list_', '', $list_or_tag_id ) ) );
|
||||
} else {
|
||||
$contact['tags'] = array( intval( str_replace( 'tags_', '', $list_or_tag_id ) ) );
|
||||
}
|
||||
|
||||
$contact = array_filter( $contact );
|
||||
|
||||
// Email.
|
||||
if ( empty( $contact['email'] ) || ! is_email( $contact['email'] ) ) {
|
||||
return esc_html__( 'Email Validation has been failed.', 'et_core' );
|
||||
}
|
||||
|
||||
FluentCrmApi( 'contacts' )->createOrUpdate( $contact );
|
||||
|
||||
return 'success';
|
||||
}
|
||||
}
|
184
core/components/api/email/GetResponse.php
Normal file
184
core/components/api/email/GetResponse.php
Normal file
@ -0,0 +1,184 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Wrapper for GetResponse's API.
|
||||
*
|
||||
* @since 1.1.0
|
||||
*
|
||||
* @package ET\Core\API\Email
|
||||
*/
|
||||
class ET_Core_API_Email_GetResponse extends ET_Core_API_Email_Provider {
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $BASE_URL = 'https://api.getresponse.com/v3';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $FIELDS_URL = 'https://api.getresponse.com/v3/custom-fields';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $LISTS_URL = 'https://api.getresponse.com/v3/campaigns';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $SUBSCRIBE_URL = 'https://api.getresponse.com/v3/contacts';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $name = 'GetResponse';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $name_field_only = true;
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $slug = 'getresponse';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @internal If true, oauth endpoints properties must also be defined.
|
||||
*/
|
||||
public $uses_oauth = false;
|
||||
|
||||
public function __construct( $owner = '', $account_name = '', $api_key = '' ) {
|
||||
parent::__construct( $owner, $account_name, $api_key );
|
||||
|
||||
$this->_maybe_set_custom_headers();
|
||||
}
|
||||
|
||||
protected function _maybe_set_custom_headers() {
|
||||
if ( empty( $this->custom_headers ) && isset( $this->data['api_key'] ) ) {
|
||||
$this->custom_headers = array( 'X-Auth-Token' => "api-key {$this->data['api_key']}" );
|
||||
}
|
||||
}
|
||||
|
||||
protected function _process_custom_fields( $args ) {
|
||||
if ( ! isset( $args['custom_fields'] ) ) {
|
||||
return $args;
|
||||
}
|
||||
|
||||
$fields_unprocessed = $args['custom_fields'];
|
||||
$fields = array();
|
||||
|
||||
unset( $args['custom_fields'] );
|
||||
|
||||
foreach ( $fields_unprocessed as $field_id => $value ) {
|
||||
if ( is_array( $value ) && $value ) {
|
||||
// This is a multiple choice field (eg. checkbox, radio, select)
|
||||
$value = array_values( $value );
|
||||
} else {
|
||||
$value = array( $value );
|
||||
}
|
||||
|
||||
$fields[] = array(
|
||||
'customFieldId' => $field_id,
|
||||
'value' => $value,
|
||||
);
|
||||
}
|
||||
|
||||
$args['customFieldValues'] = $fields;
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function get_account_fields() {
|
||||
return array(
|
||||
'api_key' => array(
|
||||
'label' => esc_html__( 'API Key', 'et_core' ),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function get_data_keymap( $keymap = array() ) {
|
||||
$keymap = array(
|
||||
'list' => array(
|
||||
'name' => 'name',
|
||||
'list_id' => 'campaignId',
|
||||
'subscribers_count' => 'totalSubscribers',
|
||||
),
|
||||
'subscriber' => array(
|
||||
'name' => 'name',
|
||||
'email' => 'email',
|
||||
'list_id' => 'campaign.campaignId',
|
||||
'ip_address' => 'ipAddress',
|
||||
'custom_fields' => 'custom_fields',
|
||||
),
|
||||
'error' => array(
|
||||
'error_message' => 'message',
|
||||
),
|
||||
'custom_field' => array(
|
||||
'field_id' => 'customFieldId',
|
||||
'name' => 'name',
|
||||
'type' => 'fieldType',
|
||||
'options' => 'values',
|
||||
'hidden' => 'hidden',
|
||||
),
|
||||
'custom_field_type' => array(
|
||||
// Us <=> Them
|
||||
'textarea' => 'textarea',
|
||||
'radio' => 'radio',
|
||||
'checkbox' => 'checkbox',
|
||||
// Us => Them
|
||||
'input' => 'text',
|
||||
'select' => 'single_select',
|
||||
// Them => Us
|
||||
'text' => 'input',
|
||||
'single_select' => 'select',
|
||||
),
|
||||
);
|
||||
|
||||
return parent::get_data_keymap( $keymap );
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function fetch_subscriber_lists() {
|
||||
if ( empty( $this->data['api_key'] ) ) {
|
||||
return $this->API_KEY_REQUIRED;
|
||||
}
|
||||
|
||||
$this->_maybe_set_custom_headers();
|
||||
|
||||
$this->response_data_key = false;
|
||||
|
||||
return parent::fetch_subscriber_lists();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function subscribe( $args, $url = '' ) {
|
||||
$ip_address = 'true' === self::$_->array_get( $args, 'ip_address', 'true' ) ? et_core_get_ip_address() : '0.0.0.0';
|
||||
|
||||
$args['ip_address'] = $ip_address;
|
||||
$args = $this->transform_data_to_provider_format( $args, 'subscriber' );
|
||||
$args = $this->_process_custom_fields( $args );
|
||||
$args['note'] = $this->SUBSCRIBED_VIA;
|
||||
$args['dayOfCycle'] = 0;
|
||||
|
||||
if ( empty( $args['name'] ) ) {
|
||||
unset( $args['name'] );
|
||||
}
|
||||
|
||||
$this->prepare_request( $this->SUBSCRIBE_URL, 'POST', false, $args );
|
||||
|
||||
return parent::subscribe( $args, $this->SUBSCRIBE_URL );
|
||||
}
|
||||
}
|
273
core/components/api/email/HubSpot.php
Normal file
273
core/components/api/email/HubSpot.php
Normal file
@ -0,0 +1,273 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Wrapper for HubSpot's API.
|
||||
*
|
||||
* @since 3.0.72
|
||||
*
|
||||
* @package ET\Core\API\Email
|
||||
*/
|
||||
class ET_Core_API_Email_HubSpot extends ET_Core_API_Email_Provider {
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $BASE_URL = 'https://api.hubapi.com/contacts/v1';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $FIELDS_URL = 'https://api.hubapi.com/properties/v1/contacts/properties';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $LISTS_URL = 'https://api.hubapi.com/contacts/v1/lists/static';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $SUBSCRIBE_URL = 'https://api.hubapi.com/contacts/v1/contact/createOrUpdate/email/@email@';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $custom_fields_scope = 'account';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $name = 'HubSpot';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $slug = 'hubspot';
|
||||
|
||||
protected function _fetch_custom_fields( $list_id = '', $list = array() ) {
|
||||
$this->response_data_key = false;
|
||||
|
||||
$fields_unprocessed = parent::_fetch_custom_fields( $list_id, $list );
|
||||
$fields = array();
|
||||
|
||||
foreach ( $fields_unprocessed as $field ) {
|
||||
$field_id = $field['field_id'];
|
||||
|
||||
if ( ! isset( $field['options'] ) ) {
|
||||
$fields[ $field_id ] = $field;
|
||||
continue;
|
||||
}
|
||||
|
||||
$options = array();
|
||||
|
||||
foreach ( $field['options'] as $option ) {
|
||||
$option = $this->transform_data_to_our_format( $option, 'custom_field_option' );
|
||||
$id = $option['id'];
|
||||
|
||||
$options[ $id ] = $option['name'];
|
||||
}
|
||||
|
||||
$field['options'] = $options;
|
||||
|
||||
$fields[ $field_id ] = $field;
|
||||
}
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
protected function _get_list_add_contact_url( $list_id ) {
|
||||
$url = "{$this->BASE_URL}/lists/{$list_id}/add";
|
||||
|
||||
return add_query_arg( 'hapikey', $this->data['api_key'], $url );
|
||||
}
|
||||
|
||||
protected function _maybe_set_urls( $email = '' ) {
|
||||
if ( empty( $this->data['api_key'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->FIELDS_URL = add_query_arg( 'hapikey', $this->data['api_key'], $this->FIELDS_URL );
|
||||
$this->LISTS_URL = add_query_arg( 'hapikey', $this->data['api_key'], $this->LISTS_URL );
|
||||
$this->SUBSCRIBE_URL = add_query_arg( 'hapikey', $this->data['api_key'], $this->SUBSCRIBE_URL );
|
||||
|
||||
if ( $email ) {
|
||||
$this->SUBSCRIBE_URL = str_replace( '@email@', rawurlencode( $email ), $this->SUBSCRIBE_URL );
|
||||
}
|
||||
}
|
||||
|
||||
protected function _process_custom_fields( $args ) {
|
||||
$args['properties'] = array();
|
||||
|
||||
if ( ! isset( $args['custom_fields'] ) ) {
|
||||
return $args;
|
||||
}
|
||||
|
||||
$fields = $args['custom_fields'];
|
||||
$properties = array();
|
||||
|
||||
unset( $args['custom_fields'] );
|
||||
|
||||
$field_types = array(
|
||||
'radio',
|
||||
'booleancheckbox',
|
||||
);
|
||||
|
||||
foreach ( $fields as $field_id => $value ) {
|
||||
if ( is_array( $value ) && $value ) {
|
||||
// This is a multiple choice field (eg. checkbox, radio, select)
|
||||
$value = array_values( $value );
|
||||
$value = implode( ';', $value );
|
||||
} elseif ( in_array( $this->data['custom_fields'][ $field_id ]['type'], $field_types, true ) ) {
|
||||
// Should use array key. Sometimes it's different than value and Hubspot expects the key
|
||||
$radio_options = $this->data['custom_fields'][ $field_id ]['options'];
|
||||
$value = array_search( $value, $radio_options );
|
||||
}
|
||||
|
||||
$properties[] = array(
|
||||
'property' => $field_id,
|
||||
'value' => $value,
|
||||
);
|
||||
}
|
||||
|
||||
$args['properties'] = $properties;
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function get_account_fields() {
|
||||
return array(
|
||||
'api_key' => array(
|
||||
'label' => esc_html__( 'API Key', 'et_core' ),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function get_data_keymap( $keymap = array() ) {
|
||||
$keymap = array(
|
||||
'list' => array(
|
||||
'list_id' => 'listId',
|
||||
'name' => 'name',
|
||||
'subscribers_count' => 'metaData.size',
|
||||
),
|
||||
'subscriber' => array(
|
||||
'email' => 'email',
|
||||
'name' => 'firstname',
|
||||
'last_name' => 'lastname',
|
||||
'custom_fields' => 'custom_fields',
|
||||
),
|
||||
'error' => array(
|
||||
'error_message' => 'message',
|
||||
),
|
||||
'custom_field' => array(
|
||||
'field_id' => 'name',
|
||||
'name' => 'label',
|
||||
'type' => 'fieldType',
|
||||
'options' => 'options',
|
||||
'hidden' => 'hidden',
|
||||
),
|
||||
'custom_field_option' => array(
|
||||
'id' => 'value',
|
||||
'name' => 'label',
|
||||
),
|
||||
'custom_field_type' => array(
|
||||
// Us <=> Them
|
||||
'select' => 'select',
|
||||
'radio' => 'radio',
|
||||
'checkbox' => 'checkbox',
|
||||
// Us => Them
|
||||
'input' => 'text',
|
||||
'textarea' => 'text',
|
||||
// Them => Us
|
||||
'text' => 'input',
|
||||
'booleancheckbox' => 'booleancheckbox',
|
||||
),
|
||||
);
|
||||
|
||||
return parent::get_data_keymap( $keymap );
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function fetch_subscriber_lists() {
|
||||
if ( empty( $this->data['api_key'] ) ) {
|
||||
return $this->API_KEY_REQUIRED;
|
||||
}
|
||||
|
||||
$this->_maybe_set_urls();
|
||||
|
||||
/**
|
||||
* The maximum number of subscriber lists to request from Hubspot's API at a time.
|
||||
*
|
||||
* @since 3.0.75
|
||||
*
|
||||
* @param int $max_lists Value must be <= 250.
|
||||
*/
|
||||
$max_lists = (int) apply_filters( 'et_core_api_email_hubspot_max_lists', 250 );
|
||||
|
||||
$this->LISTS_URL = add_query_arg( 'count', $max_lists, $this->LISTS_URL );
|
||||
|
||||
$this->response_data_key = 'lists';
|
||||
|
||||
return parent::fetch_subscriber_lists();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function subscribe( $args, $url = '' ) {
|
||||
if ( empty( $this->data['api_key'] ) ) {
|
||||
return $this->API_KEY_REQUIRED;
|
||||
}
|
||||
|
||||
$this->_maybe_set_urls( $args['email'] );
|
||||
|
||||
$args = $this->_process_custom_fields( $args );
|
||||
|
||||
$data = array(
|
||||
'properties' => array(
|
||||
array(
|
||||
'property' => 'email',
|
||||
'value' => et_core_sanitized_previously( $args['email'] ),
|
||||
),
|
||||
array(
|
||||
'property' => 'firstname',
|
||||
'value' => et_core_sanitized_previously( $args['name'] ),
|
||||
),
|
||||
array(
|
||||
'property' => 'lastname',
|
||||
'value' => et_core_sanitized_previously( $args['last_name'] ),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
$data['properties'] = array_merge( $data['properties'], $args['properties'] );
|
||||
|
||||
$this->prepare_request( $this->SUBSCRIBE_URL, 'POST', false, $data, true );
|
||||
$this->make_remote_request();
|
||||
|
||||
if ( $this->response->ERROR ) {
|
||||
return $this->get_error_message();
|
||||
}
|
||||
|
||||
$url = $this->_get_list_add_contact_url( $args['list_id'] );
|
||||
$data = array(
|
||||
'emails' => array( $args['email'] ),
|
||||
);
|
||||
|
||||
$this->prepare_request( $url, 'POST', false, $data, true );
|
||||
$this->make_remote_request();
|
||||
|
||||
if ( $this->response->ERROR ) {
|
||||
return $this->get_error_message();
|
||||
}
|
||||
|
||||
return 'success';
|
||||
}
|
||||
}
|
439
core/components/api/email/Infusionsoft.php
Normal file
439
core/components/api/email/Infusionsoft.php
Normal file
@ -0,0 +1,439 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Wrapper for Infusionsoft's API.
|
||||
*
|
||||
* @since 1.1.0
|
||||
*
|
||||
* @package ET\Core\API\Email
|
||||
*/
|
||||
class ET_Core_API_Email_Infusionsoft extends ET_Core_API_Email_Provider {
|
||||
|
||||
private static $_data_keys = array(
|
||||
'app_name' => 'client_id',
|
||||
'api_key' => 'api_key',
|
||||
);
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $ACCESS_TOKEN_URL = 'https://api.infusionsoft.com/token';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $AUTHORIZATION_URL = 'https://signin.infusionsoft.com/app/oauth/authorize';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $BASE_URL = '';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* Use this variable to hold the pattern and update $BASE_URL dynamically when needed
|
||||
*/
|
||||
public $BASE_URL_PATTERN = 'https://@app_name@.infusionsoft.com/api/xmlrpc';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $custom_fields_scope = 'account';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $name = 'Infusionsoft';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $oauth_version = '2.0';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $slug = 'infusionsoft';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @internal If true, oauth endpoints properties must also be defined.
|
||||
*/
|
||||
public $uses_oauth = false;
|
||||
|
||||
public function __construct( $owner = '', $account_name = '', $api_key = '' ) {
|
||||
parent::__construct( $owner, $account_name, $api_key );
|
||||
|
||||
$this->http->expects_json = false;
|
||||
}
|
||||
|
||||
protected function _add_contact_to_list( $contact_id, $list_id ) {
|
||||
$params = array( $this->data[ self::$_data_keys['api_key'] ], (int) $contact_id, (int) $list_id );
|
||||
$data = self::$_->prepare_xmlrpc_method_call( 'ContactService.addToGroup', $params );
|
||||
|
||||
$this->_do_request( $data );
|
||||
|
||||
if ( $this->response->ERROR ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return self::$_->process_xmlrpc_response( $this->response->DATA );
|
||||
}
|
||||
|
||||
protected function _create_contact( $contact_details ) {
|
||||
$params = array( $this->data[ self::$_data_keys['api_key'] ], $contact_details );
|
||||
$data = self::$_->prepare_xmlrpc_method_call( 'ContactService.add', $params );
|
||||
|
||||
$this->_do_request( $data );
|
||||
|
||||
if ( $this->response->ERROR ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$result = self::$_->process_xmlrpc_response( $this->response->DATA );
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
protected function _do_request( $data ) {
|
||||
$this->prepare_request( $this->_get_base_url(), 'POST', false, $data );
|
||||
$this->request->HEADERS = array( 'Content-Type' => 'application/xml', 'Accept-Charset' => 'UTF-8' );
|
||||
$this->make_remote_request();
|
||||
}
|
||||
|
||||
protected function _fetch_custom_fields( $list_id = '', $list = array() ) {
|
||||
$params = array( $this->data[ self::$_data_keys['api_key'] ], 'DataFormField', 100, 0, array( 'FormId' => -1 ), array( 'Name', 'Label', 'DataType', 'Values' ) );
|
||||
$data = self::$_->prepare_xmlrpc_method_call( 'DataService.query', $params );
|
||||
|
||||
$this->_do_request( $data );
|
||||
|
||||
if ( $this->response->ERROR ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$data = self::$_->process_xmlrpc_response( $this->response->DATA );
|
||||
|
||||
foreach ( $data as &$custom_field ) {
|
||||
$custom_field = (array) $custom_field;
|
||||
$custom_field = $this->transform_data_to_our_format( $custom_field, 'custom_field' );
|
||||
}
|
||||
|
||||
$fields = array();
|
||||
|
||||
foreach ( $data as $field ) {
|
||||
$field_id = $field['field_id'];
|
||||
$type = self::$_->array_get( $field, 'type', 'any' );
|
||||
|
||||
$field['type'] = self::$_->array_get( $this->data_keys, "custom_field_type.{$type}", 'any' );
|
||||
|
||||
if ( isset( $field['options'] ) ) {
|
||||
$field['options'] = explode( "\n", $field['options'] );
|
||||
$field['options'] = array_filter( $field['options'] );
|
||||
}
|
||||
|
||||
$fields[ $field_id ] = $field;
|
||||
}
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
protected function _get_base_url() {
|
||||
$this->BASE_URL = str_replace( '@app_name@', $this->data[ self::$_data_keys['app_name'] ], $this->BASE_URL_PATTERN );
|
||||
return $this->BASE_URL;
|
||||
}
|
||||
|
||||
protected function _get_contact_by_email( $email ) {
|
||||
$params = array( $this->data[ self::$_data_keys['api_key'] ], 'Contact', 1, 0, array( 'Email' => $email ), array( 'Id', 'Groups' ) );
|
||||
$data = self::$_->prepare_xmlrpc_method_call( 'DataService.query', $params );
|
||||
|
||||
$this->_do_request( $data );
|
||||
|
||||
if ( $this->response->ERROR ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return self::$_->process_xmlrpc_response( $this->response->DATA );
|
||||
}
|
||||
|
||||
protected function _optin_email_address( $email ) {
|
||||
$params = array( $this->data[ self::$_data_keys['api_key'] ], $email, $this->SUBSCRIBED_VIA );
|
||||
$data = self::$_->prepare_xmlrpc_method_call('APIEmailService.optIn', $params );
|
||||
|
||||
$this->_do_request( $data );
|
||||
|
||||
if ( $this->response->ERROR ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return self::$_->process_xmlrpc_response( $this->response->DATA );
|
||||
}
|
||||
|
||||
protected function _process_custom_fields( $args ) {
|
||||
if ( ! isset( $args['custom_fields'] ) ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$fields = array();
|
||||
|
||||
foreach ( $args['custom_fields'] as $field_id => $value ) {
|
||||
if ( is_array( $value ) && $value ) {
|
||||
// This is a multiple choice field (eg. checkbox, radio, select)
|
||||
$value = array_values( $value );
|
||||
$value = implode( ',', $value );
|
||||
}
|
||||
|
||||
$fields[ "_{$field_id}" ] = $value;
|
||||
}
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
public function retrieve_subscribers_count() {
|
||||
$existing_lists = $this->data['lists'];
|
||||
|
||||
if ( empty( $existing_lists ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach( $existing_lists as $list_id => $list_data ) {
|
||||
$params = array( $this->data[ self::$_data_keys['api_key'] ], 'Contact', array( 'Groups' => "%{$list_id}%" ) );
|
||||
$data = self::$_->prepare_xmlrpc_method_call( 'DataService.count', $params );
|
||||
|
||||
$this->_do_request( $data );
|
||||
|
||||
if ( $this->response->ERROR ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$subscribers_count = self::$_->process_xmlrpc_response( $this->response->DATA );
|
||||
|
||||
if ( empty( $subscribers_count ) || self::$_->is_xmlrpc_error( $subscribers_count ) ) {
|
||||
$subscribers_count = 0;
|
||||
}
|
||||
|
||||
$existing_lists[ $list_id ]['subscribers_count'] = $subscribers_count;
|
||||
|
||||
$this->data['lists'] = $existing_lists;
|
||||
|
||||
$this->save_data();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
protected function _process_subscriber_lists( $lists ) {
|
||||
$result = array();
|
||||
|
||||
if ( empty( $lists ) || ! is_array( $lists ) ) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
foreach( $lists as $list ) {
|
||||
$list_id = (string) $list->Id;
|
||||
$list_name = (string) $list->GroupName;
|
||||
|
||||
$result[ $list_id ]['list_id'] = $list_id;
|
||||
$result[ $list_id ]['name'] = $list_name;
|
||||
$result[ $list_id ]['subscribers_count'] = 0;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function get_account_fields() {
|
||||
return array(
|
||||
self::$_data_keys['api_key'] => array(
|
||||
'label' => esc_html__( 'API Key', 'et_core' ),
|
||||
),
|
||||
self::$_data_keys['app_name'] => array(
|
||||
'label' => esc_html__( 'App Name', 'et_core' ),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function get_data_keymap( $keymap = array() ) {
|
||||
$keymap = array(
|
||||
'subscriber' => array(
|
||||
'name' => 'FirstName',
|
||||
'last_name' => 'LastName',
|
||||
'email' => 'Email',
|
||||
'custom_fields' => 'custom_fields',
|
||||
),
|
||||
'custom_field' => array(
|
||||
'field_id' => 'Name',
|
||||
'name' => 'Label',
|
||||
'type' => 'DataType',
|
||||
'options' => 'Values',
|
||||
),
|
||||
'custom_field_type' => array(
|
||||
// Us => Them
|
||||
'input' => 15,
|
||||
'textarea' => 16,
|
||||
'checkbox' => 17,
|
||||
'radio' => 20,
|
||||
'select' => 21,
|
||||
// Them => Us
|
||||
15 => 'input',
|
||||
16 => 'textarea',
|
||||
17 => 'checkbox',
|
||||
20 => 'radio',
|
||||
21 => 'select',
|
||||
),
|
||||
);
|
||||
|
||||
return parent::get_data_keymap( $keymap );
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function fetch_subscriber_lists() {
|
||||
if ( empty( $this->data[ self::$_data_keys['api_key'] ] ) || empty( $this->data[ self::$_data_keys['app_name'] ] ) ) {
|
||||
return $this->API_KEY_REQUIRED;
|
||||
}
|
||||
|
||||
$this->response_data_key = false;
|
||||
|
||||
$params_count = array( $this->data[ self::$_data_keys['api_key'] ], 'ContactGroup', array( 'Id' => '%' ) );
|
||||
$data_count = self::$_->prepare_xmlrpc_method_call( 'DataService.count', $params_count );
|
||||
|
||||
$this->_do_request( $data_count );
|
||||
|
||||
if ( $this->response->ERROR ) {
|
||||
return $this->response->ERROR_MESSAGE;
|
||||
}
|
||||
|
||||
$records_count = (int) self::$_->process_xmlrpc_response( $this->http->response->DATA );
|
||||
|
||||
if ( 0 === $records_count ) {
|
||||
return 'success';
|
||||
}
|
||||
|
||||
// determine how many requests we need to retrieve all lists
|
||||
$number_of_additional_requests = floor( $records_count / 1000 );
|
||||
|
||||
$list_data = array();
|
||||
|
||||
for ( $i = 0; $i <= $number_of_additional_requests; $i++ ) {
|
||||
$params = array( $this->data[ self::$_data_keys['api_key'] ], 'ContactGroup', 1000, $i, array( 'Id' => '%' ), array( 'Id', 'GroupName' ) );
|
||||
$data = self::$_->prepare_xmlrpc_method_call( 'DataService.query', $params );
|
||||
|
||||
$this->_do_request( $data );
|
||||
|
||||
if ( $this->http->response->ERROR ) {
|
||||
return $this->http->response->ERROR_MESSAGE;
|
||||
}
|
||||
|
||||
$response = self::$_->process_xmlrpc_response( $this->http->response->DATA );
|
||||
|
||||
if ( self::$_->is_xmlrpc_error( $response ) ) {
|
||||
return $response->faultString;
|
||||
}
|
||||
|
||||
$list_data = array_merge( $list_data, $response );
|
||||
}
|
||||
|
||||
$lists = $this->_process_subscriber_lists( $list_data );
|
||||
|
||||
if ( false === $lists ) {
|
||||
return $this->response->ERROR_MESSAGE;
|
||||
} else if ( self::$_->is_xmlrpc_error( $lists ) ) {
|
||||
return $lists->faultString;
|
||||
}
|
||||
|
||||
$result = 'success';
|
||||
|
||||
$this->data['lists'] = $lists;
|
||||
$this->data['custom_fields'] = $this->_fetch_custom_fields();
|
||||
$this->data['is_authorized'] = true;
|
||||
|
||||
// retrieve counts right away if it can be done in reasonable time ( in 20 seconds )
|
||||
if ( 20 >= count( $lists ) ) {
|
||||
$this->retrieve_subscribers_count();
|
||||
} else {
|
||||
// estimate the time for all lists update assuming that one list can be updated in 1 second
|
||||
$estimated_time = ceil( count( $lists ) / 60 );
|
||||
$result = array(
|
||||
'need_counts_update' => true,
|
||||
'message' => sprintf(
|
||||
esc_html__( 'Successfully authorized. Subscribers count will be updated in background, please check back in %1$s %2$s', 'et_core' ),
|
||||
$estimated_time,
|
||||
1 === (int) $estimated_time ? esc_html__( 'minute', 'et_core' ) : esc_html__( 'minutes', 'et_core' )
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
$this->save_data();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function subscribe( $args, $url = '' ) {
|
||||
if ( empty( $this->data[ self::$_data_keys['api_key'] ] ) || empty( $this->data[ self::$_data_keys['app_name'] ] ) ) {
|
||||
return $this->API_KEY_REQUIRED;
|
||||
}
|
||||
|
||||
$message = '';
|
||||
$search_result = $this->_get_contact_by_email( $args['email'] );
|
||||
|
||||
if ( false === $search_result ) {
|
||||
return $this->response->ERROR_MESSAGE;
|
||||
} else if ( self::$_->is_xmlrpc_error( $search_result ) ) {
|
||||
return $search_result->faultString;
|
||||
}
|
||||
|
||||
if ( ! empty( $search_result ) ) {
|
||||
$message = esc_html__( 'Already subscribed', 'bloom' );
|
||||
|
||||
if ( false === strpos( $search_result[0]->Groups, $args['list_id'] ) ) {
|
||||
$result = $this->_add_contact_to_list( $search_result[0]->Id, $args['list_id'] );
|
||||
$message = 'success';
|
||||
|
||||
if ( false === $result ) {
|
||||
return $this->response->ERROR_MESSAGE;
|
||||
} else if ( self::$_->is_xmlrpc_error( $result ) ) {
|
||||
return $result->faultString;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$custom_fields = $this->_process_custom_fields( $args );
|
||||
$contact_details = array(
|
||||
'FirstName' => $args['name'],
|
||||
'LastName' => $args['last_name'],
|
||||
'Email' => $args['email'],
|
||||
);
|
||||
|
||||
$new_contact_id = $this->_create_contact( array_merge( $contact_details, $custom_fields ) );
|
||||
|
||||
if ( false === $new_contact_id ) {
|
||||
return $this->response->ERROR_MESSAGE;
|
||||
} else if ( self::$_->is_xmlrpc_error( $new_contact_id ) ) {
|
||||
return $new_contact_id->faultString;
|
||||
}
|
||||
|
||||
$result = $this->_add_contact_to_list( $new_contact_id, $args['list_id'] );
|
||||
|
||||
if ( false === $result ) {
|
||||
return $this->response->ERROR_MESSAGE;
|
||||
} else if ( self::$_->is_xmlrpc_error( $result ) ) {
|
||||
return $search_result->faultString;
|
||||
}
|
||||
|
||||
if ( $this->_optin_email_address( $args['email'] ) ) {
|
||||
$message = 'success';
|
||||
}
|
||||
}
|
||||
|
||||
return ( '' !== $message ) ? $message : $this->FAILURE_MESSAGE;
|
||||
}
|
||||
}
|
164
core/components/api/email/MadMimi.php
Normal file
164
core/components/api/email/MadMimi.php
Normal file
@ -0,0 +1,164 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Wrapper for MadMimi's API.
|
||||
*
|
||||
* @since 1.1.0
|
||||
*
|
||||
* @package ET\Core\API\Email
|
||||
*/
|
||||
class ET_Core_API_Email_MadMimi extends ET_Core_API_Email_Provider {
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $BASE_URL = 'https://api.madmimi.com';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $LISTS_URL = 'https://api.madmimi.com/audience_lists/lists.json';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $SUBSCRIBE_URL = 'https://api.madmimi.com/audience_lists/@list_id@/add';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $custom_fields = 'dynamic';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $name = 'MadMimi';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $slug = 'madmimi';
|
||||
|
||||
public function __construct( $owner, $account_name, $api_key = '' ) {
|
||||
parent::__construct( $owner, $account_name, $api_key );
|
||||
|
||||
$this->_maybe_set_urls();
|
||||
}
|
||||
|
||||
protected function _maybe_set_urls( $list_id = '' ) {
|
||||
if ( ! empty( $this->data['api_key'] ) && ! empty( $this->data['username'] ) ) {
|
||||
$args = array(
|
||||
'username' => rawurlencode( $this->data['username'] ),
|
||||
'api_key' => $this->data['api_key'],
|
||||
);
|
||||
|
||||
$this->LISTS_URL = add_query_arg( $args, $this->LISTS_URL );
|
||||
$this->SUBSCRIBE_URL = add_query_arg( $args, $this->SUBSCRIBE_URL );
|
||||
|
||||
if ( $list_id ) {
|
||||
$this->SUBSCRIBE_URL = str_replace( '@list_id@', rawurlencode( $list_id ), $this->SUBSCRIBE_URL );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function _process_custom_fields( $args ) {
|
||||
if ( ! isset( $args['custom_fields'] ) ) {
|
||||
return $args;
|
||||
}
|
||||
|
||||
$fields = $args['custom_fields'];
|
||||
|
||||
unset( $args['custom_fields'] );
|
||||
|
||||
foreach ( $fields as $field_id => $value ) {
|
||||
if ( is_array( $value ) && $value ) {
|
||||
// This is a multiple choice field (eg. checkbox, radio, select)
|
||||
$value = array_values( $value );
|
||||
|
||||
if ( count( $value ) > 1 ) {
|
||||
$value = implode( ',', $value );
|
||||
} else {
|
||||
$value = array_pop( $value );
|
||||
}
|
||||
}
|
||||
|
||||
self::$_->array_set( $args, $field_id, $value );
|
||||
}
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function get_account_fields() {
|
||||
return array(
|
||||
'username' => array(
|
||||
'label' => esc_html__( 'Username', 'et_core' ),
|
||||
),
|
||||
'api_key' => array(
|
||||
'label' => esc_html__( 'API Key', 'et_core' ),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function get_data_keymap( $keymap = array() ) {
|
||||
$keymap = array(
|
||||
'list' => array(
|
||||
'list_id' => 'id',
|
||||
'name' => 'name',
|
||||
'subscribers_count' => 'list_size',
|
||||
),
|
||||
'subscriber' => array(
|
||||
'name' => 'first_name',
|
||||
'last_name' => 'last_name',
|
||||
'email' => 'email',
|
||||
'custom_fields' => 'custom_fields',
|
||||
),
|
||||
);
|
||||
|
||||
return parent::get_data_keymap( $keymap );
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function fetch_subscriber_lists() {
|
||||
if ( empty( $this->data['api_key'] ) || empty( $this->data['username'] ) ) {
|
||||
return $this->API_KEY_REQUIRED;
|
||||
}
|
||||
|
||||
$this->_maybe_set_urls();
|
||||
|
||||
$this->response_data_key = false;
|
||||
|
||||
return parent::fetch_subscriber_lists();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function subscribe( $args, $url = '' ) {
|
||||
if ( empty( $this->data['api_key'] ) || empty( $this->data['username'] ) ) {
|
||||
return $this->API_KEY_REQUIRED;
|
||||
}
|
||||
|
||||
$this->_maybe_set_urls( $args['list_id'] );
|
||||
|
||||
$ip_address = 'true' === self::$_->array_get( $args, 'ip_address', 'true' ) ? et_core_get_ip_address() : '0.0.0.0';
|
||||
|
||||
$args = $this->transform_data_to_provider_format( $args, 'subscriber' );
|
||||
$args = $this->_process_custom_fields( $args );
|
||||
$args['ip_address'] = $ip_address;
|
||||
$args['subscribed_via'] = $this->SUBSCRIBED_VIA;
|
||||
|
||||
$this->SUBSCRIBE_URL = add_query_arg( $args, $this->SUBSCRIBE_URL );
|
||||
|
||||
$this->prepare_request( $this->SUBSCRIBE_URL, 'POST', false );
|
||||
|
||||
return parent::subscribe( $args, $url );
|
||||
}
|
||||
}
|
345
core/components/api/email/MailChimp.php
Normal file
345
core/components/api/email/MailChimp.php
Normal file
@ -0,0 +1,345 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Wrapper for MailChimp's API.
|
||||
*
|
||||
* @since 1.1.0
|
||||
*
|
||||
* @package ET\Core\API\Email
|
||||
*/
|
||||
class ET_Core_API_Email_MailChimp extends ET_Core_API_Email_Provider {
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $BASE_URL = '';
|
||||
|
||||
/**
|
||||
* Use this variable to hold the pattern and update $BASE_URL dynamically when needed
|
||||
*/
|
||||
public $BASE_URL_PATTERN = 'https://@datacenter@.api.mailchimp.com/3.0';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $http_auth = array(
|
||||
'username' => '-',
|
||||
'password' => 'api_key',
|
||||
);
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $name = 'MailChimp';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $slug = 'mailchimp';
|
||||
|
||||
public function __construct( $owner, $account_name, $api_key = '' ) {
|
||||
parent::__construct( $owner, $account_name, $api_key );
|
||||
|
||||
if ( ! empty( $this->data['api_key'] ) ) {
|
||||
$this->_set_base_url();
|
||||
}
|
||||
|
||||
$this->http_auth['username'] = $owner;
|
||||
}
|
||||
|
||||
protected function _add_note_to_subscriber( $email, $url ) {
|
||||
$email = md5( $email );
|
||||
|
||||
$this->prepare_request( "{$url}/$email/notes", 'POST' );
|
||||
|
||||
$this->request->BODY = json_encode( array( 'note' => $this->SUBSCRIBED_VIA ) );
|
||||
|
||||
$this->make_remote_request();
|
||||
}
|
||||
|
||||
protected function _fetch_custom_fields( $list_id = '', $list = array() ) {
|
||||
$this->response_data_key = 'merge_fields';
|
||||
|
||||
$this->prepare_request( "{$this->BASE_URL}/lists/{$list_id}/merge-fields?count={$this->COUNT}" );
|
||||
|
||||
$fields = parent::_fetch_custom_fields( $list_id, $list );
|
||||
|
||||
foreach ( $fields as $id => $field ) {
|
||||
if ( in_array( $id, array( 1, 2 ) ) ) {
|
||||
unset( $fields[ $id ] );
|
||||
}
|
||||
}
|
||||
|
||||
// MailChimp is weird in that they treat checkbox fields as an entirely different concept in their API (Groups)
|
||||
// We'll grab the groups and treat them as checkbox fields in our UI.
|
||||
$groups = $this->_fetch_subscriber_list_groups( $list_id );
|
||||
|
||||
return $fields + $groups;
|
||||
}
|
||||
|
||||
protected function _fetch_subscriber_list_group_options( $list_id, $group_id ) {
|
||||
$this->prepare_request( "{$this->BASE_URL}/lists/{$list_id}/interest-categories/{$group_id}/interests?count={$this->COUNT}" );
|
||||
|
||||
$this->make_remote_request();
|
||||
|
||||
if ( $this->response->ERROR ) {
|
||||
et_debug( $this->get_error_message() );
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
$data = $this->response->DATA['interests'];
|
||||
$options = array();
|
||||
|
||||
foreach ( $data as $option ) {
|
||||
$option = $this->transform_data_to_our_format( $option, 'group_option' );
|
||||
$id = $option['id'];
|
||||
|
||||
$options[ $id ] = $option['name'];
|
||||
}
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
protected function _fetch_subscriber_list_groups( $list_id ) {
|
||||
$this->response_data_key = 'categories';
|
||||
|
||||
$this->prepare_request( "{$this->BASE_URL}/lists/{$list_id}/interest-categories?count={$this->COUNT}" );
|
||||
$this->make_remote_request();
|
||||
|
||||
$groups = array();
|
||||
|
||||
if ( false !== $this->response_data_key && empty( $this->response_data_key ) ) {
|
||||
// Let child class handle parsing the response data themselves.
|
||||
return $groups;
|
||||
}
|
||||
|
||||
if ( $this->response->ERROR ) {
|
||||
et_debug( $this->get_error_message() );
|
||||
|
||||
return $groups;
|
||||
}
|
||||
|
||||
$data = $this->response->DATA[ $this->response_data_key ];
|
||||
|
||||
foreach ( $data as $group ) {
|
||||
$group = $this->transform_data_to_our_format( $group, 'group' );
|
||||
$field_id = $group['field_id'];
|
||||
$type = $group['type'];
|
||||
|
||||
if ( 'hidden' === $type ) {
|
||||
// MailChimp only allows groups of type: 'checkbox' to be hidden.
|
||||
$group['type'] = 'checkbox';
|
||||
$group['hidden'] = true;
|
||||
}
|
||||
|
||||
$group['is_group'] = true;
|
||||
$group['options'] = $this->_fetch_subscriber_list_group_options( $list_id, $field_id );
|
||||
$group['type'] = self::$_->array_get( $this->data_keys, "custom_field_type.{$type}", 'text' );
|
||||
|
||||
$groups[ $field_id ] = $group;
|
||||
}
|
||||
|
||||
return $groups;
|
||||
}
|
||||
|
||||
protected function _process_custom_fields( $args ) {
|
||||
if ( ! isset( $args['custom_fields'] ) ) {
|
||||
return $args;
|
||||
}
|
||||
|
||||
$fields = $args['custom_fields'];
|
||||
$list_id = self::$_->array_get( $args, 'list_id', '' );
|
||||
|
||||
unset( $args['custom_fields'] );
|
||||
unset( $args['list_id'] );
|
||||
|
||||
$custom_fields_data = self::$_->array_get( $this->data, "lists.{$list_id}.custom_fields", array() );
|
||||
|
||||
foreach ( $fields as $field_id => $value ) {
|
||||
$is_group = self::$_->array_get( $custom_fields_data, "{$field_id}.is_group", false );
|
||||
|
||||
if ( is_array( $value ) && $value ) {
|
||||
foreach ( $value as $id => $field_value ) {
|
||||
if ( $is_group ) {
|
||||
// If it is a group custom field, set as `interests` and don't process the `merge_fields`
|
||||
self::$_->array_set( $args, "interests.{$id}", true );
|
||||
$field_id = false;
|
||||
} else {
|
||||
$value = $field_value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( false === $field_id ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// In previous version of Mailchimp implementation we only supported default field tag, but it can be customized and our code fails.
|
||||
// Added `field_tag` attribute which is actual field tag. Fallback to default field tag if `field_tag` doesn't exist for backward compatibility.
|
||||
$custom_field_tag = self::$_->array_get( $custom_fields_data, "{$field_id}.field_tag", "MMERGE{$field_id}" );
|
||||
|
||||
// Need to strips existing slash chars.
|
||||
self::$_->array_set( $args, "merge_fields.{$custom_field_tag}", stripslashes( $value ) );
|
||||
}
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
protected function _set_base_url() {
|
||||
$api_key_pieces = explode( '-', $this->data['api_key'] );
|
||||
$datacenter = empty( $api_key_pieces[1] ) ? '' : $api_key_pieces[1];
|
||||
$this->BASE_URL = str_replace( '@datacenter@', $datacenter, $this->BASE_URL_PATTERN );
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function fetch_subscriber_lists() {
|
||||
if ( empty( $this->data['api_key'] ) ) {
|
||||
return $this->API_KEY_REQUIRED;
|
||||
}
|
||||
|
||||
$this->_set_base_url();
|
||||
|
||||
/**
|
||||
* The maximum number of subscriber lists to request from MailChimp's API.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param int $max_lists
|
||||
*/
|
||||
$max_lists = (int) apply_filters( 'et_core_api_email_mailchimp_max_lists', 250 );
|
||||
|
||||
$url = "{$this->BASE_URL}/lists?count={$max_lists}&fields=lists.name,lists.id,lists.stats,lists.double_optin";
|
||||
|
||||
$this->prepare_request( $url );
|
||||
|
||||
$this->response_data_key = 'lists';
|
||||
|
||||
$result = parent::fetch_subscriber_lists();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function get_account_fields() {
|
||||
return array(
|
||||
'api_key' => array(
|
||||
'label' => esc_html__( 'API Key', 'et_core' ),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function get_data_keymap( $keymap = array() ) {
|
||||
$keymap = array(
|
||||
'list' => array(
|
||||
'list_id' => 'id',
|
||||
'name' => 'name',
|
||||
'double_optin' => 'double_optin',
|
||||
'subscribers_count' => 'stats.member_count',
|
||||
),
|
||||
'subscriber' => array(
|
||||
'email' => 'email_address',
|
||||
'name' => 'merge_fields.FNAME',
|
||||
'last_name' => 'merge_fields.LNAME',
|
||||
'custom_fields' => 'custom_fields',
|
||||
),
|
||||
'error' => array(
|
||||
'error_message' => 'detail',
|
||||
),
|
||||
'custom_field' => array(
|
||||
'field_id' => 'merge_id',
|
||||
'field_tag' => 'tag',
|
||||
'name' => 'name',
|
||||
'type' => 'type',
|
||||
'hidden' => '!public',
|
||||
'options' => 'options.choices',
|
||||
),
|
||||
'custom_field_type' => array(
|
||||
// Us <=> Them
|
||||
'radio' => 'radio',
|
||||
// Us => Them
|
||||
'input' => 'text',
|
||||
'select' => 'dropdown',
|
||||
'checkbox' => 'checkboxes',
|
||||
// Them => Us
|
||||
'text' => 'input',
|
||||
'dropdown' => 'select',
|
||||
'checkboxes' => 'checkbox',
|
||||
),
|
||||
'group' => array(
|
||||
'field_id' => 'id',
|
||||
'name' => 'title',
|
||||
'type' => 'type',
|
||||
),
|
||||
'group_option' => array(
|
||||
'id' => 'id',
|
||||
'name' => 'name',
|
||||
),
|
||||
);
|
||||
|
||||
return parent::get_data_keymap( $keymap );
|
||||
}
|
||||
|
||||
public function get_subscriber( $list_id, $email ) {
|
||||
$hash = md5( strtolower( $email ) );
|
||||
$this->prepare_request( implode( '/', array( $this->BASE_URL, 'lists', $list_id, 'members', $hash ) ) );
|
||||
$this->make_remote_request();
|
||||
|
||||
return $this->response->STATUS_CODE !== 200 ? null : $this->response->DATA;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function subscribe( $args, $url = '' ) {
|
||||
$list_id = $args['list_id'];
|
||||
$args = $this->transform_data_to_provider_format( $args, 'subscriber' );
|
||||
$url = "{$this->BASE_URL}/lists/{$list_id}/members";
|
||||
$email = $args['email_address'];
|
||||
$err = esc_html__( 'An error occurred, please try later.', 'et_core' );
|
||||
$dbl_optin = self::$_->array_get( $this->data, "lists.{$list_id}.double_optin", true );
|
||||
|
||||
$ip_address = 'true' === self::$_->array_get( $args, 'ip_address', 'true' ) ? et_core_get_ip_address() : '0.0.0.0';
|
||||
|
||||
$args['ip_signup'] = $ip_address;
|
||||
$args['status'] = $dbl_optin ? 'pending' : 'subscribed';
|
||||
$args['list_id'] = $list_id;
|
||||
|
||||
$args = $this->_process_custom_fields( $args );
|
||||
|
||||
$this->prepare_request( $url, 'POST', false, $args, true );
|
||||
$result = parent::subscribe( $args, $url );
|
||||
|
||||
if ( false !== stripos( $result, 'already a list member' ) ) {
|
||||
$result = $err;
|
||||
|
||||
if ( $user = $this->get_subscriber( $list_id, $email ) ) {
|
||||
if ( 'subscribed' === $user['status'] ) {
|
||||
$result = 'success';
|
||||
} else {
|
||||
$this->prepare_request( implode( '/', array( $url, $user['id'] ) ), 'PUT', false, $args, true );
|
||||
|
||||
$result = parent::subscribe( $args, $url );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( 'success' === $result ) {
|
||||
$this->_add_note_to_subscriber( $email, $url );
|
||||
} else if ( false !== stripos( $result, 'has signed up to a lot of lists ' ) ) {
|
||||
// return message which can be translated. Generic Mailchimp messages are not translatable.
|
||||
$result = esc_html__( 'You have signed up to a lot of lists very recently, please try again later', 'et_core' );
|
||||
} else {
|
||||
$result = $err;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
112
core/components/api/email/MailPoet.php
Normal file
112
core/components/api/email/MailPoet.php
Normal file
@ -0,0 +1,112 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Wrapper for MailPoet's API.
|
||||
*
|
||||
* @since 3.0.76
|
||||
*
|
||||
* @package ET\Core\API\Email
|
||||
*/
|
||||
class ET_Core_API_Email_MailPoet extends ET_Core_API_Email_Provider {
|
||||
|
||||
/**
|
||||
* @var ET_Core_API_Email_Provider
|
||||
*/
|
||||
private $_MP;
|
||||
|
||||
public static $PLUGIN_REQUIRED;
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $custom_fields_scope = 'account';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $name = 'MailPoet';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $slug = 'mailpoet';
|
||||
|
||||
public function __construct( $owner = '', $account_name = '', $api_key = '' ) {
|
||||
parent::__construct( $owner, $account_name, $api_key );
|
||||
|
||||
if ( null === self::$PLUGIN_REQUIRED ) {
|
||||
self::$PLUGIN_REQUIRED = esc_html__( 'MailPoet plugin is either not installed or not activated.', 'et_core' );
|
||||
}
|
||||
|
||||
$has_php53 = version_compare( PHP_VERSION, '5.3', '>=' );
|
||||
|
||||
if ( $has_php53 && class_exists( '\MailPoet\API\API' ) ) {
|
||||
require_once( ET_CORE_PATH . 'components/api/email/_MailPoet3.php' );
|
||||
$this->_init_provider_class( '3', $owner, $account_name, $api_key );
|
||||
|
||||
} else if ( class_exists( 'WYSIJA' ) ) {
|
||||
require_once( ET_CORE_PATH . 'components/api/email/_MailPoet2.php' );
|
||||
$this->_init_provider_class( '2', $owner, $account_name, $api_key );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initiate provider class based on the version number.
|
||||
*
|
||||
* @param string $version Version number.
|
||||
* @param string $owner Owner.
|
||||
* @param string $account_name Account name.
|
||||
* @param string $api_key API key.
|
||||
*/
|
||||
protected function _init_provider_class( $version, $owner, $account_name, $api_key ) {
|
||||
if ( '3' === $version ) {
|
||||
$this->_MP = new ET_Core_API_Email_MailPoet3( $owner, $account_name, $api_key );
|
||||
} else {
|
||||
$this->_MP = new ET_Core_API_Email_MailPoet2( $owner, $account_name, $api_key );
|
||||
$this->custom_fields = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function get_account_fields() {
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function get_data_keymap( $keymap = array() ) {
|
||||
if ( $this->_MP ) {
|
||||
return $this->_MP->get_data_keymap( $keymap );
|
||||
}
|
||||
|
||||
return parent::get_data_keymap( $keymap );
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function fetch_subscriber_lists() {
|
||||
$lists_data = $this->_MP ? $this->_MP->fetch_subscriber_lists() : self::$PLUGIN_REQUIRED;
|
||||
|
||||
// Update data in Main MailPoet class, so correct lists data can be accessed
|
||||
if ( isset( $lists_data['success'] ) ) {
|
||||
$this->data = $lists_data['success'];
|
||||
|
||||
$this->save_data();
|
||||
|
||||
return 'success';
|
||||
}
|
||||
|
||||
return $lists_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function subscribe( $args, $url = '' ) {
|
||||
return $this->_MP ? $this->_MP->subscribe( $args, $url ) : self::$PLUGIN_REQUIRED;
|
||||
}
|
||||
}
|
151
core/components/api/email/MailerLite.php
Normal file
151
core/components/api/email/MailerLite.php
Normal file
@ -0,0 +1,151 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Wrapper for MailerLite's API.
|
||||
*
|
||||
* @since 1.1.0
|
||||
*
|
||||
* @package ET\Core\API\Email
|
||||
*/
|
||||
class ET_Core_API_Email_MailerLite extends ET_Core_API_Email_Provider {
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $BASE_URL = 'https://api.mailerlite.com/api/v2';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $FIELDS_URL = 'https://api.mailerlite.com/api/v2/fields';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $LISTS_URL = 'https://api.mailerlite.com/api/v2/groups';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $custom_fields_scope = 'account';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $name = 'MailerLite';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $slug = 'mailerlite';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @internal If true, oauth endpoints properties must also be defined.
|
||||
*/
|
||||
public $uses_oauth = false;
|
||||
|
||||
public function __construct( $owner = '', $account_name = '', $api_key = '' ) {
|
||||
parent::__construct( $owner, $account_name, $api_key );
|
||||
|
||||
$this->_maybe_set_custom_headers();
|
||||
}
|
||||
|
||||
protected function _maybe_set_custom_headers() {
|
||||
if ( empty( $this->custom_headers ) && isset( $this->data['api_key'] ) ) {
|
||||
$this->custom_headers = array( 'X-MailerLite-ApiKey' => "{$this->data['api_key']}" );
|
||||
}
|
||||
}
|
||||
|
||||
protected function _process_custom_fields( $args ) {
|
||||
if ( ! isset( $args['custom_fields'] ) ) {
|
||||
return $args;
|
||||
}
|
||||
|
||||
$fields = $args['custom_fields'];
|
||||
|
||||
unset( $args['custom_fields'] );
|
||||
|
||||
foreach ( $fields as $field_id => $value ) {
|
||||
if ( is_array( $value ) && $value ) {
|
||||
// This is a multiple choice field (eg. checkbox, radio, select)
|
||||
$value = array_values( $value );
|
||||
|
||||
if ( count( $value ) > 1 ) {
|
||||
$value = implode( ',', $value );
|
||||
} else {
|
||||
$value = array_pop( $value );
|
||||
}
|
||||
}
|
||||
|
||||
self::$_->array_set( $args, "fields.{$field_id}", $value );
|
||||
}
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function get_account_fields() {
|
||||
return array(
|
||||
'api_key' => array(
|
||||
'label' => esc_html__( 'API Key', 'et_core' ),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function get_data_keymap( $keymap = array() ) {
|
||||
$keymap = array(
|
||||
'list' => array(
|
||||
'list_id' => 'id',
|
||||
'name' => 'name',
|
||||
'subscribers_count' => 'active',
|
||||
),
|
||||
'subscriber' => array(
|
||||
'name' => 'fields.name',
|
||||
'last_name' => 'fields.last_name',
|
||||
'email' => 'email',
|
||||
'custom_fields' => 'custom_fields',
|
||||
'resubscribe' => 'resubscribe',
|
||||
),
|
||||
'error' => array(
|
||||
'error_message' => 'error.message',
|
||||
),
|
||||
'custom_field' => array(
|
||||
'field_id' => 'key',
|
||||
'name' => 'title',
|
||||
),
|
||||
);
|
||||
|
||||
return parent::get_data_keymap( $keymap );
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function fetch_subscriber_lists() {
|
||||
if ( empty( $this->data['api_key'] ) ) {
|
||||
return $this->API_KEY_REQUIRED;
|
||||
}
|
||||
|
||||
$this->_maybe_set_custom_headers();
|
||||
|
||||
$this->response_data_key = false;
|
||||
|
||||
return parent::fetch_subscriber_lists();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function subscribe( $args, $url = '' ) {
|
||||
$args['resubscribe'] = 1;
|
||||
$url = "{$this->LISTS_URL}/{$args['list_id']}/subscribers";
|
||||
|
||||
return parent::subscribe( $args, $url );
|
||||
}
|
||||
}
|
211
core/components/api/email/Mailster.php
Normal file
211
core/components/api/email/Mailster.php
Normal file
@ -0,0 +1,211 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Wrapper for integration with Mailster plugin.
|
||||
*
|
||||
* @license
|
||||
* Copyright © 2017 Elegant Themes, Inc.
|
||||
* Copyright © 2017 Xaver Birsak
|
||||
*
|
||||
* @since 1.1.0
|
||||
* @package ET\Core\API\Email
|
||||
*/
|
||||
class ET_Core_API_Email_Mailster extends ET_Core_API_Email_Provider {
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $name = 'Mailster';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $slug = 'mailster';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $uses_oauth = false;
|
||||
|
||||
/**
|
||||
* Creates a referrer string that includes the name of the opt-in used to subscribe.
|
||||
*
|
||||
* @param array $args The args array that was passed to {@link self::subscribe()}
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function _get_referrer( $args ) {
|
||||
$optin_name = '';
|
||||
$owner = ucfirst( $this->owner );
|
||||
|
||||
if ( 'bloom' === $this->owner && isset( $args['optin_id'] ) ) {
|
||||
$optin_form = ET_Bloom::get_this()->dashboard_options[ $args['optin_id'] ];
|
||||
$optin_name = $optin_form['optin_name'];
|
||||
}
|
||||
|
||||
return sprintf( '%1$s %2$s "%3$s" on %4$s',
|
||||
esc_html( $owner ),
|
||||
esc_html__( 'Opt-in', 'et_core' ),
|
||||
esc_html( $optin_name ),
|
||||
wp_get_referer()
|
||||
);
|
||||
}
|
||||
|
||||
protected function _fetch_custom_fields( $list_id = '', $list = array() ) {
|
||||
static $fields = null;
|
||||
|
||||
if ( is_null( $fields ) ) {
|
||||
$customfields = mailster()->get_custom_fields();
|
||||
|
||||
if ( empty( $customfields ) ) {
|
||||
return $fields;
|
||||
}
|
||||
|
||||
$field_types = self::$_->array_get( $this->data_keys, 'custom_field_type' );
|
||||
foreach ( $customfields as $field_id => $field ) {
|
||||
$field = $this->transform_data_to_our_format( $field, 'custom_field' );
|
||||
$type = self::$_->array_get( $field, 'type', 'any' );
|
||||
$field['field_id'] = $field_id;
|
||||
|
||||
if ( $field_types && ! isset( $field_types[ $type ] ) ) {
|
||||
// Unsupported field type. Make it 'text' instead.
|
||||
$type = 'textfield';
|
||||
}
|
||||
$field['type'] = self::$_->array_get( $this->data_keys, "custom_field_type.{$type}", 'input' );
|
||||
|
||||
$fields[ $field_id ] = $field;
|
||||
}
|
||||
}
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
protected function _process_custom_fields( $args ) {
|
||||
if ( ! isset( $args['custom_fields'] ) ) {
|
||||
return $args;
|
||||
}
|
||||
|
||||
$fields = $args['custom_fields'];
|
||||
|
||||
unset( $args['custom_fields'] );
|
||||
$registered_custom_fields = self::$_->array_get( $this->data, 'custom_fields', array() );
|
||||
foreach ( $fields as $field_id => $value ) {
|
||||
$field_type = isset( $registered_custom_fields[ $field_id ] ) && isset( $registered_custom_fields[ $field_id ]['type'] ) ? $registered_custom_fields[ $field_id ]['type'] : false;
|
||||
// Mailster doesn't support multiple checkboxes and if it appears here that means the checkbox is checked
|
||||
if ( 'checkbox' === $field_type ) {
|
||||
$value = 1;
|
||||
}
|
||||
|
||||
if ( is_array( $value ) && $value ) {
|
||||
// This is a multiple choice field (eg. radio, select)
|
||||
$value = array_values( $value );
|
||||
|
||||
if ( count( $value ) > 1 ) {
|
||||
$value = implode( ',', $value );
|
||||
} else {
|
||||
$value = array_pop( $value );
|
||||
}
|
||||
}
|
||||
|
||||
self::$_->array_set( $args, $field_id, $value );
|
||||
}
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function get_account_fields() {
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function get_data_keymap( $keymap = array() ) {
|
||||
$keymap = array(
|
||||
'list' => array(
|
||||
'list_id' => 'ID',
|
||||
'name' => 'name',
|
||||
'subscribers_count' => 'subscribers',
|
||||
),
|
||||
'subscriber' => array(
|
||||
'dbl_optin' => 'status',
|
||||
'email' => 'email',
|
||||
'last_name' => 'lastname',
|
||||
'name' => 'firstname',
|
||||
'custom_fields' => 'custom_fields',
|
||||
),
|
||||
'custom_field' => array(
|
||||
'name' => 'name',
|
||||
'type' => 'type',
|
||||
'options' => 'values',
|
||||
'hidden' => 'hidden',
|
||||
),
|
||||
'custom_field_type' => array(
|
||||
// Us => Them
|
||||
'textarea' => 'textarea',
|
||||
'radio' => 'radio',
|
||||
'checkbox' => 'checkbox',
|
||||
'input' => 'textfield',
|
||||
'select' => 'dropdown',
|
||||
// Them => Us
|
||||
'textfield' => 'input',
|
||||
'dropdown' => 'select',
|
||||
),
|
||||
);
|
||||
|
||||
return parent::get_data_keymap( $keymap );
|
||||
}
|
||||
|
||||
public function fetch_subscriber_lists() {
|
||||
if ( ! function_exists( 'mailster' ) ) {
|
||||
return esc_html__( 'Mailster Newsletter Plugin is not enabled!', 'et_core' );
|
||||
}
|
||||
|
||||
$lists = mailster( 'lists' )->get( null, null, true );
|
||||
$error_message = esc_html__( 'No lists were found. Please create a Mailster list first!', 'et_core' );
|
||||
|
||||
if ( $lists ) {
|
||||
$error_message = 'success';
|
||||
$this->data['lists'] = $this->_process_subscriber_lists( $lists );
|
||||
$this->data['is_authorized'] = true;
|
||||
$this->data['custom_fields'] = $this->_fetch_custom_fields();
|
||||
$this->save_data();
|
||||
}
|
||||
|
||||
return $error_message;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function subscribe( $args, $url = '' ) {
|
||||
$error = esc_html__( 'An error occurred. Please try again later.', 'et_core' );
|
||||
|
||||
if ( ! function_exists( 'mailster' ) ) {
|
||||
return $error;
|
||||
}
|
||||
|
||||
$params = $this->transform_data_to_provider_format( $args, 'subscriber', array( 'dbl_optin' ) );
|
||||
$params = $this->_process_custom_fields( $params );
|
||||
$extra_params = array(
|
||||
'status' => 'disable' === $args['dbl_optin'] ? 1 : 0,
|
||||
'referrer' => $this->_get_referrer( $args ),
|
||||
);
|
||||
|
||||
$params = array_merge( $params, $extra_params );
|
||||
$subscriber_id = mailster( 'subscribers' )->merge( $params );
|
||||
|
||||
if ( is_wp_error( $subscriber_id ) ) {
|
||||
$result = htmlspecialchars_decode( $subscriber_id->get_error_message() );
|
||||
} else if ( mailster( 'subscribers' )->assign_lists( $subscriber_id, $args['list_id'], false ) ) {
|
||||
$result = 'success';
|
||||
} else {
|
||||
$result = $error;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
311
core/components/api/email/Ontraport.php
Normal file
311
core/components/api/email/Ontraport.php
Normal file
@ -0,0 +1,311 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Wrapper for Ontraport's API.
|
||||
*
|
||||
* @since 1.1.0
|
||||
*
|
||||
* @package ET\Core\API\Email
|
||||
*/
|
||||
class ET_Core_API_Email_Ontraport extends ET_Core_API_Email_Provider {
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $FIELDS_URL = 'https://api.ontraport.com/1/Contacts/meta';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $LISTS_URL = 'https://api.ontraport.com/1/objects?objectID=5';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $SUBSCRIBE_URL = 'https://api.ontraport.com/1';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $custom_fields_scope = 'account';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $name = 'Ontraport';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $slug = 'ontraport';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @internal If true, oauth endpoints properties must also be defined.
|
||||
*/
|
||||
public $uses_oauth = false;
|
||||
|
||||
public function __construct( $owner = '', $account_name = '', $api_key = '' ) {
|
||||
parent::__construct( $owner, $account_name, $api_key );
|
||||
|
||||
$this->_maybe_set_custom_headers();
|
||||
}
|
||||
|
||||
protected function _fetch_custom_fields( $list_id = '', $list = array() ) {
|
||||
static $fields = null;
|
||||
|
||||
if ( is_null( $fields ) ) {
|
||||
$this->response_data_key = null;
|
||||
|
||||
parent::_fetch_custom_fields( $list_id, $list );
|
||||
|
||||
if ( $this->response->ERROR ) {
|
||||
et_debug( $this->get_error_message() );
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
$fields = array();
|
||||
$fields_unprocessed = self::$_->array_get( $this->response->DATA, 'data.[0].fields', $fields );
|
||||
|
||||
foreach ( $fields_unprocessed as $field_id => $field ) {
|
||||
if ( in_array( $field_id, array( 'firstname', 'lastname', 'email' ) ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$type = $field['type'];
|
||||
|
||||
$field['field_id'] = $field_id;
|
||||
$field['type'] = self::$_->array_get( $this->data_keys, "custom_field_type.{$type}", 'text' );
|
||||
|
||||
$fields[ $field_id ] = $this->transform_data_to_our_format( $field, 'custom_field' );
|
||||
}
|
||||
}
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
protected function _get_subscriber_list_type( $list_id ) {
|
||||
$sequence_key = 'seq:' . $list_id;
|
||||
$campaign_key = 'camp:' . $list_id;
|
||||
|
||||
if ( isset( $this->data['lists'][ $campaign_key ] ) ) {
|
||||
return 'Campaign';
|
||||
}
|
||||
|
||||
if ( isset( $this->data['lists'][ $sequence_key ] ) ) {
|
||||
return 'Sequence';
|
||||
}
|
||||
|
||||
return 'Campaign';
|
||||
}
|
||||
|
||||
protected function _maybe_set_custom_headers() {
|
||||
if ( empty( $this->custom_headers ) && isset( $this->data['api_key'] ) && isset( $this->data['client_id'] ) ) {
|
||||
$this->custom_headers = array(
|
||||
'Api-Appid' => sanitize_text_field( $this->data['client_id'] ),
|
||||
'Api-Key' => sanitize_text_field( $this->data['api_key'] ),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
protected function _prefix_subscriber_lists( $name_prefix, $id_prefix ) {
|
||||
$lists = array();
|
||||
|
||||
foreach ( $this->data['lists'] as $list_id => $list ) {
|
||||
$key = $id_prefix . $list_id;
|
||||
|
||||
if ( ! $list['name'] ) {
|
||||
$list['name'] = $list_id;
|
||||
}
|
||||
|
||||
$lists[ $key ] = $list;
|
||||
$lists[ $key ]['name'] = $name_prefix . $list['name'];
|
||||
$lists[ $key ]['list_id'] = $key;
|
||||
}
|
||||
|
||||
$this->data['lists'] = $lists;
|
||||
|
||||
$this->save_data();
|
||||
}
|
||||
|
||||
protected function _process_custom_fields( $args ) {
|
||||
if ( ! isset( $args['custom_fields'] ) ) {
|
||||
return $args;
|
||||
}
|
||||
|
||||
$fields = $args['custom_fields'];
|
||||
|
||||
unset( $args['custom_fields'] );
|
||||
|
||||
foreach ( $fields as $field_id => $value ) {
|
||||
if ( is_array( $value ) && $value ) {
|
||||
// This is a multiple choice field (eg. checkbox, radio, select)
|
||||
$value = array_keys( $value );
|
||||
|
||||
if ( 'checkbox' === $this->data['custom_fields'][ $field_id ]['type'] ) {
|
||||
// Determine if checkbox is a single checkbox or a list.
|
||||
// In case of single checkbox pass `1` as a value
|
||||
if ( ! empty( $this->data['custom_fields'][ $field_id ]['options'] ) ) {
|
||||
$value = implode( '*/*', $value );
|
||||
$value = "*/*{$value}*/*";
|
||||
} else {
|
||||
$value = '1';
|
||||
}
|
||||
} else {
|
||||
$value = array_pop( $value );
|
||||
}
|
||||
}
|
||||
|
||||
self::$_->array_set( $args, $field_id, $value );
|
||||
}
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function get_account_fields() {
|
||||
return array(
|
||||
'api_key' => array(
|
||||
'label' => esc_html__( 'API Key', 'et_core' ),
|
||||
),
|
||||
'client_id' => array(
|
||||
'label' => esc_html__( 'APP ID', 'et_core' ),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function get_data_keymap( $keymap = array() ) {
|
||||
$keymap = array(
|
||||
'list' => array(
|
||||
'name' => 'name',
|
||||
'list_id' => 'drip_id',
|
||||
'subscribers_count' => 'subscriber_count',
|
||||
),
|
||||
'subscriber' => array(
|
||||
'name' => 'firstname',
|
||||
'last_name' => 'lastname',
|
||||
'email' => 'email',
|
||||
'custom_fields' => 'custom_fields',
|
||||
),
|
||||
'custom_field' => array(
|
||||
'field_id' => 'field_id',
|
||||
'type' => 'type',
|
||||
'name' => 'alias',
|
||||
'options' => 'options',
|
||||
),
|
||||
'custom_field_type' => array(
|
||||
// Us => Them
|
||||
'input' => 'text',
|
||||
'textarea' => 'textlong',
|
||||
'checkbox' => 'list',
|
||||
'select' => 'drop',
|
||||
// Them => Us
|
||||
'text' => 'input',
|
||||
'textlong' => 'textarea',
|
||||
'list' => 'checkbox',
|
||||
'check' => 'checkbox',
|
||||
'drop' => 'select',
|
||||
),
|
||||
);
|
||||
|
||||
return parent::get_data_keymap( $keymap );
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function fetch_subscriber_lists() {
|
||||
if ( empty( $this->data['api_key'] ) || empty( $this->data['client_id'] ) ) {
|
||||
return $this->API_KEY_REQUIRED;
|
||||
}
|
||||
|
||||
$this->_maybe_set_custom_headers();
|
||||
|
||||
$this->response_data_key = 'data';
|
||||
|
||||
parent::fetch_subscriber_lists();
|
||||
|
||||
$this->_prefix_subscriber_lists( 'Sequence: ', 'seq:' );
|
||||
|
||||
$sequences = $this->data['lists'];
|
||||
$url = 'https://api.ontraport.com/1/CampaignBuilderItems';
|
||||
$url = add_query_arg( 'listFields', 'id,name,subs', $url );
|
||||
|
||||
$this->data_keys['list']['list_id'] = 'id';
|
||||
$this->data_keys['list']['subscribers_count'] = 'subs';
|
||||
|
||||
$this->prepare_request( $url );
|
||||
|
||||
$this->response_data_key = 'data';
|
||||
|
||||
$result = parent::fetch_subscriber_lists();
|
||||
|
||||
$this->_prefix_subscriber_lists( 'Campaign: ', 'camp:' );
|
||||
|
||||
$this->data['lists'] = array_merge( $this->data['lists'], $sequences );
|
||||
|
||||
$this->save_data();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function get_subscriber( $email ) {
|
||||
$args = array(
|
||||
'objectID' => '0',
|
||||
'email' => rawurlencode( $email ),
|
||||
);
|
||||
|
||||
$url = add_query_arg( $args, $this->SUBSCRIBE_URL . '/object/getByEmail' );
|
||||
|
||||
$this->prepare_request( $url );
|
||||
$this->make_remote_request();
|
||||
|
||||
return self::$_->array_get( $this->response->DATA, 'data.id', false );
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function subscribe( $args, $url = '' ) {
|
||||
if ( empty( $this->data['api_key'] ) || empty( $this->data['client_id'] ) ) {
|
||||
return $this->API_KEY_REQUIRED;
|
||||
}
|
||||
|
||||
$list_id = $args['list_id'];
|
||||
$args = $this->transform_data_to_provider_format( $args, 'subscriber' );
|
||||
$args = $this->_process_custom_fields( $args );
|
||||
$args['objectID'] = 0;
|
||||
$url = $this->SUBSCRIBE_URL . '/Contacts/saveorupdate';
|
||||
|
||||
// Create or update contact
|
||||
$this->prepare_request( $url, 'POST', false, $args );
|
||||
$this->make_remote_request();
|
||||
|
||||
if ( $this->response->ERROR ) {
|
||||
return $this->get_error_message();
|
||||
}
|
||||
|
||||
$list_id_parts = explode( ':', $list_id );
|
||||
$list_id = array_pop( $list_id_parts );
|
||||
$data = $this->response->DATA['data'];
|
||||
|
||||
// Subscribe contact to list
|
||||
$url = $this->SUBSCRIBE_URL . '/objects/subscribe';
|
||||
$args = array(
|
||||
'ids' => self::$_->array_get( $data, 'id', $data['attrs']['id'] ),
|
||||
'add_list' => $list_id,
|
||||
'sub_type' => $this->_get_subscriber_list_type( $list_id ),
|
||||
'objectID' => 0,
|
||||
);
|
||||
|
||||
$this->prepare_request( $url, 'PUT', false, $args );
|
||||
|
||||
return parent::subscribe( $args, $url );
|
||||
}
|
||||
}
|
426
core/components/api/email/Provider.php
Normal file
426
core/components/api/email/Provider.php
Normal file
@ -0,0 +1,426 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* High-level wrapper for interacting with the external API's offered by 3rd-party mailing list providers.
|
||||
*
|
||||
* @since 1.1.0
|
||||
*
|
||||
* @package ET\Core\API
|
||||
*/
|
||||
abstract class ET_Core_API_Email_Provider extends ET_Core_API_Service {
|
||||
|
||||
/**
|
||||
* The URL from which custom fields for a list on this account can be retrieved.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $FIELDS_URL;
|
||||
|
||||
/**
|
||||
* The URL from which groups/tags for a list on this account can be retrieved.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $GROUPS_URL;
|
||||
|
||||
/**
|
||||
* The number of records to return from API (per request).
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $COUNT;
|
||||
|
||||
/**
|
||||
* The URL from which subscriber lists for this account can be retrieved.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $LISTS_URL;
|
||||
|
||||
/**
|
||||
* The URL to which new subscribers can be posted.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $SUBSCRIBE_URL;
|
||||
|
||||
/**
|
||||
* The URL from which subscribers for this account can be retrieved.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $SUBSCRIBERS_URL;
|
||||
|
||||
/**
|
||||
* "Subscribed via..." translated string.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $SUBSCRIBED_VIA;
|
||||
|
||||
/**
|
||||
* Type of support for custom fields offered by provider.
|
||||
*
|
||||
* @since 3.17.2
|
||||
*
|
||||
* @var bool|string Accepts `dynamic`, `predefined`, `false`. Default `predefined`.
|
||||
*/
|
||||
public $custom_fields = 'predefined';
|
||||
|
||||
/**
|
||||
* Type of support for custom fields offered by provider.
|
||||
*
|
||||
* @since 3.17.2
|
||||
*
|
||||
* @var string Accepts `list`, `account`.
|
||||
*/
|
||||
public $custom_fields_scope = 'list';
|
||||
|
||||
/**
|
||||
* Whether or not only a single name field is supported instead of first/last name fields.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $name_field_only = false;
|
||||
|
||||
/**
|
||||
* ET_Core_API_Email_Provider constructor.
|
||||
*
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function __construct( $owner = '', $account_name = '', $api_key = '' ) {
|
||||
$this->service_type = 'email';
|
||||
|
||||
parent::__construct( $owner, $account_name, $api_key );
|
||||
|
||||
if ( 'builder' === $this->owner ) {
|
||||
$owner = 'Divi Builder';
|
||||
} else {
|
||||
$owner = ucfirst( $this->owner );
|
||||
}
|
||||
|
||||
$this->SUBSCRIBED_VIA = sprintf( '%1$s %2$s.', esc_html__( 'Subscribed via', 'et_core' ), $owner );
|
||||
|
||||
/**
|
||||
* Filters the max number of results returned from email API provider per request.
|
||||
*
|
||||
* @since 3.17.2
|
||||
*
|
||||
* @param int $max_results_count
|
||||
*/
|
||||
$this->COUNT = apply_filters( 'et_core_api_email_max_results_count', 250 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get custom fields for a subscriber list.
|
||||
*
|
||||
* @param int|string $list_id
|
||||
* @param array $list
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function _fetch_custom_fields( $list_id = '', $list = array() ) {
|
||||
if ( 'dynamic' === $this->custom_fields ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
if ( null === $this->request || $this->request->COMPLETE ) {
|
||||
$this->prepare_request( $this->FIELDS_URL );
|
||||
}
|
||||
|
||||
$this->make_remote_request();
|
||||
|
||||
$result = array();
|
||||
|
||||
if ( false !== $this->response_data_key && empty( $this->response_data_key ) ) {
|
||||
// Let child class handle parsing the response data themselves.
|
||||
return $result;
|
||||
}
|
||||
|
||||
if ( $this->response->ERROR ) {
|
||||
et_debug( $this->get_error_message() );
|
||||
return $result;
|
||||
}
|
||||
|
||||
if ( false === $this->response_data_key ) {
|
||||
// The data returned by the service is not nested.
|
||||
$data = $this->response->DATA;
|
||||
} else {
|
||||
// The data returned by the service is nested under a single key.
|
||||
$data = $this->response->DATA[ $this->response_data_key ];
|
||||
}
|
||||
|
||||
foreach ( $data as &$custom_field ) {
|
||||
$custom_field = $this->transform_data_to_our_format( $custom_field, 'custom_field' );
|
||||
}
|
||||
|
||||
$fields = array();
|
||||
$field_types = self::$_->array_get( $this->data_keys, 'custom_field_type' );
|
||||
|
||||
foreach ( $data as $field ) {
|
||||
$field_id = $field['field_id'];
|
||||
$type = self::$_->array_get( $field, 'type', 'any' );
|
||||
|
||||
if ( $field_types && ! isset( $field_types[ $type ] ) ) {
|
||||
// Unsupported field type. Make it 'text' instead.
|
||||
$type = 'text';
|
||||
}
|
||||
|
||||
if ( isset( $field['hidden'] ) && is_string( $field['hidden'] ) ) {
|
||||
$field['hidden'] = 'false' === $field['hidden'] ? false : true;
|
||||
}
|
||||
|
||||
$field['type'] = self::$_->array_get( $this->data_keys, "custom_field_type.{$type}", 'any' );
|
||||
|
||||
$fields[ $field_id ] = $field;
|
||||
}
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
protected function _get_data() {
|
||||
$options = parent::_get_data();
|
||||
|
||||
// return empty array in case of empty name
|
||||
if ( '' === $this->account_name || ! is_string( $this->account_name ) ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$provider = sanitize_text_field( $this->slug );
|
||||
$account = sanitize_text_field( $this->account_name );
|
||||
|
||||
if ( ! isset( $options['accounts'][ $provider ][ $account ] ) ) {
|
||||
$options['accounts'][ $provider ][ $account ] = array();
|
||||
update_option( "et_core_api_email_options", $options );
|
||||
}
|
||||
|
||||
return $options['accounts'][ $provider ][ $account ];
|
||||
}
|
||||
|
||||
protected function _process_custom_fields( $args ) {
|
||||
return $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes subscriber lists data from the provider's API and returns only the data we're interested in.
|
||||
*
|
||||
* @since 1.1.0
|
||||
*
|
||||
* @param array $lists Subscriber lists data to process.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function _process_subscriber_lists( $lists ) {
|
||||
$id_key = $this->data_keys['list']['list_id'];
|
||||
$result = array();
|
||||
|
||||
foreach ( (array) $lists as $list ) {
|
||||
if ( ! is_array( $list ) ) {
|
||||
$list = (array) $list;
|
||||
}
|
||||
|
||||
if ( ! isset( $list[ $id_key ] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$id = $list[ $id_key ];
|
||||
$result[ $id ] = $this->transform_data_to_our_format( $list, 'list' );
|
||||
|
||||
if ( ! array_key_exists( 'subscribers_count', $result[ $id ] ) ) {
|
||||
$result[ $id ]['subscribers_count'] = 0;
|
||||
}
|
||||
|
||||
$get_custom_fields = $this->custom_fields && 'list' === $this->custom_fields_scope;
|
||||
|
||||
if ( $get_custom_fields && $custom_fields = $this->_fetch_custom_fields( $id, $list ) ) {
|
||||
$result[ $id ]['custom_fields'] = $custom_fields;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not an account exists in the database.
|
||||
*
|
||||
* @param string $provider
|
||||
* @param string $account_name
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function account_exists( $provider, $account_name ) {
|
||||
$all_accounts = self::get_accounts();
|
||||
|
||||
return isset( $all_accounts[ $provider ][ $account_name ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function delete() {
|
||||
self::remove_account( $this->slug, $this->account_name );
|
||||
|
||||
$this->account_name = '';
|
||||
|
||||
$this->_get_data();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the email accounts data from the database.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_accounts() {
|
||||
$options = (array) get_option( 'et_core_api_email_options' );
|
||||
|
||||
return isset( $options['accounts'] ) ? $options['accounts'] : array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function get_data_keymap( $keymap = array() ) {
|
||||
return $keymap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the subscriber lists for the account assigned to the current instance.
|
||||
*
|
||||
* @return string 'success' if successful, an error message otherwise.
|
||||
*/
|
||||
public function fetch_subscriber_lists() {
|
||||
if ( null === $this->request || $this->request->COMPLETE ) {
|
||||
$this->prepare_request( $this->LISTS_URL );
|
||||
}
|
||||
|
||||
$this->make_remote_request();
|
||||
$result = 'success';
|
||||
|
||||
if ( false !== $this->response_data_key && empty( $this->response_data_key ) ) {
|
||||
// Let child class handle parsing the response data themselves.
|
||||
return '';
|
||||
}
|
||||
|
||||
if ( $this->response->ERROR ) {
|
||||
return $this->get_error_message();
|
||||
}
|
||||
|
||||
if ( false === $this->response_data_key ) {
|
||||
// The data returned by the service is not nested.
|
||||
$data = $this->response->DATA;
|
||||
} else {
|
||||
// The data returned by the service is nested under a single key.
|
||||
$data = $this->response->DATA[ $this->response_data_key ];
|
||||
}
|
||||
|
||||
if ( ! empty( $data ) ) {
|
||||
$this->data['lists'] = $this->_process_subscriber_lists( $data );
|
||||
$this->data['is_authorized'] = true;
|
||||
|
||||
$list = is_array( $data ) ? array_shift( $data ) : array();
|
||||
|
||||
if ( $this->custom_fields && 'account' === $this->custom_fields_scope ) {
|
||||
$this->data['custom_fields'] = $this->_fetch_custom_fields( '', $list );
|
||||
}
|
||||
|
||||
$this->save_data();
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an account
|
||||
*
|
||||
* @param $provider
|
||||
* @param $account_name
|
||||
*/
|
||||
public static function remove_account( $provider, $account_name ) {
|
||||
$options = (array) get_option( 'et_core_api_email_options' );
|
||||
|
||||
unset( $options['accounts'][ $provider ][ $account_name ] );
|
||||
|
||||
update_option( 'et_core_api_email_options', $options );
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function save_data() {
|
||||
self::update_account( $this->slug, $this->account_name, $this->data );
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function set_account_name( $name ) {
|
||||
$this->account_name = $name;
|
||||
$this->data = $this->_get_data();
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes an HTTP POST request to add a subscriber to a list.
|
||||
*
|
||||
* @param string[] $args Data for the POST request.
|
||||
* @param string $url The URL for the POST request. Optional when called on child classes.
|
||||
*
|
||||
* @return string 'success' if successful, an error message otherwise.
|
||||
*/
|
||||
public function subscribe( $args, $url = '' ) {
|
||||
if ( null === $this->request || $this->request->COMPLETE ) {
|
||||
if ( ! in_array( 'ip_address', $args ) || 'true' === $args['ip_address'] ) {
|
||||
$args['ip_address'] = et_core_get_ip_address();
|
||||
} else if ( 'false' === $args['ip_address'] ) {
|
||||
$args['ip_address'] = '0.0.0.0';
|
||||
}
|
||||
|
||||
$args = $this->transform_data_to_provider_format( $args, 'subscriber' );
|
||||
|
||||
if ( $this->custom_fields ) {
|
||||
$args = $this->_process_custom_fields( $args );
|
||||
}
|
||||
|
||||
$this->prepare_request( $url, 'POST', false, $args );
|
||||
} else if ( $this->request->JSON_BODY && ! is_string( $this->request->BODY ) && ! $this->uses_oauth ) {
|
||||
$this->request->BODY = json_encode( $this->request->BODY );
|
||||
} else if ( is_array( $this->request->BODY ) ) {
|
||||
$this->request->BODY = array_merge( $this->request->BODY, $args );
|
||||
} else if ( ! $this->request->JSON_BODY ) {
|
||||
$this->request->BODY = $args;
|
||||
}
|
||||
|
||||
$this->make_remote_request();
|
||||
|
||||
return $this->response->ERROR ? $this->get_error_message() : 'success';
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the data for a provider account.
|
||||
*
|
||||
* @param string $provider The provider's slug.
|
||||
* @param string $account The account name.
|
||||
* @param array $data The new data for the account.
|
||||
*/
|
||||
public static function update_account( $provider, $account, $data ) {
|
||||
$options = (array) get_option( 'et_core_api_email_options' );
|
||||
$existing_data = array();
|
||||
|
||||
if ( empty( $account ) || empty( $provider ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$provider = sanitize_text_field( $provider );
|
||||
$account = sanitize_text_field( $account );
|
||||
|
||||
if ( isset( $options['accounts'][ $provider ][ $account ] ) ) {
|
||||
$existing_data = $options['accounts'][ $provider ][ $account ];
|
||||
}
|
||||
|
||||
$options['accounts'][ $provider ][ $account ] = array_merge( $existing_data, $data );
|
||||
|
||||
update_option( 'et_core_api_email_options', $options );
|
||||
}
|
||||
}
|
300
core/components/api/email/Providers.php
Normal file
300
core/components/api/email/Providers.php
Normal file
@ -0,0 +1,300 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Manages email provider class instances.
|
||||
*/
|
||||
class ET_Core_API_Email_Providers {
|
||||
|
||||
private static $_instance;
|
||||
|
||||
/**
|
||||
* @var ET_Core_Data_Utils
|
||||
*/
|
||||
protected static $_;
|
||||
|
||||
protected static $_any_custom_field_type;
|
||||
protected static $_custom_fields_support;
|
||||
protected static $_fields;
|
||||
protected static $_metadata;
|
||||
protected static $_names;
|
||||
protected static $_names_by_slug;
|
||||
protected static $_name_field_only = array();
|
||||
protected static $_slugs;
|
||||
|
||||
public static $providers = array();
|
||||
|
||||
public function __construct() {
|
||||
if ( null === self::$_metadata ) {
|
||||
$this->_initialize();
|
||||
}
|
||||
}
|
||||
|
||||
protected function _initialize() {
|
||||
self::$_ = ET_Core_Data_Utils::instance();
|
||||
self::$_metadata = et_core_get_components_metadata();
|
||||
$third_party_providers = et_core_get_third_party_components( 'api/email' );
|
||||
|
||||
$load_fields = is_admin() || et_core_is_saving_builder_modules_cache() || et_core_is_fb_enabled() || isset( $_GET['et_fb'] ); // phpcs:ignore WordPress.Security.NonceVerification.NoNonceVerification
|
||||
$all_names = array(
|
||||
'official' => self::$_metadata['groups']['api/email']['members'],
|
||||
'third-party' => array_keys( $third_party_providers ),
|
||||
);
|
||||
|
||||
$_names_by_slug = array();
|
||||
$_custom_fields_support = array( 'dynamic' => array(), 'predefined' => array(), 'none' => array() );
|
||||
$_any_custom_field_type = array();
|
||||
|
||||
foreach ( $all_names as $provider_type => $provider_names ) {
|
||||
$_names_by_slug[ $provider_type ] = array();
|
||||
|
||||
foreach ( $provider_names as $provider_name ) {
|
||||
if ( 'Fields' === $provider_name || self::$_->includes( $provider_name, 'Provider' ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( 'official' === $provider_type ) {
|
||||
$class_name = self::$_metadata[ $provider_name ];
|
||||
$provider_slug = self::$_metadata[ $class_name ]['slug'];
|
||||
$provider = $load_fields ? new $class_name( 'ET_Core', '' ) : null;
|
||||
} else {
|
||||
$provider = $third_party_providers[ $provider_name ];
|
||||
$provider_slug = is_object( $provider ) ? $provider->slug : '';
|
||||
}
|
||||
|
||||
if ( ! $provider_slug ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$_names_by_slug[ $provider_type ][ $provider_slug ] = $provider_name;
|
||||
|
||||
if ( $load_fields && is_object( $provider ) ) {
|
||||
self::$_fields[ $provider_slug ] = $provider->get_account_fields();
|
||||
|
||||
if ( $scope = $provider->custom_fields ) {
|
||||
$_custom_fields_support[ $scope ][ $provider_slug ] = $provider_name;
|
||||
|
||||
if ( ! self::$_->array_get( $provider->data_keys, 'custom_field_type' ) ) {
|
||||
$_any_custom_field_type[] = $provider_slug;
|
||||
}
|
||||
} else {
|
||||
$_custom_fields_support['none'][ $provider_slug ] = $provider_name;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the enabled email providers.
|
||||
*
|
||||
* @param array[] {
|
||||
*
|
||||
* @type string[] $provider_type {
|
||||
*
|
||||
* @type string $slug Provider name
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
self::$_names_by_slug = apply_filters( 'et_core_api_email_enabled_providers', $_names_by_slug );
|
||||
|
||||
foreach ( array_keys( $all_names ) as $provider_type ) {
|
||||
self::$_names[ $provider_type ] = array_values( self::$_names_by_slug[ $provider_type ] );
|
||||
self::$_slugs[ $provider_type ] = array_keys( self::$_names_by_slug[ $provider_type ] );
|
||||
}
|
||||
|
||||
self::$_name_field_only = self::$_metadata['groups']['api/email']['name_field_only'];
|
||||
self::$_custom_fields_support = $_custom_fields_support;
|
||||
self::$_any_custom_field_type = $_any_custom_field_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the email provider accounts array from core.
|
||||
*
|
||||
* @return array|mixed
|
||||
*/
|
||||
public function accounts() {
|
||||
return ET_Core_API_Email_Provider::get_accounts();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see {@link \ET_Core_API_Email_Provider::account_exists()}
|
||||
*/
|
||||
public function account_exists( $provider, $account_name ) {
|
||||
return ET_Core_API_Email_Provider::account_exists( $provider, $account_name );
|
||||
}
|
||||
|
||||
public function account_fields( $provider = 'all' ) {
|
||||
if ( 'all' !== $provider ) {
|
||||
return isset( self::$_fields[ $provider ] ) ? self::$_fields[ $provider ] : array();
|
||||
}
|
||||
|
||||
return self::$_fields;
|
||||
}
|
||||
|
||||
public function custom_fields_data() {
|
||||
$enabled_providers = self::slugs();
|
||||
$custom_fields_data = array();
|
||||
|
||||
foreach ( $this->accounts() as $provider_slug => $accounts ) {
|
||||
if ( ! in_array( $provider_slug, $enabled_providers ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ( $accounts as $account_name => $account_details ) {
|
||||
if ( empty( $account_details['lists'] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( ! empty( $account_details['custom_fields'] ) ) {
|
||||
$custom_fields_data[$provider_slug][$account_name]['custom_fields'] = $account_details['custom_fields'];
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ( (array) $account_details['lists'] as $list_id => $list_details ) {
|
||||
if ( ! empty( $list_details['custom_fields'] ) ) {
|
||||
$custom_fields_data[$provider_slug][$account_name][$list_id] = $list_details['custom_fields'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $custom_fields_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get class instance for a provider. Instance will be created if necessary.
|
||||
*
|
||||
* @param string $name_or_slug The provider's name or slug.
|
||||
* @param string $account_name The identifier for the desired account with the provider.
|
||||
* @param string $owner The owner for the instance.
|
||||
*
|
||||
* @return bool|ET_Core_API_Email_Provider The provider instance or `false` if not found.
|
||||
*/
|
||||
public function get( $name_or_slug, $account_name, $owner = 'ET_Core' ) {
|
||||
$name_or_slug = str_replace( ' ', '', $name_or_slug );
|
||||
$is_official = isset( self::$_metadata[ $name_or_slug ] );
|
||||
|
||||
if ( ! $is_official && ! $this->is_third_party( $name_or_slug ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! in_array( $name_or_slug, array_merge( self::names(), self::slugs() ) ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Make sure we have the component name
|
||||
if ( $is_official ) {
|
||||
$class_name = self::$_metadata[ $name_or_slug ];
|
||||
$name = self::$_metadata[ $class_name ]['name'];
|
||||
} else {
|
||||
$components = et_core_get_third_party_components( 'api/email' );
|
||||
|
||||
if ( ! $name = array_search( $name_or_slug, self::$_names_by_slug['third-party'] ) ) {
|
||||
$name = $name_or_slug;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! isset( self::$providers[ $name ][ $owner ] ) ) {
|
||||
self::$providers[ $name ][ $owner ] = $is_official
|
||||
? new $class_name( $owner, $account_name )
|
||||
: $components[ $name ];
|
||||
}
|
||||
|
||||
return self::$providers[ $name ][ $owner ];
|
||||
}
|
||||
|
||||
public static function instance() {
|
||||
if ( null === self::$_instance ) {
|
||||
self::$_instance = new self;
|
||||
}
|
||||
|
||||
return self::$_instance;
|
||||
}
|
||||
|
||||
public function is_third_party( $name_or_slug ) {
|
||||
$is_third_party = in_array( $name_or_slug, self::$_names['third-party'] );
|
||||
|
||||
return $is_third_party ? $is_third_party : in_array( $name_or_slug, self::$_slugs['third-party'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the names of available providers. List can optionally be filtered.
|
||||
*
|
||||
* @param string $type The component type to include ('official'|'third-party'|'all'). Default is 'all'.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function names( $type = 'all' ) {
|
||||
if ( 'all' === $type ) {
|
||||
$names = array_merge( self::$_names['third-party'], self::$_names['official'] );
|
||||
} else {
|
||||
$names = self::$_names[ $type ];
|
||||
}
|
||||
|
||||
return $names;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array mapping the slugs of available providers to their names. List can optionally be filtered.
|
||||
*
|
||||
* @param string $type The component type to include ('official'|'third-party'|'all'). Default is 'all'.
|
||||
* @param string $filter Optionally filter the list by a condition.
|
||||
* Accepts 'name_field_only', 'predefined_custom_fields', 'dynamic_custom_fields',
|
||||
* 'no_custom_fields', 'any_custom_field_type', 'custom_fields'.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function names_by_slug( $type = 'all', $filter = '' ) {
|
||||
if ( 'all' === $type ) {
|
||||
$names_by_slug = array_merge( self::$_names_by_slug['third-party'], self::$_names_by_slug['official'] );
|
||||
} else {
|
||||
$names_by_slug = self::$_names_by_slug[ $type ];
|
||||
}
|
||||
|
||||
if ( 'name_field_only' === $filter ) {
|
||||
$names_by_slug = self::$_name_field_only;
|
||||
} else if ( 'predefined_custom_fields' === $filter ) {
|
||||
$names_by_slug = self::$_custom_fields_support['predefined'];
|
||||
} else if ( 'dynamic_custom_fields' === $filter ) {
|
||||
$names_by_slug = self::$_custom_fields_support['dynamic'];
|
||||
} else if ( 'no_custom_fields' === $filter ) {
|
||||
$names_by_slug = self::$_custom_fields_support['none'];
|
||||
} else if ( 'any_custom_field_type' === $filter ) {
|
||||
$names_by_slug = self::$_any_custom_field_type;
|
||||
} else if ( 'custom_fields' === $filter ) {
|
||||
$names_by_slug = array_merge( self::$_custom_fields_support['predefined'], self::$_custom_fields_support['dynamic'] );
|
||||
}
|
||||
|
||||
return $names_by_slug;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see {@link \ET_Core_API_Email_Provider::remove_account()}
|
||||
*/
|
||||
public function remove_account( $provider, $account_name ) {
|
||||
ET_Core_API_Email_Provider::remove_account( $provider, $account_name );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the slugs of available providers. List can optionally be filtered.
|
||||
*
|
||||
* @param string $type The component type to include ('official'|'third-party'|'all'). Default is 'all'.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function slugs( $type = 'all' ) {
|
||||
if ( 'all' === $type ) {
|
||||
$names = array_merge( self::$_slugs['third-party'], self::$_slugs['official'] );
|
||||
} else {
|
||||
$names = self::$_slugs[ $type ];
|
||||
}
|
||||
|
||||
return $names;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see {@link \ET_Core_API_Email_Provider::update_account()}
|
||||
*/
|
||||
public function update_account( $provider, $account, $data ) {
|
||||
ET_Core_API_Email_Provider::update_account( $provider, $account, $data );
|
||||
}
|
||||
}
|
383
core/components/api/email/SalesForce.php
Normal file
383
core/components/api/email/SalesForce.php
Normal file
@ -0,0 +1,383 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Wrapper for SalesForce's API.
|
||||
*
|
||||
* @since 1.1.0
|
||||
*
|
||||
* @package ET\Core\API\Email
|
||||
*/
|
||||
class ET_Core_API_Email_SalesForce extends ET_Core_API_Email_Provider {
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $ACCESS_TOKEN_URL = 'https://login.salesforce.com/services/oauth2/token';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $AUTHORIZATION_URL = 'https://login.salesforce.com/services/oauth2/authorize';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $BASE_URL = '';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $custom_fields_scope = 'account';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $name = 'SalesForce';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $slug = 'salesforce';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $oauth_version = '2.0';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $uses_oauth = true;
|
||||
|
||||
/**
|
||||
* ET_Core_API_SalesForce constructor.
|
||||
*
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function __construct( $owner, $account_name = '' ) {
|
||||
parent::__construct( $owner, $account_name );
|
||||
|
||||
if ( 'builder' === $owner ) {
|
||||
$this->REDIRECT_URL = add_query_arg( 'et-core-api-email-auth', 1, home_url( '', 'https' ) ); // @phpcs:ignore ET.Sniffs.ValidVariableName.UsedPropertyNotSnakeCase -- No need to change prop name.
|
||||
} else {
|
||||
$this->REDIRECT_URL = admin_url( 'admin.php?page=et_bloom_options', 'https' ); // @phpcs:ignore ET.Sniffs.ValidVariableName.UsedPropertyNotSnakeCase -- No need to change prop name.
|
||||
}
|
||||
|
||||
$this->_set_base_url();
|
||||
}
|
||||
|
||||
protected function _fetch_custom_fields( $list_id = '', $list = array() ) {
|
||||
static $fields = null;
|
||||
|
||||
$this->response_data_key = 'fields';
|
||||
|
||||
$this->prepare_request( "{$this->BASE_URL}/services/data/v39.0/sobjects/Lead/describe" );
|
||||
|
||||
if ( is_null( $fields ) ) {
|
||||
$fields = parent::_fetch_custom_fields( $list_id, $list );
|
||||
|
||||
foreach ( $fields as $index => $field ) {
|
||||
if ( ! isset( $field['custom'] ) || ! $field['custom'] ) {
|
||||
unset( $fields[ $index ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function _fetch_subscriber_lists() {
|
||||
$query = urlencode( 'SELECT Id, Name, NumberOfLeads from Campaign LIMIT 100' );
|
||||
$url = "{$this->BASE_URL}/services/data/v39.0/query?q={$query}";
|
||||
|
||||
$this->response_data_key = 'records';
|
||||
|
||||
$this->prepare_request( $url );
|
||||
|
||||
return parent::fetch_subscriber_lists();
|
||||
}
|
||||
|
||||
protected function _process_custom_fields( $args ) {
|
||||
if ( ! isset( $args['custom_fields'] ) ) {
|
||||
return $args;
|
||||
}
|
||||
|
||||
$fields = $args['custom_fields'];
|
||||
|
||||
unset( $args['custom_fields'] );
|
||||
|
||||
foreach ( $fields as $field_id => $value ) {
|
||||
if ( is_array( $value ) && $value ) {
|
||||
// This is a multiple choice field (eg. checkbox, radio, select)
|
||||
$value = array_values( $value );
|
||||
|
||||
if ( 'checkbox' === $this->data['custom_fields'][ $field_id ]['type'] ) {
|
||||
$value = implode( ';', $value );
|
||||
} else {
|
||||
$value = array_pop( $value );
|
||||
}
|
||||
}
|
||||
|
||||
self::$_->array_set( $args, "custom_fields.{$field_id}", $value );
|
||||
}
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
public function _set_base_url() {
|
||||
// If we already have the `instance_url`, use it as the base API url.
|
||||
if ( isset( $this->data['instance_url'] ) && ! empty( $this->data['instance_url'] ) ) {
|
||||
$this->BASE_URL = untrailingslashit( $this->data['instance_url'] ); // @phpcs:ignore ET.Sniffs.ValidVariableName.UsedPropertyNotSnakeCase -- No need to change prop name.
|
||||
} else {
|
||||
$this->BASE_URL = empty( $this->data['login_url'] ) ? '' : untrailingslashit( $this->data['login_url'] ); // @phpcs:ignore ET.Sniffs.ValidVariableName.UsedPropertyNotSnakeCase -- No need to change prop name.
|
||||
}
|
||||
}
|
||||
|
||||
public function authenticate() {
|
||||
$this->data['consumer_secret'] = $this->data['client_secret'];
|
||||
$this->data['consumer_key'] = $this->data['api_key'];
|
||||
|
||||
return parent::authenticate();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function get_account_fields() {
|
||||
return array(
|
||||
// SalesForce supports OAuth for SSL websites so generate different fields in this case
|
||||
'login_url' => array(
|
||||
'label' => esc_html__( 'Instance URL', 'et_core' ),
|
||||
'required' => 'https',
|
||||
'show_if' => array( 'function.protocol' => 'https' ),
|
||||
),
|
||||
'api_key' => array(
|
||||
'label' => esc_html__( 'Consumer Key', 'et_core' ),
|
||||
'required' => 'https',
|
||||
'show_if' => array( 'function.protocol' => 'https' ),
|
||||
),
|
||||
'client_secret' => array(
|
||||
'label' => esc_html__( 'Consumer Secret', 'et_core' ),
|
||||
'required' => 'https',
|
||||
'show_if' => array( 'function.protocol' => 'https' ),
|
||||
),
|
||||
// This has to be the last field because is the only one shown in both cases and
|
||||
// CANCEL / SUBMIT buttons will be attached to it.
|
||||
'organization_id' => array(
|
||||
'label' => esc_html__( 'Organization ID', 'et_core' ),
|
||||
'required' => 'http',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function fetch_subscriber_lists() {
|
||||
$this->_set_base_url();
|
||||
// SalesForce supports 2 types of authentication: Simple and OAuth2
|
||||
if ( isset( $this->data['api_key'], $this->data['client_secret'] ) && ! empty( $this->data['api_key'] ) && ! empty( $this->data['client_secret'] ) ) {
|
||||
|
||||
// Fetch lists if user already authenticated.
|
||||
if ( $this->is_authenticated() ) {
|
||||
return $this->_fetch_subscriber_lists();
|
||||
}
|
||||
|
||||
$authenticated = $this->authenticate();
|
||||
// If the authenticating process returns an array with redirect url to complete OAuth authorization.
|
||||
if ( is_array( $authenticated ) ) {
|
||||
return $authenticated;
|
||||
}
|
||||
|
||||
if ( true === $authenticated ) {
|
||||
// Need to reinitialize the OAuthHelper with the new data, to set the authorization header in the next request.
|
||||
$urls = array(
|
||||
'access_token_url' => $this->ACCESS_TOKEN_URL, // @phpcs:ignore -- No need to change the class property
|
||||
'request_token_url' => $this->REQUEST_TOKEN_URL, // @phpcs:ignore -- No need to change the class property
|
||||
'authorization_url' => $this->AUTHORIZATION_URL, // @phpcs:ignore -- No need to change the class property
|
||||
'redirect_url' => $this->REDIRECT_URL, // @phpcs:ignore -- No need to change the class property
|
||||
);
|
||||
$this->OAuth_Helper = new ET_Core_API_OAuthHelper( $this->data, $urls, $this->owner ); // @phpcs:ignore ET.Sniffs.ValidVariableName.UsedPropertyNotSnakeCase -- No need to change the prop name.
|
||||
return $this->_fetch_subscriber_lists();
|
||||
}
|
||||
|
||||
return false;
|
||||
} elseif ( isset( $this->data['organization_id'] ) && '' !== $this->data['organization_id'] ) {
|
||||
// Simple
|
||||
$this->data['is_authorized'] = 'true';
|
||||
$this->data['lists'] = array( array( 'list_id' => 0, 'name' => 'WebToLead', 'subscribers_count' => 0 ) );
|
||||
|
||||
$this->save_data();
|
||||
|
||||
// return 'success' immediately in case of simple authentication. Lists cannot be retrieved with this type.
|
||||
return 'success';
|
||||
} else {
|
||||
return esc_html__( 'Organization ID cannot be empty', 'et_core' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function get_data_keymap( $keymap = array() ) {
|
||||
$keymap = array(
|
||||
'list' => array(
|
||||
'list_id' => 'Id',
|
||||
'name' => 'Name',
|
||||
'subscribers_count' => 'NumberOfLeads',
|
||||
),
|
||||
'subscriber' => array(
|
||||
'name' => 'FirstName',
|
||||
'last_name' => 'LastName',
|
||||
'email' => 'Email',
|
||||
'custom_fields' => 'custom_fields',
|
||||
),
|
||||
'custom_field' => array(
|
||||
'field_id' => 'name',
|
||||
'name' => 'label',
|
||||
'type' => 'type',
|
||||
'options' => 'valueSet',
|
||||
),
|
||||
'custom_field_type' => array(
|
||||
// Us => Them
|
||||
'input' => 'Text',
|
||||
'textarea' => 'TextArea',
|
||||
'checkbox' => 'MultiselectPicklist',
|
||||
'select' => 'Picklist',
|
||||
// Them => Us
|
||||
'Text' => 'input',
|
||||
'TextArea' => 'textarea',
|
||||
'MultiselectPicklist' => 'checkbox',
|
||||
'Picklist' => 'select',
|
||||
),
|
||||
);
|
||||
|
||||
return parent::get_data_keymap( $keymap );
|
||||
}
|
||||
|
||||
public function get_subscriber( $email ) {
|
||||
$query = urlencode( "SELECT Id from Lead where Email='{$email}' LIMIT 100" );
|
||||
$url = "{$this->BASE_URL}/services/data/v39.0/query?q={$query}";
|
||||
|
||||
$this->response_data_key = 'records';
|
||||
|
||||
$this->prepare_request( $url );
|
||||
$this->make_remote_request();
|
||||
|
||||
$response = $this->response;
|
||||
|
||||
if ( $response->ERROR || empty( $response->DATA['records'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return isset( $response->DATA['records'][0]['Id'] ) ? $response->DATA['records'][0]['Id'] : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function subscribe( $args, $url = '' ) {
|
||||
if ( empty( $this->data['access_secret'] ) ) {
|
||||
// Try to use simple web form
|
||||
return $this->subscribe_salesforce_web( $args );
|
||||
}
|
||||
|
||||
$error_message = esc_html__( 'An error occurred. Please try again.', 'et_core' );
|
||||
$subscriber_id = $this->get_subscriber( $args['email'] );
|
||||
|
||||
if ( ! $subscriber_id ) {
|
||||
$url = "{$this->BASE_URL}/services/data/v39.0/sobjects/Lead";
|
||||
$content = $this->transform_data_to_provider_format( $args, 'subscriber' );
|
||||
$content = $this->_process_custom_fields( $content );
|
||||
$content['Company'] = 'Bloom';
|
||||
if ( isset( $content['custom_fields'] ) && is_array( $content['custom_fields'] ) ) {
|
||||
$content = array_merge( $content, $content['custom_fields'] );
|
||||
unset( $content['custom_fields'] );
|
||||
}
|
||||
|
||||
// The LastName is required by Salesforce, whereas it is possible for Optin Form to not have the last name field.
|
||||
if ( ! isset( $content['LastName'] ) || empty( $content['LastName'] ) ) {
|
||||
$content['LastName'] = '[not provided]';
|
||||
}
|
||||
|
||||
$this->prepare_request( $url, 'POST', false, json_encode( $content ), true );
|
||||
|
||||
$this->response_data_key = false;
|
||||
|
||||
$result = parent::subscribe( $content, $url );
|
||||
|
||||
if ( 'success' !== $result || empty( $this->response->DATA['id'] ) ) {
|
||||
return $error_message;
|
||||
}
|
||||
|
||||
$subscriber_id = $this->response->DATA['id'];
|
||||
}
|
||||
|
||||
$url = "{$this->BASE_URL}/services/data/v39.0/sobjects/CampaignMember";
|
||||
$content = array(
|
||||
'LeadId' => $subscriber_id,
|
||||
'CampaignId' => $args['list_id'],
|
||||
);
|
||||
|
||||
$this->prepare_request( $url, 'POST', false, json_encode( $content ), true );
|
||||
|
||||
$result = parent::subscribe( $content, $url );
|
||||
|
||||
if ( 'success' !== $result && ! empty( $this->response->DATA['errors'] ) ) {
|
||||
return $this->response->DATA['errors'][0];
|
||||
} else if ( 'success' !== $result ) {
|
||||
return $error_message;
|
||||
}
|
||||
|
||||
return 'success';
|
||||
}
|
||||
|
||||
/**
|
||||
* Post web-to-lead request to SalesForce
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function subscribe_salesforce_web( $args ) {
|
||||
if ( ! isset( $this->data['organization_id'] ) || '' === $this->data['organization_id'] ) {
|
||||
return esc_html__( 'Unknown Organization ID', 'et_core' );
|
||||
}
|
||||
|
||||
// Define SalesForce web-to-lead endpoint
|
||||
$url = 'https://webto.salesforce.com/servlet/servlet.WebToLead?encoding=UTF-8';
|
||||
$args = $this->transform_data_to_provider_format( $args, 'subscriber' );
|
||||
$args = $this->_process_custom_fields( $args );
|
||||
|
||||
// Prepare arguments for web-to-lead POST
|
||||
$form_args = array(
|
||||
'body' => array(
|
||||
'oid' => sanitize_text_field( $this->data['organization_id'] ),
|
||||
'retURL' => esc_url( home_url( '/' ) ),
|
||||
'email' => sanitize_email( $args['Email'] ),
|
||||
),
|
||||
);
|
||||
|
||||
if ( '' !== $args['FirstName'] ) {
|
||||
$form_args['body']['first_name'] = sanitize_text_field( $args['FirstName'] );
|
||||
}
|
||||
|
||||
if ( '' !== $args['LastName'] ) {
|
||||
$form_args['body']['last_name'] = sanitize_text_field( $args['LastName'] );
|
||||
}
|
||||
|
||||
if ( isset( $args['custom_fields'] ) && is_array( $args['custom_fields'] ) ) {
|
||||
$form_args = array_merge( $form_args, $args['custom_fields'] );
|
||||
}
|
||||
|
||||
// Post to SalesForce web-to-lead endpoint
|
||||
$request = wp_remote_post( $url, $form_args );
|
||||
|
||||
if ( ! is_wp_error( $request ) && 200 === wp_remote_retrieve_response_code( $request ) ) {
|
||||
return 'success';
|
||||
}
|
||||
|
||||
return esc_html__( 'An error occurred. Please try again.', 'et_core' );
|
||||
}
|
||||
}
|
274
core/components/api/email/SendinBlue.php
Normal file
274
core/components/api/email/SendinBlue.php
Normal file
@ -0,0 +1,274 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Wrapper for SendinBlue's API.
|
||||
*
|
||||
* @since 1.1.0
|
||||
*
|
||||
* @package ET\Core\API\Email
|
||||
*/
|
||||
class ET_Core_API_Email_SendinBlue extends ET_Core_API_Email_Provider {
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $BASE_URL = 'https://api.sendinblue.com/v3'; // @phpcs:ignore ET.Sniffs.ValidVariableName.PropertyNotSnakeCase -- Keep the variable name.
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $FIELDS_URL = 'https://api.sendinblue.com/v3/contacts/attributes'; // @phpcs:ignore ET.Sniffs.ValidVariableName.PropertyNotSnakeCase -- Keep the variable name.
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $LISTS_URL = 'https://api.sendinblue.com/v3/contacts/lists/'; // @phpcs:ignore ET.Sniffs.ValidVariableName.PropertyNotSnakeCase -- Keep the variable name.
|
||||
|
||||
/**
|
||||
* The URL to which new subscribers can be posted.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $SUBSCRIBE_URL = 'https://api.sendinblue.com/v3/contacts'; // @phpcs:ignore ET.Sniffs.ValidVariableName.PropertyNotSnakeCase -- Keep the variable name.
|
||||
|
||||
/**
|
||||
* The URL to get the subscriber information.
|
||||
* Only used by legacy mode (v2) to check whether we should create or update subscription.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $USERS_URL = 'https://api.sendinblue.com/v2.0/user';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $custom_fields_scope = 'account';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $name = 'SendinBlue';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $slug = 'sendinblue';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $uses_oauth = false;
|
||||
|
||||
public function __construct( $owner, $account_name, $api_key = '' ) {
|
||||
parent::__construct( $owner, $account_name, $api_key );
|
||||
|
||||
$this->_maybe_set_custom_headers();
|
||||
}
|
||||
|
||||
protected function _maybe_set_custom_headers() {
|
||||
if ( empty( $this->custom_headers ) && isset( $this->data['api_key'] ) ) {
|
||||
$this->custom_headers = array( 'api-key' => $this->data['api_key'] );
|
||||
}
|
||||
}
|
||||
|
||||
protected function _process_custom_fields( $args ) {
|
||||
if ( ! isset( $args['custom_fields'] ) ) {
|
||||
return $args;
|
||||
}
|
||||
|
||||
$fields = $args['custom_fields'];
|
||||
|
||||
unset( $args['custom_fields'] );
|
||||
|
||||
foreach ( $fields as $field_id => $value ) {
|
||||
if ( is_array( $value ) && $value ) {
|
||||
// This is a multiple choice field (eg. checkbox, radio, select)
|
||||
$value = array_values( $value );
|
||||
|
||||
if ( count( $value ) > 1 ) {
|
||||
$value = implode( ',', $value );
|
||||
} else {
|
||||
$value = array_pop( $value );
|
||||
}
|
||||
}
|
||||
|
||||
self::$_->array_set( $args, "attributes.{$field_id}", $value );
|
||||
}
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function get_account_fields() {
|
||||
return array(
|
||||
'api_key' => array(
|
||||
'label' => esc_html__( 'API Key', 'et_core' ),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function get_data_keymap( $keymap = array() ) {
|
||||
$keymap = array(
|
||||
'list' => array(
|
||||
'list_id' => 'id',
|
||||
'name' => 'name',
|
||||
'subscribers_count' => $this->_should_use_legacy_api() ? 'total_subscribers' : 'totalSubscribers',
|
||||
),
|
||||
'subscriber' => array(
|
||||
'email' => 'email',
|
||||
'name' => 'attributes.FIRSTNAME',
|
||||
'last_name' => 'attributes.LASTNAME',
|
||||
'list_id' => $this->_should_use_legacy_api() ? '@listid' : '@listIds',
|
||||
'custom_fields' => 'custom_fields',
|
||||
'updateEnabled' => 'updateEnabled',
|
||||
),
|
||||
'custom_field' => array(
|
||||
'field_id' => 'name',
|
||||
'name' => 'name',
|
||||
),
|
||||
);
|
||||
|
||||
return parent::get_data_keymap( $keymap );
|
||||
}
|
||||
|
||||
public function get_subscriber( $email ) {
|
||||
$this->prepare_request( "{$this->USERS_URL}/{$email}", 'GET' );
|
||||
$this->make_remote_request();
|
||||
|
||||
if ( $this->response->ERROR || ! isset( $this->response->DATA['listid'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( isset( $this->response->DATA['code'] ) && 'success' !== $this->response->DATA['code'] ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->response->DATA;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function fetch_subscriber_lists() {
|
||||
if ( empty( $this->data['api_key'] ) ) {
|
||||
return $this->API_KEY_REQUIRED;
|
||||
}
|
||||
|
||||
if ( empty( $this->custom_headers ) ) {
|
||||
$this->_maybe_set_custom_headers();
|
||||
}
|
||||
|
||||
$use_legacy_api = $this->_should_use_legacy_api();
|
||||
if ( $use_legacy_api ) {
|
||||
$this->LISTS_URL = 'https://api.sendinblue.com/v2.0/list'; // @phpcs:ignore ET.Sniffs.ValidVariableName.UsedPropertyNotSnakeCase -- Keep the variable name.
|
||||
$this->response_data_key = 'data';
|
||||
$params = array(
|
||||
'page' => 1,
|
||||
'page_limit' => 2,
|
||||
);
|
||||
} else {
|
||||
$this->response_data_key = 'lists';
|
||||
}
|
||||
|
||||
/**
|
||||
* The maximum number of subscriber lists to request from Sendinblue's API.
|
||||
*
|
||||
* @since 4.11.4
|
||||
*
|
||||
* @param int $max_lists
|
||||
*/
|
||||
$max_lists = (int) apply_filters( 'et_core_api_email_sendinblue_max_lists', 50 );
|
||||
$url = "{$this->LISTS_URL}?limit={$max_lists}&offset=0&sort=desc";
|
||||
|
||||
$this->prepare_request( $url, 'GET', false, $params );
|
||||
|
||||
$this->request->data_format = 'body';
|
||||
|
||||
parent::fetch_subscriber_lists();
|
||||
|
||||
if ( $this->response->ERROR ) {
|
||||
return $this->response->ERROR_MESSAGE;
|
||||
}
|
||||
|
||||
if ( isset( $this->response->DATA['code'] ) && 'success' !== $this->response->DATA['code'] ) {
|
||||
return $this->response->DATA['message'];
|
||||
}
|
||||
|
||||
$result = 'success';
|
||||
$this->data['is_authorized'] = 'true';
|
||||
$list_data = $use_legacy_api ? $this->response->DATA['data']['lists'] : $this->response->DATA['lists'];
|
||||
|
||||
if ( ! empty( $list_data ) ) {
|
||||
$this->data['lists'] = $this->_process_subscriber_lists( $list_data );
|
||||
$this->save_data();
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get custom fields for a subscriber list.
|
||||
* Need to override the method in the child class to dynamically use the API endpoint
|
||||
* and response_data_key based on the API version being used.
|
||||
*
|
||||
* @param int|string $list_id The list ID.
|
||||
* @param array $list The lists array.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function _fetch_custom_fields( $list_id = '', $list = array() ) {
|
||||
if ( $this->_should_use_legacy_api() ) {
|
||||
$this->FIELDS_URL = 'https://api.sendinblue.com/v2.0/attribute/normal'; // @phpcs:ignore ET.Sniffs.ValidVariableName.UsedPropertyNotSnakeCase -- Keep the variable name.
|
||||
$this->response_data_key = 'data';
|
||||
} else {
|
||||
$this->response_data_key = 'attributes';
|
||||
}
|
||||
|
||||
return parent::_fetch_custom_fields( $list_id, $list );
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function subscribe( $args, $url = '' ) {
|
||||
$args['list_id'] = array( absint( $args['list_id'] ) ); // in V3 the list id has to be integer.
|
||||
if ( $this->_should_use_legacy_api() ) {
|
||||
$this->SUBSCRIBE_URL = 'https://api.sendinblue.com/v2.0/user/createdituser'; // @phpcs:ignore ET.Sniffs.ValidVariableName.UsedPropertyNotSnakeCase -- Keep the variable name.
|
||||
$existing_user = $this->get_subscriber( $args['email'] );
|
||||
if ( false !== $existing_user ) {
|
||||
$args['list_id'] = array_unique( array_merge( $args['list_id'], $existing_user['listid'] ) );
|
||||
}
|
||||
} else {
|
||||
$args['updateEnabled'] = true; // Update existing contact if exists.
|
||||
// Process data and encode to json, the new API (v3) uses json encoded body params.
|
||||
if ( ! in_array( 'ip_address', $args, true ) || 'true' === $args['ip_address'] ) {
|
||||
$args['ip_address'] = et_core_get_ip_address();
|
||||
} elseif ( 'false' === $args['ip_address'] ) {
|
||||
$args['ip_address'] = '0.0.0.0';
|
||||
}
|
||||
|
||||
$args = $this->transform_data_to_provider_format( $args, 'subscriber' );
|
||||
if ( $this->custom_fields ) {
|
||||
$args = $this->_process_custom_fields( $args );
|
||||
}
|
||||
$this->prepare_request( $this->SUBSCRIBE_URL, 'POST', false, $args, true ); // @phpcs:ignore ET.Sniffs.ValidVariableName.UsedPropertyNotSnakeCase -- Keep the variable name.
|
||||
}
|
||||
|
||||
return parent::subscribe( $args, $this->SUBSCRIBE_URL );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the api-key being used is legacy (v2).
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
protected function _should_use_legacy_api() {
|
||||
$api_key = isset( $this->data['api_key'] ) ? $this->data['api_key'] : '';
|
||||
return ! empty( $api_key ) && 'xkeysib-' !== substr( $api_key, 0, 8 );
|
||||
}
|
||||
}
|
149
core/components/api/email/_MailPoet2.php
Normal file
149
core/components/api/email/_MailPoet2.php
Normal file
@ -0,0 +1,149 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Wrapper for MailPoet's API.
|
||||
*
|
||||
* @since 3.0.76
|
||||
*
|
||||
* @package ET\Core\API\Email
|
||||
*/
|
||||
class ET_Core_API_Email_MailPoet2 extends ET_Core_API_Email_Provider {
|
||||
|
||||
public static $PLUGIN_REQUIRED;
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $name = 'MailPoet';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $slug = 'mailpoet';
|
||||
|
||||
public function __construct( $owner = '', $account_name = '', $api_key = '' ) {
|
||||
parent::__construct( $owner, $account_name, $api_key );
|
||||
|
||||
if ( null === self::$PLUGIN_REQUIRED ) {
|
||||
self::$PLUGIN_REQUIRED = esc_html__( 'MailPoet plugin is either not installed or not activated.', 'et_core' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function get_account_fields() {
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function get_data_keymap( $keymap = array() ) {
|
||||
$keymap = array(
|
||||
'list' => array(
|
||||
'list_id' => 'id',
|
||||
'name' => 'name',
|
||||
),
|
||||
'subscriber' => array(
|
||||
'name' => 'first_name',
|
||||
'last_name' => 'last_name',
|
||||
'email' => 'email',
|
||||
),
|
||||
);
|
||||
|
||||
return parent::get_data_keymap( $keymap );
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function fetch_subscriber_lists() {
|
||||
if ( ! class_exists( 'WYSIJA' ) ) {
|
||||
return self::$PLUGIN_REQUIRED;
|
||||
}
|
||||
|
||||
$lists = array();
|
||||
$list_model = WYSIJA::get( 'list', 'model' );
|
||||
$all_lists_array = $list_model->get( array( 'name', 'list_id' ), array( 'is_enabled' => '1' ) );
|
||||
|
||||
foreach ( $all_lists_array as $list_details ) {
|
||||
$lists[ $list_details['list_id'] ]['name'] = sanitize_text_field( $list_details['name'] );
|
||||
|
||||
$user_model = WYSIJA::get( 'user_list', 'model' );
|
||||
$all_subscribers_array = $user_model->get( array( 'user_id' ), array( 'list_id' => $list_details['list_id'] ) );
|
||||
|
||||
$subscribers_count = count( $all_subscribers_array );
|
||||
$lists[ $list_details['list_id'] ]['subscribers_count'] = sanitize_text_field( $subscribers_count );
|
||||
}
|
||||
|
||||
$this->data['is_authorized'] = true;
|
||||
|
||||
if ( ! empty( $lists ) ) {
|
||||
$this->data['lists'] = $lists;
|
||||
}
|
||||
|
||||
$this->save_data();
|
||||
|
||||
return array( 'success' => $this->data );
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function subscribe( $args, $url = '' ) {
|
||||
if ( ! class_exists( 'WYSIJA' ) ) {
|
||||
ET_Core_Logger::error( self::$PLUGIN_REQUIRED );
|
||||
return esc_html__( 'An error occurred. Please try again later.', 'et_core' );
|
||||
}
|
||||
|
||||
global $wpdb;
|
||||
$wpdb->wysija_user_table = $wpdb->prefix . 'wysija_user';
|
||||
$wpdb->wysija_user_lists_table = $wpdb->prefix . 'wysija_user_list';
|
||||
|
||||
// get the ID of subscriber if they're in the list already
|
||||
$subscriber_id = $wpdb->get_var( $wpdb->prepare(
|
||||
"SELECT user_id FROM {$wpdb->wysija_user_table} WHERE email = %s",
|
||||
array(
|
||||
et_core_sanitized_previously( $args['email'] ),
|
||||
)
|
||||
) );
|
||||
$already_subscribed = 0;
|
||||
|
||||
// if current email is subscribed, then check whether it subscribed to the current list
|
||||
if ( ! empty( $subscriber_id ) ) {
|
||||
$already_subscribed = (int) $wpdb->get_var( $wpdb->prepare(
|
||||
"SELECT COUNT(*) FROM {$wpdb->wysija_user_lists_table} WHERE user_id = %s AND list_id = %s",
|
||||
array(
|
||||
$subscriber_id,
|
||||
et_core_sanitized_previously( $args['list_id'] ),
|
||||
)
|
||||
) );
|
||||
}
|
||||
|
||||
unset( $wpdb->wysija_user_table );
|
||||
unset( $wpdb->wysija_user_list_table );
|
||||
|
||||
// if email is not subscribed to current list, then subscribe.
|
||||
if ( 0 === $already_subscribed ) {
|
||||
$new_user = array(
|
||||
'user' => array(
|
||||
'email' => et_core_sanitized_previously( $args['email'] ),
|
||||
'firstname' => et_core_sanitized_previously( $args['name'] ),
|
||||
'lastname' => et_core_sanitized_previously( $args['last_name'] ),
|
||||
),
|
||||
'user_list' => array(
|
||||
'list_ids' => array( et_core_sanitized_previously( $args['list_id'] ) ),
|
||||
),
|
||||
);
|
||||
|
||||
$mailpoet_class = WYSIJA::get( 'user', 'helper' );
|
||||
$error_message = $mailpoet_class->addSubscriber( $new_user );
|
||||
$error_message = is_int( $error_message ) ? 'success' : $error_message;
|
||||
} else {
|
||||
$error_message = esc_html__( 'Already Subscribed', 'bloom' );
|
||||
}
|
||||
|
||||
return $error_message;
|
||||
}
|
||||
}
|
188
core/components/api/email/_MailPoet3.php
Normal file
188
core/components/api/email/_MailPoet3.php
Normal file
@ -0,0 +1,188 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Wrapper for MailPoet's API.
|
||||
*
|
||||
* @since 3.0.76
|
||||
*
|
||||
* @package ET\Core\API\Email
|
||||
*/
|
||||
class ET_Core_API_Email_MailPoet3 extends ET_Core_API_Email_Provider {
|
||||
|
||||
public static $PLUGIN_REQUIRED;
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $name = 'MailPoet';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $slug = 'mailpoet';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $custom_fields_scope = 'account';
|
||||
|
||||
public function __construct( $owner = '', $account_name = '', $api_key = '' ) {
|
||||
parent::__construct( $owner, $account_name, $api_key );
|
||||
|
||||
if ( null === self::$PLUGIN_REQUIRED ) {
|
||||
self::$PLUGIN_REQUIRED = esc_html__( 'MailPoet plugin is either not installed or not activated.', 'et_core' );
|
||||
}
|
||||
}
|
||||
|
||||
protected function _fetch_custom_fields( $list_id = '', $list = array() ) {
|
||||
static $processed = null;
|
||||
|
||||
if ( is_null( $processed ) ) {
|
||||
$fields = \MailPoet\API\API::MP( 'v1' )->getSubscriberFields();
|
||||
$processed = array();
|
||||
|
||||
foreach ( $fields as $field ) {
|
||||
$field_id = $field['id'];
|
||||
$field_name = $field['name'];
|
||||
|
||||
if ( in_array( $field_id, array( 'email', 'first_name', 'last_name' ) ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$processed[ $field_id ] = array(
|
||||
'field_id' => $field_id,
|
||||
'name' => $field_name,
|
||||
'type' => 'any',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $processed;
|
||||
}
|
||||
|
||||
protected function _process_custom_fields( $args ) {
|
||||
if ( ! isset( $args['custom_fields'] ) ) {
|
||||
return $args;
|
||||
}
|
||||
|
||||
$fields = $args['custom_fields'];
|
||||
|
||||
unset( $args['custom_fields'] );
|
||||
|
||||
foreach ( $fields as $field_id => $value ) {
|
||||
if ( is_array( $value ) && $value ) {
|
||||
// This is a multiple choice field (eg. checkbox, radio, select)
|
||||
$value = array_keys( $value );
|
||||
|
||||
if ( count( $value ) > 1 ) {
|
||||
$value = implode( ',', $value );
|
||||
} else {
|
||||
$value = array_pop( $value );
|
||||
}
|
||||
}
|
||||
|
||||
self::$_->array_set( $args, $field_id, $value );
|
||||
}
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function get_account_fields() {
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function get_data_keymap( $keymap = array() ) {
|
||||
$keymap = array(
|
||||
'list' => array(
|
||||
'list_id' => 'id',
|
||||
'name' => 'name',
|
||||
),
|
||||
'subscriber' => array(
|
||||
'name' => 'first_name',
|
||||
'last_name' => 'last_name',
|
||||
'email' => 'email',
|
||||
'custom_fields' => 'custom_fields',
|
||||
),
|
||||
);
|
||||
|
||||
return parent::get_data_keymap( $keymap );
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function fetch_subscriber_lists() {
|
||||
if ( ! class_exists( '\MailPoet\API\API' ) ) {
|
||||
return self::$PLUGIN_REQUIRED;
|
||||
}
|
||||
|
||||
$data = \MailPoet\API\API::MP( 'v1' )->getLists();
|
||||
|
||||
if ( ! empty( $data ) ) {
|
||||
$this->data['lists'] = $this->_process_subscriber_lists( $data );
|
||||
|
||||
$list = is_array( $data ) ? array_shift( $data ) : array();
|
||||
$this->data['custom_fields'] = $this->_fetch_custom_fields( '', $list );
|
||||
}
|
||||
|
||||
$this->data['is_authorized'] = true;
|
||||
|
||||
$this->save_data();
|
||||
|
||||
return array( 'success' => $this->data );
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function subscribe( $args, $url = '' ) {
|
||||
if ( ! class_exists( '\MailPoet\API\API' ) ) {
|
||||
ET_Core_Logger::error( self::$PLUGIN_REQUIRED );
|
||||
|
||||
return esc_html__( 'An error occurred. Please try again later.', 'et_core' );
|
||||
}
|
||||
|
||||
$subscriber = array();
|
||||
$args = et_core_sanitized_previously( $args );
|
||||
$subscriber_data = $this->transform_data_to_provider_format( $args, 'subscriber' );
|
||||
$subscriber_data = $this->_process_custom_fields( $subscriber_data );
|
||||
$subscriber_data = self::$_->array_flatten( $subscriber_data );
|
||||
$result = 'success';
|
||||
$lists = array( $args['list_id'] );
|
||||
|
||||
unset( $subscriber_data['custom_fields'] );
|
||||
|
||||
/**
|
||||
* Check if the subscriber with this email already exists.
|
||||
*/
|
||||
$subscriber = \MailPoet\Models\Subscriber::findOne( $subscriber_data['email'] );
|
||||
|
||||
if ( $subscriber ) {
|
||||
$subscriber = $subscriber->withCustomFields()->withSubscriptions()->asArray();
|
||||
}
|
||||
/**
|
||||
* If subscriber is not found, add as a new subscriber. Otherwise, add existing subscriber to the lists.
|
||||
*/
|
||||
if ( empty( $subscriber ) ) {
|
||||
try {
|
||||
\MailPoet\API\API::MP( 'v1' )->addSubscriber( $subscriber_data, $lists );
|
||||
} catch ( Exception $exception ) {
|
||||
$result = $exception->getMessage();
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
\MailPoet\API\API::MP( 'v1' )->subscribeToLists( $subscriber['id'], $lists );
|
||||
} catch ( Exception $exception ) {
|
||||
$result = $exception->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
82
core/components/api/email/_ProviderName.php
Normal file
82
core/components/api/email/_ProviderName.php
Normal file
@ -0,0 +1,82 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Wrapper for ProviderName's API.
|
||||
*
|
||||
* @since 1.1.0
|
||||
*
|
||||
* @package ET\Core\API\Email
|
||||
*/
|
||||
class ET_Core_API_Email_ProviderName extends ET_Core_API_Email_Provider {
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $BASE_URL = '';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $name = 'ProviderName';
|
||||
|
||||
/**
|
||||
* Whether or not only a single name field is supported instead of first/last name fields.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public static $name_field_only = false;
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $slug = 'providername';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @internal If true, oauth endpoints properties must also be defined.
|
||||
*/
|
||||
public $uses_oauth = false;
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function get_account_fields() {
|
||||
// Implement get_account_fields() method.
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function get_data_keymap( $keymap = array(), $custom_fields_key = '' ) {
|
||||
// Implement get_data_keys() method.
|
||||
$keymap = array(
|
||||
'list' => array(
|
||||
'list_id' => '',
|
||||
'name' => '',
|
||||
'subscribers_count' => '',
|
||||
),
|
||||
'subscriber' => array(
|
||||
'name' => '',
|
||||
'email' => '',
|
||||
'list_id' => '',
|
||||
'ip_address' => '',
|
||||
),
|
||||
);
|
||||
|
||||
return parent::get_data_keymap( $keymap, $custom_fields_key );
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function fetch_subscriber_lists() {
|
||||
// Implement get_subscriber_lists() method.
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function subscribe( $args, $url = '' ) {
|
||||
// Implement subscribe() method.
|
||||
}
|
||||
}
|
278
core/components/api/email/iContact.php
Normal file
278
core/components/api/email/iContact.php
Normal file
@ -0,0 +1,278 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Wrapper for iContact's API.
|
||||
*
|
||||
* @since 1.1.0
|
||||
*
|
||||
* @package ET\Core\API\Email
|
||||
*/
|
||||
class ET_Core_API_Email_iContact extends ET_Core_API_Email_Provider {
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $BASE_URL = 'https://app.icontact.com/icp/a';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $custom_fields_scope = 'account';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $name = 'iContact';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $slug = 'icontact';
|
||||
|
||||
protected function _fetch_custom_fields( $list_id = '', $list = array() ) {
|
||||
$this->prepare_request( $this->FIELDS_URL );
|
||||
$this->make_remote_request();
|
||||
|
||||
$result = array();
|
||||
|
||||
if ( $this->response->ERROR ) {
|
||||
et_debug( $this->get_error_message() );
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
$data = $this->response->DATA['customfields'];
|
||||
|
||||
foreach ( $data as &$custom_field ) {
|
||||
$custom_field = $this->transform_data_to_our_format( $custom_field, 'custom_field' );
|
||||
}
|
||||
|
||||
$fields = array();
|
||||
|
||||
foreach ( $data as $field ) {
|
||||
if ( 'text' !== $field['type'] ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$field_id = $field['field_id'];
|
||||
$type = self::$_->array_get( $field, 'type', 'any' );
|
||||
|
||||
$field['type'] = self::$_->array_get( $this->data_keys, "custom_field_type.{$type}", 'any' );
|
||||
|
||||
$fields[ $field_id ] = $field;
|
||||
}
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
protected function _set_custom_headers() {
|
||||
if ( ! empty( $this->custom_headers ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->custom_headers = array(
|
||||
'Accept' => 'application/json',
|
||||
'API-Version' => '2.2',
|
||||
'API-AppId' => sanitize_text_field( $this->data['client_id'] ),
|
||||
'API-Username' => sanitize_text_field( $this->data['username'] ),
|
||||
'API-Password' => sanitize_text_field( $this->data['password'] ),
|
||||
);
|
||||
}
|
||||
|
||||
protected function _get_account_id() {
|
||||
if ( ! empty( $this->data['account_id'] ) ) {
|
||||
return $this->data['account_id'];
|
||||
}
|
||||
|
||||
$this->prepare_request( 'https://app.icontact.com/icp/a' );
|
||||
$this->make_remote_request();
|
||||
|
||||
if ( isset( $this->response->DATA['accounts'][0]['accountId'] ) ) {
|
||||
$this->data['account_id'] = $this->response->DATA['accounts'][0]['accountId'];
|
||||
}
|
||||
|
||||
return $this->data['account_id'];
|
||||
}
|
||||
|
||||
protected function _get_subscriber( $args, $exclude = null ) {
|
||||
$default_excludes = array( 'name', 'last_name' );
|
||||
|
||||
if ( is_array( $exclude ) ) {
|
||||
$exclude = array_merge( $default_excludes, $exclude );
|
||||
} else if ( $exclude ) {
|
||||
$default_excludes[] = $exclude;
|
||||
$exclude = $default_excludes;
|
||||
}
|
||||
|
||||
$args = $this->transform_data_to_provider_format( $args, 'subscriber', $exclude );
|
||||
$url = add_query_arg( $args, $this->SUBSCRIBERS_URL );
|
||||
|
||||
$this->prepare_request( $url );
|
||||
$this->make_remote_request();
|
||||
|
||||
if ( $this->response->ERROR || ! $this->response->DATA['contacts'] ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->response->DATA['contacts'][0];
|
||||
}
|
||||
|
||||
protected function _get_folder_id() {
|
||||
if ( ! empty( $this->data['folder_id'] ) ) {
|
||||
return $this->data['folder_id'];
|
||||
}
|
||||
|
||||
$this->prepare_request( "{$this->BASE_URL}/{$this->data['account_id']}/c" );
|
||||
$this->make_remote_request();
|
||||
|
||||
if ( isset( $this->response->DATA['clientfolders'][0]['clientFolderId'] ) ) {
|
||||
$this->data['folder_id'] = $this->response->DATA['clientfolders'][0]['clientFolderId'];
|
||||
}
|
||||
|
||||
return $this->data['folder_id'];
|
||||
}
|
||||
|
||||
protected function _process_custom_fields( $args ) {
|
||||
if ( ! isset( $args['custom_fields'] ) ) {
|
||||
return $args;
|
||||
}
|
||||
|
||||
$fields = $args['custom_fields'];
|
||||
|
||||
unset( $args['custom_fields'] );
|
||||
|
||||
foreach ( $fields as $field_id => $value ) {
|
||||
if ( is_array( $value ) && $value ) {
|
||||
// This is a multiple choice field (eg. checkbox, radio, select)
|
||||
$value = array_values( $value );
|
||||
|
||||
if ( count( $value ) > 1 ) {
|
||||
$value = implode( ',', $value );
|
||||
} else {
|
||||
$value = array_pop( $value );
|
||||
}
|
||||
}
|
||||
|
||||
self::$_->array_set( $args, $field_id, $value );
|
||||
}
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
protected function _set_urls() {
|
||||
$this->_set_custom_headers();
|
||||
|
||||
$account_id = $this->_get_account_id();
|
||||
$folder_id = $this->_get_folder_id();
|
||||
|
||||
$this->BASE_URL = "{$this->BASE_URL}/{$account_id}/c/{$folder_id}";
|
||||
$this->FIELDS_URL = "{$this->BASE_URL}/customfields";
|
||||
$this->LISTS_URL = "{$this->BASE_URL}/lists";
|
||||
$this->SUBSCRIBE_URL = "{$this->BASE_URL}/subscriptions";
|
||||
$this->SUBSCRIBERS_URL = "{$this->BASE_URL}/contacts";
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function get_account_fields() {
|
||||
return array(
|
||||
'client_id' => array(
|
||||
'label' => esc_html__( 'App ID', 'et_core' ),
|
||||
),
|
||||
'username' => array(
|
||||
'label' => esc_html__( 'Username', 'et_core' ),
|
||||
),
|
||||
'password' => array(
|
||||
'label' => esc_html__( 'App Password', 'et_core' ),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function get_data_keymap( $keymap = array() ) {
|
||||
$keymap = array(
|
||||
'list' => array(
|
||||
'list_id' => 'listId',
|
||||
'name' => 'name',
|
||||
'subscribers_count' => 'total',
|
||||
),
|
||||
'subscriber' => array(
|
||||
'name' => 'firstName',
|
||||
'last_name' => 'lastName',
|
||||
'email' => 'email',
|
||||
'list_id' => 'listId',
|
||||
'custom_fields' => 'custom_fields',
|
||||
),
|
||||
'subscriptions' => array(
|
||||
'list_id' => 'listId',
|
||||
'message_id' => 'confirmationMessageId',
|
||||
),
|
||||
'custom_field' => array(
|
||||
'field_id' => 'privateName',
|
||||
'name' => 'publicName',
|
||||
'type' => 'fieldType',
|
||||
'hidden' => '!displayToUser',
|
||||
),
|
||||
);
|
||||
|
||||
return parent::get_data_keymap( $keymap );
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function fetch_subscriber_lists() {
|
||||
if ( empty( $this->data['client_id'] ) || empty( $this->data['username'] ) || empty( $this->data['password'] ) ) {
|
||||
return $this->API_KEY_REQUIRED;
|
||||
}
|
||||
|
||||
$this->_set_urls();
|
||||
|
||||
$this->response_data_key = 'lists';
|
||||
|
||||
return parent::fetch_subscriber_lists();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function subscribe( $args, $url = '' ) {
|
||||
if ( empty( $this->data['client_id'] ) || empty( $this->data['username'] ) || empty( $this->data['password'] ) ) {
|
||||
return $this->API_KEY_REQUIRED;
|
||||
}
|
||||
|
||||
$this->_set_urls();
|
||||
|
||||
if ( $this->_get_subscriber( $args ) ) {
|
||||
// Subscriber exists and is already subscribed to the list.
|
||||
return 'success';
|
||||
}
|
||||
|
||||
if ( ! $contact = $this->_get_subscriber( $args, 'list_id' ) ) {
|
||||
// Create new contact
|
||||
$body = $this->transform_data_to_provider_format( $args, 'subscriber' );
|
||||
$body = $this->_process_custom_fields( $body );
|
||||
|
||||
$this->prepare_request( $this->SUBSCRIBERS_URL, 'POST', false, array( $body ), true );
|
||||
$this->make_remote_request();
|
||||
|
||||
if ( $this->response->ERROR ) {
|
||||
return $this->get_error_message();
|
||||
}
|
||||
|
||||
$contact = $this->response->DATA['contacts'][0];
|
||||
}
|
||||
|
||||
// Subscribe contact to list
|
||||
$body = $this->transform_data_to_provider_format( $args, 'subscriptions' );
|
||||
$body['contactId'] = $contact['contactId'];
|
||||
$body['status'] = isset( $args['message_id'] ) ? 'pending' : 'normal';
|
||||
|
||||
$this->prepare_request( $this->SUBSCRIBE_URL, 'POST', false, array( $body ), true );
|
||||
|
||||
return parent::subscribe( $args, $this->SUBSCRIBE_URL );
|
||||
}
|
||||
}
|
130
core/components/api/email/init.php
Normal file
130
core/components/api/email/init.php
Normal file
@ -0,0 +1,130 @@
|
||||
<?php
|
||||
|
||||
if ( ! function_exists( 'et_core_api_email_init' ) ):
|
||||
function et_core_api_email_init() {
|
||||
if ( defined( 'ET_CORE_UPDATED' ) ) {
|
||||
et_core_api_email_fetch_all_lists();
|
||||
}
|
||||
}
|
||||
endif;
|
||||
|
||||
|
||||
if ( ! function_exists( 'et_core_api_email_fetch_all_lists' ) ):
|
||||
/**
|
||||
* Fetch the latest email lists for all provider accounts and update the database accordingly.
|
||||
*
|
||||
* @since 3.4
|
||||
*/
|
||||
function et_core_api_email_fetch_all_lists() {
|
||||
$providers = ET_Core_API_Email_Providers::instance();
|
||||
$all_accounts = $providers->accounts();
|
||||
|
||||
foreach ( $all_accounts as $provider_slug => $accounts ) {
|
||||
$provider = $providers->get( $provider_slug, '' );
|
||||
|
||||
foreach ( $accounts as $account ) {
|
||||
$provider->set_account_name( $account );
|
||||
$provider->fetch_subscriber_lists();
|
||||
}
|
||||
}
|
||||
}
|
||||
endif;
|
||||
|
||||
|
||||
if ( ! function_exists( 'et_core_api_email_fetch_lists' ) ):
|
||||
/**
|
||||
* Fetch the latest email lists for a provider account and update the database accordingly.
|
||||
*
|
||||
* @param string $name_or_slug The provider name or slug.
|
||||
* @param string $account The account name.
|
||||
* @param string $api_key Optional. The api key (if fetch succeeds, the key will be saved).
|
||||
*
|
||||
* @return string 'success' if successful, an error message otherwise.
|
||||
*/
|
||||
function et_core_api_email_fetch_lists( $name_or_slug, $account, $api_key = '' ) {
|
||||
if ( ! empty( $api_key ) ) {
|
||||
// The account provided either doesn't exist yet or has a new api key.
|
||||
et_core_security_check( 'manage_options' );
|
||||
}
|
||||
|
||||
if ( empty( $name_or_slug ) || empty( $account ) ) {
|
||||
return __( 'ERROR: Invalid arguments.', 'et_core' );
|
||||
}
|
||||
|
||||
$providers = ET_Core_API_Email_Providers::instance();
|
||||
$provider = $providers->get( $name_or_slug, $account, 'builder' );
|
||||
|
||||
if ( ! $provider ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if ( is_array( $api_key ) ) {
|
||||
foreach ( $api_key as $field_name => $value ) {
|
||||
$provider->data[ $field_name ] = sanitize_text_field( $value );
|
||||
}
|
||||
} else if ( '' !== $api_key ) {
|
||||
$provider->data['api_key'] = sanitize_text_field( $api_key );
|
||||
}
|
||||
|
||||
return $provider->fetch_subscriber_lists();
|
||||
}
|
||||
endif;
|
||||
|
||||
|
||||
if ( ! function_exists( 'et_core_api_email_providers' ) ):
|
||||
/**
|
||||
* @deprecated {@see ET_Core_API_Email_Providers::instance()}
|
||||
*
|
||||
* @return ET_Core_API_Email_Providers
|
||||
*/
|
||||
function et_core_api_email_providers() {
|
||||
return ET_Core_API_Email_Providers::instance();
|
||||
}
|
||||
endif;
|
||||
|
||||
|
||||
if ( ! function_exists( 'et_core_api_email_remove_account' ) ):
|
||||
/**
|
||||
* Delete an existing provider account.
|
||||
*
|
||||
* @param string $name_or_slug The provider name or slug.
|
||||
* @param string $account The account name.
|
||||
*/
|
||||
function et_core_api_email_remove_account( $name_or_slug, $account ) {
|
||||
et_core_security_check( 'manage_options' );
|
||||
|
||||
if ( empty( $name_or_slug ) || empty( $account ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If the account being removed is a legacy account (pre-dates core api), remove the old data.
|
||||
switch( $account ) {
|
||||
case 'Divi Builder Aweber':
|
||||
et_delete_option( 'divi_aweber_consumer_key' );
|
||||
et_delete_option( 'divi_aweber_consumer_secret' );
|
||||
et_delete_option( 'divi_aweber_access_key' );
|
||||
et_delete_option( 'divi_aweber_access_secret' );
|
||||
break;
|
||||
case 'Divi Builder Plugin Aweber':
|
||||
$opts = (array) get_option( 'et_pb_builder_options' );
|
||||
unset( $opts['aweber_consumer_key'], $opts['aweber_consumer_secret'], $opts['aweber_access_key'], $opts['aweber_access_secret'] );
|
||||
update_option( 'et_pb_builder_options', $opts );
|
||||
break;
|
||||
case 'Divi Builder MailChimp':
|
||||
et_delete_option( 'divi_mailchimp_api_key' );
|
||||
break;
|
||||
case 'Divi Builder Plugin MailChimp':
|
||||
$options = (array) get_option( 'et_pb_builder_options' );
|
||||
unset( $options['newsletter_main_mailchimp_key'] );
|
||||
update_option( 'et_pb_builder_options', $options );
|
||||
break;
|
||||
}
|
||||
|
||||
$providers = ET_Core_API_Email_Providers::instance();
|
||||
$provider = $providers->get( $name_or_slug, $account );
|
||||
|
||||
if ( $provider ) {
|
||||
$provider->delete();
|
||||
}
|
||||
}
|
||||
endif;
|
Reference in New Issue
Block a user