first commit

This commit is contained in:
2026-03-05 13:07:40 +01:00
commit 64ba0721ee
25709 changed files with 4691006 additions and 0 deletions

View File

@@ -0,0 +1,344 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( ! class_exists( 'ES_Base_Mailer' ) ) {
/**
* Class ES_Base_Mailer
*
* @since 4.3.2
*/
class ES_Base_Mailer {
/**
* Mailer name
*
* @since 4.3.2
* @var
*/
public $name;
/**
* Mailer Slug
*
* @since 4.3.2
* @var
*/
public $slug;
/**
* Mailer Version
*
* @since 4.3.2
* @var string
*/
public $version = '1.0';
/**
* Request headers
*
* @var array
*/
public $headers = array();
/**
* Request body
*
* @var array
*/
public $body = array();
/**
* Added Logger Context
*
* @since 4.2.0
* @var array
*/
public $logger_context = array(
'source' => 'ig_es_email_sending',
);
/**
* Flag to determine whether this mailer support batch sending or not
*
* @var boolean
*
* @since 4.7.0
*/
public $support_batch_sending = false;
/**
* Stores batch sending mode
*
* @var boolean
*
* @since 4.7.1
*/
public $batch_sending_mode = '';
/**
* Batch limit
*
* @var boolean
*
* @since 4.7.0
*/
public $batch_limit = 0;
/**
* Current batch size
*
* @var boolean
*
* @since 4.7.0
*/
public $current_batch_size = 0;
/**
* Batch data
*
* @var boolean
*
* @since 4.7.0
*/
public $batch_data = array();
/**
* Links
*
* @var array
*
* @since 4.7.0
*/
public $links = array();
protected $account_url = '';
/**
* ES_Base_Mailer constructor.
*
* @since 4.3.2
*/
public function __construct() {
}
public function get_name() {
return $this->name;
}
/**
* Send Method
*
* @since 4.3.2
*/
public function send( ES_Message $message ) {
return new WP_Error( 'ig_es_email_sending_failed', 'Send Method Not Implemented' );
}
/**
* Method will be called before email send
*
* @since 4.3.2
*/
public function pre_send( ES_Message $message ) {
}
/**
* Method will be called after email send
*
* @since 4.3.2
*/
public function post_send( ES_Message $message ) {
}
/**
* Prepare Response
*
* @param string $status
* @param string $message
*
* @return bool|WP_Error
*
* @since 4.3.2
*/
public function do_response( $status = 'success', $message = '' ) {
if ( 'success' !== $status ) {
ES()->logger->error( 'Error in Email Sending', $this->logger_context );
ES()->logger->error( $message, $this->logger_context );
return new WP_Error( 'ig_es_email_sending_failed', $message );
}
return true;
}
/**
* Set individual header key=>value pair for the email.
*
* @param string $name
* @param string $value
*
* @since 4.6.14
*/
public function set_header( $name, $value ) {
$name = sanitize_text_field( $name );
$this->headers[ $name ] = sanitize_text_field( $value );
}
/**
* Set email subject.
*
* @param string $subject
*
* @since 4.6.14
*/
public function set_subject( $subject ) {
$this->set_body_param(
array(
'subject' => $subject,
)
);
}
/**
* Set the request params, that goes to the body of the HTTP request.
*
* @param array $param Key=>value of what should be sent to a 3rd party mailing API.
*
* @since 4.6.14
*/
public function set_body_param( $param ) {
$this->body = array_merge_recursive( $this->body, $param );
}
/**
* Get the default params
*
* @return array
*
* @since 4.6.14
*/
public function get_default_params() {
return apply_filters(
'ig_es_mailer_default_params',
array(
'timeout' => 15,
'httpversion' => '1.1',
'blocking' => true,
)
);
}
/**
* Get the email body.
*
* @return string|array
*
* @since 4.6.14
*/
public function get_body() {
return apply_filters( 'ig_es_mailer_get_body', $this->body, $this );
}
/**
* Get the email headers.
*
* @return array
*
* @since 4.6.14
*/
public function get_headers() {
return apply_filters( 'ig_es_mailer_get_headers', $this->headers, $this );
}
/**
* Get placeholder variable name string
*
* @return string $variable_string
*
* @since 4.7.2
*/
public function get_variable_string( $variable_name = '' ) {
return $variable_name;
}
/**
* Reset mailer data
*
* @return array
*
* @since 4.6.14
*/
public function reset_mailer_data() {
$this->body = array();
$this->headers = array();
}
/**
* Check if the batch limit has been reached or not
*
* @return boolean
*
* @since 4.7.0
*/
public function is_batch_limit_reached() {
return $this->current_batch_size >= $this->batch_limit;
}
/**
* Convert ES tags to mailer tags
*
* @param string $string
*
* @return string $string
*
* @since 4.7.0
*/
public function convert_es_tags_to_mailer_tags( $string = '' ) {
return $string;
}
/**
* Send batch email
*
* @since 4.7.2
*/
public function send_batch() {
$response = $this->send_email();
return $response;
}
/**
* Clear mailer data
*
* @since 4.7.2
*/
public function clear_email_data() {
// Clear mailer specific data
}
/**
* Handle throttling
*
* @return void
*
* @since 5.0.5
*/
public function handle_throttling() {
// Add ESP specific throttling logic here
// Should be ovverriden in the ESP mailer class
}
public function get_account_url() {
return $this->account_url;
}
}
}

View File

@@ -0,0 +1,798 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( ! class_exists( 'ES_Icegram_Mailer' ) ) {
/**
* Class ES_Icegram_Mailer
*
* @since 5.6.0
*/
class ES_Icegram_Mailer extends ES_Base_Mailer {
/**
* Mailer name
*
* @since 5.6.0
* @var
*/
public $name = 'Icegram';
/**
* Mailer Slug
*
* @since 5.6.0
* @var
*/
public $slug = 'icegram';
/**
* Which response code from HTTP provider is considered to be successful?
*
* @var int
*/
public $email_sent_code = 200;
/**
* Icegram API Url
*
* @var string
*
*/
public $api_url = 'https://api.igeml.com/accounts/mail/send/';
/**
* Private API Key
*
* @var string
*
*/
public $api_key = '';
/**
* Domain Name
*
* @var string
*
*/
public $domain_name = '';
/**
* Region
*
* @var string
*
*/
public $region = 'us';
/**
* Flag to determine whether this mailer support batch sending or not
*
* @var boolean
*
* @since 5.6.0
*/
public $support_batch_sending = true;
/**
* Stores batch sending mode
*
* @var boolean
*
* @since 5.6.0
*/
public $batch_sending_mode = 'multiple';
/**
* Batch limit
*
* @var boolean
*
* @since 5.6.0
*/
public $batch_limit = 100;
public $remaining_limit = null;
/**
* ES_Icegram_Mailer constructor.
*
* @since 5.6.0
*/
public function __construct() {
parent::__construct();
}
/**
* Set mailer data
*
* @since 5.6.0
*/
public function set_mailer_data() {
ES()->logger->info( 'Start Sending Email Using Icegram', $this->logger_context );
$ig_es_ess_data = get_option( 'ig_es_ess_data', array() );
if ( ES()->is_const_defined( 'icegram', 'api_key' ) ) {
$this->api_key = ES()->get_const_value( 'icegram', 'api_key' );
} else {
$this->api_key = ! empty( $ig_es_ess_data['api_key'] ) ? $ig_es_ess_data['api_key'] : '';
}
if ( empty( $this->api_key ) ) {
return $this->do_response( 'error', __( 'API key is empty.', 'email-subscribers' ) );
}
// Reset body and headers.
$this->reset_mailer_data();
// We don't need to encode the api key using base64 since it now not required in Icegram api
$this->set_header( 'Authorization', 'Bearer ' . $this->api_key );
$this->set_header( 'Content-Type', 'application/json' );
$this->set_tracking_options();
$this->enable_sandbox_mode();
$this->set_ess_metadata();
}
/**
* Set email data
* e.g. Sender email, name
*
* @since 5.6.0
*/
public function set_email_data( $email_data = array() ) {
$sender_email = ! empty( $email_data['sender_email'] ) ? $email_data['sender_email'] : '';
$sender_name = ! empty( $email_data['sender_name'] ) ? $email_data['sender_name'] : '';
$reply_to_email = ! empty( $email_data['reply_to_email'] ) ? $email_data['reply_to_email']: '';
$subject = ! empty( $email_data['subject'] ) ? $email_data['subject'] : '';
$content = ! empty( $email_data['content'] ) ? $email_data['content'] : '';
$this->set_from( $sender_email, $sender_name );
$this->set_reply_to( $reply_to_email );
$this->set_subject( $subject );
$this->set_content( array(
'html' => $content
) );
}
/**
* Add into batch
*
* @param string $email
* @param array $merge_tags
*
* @since 5.6.0
*/
public function add_into_batch( $email, $merge_tags = array(), $message = null ) {
$name = ig_es_get_data( $merge_tags, 'name', '' );
$first_name = ig_es_get_data( $merge_tags, 'first_name', '' );
$last_name = ig_es_get_data( $merge_tags, 'last_name', '' );
$list_name = ig_es_get_data( $merge_tags, 'list_name', '' );
$hash = ig_es_get_data( $merge_tags, 'hash', '' );
$contact_id = ig_es_get_data( $merge_tags, 'contact_id', 0 );
$campaign_id = ig_es_get_data( $merge_tags, 'campaign_id', 0 );
$message_id = ig_es_get_data( $merge_tags, 'message_id', 0 );
$list_ids = ig_es_get_data( $merge_tags, 'list_ids', '' );
$link_data = array(
'message_id' => $message_id,
'campaign_id' => $campaign_id,
'contact_id' => $contact_id,
'email' => $email,
'guid' => $hash,
'list_ids' => $list_ids,
);
$subscribe_link = ES()->mailer->get_subscribe_link( $link_data );
$unsubscribe_link = ES()->mailer->get_unsubscribe_link( $link_data );
$link_variables = ES()->mailer->get_link_variable( $contact_id );
$tracking_pixel_url = ES()->mailer->get_tracking_pixel_url( $link_data );
$contact_data = array(
'name' => $name,
'first_name' => $first_name,
'last_name' => $last_name,
'list_name' => $list_name,
'hash' => $hash,
'email' => $email,
'contact_id' => $contact_id,
'campaign_id' => $campaign_id,
'message_id' => $message_id,
'list_ids' => $list_ids,
'subscribe_link' => $subscribe_link,
'unsubscribe_link' => $unsubscribe_link,
);
if ( ! empty( $link_variables ) ) {
$contact_data = array_merge( $contact_data, $link_variables );
}
if ( ! empty( $tracking_pixel_url )) {
$contact_data['tracking_pixel_url'] = $tracking_pixel_url;
}
// Check if it is an campaign email and headers are enabled on the site.
$list_unsubscribe_header = ES()->mailer->get_list_unsubscribe_header( $email );
if ( $list_unsubscribe_header ) {
$contact_data['list_unsubscribe_header'] = $list_unsubscribe_header;
}
$contact_data = apply_filters( 'ig_es_contact_mail_data', $contact_data, $merge_tags );
$recipient_variables = array();
$variable_prefix = $this->get_variable_prefix();
$variable_suffix = $this->get_variable_suffix();
foreach ( $contact_data as $data_key => $data_value ) {
$recipient_variables[ $variable_prefix . $data_key . $variable_suffix ] = $data_value;
}
$this->set_recipients(
array(
'to' => array( $email ),
'substitutions' => $recipient_variables
)
);
$this->batch_data[] = $contact_data;
$this->current_batch_size++;
}
/**
* Convert ES tags to mailer tags
*
* @param string $string
*
* @return string $string
*
* @since 5.6.0
*/
public function convert_es_tags_to_mailer_tags( $string = '' ) {
$mailer_tags_mapping = array(
'subscriber.name' => '-name-',
'subscriber.first_name' => '-first_name-',
'subscriber.last_name' => '-last_name-',
'subscriber.email' => '-email-',
'subscriber.unsubscribe_link' => '-unsubscribe_link-',
'subscriber.subscribe_link' => '-subscribe_link-',
);
$mailer_tags_mapping = apply_filters( 'ig_es_mailer_tags_mapping', $mailer_tags_mapping );
$string = ES_Common::replace_keywords_with_fallback( $string, $mailer_tags_mapping );
return ES_Common::replace_keywords_with_fallback( $string, array(
'NAME' => '-name-',
'FIRSTNAME' => '-first_name-',
'LASTNAME' => '-last_name-',
'EMAIL' => '-email-',
'UNSUBSCRIBE-LINK' => '-unsubscribe_link-',
'SUBSCRIBE-LINK' => '-subscribe_link-',
) );
}
/**
* Get variable prefix
*
* @return string
*
* @since 5.6.0
*/
public function get_variable_prefix() {
return '-';
}
/**
* Get variable suffix
*
* @return string
*
* @since 5.6.0
*/
public function get_variable_suffix() {
return '-';
}
/**
* Send Email
*
* @param ES_Message $message
*
* @return bool|WP_Error
*/
public function send( ES_Message $message ) {
ES()->logger->info( 'Start Sending Email Using Icegram', $this->logger_context );
$ig_es_ess_data = get_option( 'ig_es_ess_data', array() );
if ( ES()->is_const_defined( 'icegram', 'api_key' ) ) {
$this->api_key = ES()->get_const_value( 'icegram', 'api_key' );
} else {
$this->api_key = ! empty( $ig_es_ess_data['api_key'] ) ? $ig_es_ess_data['api_key'] : '';
}
if ( empty( $this->api_key ) ) {
return $this->do_response( 'error', __( 'API key is empty.', 'email-subscribers' ) );
}
// Reset body and headers.
$this->reset_mailer_data();
// We don't need to encode the api key using base64 since it now not required in Icegram api
$this->set_header( 'Authorization', 'Bearer ' . $this->api_key );
$this->set_header( 'Content-Type', 'application/json' );
$this->set_from( $message->from, $message->from_name );
$this->set_reply_to( $message->reply_to_email );
$this->set_list_unsubscribe_header( $message->to );
$this->set_tracking_options();
$this->enable_sandbox_mode();
$this->set_ess_metadata();
$this->set_recipients(
array(
'to' => array( $message->to ),
)
);
$this->set_subject( $message->subject );
$this->set_content(
array(
'html' => $message->body,
)
);
/*
* In some cases we will need to modify the internal structure
* of the body content, if attachments are present.
* So lets make this call the last one.
*/
if ( $message->attachments ) {
$this->set_attachments( $message->attachments );
}
$params = array_merge_recursive( $this->get_default_params(), array(
'headers' => $this->get_headers(),
'body' => $this->get_body(),
));
$response = wp_remote_post( $this->api_url, $params );
if ( ! is_wp_error( $response ) ) {
$body = ! empty( $response['body'] ) && ES_Common::is_valid_json( $response['body'] ) ? json_decode( $response['body'], true ) : '';
if ( ! empty( $body ) ) {
$status = ! empty( $body['status'] ) ? $body['status'] : 'error';
if ( 'success' === $status ) {
if ( isset( $body['remaining_limit'] ) ) {
$this->remaining_limit = $body['remaining_limit'];
} else {
$this->remaining_limit -= $this->current_batch_size;
}
ES()->logger->info( 'Email Sent Successfully Using Icegram', $this->logger_context );
return $this->do_response( 'success' );
} else {
if ( ! empty( $body['message'] ) ) {
$error_message = $body['message'];
} else {
$error_message = __( 'An unknown error has occured. Please try again later.', 'email-subscribers' );
}
}
return $this->do_response( 'error', $error_message );
} else {
return $this->do_response( 'error', wp_remote_retrieve_response_message( $response ) );
}
} else {
$error_message = $response->get_error_message();
return $this->do_response( 'error', $error_message );
}
ES()->logger->info( 'Email Sent Successfully Using Icegram', $this->logger_context );
return $this->do_response( 'success' );
}
/**
* Clear batch
*
* @since 5.6.0
*/
public function clear_batch() {
$this->body['personalizations'] = array();
$this->batch_data = array();
$this->current_batch_size = 0;
}
/**
* Redefine the way email body is returned.
* By default we are sending an array of data.
* Icegram requires a JSON, so we encode the body.
*
*/
public function get_body() {
$body = parent::get_body();
return wp_json_encode( $body );
}
/**
* Set from
*/
public function set_from( $email, $name = '' ) {
if ( ! filter_var( $email, FILTER_VALIDATE_EMAIL ) ) {
return;
}
$from['email'] = $email;
if ( ! empty( $name ) ) {
$from['name'] = $name;
}
$this->set_body_param(
array(
'from' => $from,
)
);
}
/**
* Set reply to
*
* @param string $email
*
* @since 4.6.7
*/
public function set_reply_to( $email ) {
if ( ! filter_var( $email, FILTER_VALIDATE_EMAIL ) ) {
return;
}
$this->set_body_param(
array(
'reply_to' => array(
'email' => $email,
),
)
);
}
/**
* Set list unsubscribe header
*
* @param string $email
*
* @since 4.7.2
*/
public function set_list_unsubscribe_header( $email = '' ) {
if ( empty( $email ) ) {
if ( ES()->mailer->unsubscribe_headers_enabled() ) {
$this->set_body_param(
array(
'headers' => array(
'List-Unsubscribe' => '-list_unsubscribe_header-',
'List-Unsubscribe-Post' => 'List-Unsubscribe=One-Click',
),
)
);
}
} else {
$list_unsubscribe_header = ES()->mailer->get_list_unsubscribe_header( $email );
if ( ! empty( $list_unsubscribe_header ) ) {
$this->set_body_param(
array(
'headers' => array(
'List-Unsubscribe' => $list_unsubscribe_header,
'List-Unsubscribe-Post' => 'List-Unsubscribe=One-Click',
),
)
);
}
}
}
/**
* Set recipients
*/
public function set_recipients( $recipients ) {
if ( empty( $recipients ) ) {
return;
}
$data = array();
foreach ( $recipients as $type => $recipient_data ) {
$data[ $type ] = array();
if ( in_array( $type, array( 'to' ), true) ) {
$emails = $recipient_data;
if (
empty( $emails ) ||
! is_array( $emails )
) {
continue;
}
// Iterate over all emails for each type.
// There might be multiple cc/to/bcc emails.
foreach ( $emails as $email ) {
$holder = array();
if ( ! filter_var( $email, FILTER_VALIDATE_EMAIL ) ) {
continue;
}
$holder['email'] = $email;
array_push( $data[ $type ], $holder );
}
} elseif ( 'substitutions' === $type ) {
$data[ $type ] = $recipient_data;
}
}
if ( ! empty( $data ) ) {
$this->set_body_param(
array(
'personalizations' => array( $data ),
)
);
}
}
/**
* Set email content
*/
public function set_content( $content ) {
if ( empty( $content ) ) {
return;
}
if ( is_array( $content ) ) {
$default = array( 'html' );
$data = array();
foreach ( $content as $type => $body ) {
if (
! in_array( $type, $default, true ) ||
empty( $body )
) {
continue;
}
$content_value = $body;
$content_type = 'text/html';
$data[] = array(
'type' => $content_type,
'value' => $content_value,
);
}
$this->set_body_param(
array(
'content' => $data,
)
);
} else {
$data['type'] = 'text/html';
$data['value'] = $content;
$this->set_body_param(
array(
'content' => array( $data ),
)
);
}
}
/**
* This mailer supports email-related custom headers inside a body of the message.
*
* @param string $name
* @param string $value
*/
public function set_body_header( $name, $value ) {
$name = sanitize_text_field( $name );
if ( empty( $name ) ) {
return;
}
$headers = isset( $this->body['headers'] ) ? (array) $this->body['headers'] : array();
$headers[ $name ] = sanitize_text_field( $value );
$this->set_body_param(
array(
'headers' => $headers,
)
);
}
/**
* Icegram accepts an array of files content in body, so we will include all files and send.
* Doesn't handle exceeding the limits etc, as this is done and reported by Icegram API.
*
* @param array $attachments
*/
public function set_attachments( $attachments ) {
if ( empty( $attachments ) ) {
return;
}
$data = array();
foreach ( $attachments as $attachment_name => $attachment_path ) {
$file = false;
try {
if ( is_file( $attachment_path ) && is_readable( $attachment_path ) ) {
$file = file_get_contents( $attachment_path );
}
} catch ( Exception $e ) {
$file = false;
}
if ( false === $file ) {
continue;
}
$filetype = mime_content_type( $attachment_path );
$data[] = array(
'content' => base64_encode( $file ), // string, 1 character.
'type' => $filetype, // string, no ;, no CRLF.
'filename' => empty( $attachment_name ) ? 'file-' . wp_hash( microtime() ) . '.' . $filetype : trim( $attachment_name ), // required string, no CRLF.
'disposition' => 'attachment', // either inline or attachment.
);
}
if ( ! empty( $data ) ) {
$this->set_body_param(
array(
'attachments' => $data,
)
);
}
}
/**
* Set open/click tracking options
*
* @since 5.6.0
*/
public function set_tracking_options() {
$tracking_settings = array(
'open_tracking' => array(
'enable' => false,
),
'click_tracking' => array(
'enable' => false,
'enable_text' => false // Disable tracking for plain/text links
),
);
$this->set_body_param(
array(
'tracking_settings' => $tracking_settings,
)
);
}
public function enable_sandbox_mode() {
$this->set_body_param(
array(
'mail_settings' => array(
'sandbox_mode' => array(
'enable' => false,
)
),
)
);
}
public function set_ess_metadata() {
$plan = ES_Service_Email_Sending::get_plan();
$premium_plans = array( 'pro', 'max' );
$is_premium_plan = in_array( $plan, $premium_plans, true );
$ess_metadata = array();
$add_ess_footer_image = true;
$footer_image_url = trailingslashit( ES_IMG_URL ) . 'ess-footer-image.png';
if ( $is_premium_plan && ! ES_Service_Email_Sending::is_ess_branding_enabled() ) {
$add_ess_footer_image = false;
}
if ( $add_ess_footer_image ) {
$ess_metadata['footer'] = array(
'image_url' => $footer_image_url,
);
}
if ( ! empty( $ess_metadata ) ) {
$this->set_body_param(
array(
'ess_metadata' => $ess_metadata
)
);
}
}
/**
* Send email using Icegram API
*
* @since 5.6.0
*/
public function send_email() {
ES()->logger->info( 'Start Sending Email Using Icegram', $this->logger_context );
$params = array_merge_recursive( $this->get_default_params(), array(
'headers' => $this->get_headers(),
'body' => $this->get_body(),
));
$response = wp_remote_post( $this->api_url, $params );
if ( ! is_wp_error( $response ) ) {
$body = ! empty( $response['body'] ) && ES_Common::is_valid_json( $response['body'] ) ? json_decode( $response['body'], true ) : '';
if ( ! empty( $body ) ) {
$status = ! empty( $body['status'] ) ? $body['status'] : 'error';
if ( 'success' === $status ) {
if ( isset( $body['remaining_limit'] ) ) {
$this->remaining_limit = $body['remaining_limit'];
} else {
$this->remaining_limit -= $this->current_batch_size;
}
ES()->logger->info( 'Email Sent Successfully Using Icegram', $this->logger_context );
return $this->do_response( 'success' );
} else {
if ( ! empty( $body['message'] ) ) {
$error_message = $body['message'];
} else {
$error_message = __( 'An unknown error has occured. Please try again later.', 'email-subscribers' );
}
}
return $this->do_response( 'error', $error_message );
} else {
return $this->do_response( 'error', wp_remote_retrieve_response_message( $response ) );
}
} else {
$error_message = $response->get_error_message();
return $this->do_response( 'error', $error_message );
}
ES()->logger->info( 'Email Sent Successfully Using Icegram', $this->logger_context );
return $this->do_response( 'success' );
}
/**
* Check if the batch limit has been reached or not
*
* @return boolean
*
* @since 5.6.0
*/
public function is_batch_limit_reached() {
return $this->current_batch_size >= $this->batch_limit || $this->current_batch_size >= $this->remaining_limit;
}
}
}

View File

@@ -0,0 +1,558 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( ! class_exists( 'ES_Pepipost_Mailer' ) ) {
/**
* Class ES_Pepipost_Mailer
*
* @since 4.2.1
* @since 4.3.2 Modified response
*/
class ES_Pepipost_Mailer extends ES_Base_Mailer {
/**
* Mailer name
*
* @since 4.8.5
* @var
*/
public $name = 'Pepipost';
/**
* Mailer Slug
*
* @since 4.8.5
* @var
*/
public $slug = 'pepipost';
/**
* Pepipost API Url
*
* @since 4.3.2
* @var string
*/
public $api_url = 'https://api.pepipost.com/v2/sendEmail';
/**
* API Key
*
* @since 4.3.2
* @var string
*/
public $api_key = '';
/**
* Flag to determine whether this mailer support batch sending or not
*
* @var boolean
*
* @since 4.7.5
*/
public $support_batch_sending = true;
/**
* Stores batch sending mode
*
* @var boolean
*
* @since 4.7.5
*/
public $batch_sending_mode = 'multiple';
/**
* Batch limit
*
* @var boolean
*
* @since 4.7.5
*/
public $batch_limit = 1000;
/**
* ES_Pepipost_Mailer constructor.
*
* @since 4.3.2
*/
public function __construct() {
parent::__construct();
}
/**
* Set mailer data
*
* @since 4.7.5
*/
public function set_mailer_data() {
$ig_es_mailer_settings = get_option( 'ig_es_mailer_settings', array() );
if ( ES()->is_const_defined( 'pepipost', 'api_key' ) ) {
$this->api_key = ES()->get_const_value( 'pepipost', 'api_key' );
} else {
$this->api_key = ! empty( $ig_es_mailer_settings['pepipost']['api_key'] ) ? $ig_es_mailer_settings['pepipost']['api_key'] : '';
}
if ( empty( $this->api_key ) ) {
return $this->do_response( 'error', 'API Key is empty' );
}
// Reset body and headers.
$this->reset_mailer_data();
$this->set_header( 'Accept', 'application/json' );
$this->set_header( 'content-type', 'application/json; charset=utf-8' );
$this->set_header( 'user-agent', 'APIMATIC 2.0' );
$this->set_header( 'api_key', $this->api_key );
$this->set_tracking_options();
}
/**
* Set email data
* e.g. Sender email, name
*
* @since 4.7.5
*/
public function set_email_data( $email_data = array() ) {
$sender_email = ! empty( $email_data['sender_email'] ) ? $email_data['sender_email'] : '';
$sender_name = ! empty( $email_data['sender_name'] ) ? $email_data['sender_name'] : '';
$reply_to_email = ! empty( $email_data['reply_to_email'] ) ? $email_data['reply_to_email'] : '';
$subject = ! empty( $email_data['subject'] ) ? $email_data['subject'] : '';
$content = ! empty( $email_data['content'] ) ? $email_data['content'] : '';
$this->set_from( $sender_email, $sender_name );
$this->set_reply_to( $reply_to_email );
$this->set_subject( $subject );
$this->set_content( $content );
}
/**
* Add into batch
*
* @param string $email
* @param array $merge_tags
*
* @since 4.7.5
*/
public function add_into_batch( $email, $merge_tags = array() ) {
$name = ig_es_get_data( $merge_tags, 'name', '' );
$first_name = ig_es_get_data( $merge_tags, 'first_name', '' );
$last_name = ig_es_get_data( $merge_tags, 'last_name', '' );
$list_name = ig_es_get_data( $merge_tags, 'list_name', '' );
$hash = ig_es_get_data( $merge_tags, 'hash', '' );
$contact_id = ig_es_get_data( $merge_tags, 'contact_id', 0 );
$campaign_id = ig_es_get_data( $merge_tags, 'campaign_id', 0 );
$message_id = ig_es_get_data( $merge_tags, 'message_id', 0 );
$list_ids = ig_es_get_data( $merge_tags, 'list_ids', '' );
$link_data = array(
'message_id' => $message_id,
'campaign_id' => $campaign_id,
'contact_id' => $contact_id,
'email' => $email,
'guid' => $hash,
'list_ids' => $list_ids,
);
$subscribe_link = ES()->mailer->get_subscribe_link( $link_data );
$unsubscribe_link = ES()->mailer->get_unsubscribe_link( $link_data );
$link_variables = ES()->mailer->get_link_variable( $contact_id );
$tracking_pixel_url = ES()->mailer->get_tracking_pixel_url( $link_data );
$recipient_variables = array(
'NAME' => $name,
'FIRSTNAME' => $first_name,
'LASTNAME' => $last_name,
'LIST' => $list_name,
'HASH' => $hash,
'EMAIL' => $email,
'contact_id' => $contact_id,
'CAMPAIGN_ID' => $campaign_id,
'MESSAGE_ID' => $message_id,
'LIST_IDS' => $list_ids,
'SUBSCRIBE_LINK' => $subscribe_link,
'UNSUBSCRIBE_LINK' => $unsubscribe_link,
);
if ( ! empty( $link_variables ) ) {
$recipient_variables = array_merge( $recipient_variables, $link_variables );
}
if ( ! empty( $tracking_pixel_url ) ) {
$recipient_variables['tracking_pixel_url'] = $tracking_pixel_url;
}
$recipient_variables = apply_filters( 'ig_es_contact_mail_data', $recipient_variables, $merge_tags );
$this->set_recipients(
array(
'personalizations' => array(
'recipient' => $email,
'attributes' => $recipient_variables,
),
)
);
$this->batch_data[] = $recipient_variables;
$this->current_batch_size++;
}
/**
* Convert ES tags to mailer tags
*
* @param string $string
*
* @return string $string
*
* @since 4.7.5
*/
public function convert_es_tags_to_mailer_tags( $string = '' ) {
$mailer_tags_mapping = array(
'subscriber.name' => '[%name%]',
'subscriber.first_name' => '[%first_name%]',
'subscriber.last_name' => '[%last_name%]',
'subscriber.email' => '[%email%]',
'subscriber.unsubscribe_link' => '[%unsubscribe_link%]',
'subscriber.subscribe_link' => '[%subscribe_link%]',
);
$mailer_tags_mapping = apply_filters( 'ig_es_mailer_tags_mapping', $mailer_tags_mapping );
$string = ES_Common::replace_keywords_with_fallback( $string, $mailer_tags_mapping);
return ES_Common::replace_keywords_with_fallback( $string, array(
'NAME' => '[%NAME%]',
'FIRSTNAME' => '[%FIRSTNAME%]',
'LASTNAME' => '[%LASTNAME%]',
'EMAIL' => '[%EMAIL%]',
'UNSUBSCRIBE-LINK' => '[%UNSUBSCRIBE_LINK%]',
'SUBSCRIBE-LINK' => '[%SUBSCRIBE_LINK%]',
) );
}
/**
* Get variable prefix
*
* @return string
*
* @since 4.7.5
*/
public function get_variable_prefix() {
return '[%';
}
/**
* Get variable suffix
*
* @return string
*
* @since 4.7.5
*/
public function get_variable_suffix() {
return '%]';
}
/**
* Redefine the way email body is returned.
* By default we are sending an array of data.
* Pepipost requires a JSON, so we encode the body.
*
* @return string json encoded body data
*
* @since 4.7.5
*/
public function get_body() {
$body = parent::get_body();
return wp_json_encode( $body );
}
/**
* Set email subject.
*
* @param string $subject
*
* @since 4.7.5
*/
public function set_subject( $subject ) {
$this->set_body_param(
array(
'subject' => $subject,
)
);
}
/**
* Set email content
*
* @param string content
*
* @since 4.7.5
*/
public function set_content( $content ) {
if ( function_exists( 'mb_convert_encoding' ) ) {
$content = mb_convert_encoding( $content, 'UTF-8', mb_detect_encoding( $content, 'UTF-8, ISO-8859-1', true ) );
}
$this->set_body_param(
array(
'content' => $content,
)
);
}
/**
* Set from
*
* @param string $email
* @param string $name
*
* @since 4.7.5
*/
public function set_from( $email, $name = '' ) {
if ( ! filter_var( $email, FILTER_VALIDATE_EMAIL ) ) {
return;
}
if ( ! empty( $name ) ) {
$this->set_body_param(
array(
'from' => array(
'fromEmail' => $email,
'fromName' => $name,
),
)
);
} else {
$this->set_body_param(
array(
'from' => array(
'fromEmail' => $email,
),
)
);
}
}
/**
* Set reply to
*
* @param string $email
*
* @since 4.7.5
*/
public function set_reply_to( $email ) {
if ( ! filter_var( $email, FILTER_VALIDATE_EMAIL ) ) {
return;
}
$this->set_body_param(
array(
'replyToId' => $email,
)
);
}
/**
* Set recipients
*
* @param array $recipients
*
* @since 4.7.5
*/
public function set_recipients( $recipients ) {
if ( empty( $recipients ) ) {
return;
}
$default = array( 'personalizations' );
foreach ( $recipients as $kind => $recipient_data ) {
if (
! in_array( $kind, $default, true ) ||
empty( $recipient_data ) ||
! is_array( $recipient_data )
) {
continue;
}
$this->set_body_param(
array(
$kind => array( $recipient_data ),
)
);
}
}
/**
* Pepipost accepts an array of files content in body, so we will include all files and send.
*
* @param array $attachments
*
* @since 4.7.5
*/
public function set_attachments( $attachments ) {
if ( empty( $attachments ) ) {
return;
}
$data = array();
foreach ( $attachments as $attachment_name => $attachment_path ) {
$file = false;
try {
if ( is_file( $attachment_path ) && is_readable( $attachment_path ) ) {
$file = file_get_contents( $attachment_path );
}
} catch ( Exception $e ) {
$file = false;
}
if ( false === $file ) {
continue;
}
$filetype = mime_content_type( $attachment_path );
$data[] = array(
'fileName' => empty( $attachment_name ) ? 'file-' . wp_hash( microtime() ) . '.' . $filetype : trim( $attachment_name ), // required string, no CRLF.
'fileContent' => base64_encode( $file ), // string, 1 character.
);
}
if ( ! empty( $data ) ) {
$this->set_body_param(
array(
'attachments' => $data,
)
);
}
}
/**
* Set open/click tracking options
*
* @since 4.7.5
*/
public function set_tracking_options() {
$tracking_settings = array(
'opentrack' => ES()->mailer->can_track_open() ? 1 : 0,
'clicktrack' => ES()->mailer->can_track_clicks() ? 1 : 0,
);
$this->set_body_param(
array(
'settings' => $tracking_settings,
)
);
}
/**
* Clear batch
*
* @since 4.7.5
*/
public function clear_batch() {
$this->body['personalizations'] = array();
$this->batch_data = array();
$this->current_batch_size = 0;
}
/**
* Send Email
*
* @param ES_Message $message
*
* @return bool|WP_Error
*
* @since 4.2.1
* @since 4.3.2 Modified Response
* @since 4.7.5 Used common functions to set email data both when sending bulk emails and single email
*/
public function send( ES_Message $message ) {
$response = $this->set_mailer_data();
// Error setting up mailer?
if ( is_wp_error( $response ) ) {
return $response;
}
$this->set_from( $message->from, $message->from_name );
$this->set_reply_to( $message->reply_to_email );
$this->set_subject( $message->subject );
$this->set_content( $message->body );
$this->set_recipients(
array(
'personalizations' => array(
'recipient' => $message->to,
),
)
);
if ( $message->attachments ) {
$this->set_attachments( $message->attachments );
}
$response = $this->send_email();
return $response;
}
/**
* Send email using Pepipost API
*
* @since 4.7.5
*/
public function send_email() {
ES()->logger->info( 'Start Sending Email Using Pepipost', $this->logger_context );
$params = array_merge_recursive(
$this->get_default_params(),
array(
'headers' => $this->get_headers(),
'body' => $this->get_body(),
)
);
$response = wp_remote_post( $this->api_url, $params );
if ( ! is_wp_error( $response ) ) {
$body = ! empty( $response['body'] ) ? json_decode( $response['body'], true ) : '';
if ( ! empty( $body ) ) {
if ( 'Success' === $body['message'] ) {
return $this->do_response( 'success' );
} elseif ( ! empty( $body['error_info'] ) ) {
return $this->do_response( 'error', $body['error_info']['error_message'] );
}
} else {
$this->do_response( 'error', wp_remote_retrieve_response_message( $response ) );
}
} else {
$error_message = $response->get_error_message();
return $this->do_response( 'error', $error_message );
}
ES()->logger->info( 'Email Sent Successfully Using Pepipost', $this->logger_context );
return $this->do_response( 'success' );
}
}
}

View File

@@ -0,0 +1,128 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( ! class_exists( 'ES_Phpmail_Mailer' ) ) {
/**
* Class ES_Phpmail_Mailer
*
* @since 4.3.2
*/
class ES_Phpmail_Mailer extends ES_Base_Mailer {
/**
* Mailer name
*
* @since 4.8.5
* @var
*/
public $name = 'PHP mail';
/**
* Mailer Slug
*
* @since 4.8.5
* @var
*/
public $slug = 'php_mail';
/**
* ES_Phpmail_Mailer constructor.
*
* @since 4.3.2
*/
public function __construct() {
parent::__construct();
}
/**
* Send Email
*
* @param ES_Message $message
*
* @return bool|WP_Error
*
* @since 4.3.2
*/
public function send( ES_Message $message ) {
global $wp_version;
ES()->logger->info( 'Start Sending Email Using PHP Mail', $this->logger_context );
if ( version_compare( $wp_version, '5.5', '<' ) ) {
require_once ABSPATH . WPINC . '/class-phpmailer.php';
} else {
require_once ABSPATH . WPINC . '/PHPMailer/PHPMailer.php';
require_once ABSPATH . WPINC . '/PHPMailer/Exception.php';
// Check if PHPMailer class already exists before creating an alias for it.
if ( ! class_exists( 'PHPMailer' ) ) {
class_alias( PHPMailer\PHPMailer\PHPMailer::class, 'PHPMailer' );
}
// Check if phpmailerException class already exists before creating an alias for it.
if ( ! class_exists( 'phpmailerException' ) ) {
class_alias( PHPMailer\PHPMailer\Exception::class, 'phpmailerException' );
}
}
$phpmailer = new PHPMailer( true );
$phpmailer->From = $message->from;
$phpmailer->FromName = $message->from_name;
$phpmailer->CharSet = $message->charset;
$phpmailer->ClearAllRecipients();
$phpmailer->clearAttachments();
$phpmailer->clearCustomHeaders();
$phpmailer->clearReplyTos();
$phpmailer->addAddress( $message->to );
$phpmailer->addReplyTo( $message->from, $message->from_name );
$phpmailer->WordWrap = 50;
$phpmailer->isHTML( true );
$list_unsubscribe_header = ES()->mailer->get_list_unsubscribe_header( $message->to );
if ( ! empty( $list_unsubscribe_header ) ) {
$phpmailer->addCustomHeader( 'List-Unsubscribe', $list_unsubscribe_header );
$phpmailer->addCustomHeader( 'List-Unsubscribe-Post', 'List-Unsubscribe=One-Click' );
}
apply_filters( 'ig_es_php_mailer_email_headers', $phpmailer );
$phpmailer->Subject = $message->subject;
$phpmailer->Body = $message->body;
$phpmailer->AltBody = $message->body_text; // Text Email Body for non html email client
if ( ! empty( $message->attachments ) ) {
$attachments = $message->attachments;
foreach ( $attachments as $attachment ) {
try {
$phpmailer->addAttachment( $attachment );
} catch ( phpmailerException $e ) {
continue;
}
}
}
try {
if ( ! $phpmailer->send() ) {
ES()->logger->error( '[Error in Email Sending] : ' . $message->to . ' Error: ' . $phpmailer->ErrorInfo, $this->logger_context );
return $this->do_response( 'error', $phpmailer->ErrorInfo );
}
} catch ( Exception $e ) {
ES()->logger->error( '[Error in Email Sending] : ' . $message->to . ' Error: ' . $e->getMessage(), $this->logger_context );
return $this->do_response( 'error', $e->getMessage() );
}
ES()->logger->info( 'Email Sent Successfully Using PHP Mail', $this->logger_context );
return $this->do_response( 'success' );
}
}
}

View File

@@ -0,0 +1,68 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( ! class_exists( 'ES_Wpmail_Mailer' ) ) {
class ES_Wpmail_Mailer extends ES_Base_Mailer {
/**
* Mailer name
*
* @since 4.8.5
* @var
*/
public $name = 'WP Mail';
/**
* Mailer Slug
*
* @since 4.8.5
* @var
*/
public $slug = 'wp_mail';
/**
* ES_Wpmail_Mailer constructor.
*
* @since 4.3.2
*/
public function __construct() {
parent::__construct();
}
/**
* Send Email
*
* @param ES_Message $message
*
* @return boolean|WP_Error
*
* @since 4.3.2
*/
public function send( ES_Message $message ) {
ES()->logger->info( 'Start Sending Email Using WP Mail', $this->logger_context );
$send_mail = wp_mail( $message->to, $message->subject, $message->body, $message->headers, $message->attachments );
if ( ! $send_mail ) {
global $phpmailer;
if ( is_object( $phpmailer ) && $phpmailer->ErrorInfo ) {
$message = wp_strip_all_tags( $phpmailer->ErrorInfo );
} else {
$message = __( 'WP Mail Error: Unknown', 'email-subscribers' );
}
return $this->do_response( 'error', $message );
}
ES()->logger->info( 'Email Sent Successfully Using WP Mail', $this->logger_context );
return $this->do_response( 'success' );
}
}
}