id data * * @since 4.3.2 * @var array */ public $email_id_map = array(); /** * Need to add unsubscribe link ? * * @since 4.3.2 * @var bool */ public $add_unsubscribe_link = true; /** * Need to add tracking pixel ? * * @since 4.3.2 * @var bool */ public $can_track_open_clicks = true; /** * Added Logger Context * * @since 4.3.2 * @var array */ public $logger_context = array( 'source' => 'ig_es_mailer', ); /** * Mailer setting * * @since 4.3.2 * @var object|ES_Base_Mailer */ public $mailer; /** * Default mailer to be used When ESS limit is reached * * @since 4.3.2 * @var object|ES_Base_Mailer */ public $default_mailer; /** * ES_Mailer constructor. * * @since 4.3.2 */ public function __construct() { $this->set_mailer(); } /** * Check whether max execution time reaches to it's maximum or * reached email quota * * @return bool * * @since 4.3.2 */ public function limits_exceeded() { if ( ! $this->limits_set ) { $cron_interval = ES()->cron->get_cron_interval(); @set_time_limit( $cron_interval ); // Set 95% of max_execution_time as a max limit. We can reduce it as well $max_time = (int) ( @ini_get( 'max_execution_time' ) * 0.95 ); if ( 0 == $max_time || $max_time > $cron_interval ) { $max_time = (int) ( $cron_interval * 0.95 ); } $this->time_limit = $this->time_start + $max_time; $this->email_limit = $this->get_total_emails_send_now(); // We are doing heavy lifting..allocate more memory if ( function_exists( 'memory_get_usage' ) && ( (int) @ini_get( 'memory_limit' ) < 128 ) ) { // Add filter to increase memory limit add_filter( 'ig_es_memory_limit', 'ig_es_increase_memory_limit' ); wp_raise_memory_limit( 'ig_es' ); // Remove the added filter function so that it won't be called again if wp_raise_memory_limit called later on. remove_filter( 'ig_es_memory_limit', 'ig_es_increase_memory_limit' ); } $this->limits_set = true; } if ( time() > $this->time_limit ) { return true; } /** * Check if memory limit is exceeded * * For mailers supporting batch APIs, since we need to prepare and store subscriber's email data before dispatching it * memory limit can be reached in that case. */ if ( IG_ES_Background_Process_Helper::memory_exceeded() ) { return true; } if ( $this->email_limit <= 0 ) { return true; } return false; } /** * Send Sign up Notifications to admins * * @param $data * * @return bool * * @since 4.3.2 */ public function send_add_new_contact_notification_to_admins( $data ) { if ( ! $this->can_send_add_new_contact_notification() ) { return false; } $admin_emails = $this->get_admin_emails(); if ( ! empty( $admin_emails ) && is_array( $admin_emails ) && count( $admin_emails ) > 0 ) { $subject = $this->get_admin_new_contact_email_subject(); $subject = $this->replace_admin_notification_merge_tags( $data, $subject ); $content = $this->get_admin_new_contact_email_content(); $content = $this->replace_admin_notification_merge_tags( $data, $content ); $this->add_unsubscribe_link = false; $this->can_track_open_clicks = false; $this->send( $subject, $content, $admin_emails, $data ); return true; } return false; } /** * Get new contact email subject * * @return string * * @since 4.3.2 */ public function get_admin_new_contact_email_subject() { return stripslashes( get_option( 'ig_es_admin_new_contact_email_subject', '' ) ); } /** * Get new contact email content * * @return string * * @since 4.3.2 */ public function get_admin_new_contact_email_content() { return wpautop( stripslashes( get_option( 'ig_es_admin_new_contact_email_content', '' ) ) ); } /** * Can send add new contact to admin? * * @return bool * * @since 4.3.2 */ public function can_send_add_new_contact_notification() { $ig_es_notify_admin = get_option( 'ig_es_notify_admin', 'no' ); if ( 'yes' === $ig_es_notify_admin ) { return true; } return false; } /** * Send Double Optin Email * * @param $emails * @param array $merge_tags * * @since 4.3.2 */ public function send_double_optin_email( $emails, $merge_tags = array() ) { $subject = $this->get_confirmation_email_subject(); $content = $this->get_confirmation_email_content(); if ( empty( $subject ) || empty( $content ) ) { return false; } $content = str_replace( '{{LINK}}', '{{SUBSCRIBE-LINK}}', $content ); $this->add_unsubscribe_link = false; $this->can_track_open_clicks = false; return $this->send( $subject, $content, $emails, $merge_tags ); } /** * Get Confirmation Email Content * * @return string * * @since 4.3.2 */ public function get_confirmation_email_content() { return wpautop( stripslashes( get_option( 'ig_es_confirmation_mail_content', '' ) ) ); } /** * Get Confirmation Email Subject * * @return string * * @since 4.3.2 * * @modify 4.3.12 */ public function get_confirmation_email_subject() { $subject = stripslashes( get_option( 'ig_es_confirmation_mail_subject', '' ) ); if ( empty( $subject ) ) { $subject = __( 'Thanks!', 'email-subscribers' ); } return $subject; } /** * Send Cron Admin Emails * * @param string $notification_guid * * @since 4.3.2 */ public function send_cron_admin_email( $notification_guid = '' ) { if ( ! $this->can_send_cron_admin_email() ) { return; } $admin_emails = $this->get_admin_emails(); if ( ! empty( $admin_emails ) && ! empty( $notification_guid ) && is_array( $admin_emails ) && count( $admin_emails ) > 0 ) { $notification = ES_DB_Mailing_Queue::get_notification_by_hash( $notification_guid ); $subject = $this->get_cron_admin_email_subject(); $content = $this->get_cron_admin_email_content(); if ( ! empty( $content ) && isset( $notification['subject'] ) ) { $subject = str_replace( '{{SUBJECT}}', $notification['subject'], $subject ); $email_count = $notification['count']; $post_subject = $notification['subject']; $cron_date = gmdate( 'Y-m-d H:i:s' ); $cron_local_date = get_date_from_gmt( $cron_date ); // Convert from GMT to local date/time based on WordPress time zone setting. $cron_date = ES_Common::convert_date_to_wp_date( $cron_local_date ); // Get formatted date from WordPress date/time settings. $content = str_replace( '{{DATE}}', $cron_date, $content ); $content = str_replace( '{{COUNT}}', $email_count, $content ); $content = str_replace( '{{SUBJECT}}', $post_subject, $content ); $this->add_unsubscribe_link = false; $this->can_track_open_clicks = false; $this->send( $subject, $content, $admin_emails ); } } } /** * Get cron admin email subject * * @return mixed|void * * @since 4.3.2 */ public function get_cron_admin_email_subject() { return get_option( 'ig_es_cron_admin_email_subject', __( 'Campaign Sent!', 'email-subscribers' ) ); } /** * Get cron admin email content * * @return mixed|void * * @since 4.3.2 */ public function get_cron_admin_email_content() { return wpautop( get_option( 'ig_es_cron_admin_email', '' ) ); } /** * Can send cron admin email? * * @return bool * * @since 4.3.2 */ public function can_send_cron_admin_email() { $notify_admin = get_option( 'ig_es_enable_cron_admin_email', 'yes' ); if ( 'yes' === $notify_admin ) { return true; } return false; } /** * Get admin emails * * @return array * * @since 4.3.2 */ public function get_admin_emails() { $admin_email_addresses = get_option( 'ig_es_admin_emails', '' ); return explode( ',', $admin_email_addresses ); } /** * Send Welcome email after subscription * * @param $email * @param $data * * @since 4.1.13 */ public function send_welcome_email( $email, $data = array() ) { // Prepare Welcome Email Subject $subject = $this->get_welcome_email_subject(); // Prepare Welcome Email Content $content = $this->get_welcome_email_content(); // Backward Compatibility...Earlier we used to use {{LINK}} for Unsubscribe link $content = str_replace( '{{LINK}}', '{{UNSUBSCRIBE-LINK}}', $content ); // Don't add Unsubscribe link. It should be there in content $this->add_unsubscribe_link = false; $this->can_track_open_clicks = false; // Send Email $this->send( $subject, $content, $email, $data ); } /** * Get Welcome Email Subject * * @return string * * @since 4.3.2 */ public function get_welcome_email_subject() { return stripslashes( get_option( 'ig_es_welcome_email_subject', '' ) ); } /** * Get Welcome Email Message * * @return string * * @since 4.3.2 */ public function get_welcome_email_content() { return wpautop( stripslashes( get_option( 'ig_es_welcome_email_content', '' ) ) ); } /** * Enable Welcome Email? * * @return bool * * @since 4.3.2 */ public function can_send_welcome_email() { // Enable Welcome Email? $enable_welcome_email = get_option( 'ig_es_enable_welcome_email', 'no' ); if ( 'yes' === $enable_welcome_email ) { return true; } return false; } /** * Send Test Email * * @param string $email * @param array $merge_tags * * @return bool * * @since 4.3.2 */ public function send_test_email( $email = '', $subject = '', $content = '', $merge_tags = array() ) { check_ajax_referer( 'ig-es-admin-ajax-nonce', 'security' ); if ( empty( $email ) ) { return false; } if ( empty( $subject ) ) { $subject = $this->get_test_email_subject( $email ); } if ( empty( $content ) ) { $content = $this->get_test_email_content(); } // Disable unsubsribe link if it is not a campaign email. if ( empty( $merge_tags['campaign_id'] ) ) { $this->add_unsubscribe_link = false; } $this->can_track_open_clicks = false; return $this->send( $subject, $content, $email, $merge_tags ); } /** * Get Test Email Subject * * @param string $email * * @return string * * @since 4.3.2 */ public function get_test_email_subject( $email = '' ) { /* translators: %s: Email address */ return 'Icegram Express: ' . sprintf( esc_html__( 'Test email to %s', 'email-subscribers' ), $email ); } /** * Get test email content * * @return false|string * * @since 4.3.2 */ public function get_test_email_content() { ob_start(); $review_url = 'https://wordpress.org/support/plugin/email-subscribers/reviews/?filter=5'; ?>
2: */ echo sprintf( esc_html__( 'If you find this plugin useful, please consider giving us %1$s5 stars review%2$s on WordPress!', 'email-subscribers' ), '', '' ); ?>
Nirav Mehta
Founder, Icegram
time_start = time(); if ( ES_Service_Email_Sending::using_icegram_mailer() ) { $remaining_limit = ES_Service_Email_Sending::get_remaining_limit(); if ( $remaining_limit > 0 ) { $this->mailer->remaining_limit = $remaining_limit; } else { $this->switch_to_default_mailer(); } } $message_id = ! empty( $merge_tags['message_id'] ) ? $merge_tags['message_id'] : 0; $campaign_id = ! empty( $merge_tags['campaign_id'] ) ? $merge_tags['campaign_id'] : 0; $attachments = ! empty( $merge_tags['attachments'] ) ? $merge_tags['attachments'] : array(); $sender_data = array(); $campaign_type = ''; if ( ! empty( $campaign_id ) ) { $campaign = ES()->campaigns_db->get( $campaign_id ); if ( ! empty( $campaign ) ) { $campaign_type = $campaign['type']; if ( 'newsletter' === $campaign_type ) { $from_name = ! empty( $campaign['from_name'] ) ? $campaign['from_name'] : ''; $from_email = ! empty( $campaign['from_email'] ) ? $campaign['from_email'] : ''; $reply_to_email = ! empty( $campaign['reply_to_email'] ) ? $campaign['reply_to_email'] : ''; $sender_data['from_name'] = $from_name; $sender_data['from_email'] = $from_email; $sender_data['reply_to_email'] = $reply_to_email; } $campaign_meta = maybe_unserialize( $campaign['meta'] ); if ( ! empty( $campaign_meta['preheader'] ) ) { $content = '' . $content; } elseif ( ! empty( $merge_tags['preheader'] ) ) { $content = '' . $content; } if ( ! empty( $campaign_meta['attachments'] ) ) { $sender_data['attachments'] = array(); $attachments = $campaign_meta['attachments']; } } } if ( ! empty( $attachments ) ) { foreach ( $attachments as $attachment_id ) { if ( ! $attachment_id ) { continue; } $attached_file = get_attached_file( $attachment_id ); if ( ! is_file( $attached_file ) ) { continue; } $sender_data['attachments'][ basename( $attached_file ) ] = $attached_file; } } // If unsubscribe link placeholder already present in the email then don't add it from our end. if ( false !== strpos( $content, '{{UNSUBSCRIBE-LINK}}' ) ) { $this->add_unsubscribe_link = false; } $subject = $this->prepare_subject( $subject ); $content = $this->prepare_content( $content, $merge_tags, $nl2br ); $response = array(); if ( ! is_array( $emails ) ) { $emails = array( $emails ); } // When email in not sent through a campaign e.g. Test emails. if ( '' === $campaign_type ) { $this->email_id_map = ES()->contacts_db->get_email_id_map( $emails ); } else { /** * In case of sequence message campaign, fetch contact-email mapping from contacts table, since sending_queue table isn't used to store sequence campaign data. * TODO: Please check need for using sending_queue table for other campaigns type. If it is not required, then we can remove it for other campaigns types as well. */ if ( in_array( $campaign_type, array( 'sequence_message', 'workflow_email' ), true ) ) { $this->email_id_map = ES()->contacts_db->get_email_id_map( $emails ); } else { // If the campaign isn't a sequence message, then we can fetch contact-email mapping data from sending_queue table $this->email_id_map = ES_DB_Sending_Queue::get_emails_id_map_by_campaign( $campaign_id, $message_id, $emails ); } } $total_recipients = count( $emails ); $can_use_batch_api = $total_recipients > 1 && $this->mailer->support_batch_sending; $can_use_batch_api = apply_filters( 'ig_es_can_use_batch_api_' . $this->mailer->slug, $can_use_batch_api, $total_recipients, $sender_data ); // In case mailser supporting batch APIs, we are setting API credentials, sender data before running the email loop // For normal mailers, we are doing this inside the loop if ( $can_use_batch_api ) { $mailer_data_set = $this->mailer->set_mailer_data(); // Error setting up mailer? if ( is_wp_error( $mailer_data_set ) ) { $response['status'] = 'ERROR'; $response['message'] = $mailer_data_set->get_error_messages(); return $response; } if ( 'multiple' === $this->mailer->batch_sending_mode ) { $this->link_data = array( 'message_id' => $message_id, 'campaign_id' => $campaign_id, ); // If sender name is not passed then fetch it from ES settings. if ( ! empty( $sender_data['from_name'] ) ) { $sender_name = $sender_data['from_name']; } else { $sender_name = $this->get_from_name(); } // If sender email is not passed then fetch it from ES settings. if ( ! empty( $sender_data['from_email'] ) ) { $sender_email = $sender_data['from_email']; } else { $sender_email = $this->get_from_email(); } // If reply to email is not passed then fetch it from ES settings. if ( ! empty( $sender_data['reply_to_email'] ) ) { $reply_to_email = $sender_data['reply_to_email']; } elseif ( empty( $reply_to_email ) ) { $reply_to_email = $this->get_from_email(); } $charset = get_bloginfo( 'charset' ); $subject = html_entity_decode( $subject, ENT_QUOTES, $charset ); $content = preg_replace( '/data-json=".*?"/is', '', $content ); $content = preg_replace( '/ +/s', ' ', $content ); if ( $this->add_unsubscribe_link ) { $unsubscribe_message = get_option( 'ig_es_unsubscribe_link_content', '' ); $unsubscribe_message = stripslashes( $unsubscribe_message ); if ( false === strpos( $content, '