parse_parameters_from_string( trim( $variable_params ) ); if ( is_array( $parameters ) && ! empty( $parameters ) ) { if ( isset( $parameters['fallback'] ) && ! empty( $parameters['fallback'] ) ) { $replace_with_fallback = self::un_quote( $parameters['fallback'] ); $is_nested_variable = strpos( $variable_name, '.' ); // Check if variable has dont(.) in its name if ( $is_nested_variable ) { $variable_parts = explode( '.', $variable_name ); $variable_type = $variable_parts[0]; $variable_slug = $variable_parts[1]; /** * For variables like subscribers.name, we need to pass the fallback data as nested array * $default_keywords['subscribers']['name'] = fallback_value **/ $default_keywords[ $variable_type ][ $variable_slug ] = $replace_with_fallback; } else { $default_keywords[ $variable_name ] = $replace_with_fallback; } } } } } return $default_keywords; } /** * Callback to replace keywords * * @param $keyword * @param $search_and_replace * * @return mixed|string */ public static function callback_replace_keywords( $keyword, $search_and_replace ) { if ( strstr( $keyword, '|' ) ) { list( $variable_name, $variable_params ) = explode( '|', $keyword, 2 ); } else { $variable_name = $keyword; $variable_params = ''; } $variable_name = trim( $variable_name ); //If there is no key found in replaceable array, then return the keyword if ( ! isset( $search_and_replace[ $variable_name ] ) ) { return '{{' . $keyword . '}}'; } $replace_with = $search_and_replace[ $variable_name ]; $replace_with_fallback = ''; //Extract fallback content from the keyword $variable = new IG_ES_Workflow_Variable_Parser(); $parameters = $variable->parse_parameters_from_string( trim( $variable_params ) ); if ( is_array( $parameters ) && ! empty( $parameters ) ) { if ( isset( $parameters['fallback'] ) && ! empty( $parameters['fallback'] ) ) { $replace_with_fallback = self::un_quote($parameters['fallback']); } } //If replaceable value is contain fallback keyword, then return the replaceable value with fallback value if ( strstr( $replace_with, '%%fallback%%' ) ) { return str_replace( '%%fallback%%', $replace_with_fallback, $replace_with ); } //If replaceable value is not empty, then return the replaceable value if ( ! empty( $replace_with ) ) { return $replace_with; } // return fallback value return $replace_with_fallback; } /** * Decode the html quotes * * @param $string * * @return string */ public static function decode_html_quotes( $string ) { $entities_dictionary = [ '‘' => "'", // Opening single quote '’' => "'", // Closing single quote '“' => '"', // Closing double quote '”' => '"', // Opening double quote '‘' => "'", // Closing single quote '’' => "'", // Opening single quote '‚' => "'", // Single low quote '“' => '"', // Closing double quote '”' => '"', // Opening double quote '„' => '"', // Double low quote ]; // Decode decimal entities $string = str_replace( array_keys( $entities_dictionary ), array_values( $entities_dictionary ), $string ); return html_entity_decode( $string, ENT_QUOTES | ENT_HTML5, 'UTF-8' ); } /** * Remove quotes from string * * @param $string * * @return string */ public static function un_quote( $string ) { $string = self::decode_html_quotes( $string ); return trim( trim( $string ), "'" ); } /** * Parse keywords * * @since 5.3.5 * @return false|void */ public static function replace_keywords_with_fallback( $content, $search_and_replace ) { if ( empty( $content ) || empty( $search_and_replace ) ) { return $content; } $replacer = new IG_ES_Replace_Helper( $content, 'ES_Common::callback_replace_keywords', 'variables', $search_and_replace ); $processed_content = $replacer->process(); if ( $processed_content ) { return $processed_content; } return $content; } /** * Process template body * * @param $content * @param int $tmpl_id * @param int $campaign_id * * @return mixed|string * * @since 4.0.0 */ public static function es_process_template_body( $content, $tmpl_id = 0, $campaign_id = 0 ) { $content = convert_smilies( wptexturize( $content ) ); $content = self::handle_oembed_content( $content ); // Add p tag only if we aren't getting tags inside the content, otherwise html gets marked as invalid. if ( false === strpos( $content, 'contacts_db->count_active_contacts_by_list_id(); $content = str_replace( '{{TOTAL-CONTACTS}}', $total_contacts, $content ); $content = str_replace( '{{site.total_contacts}}', $total_contacts, $content ); // blog title $blog_name = get_option( 'blogname' ); $content = str_replace( '{{SITENAME}}', $blog_name, $content ); $content = str_replace( '{{site.name}}', $blog_name, $content ); // site url $site_url = home_url( '/' ); $content = str_replace( '{{SITEURL}}', $site_url, $content ); $content = str_replace( '{{site.url}}', $site_url, $content ); /* TODO: Enable it once Pre header issue fix $meta = ES()->campaigns_db->get_campaign_meta_by_id( $campaign_id ); $meta['pre_header'] = !empty($meta['pre_header']) ? $meta['pre_header'] : ''; if( !empty( $meta['pre_header'] )){ $content = ''.$content; } */ return $content; } /** * Method to handle oembed content * * @param string @content Content. * * @return string $content * * @since 4.4.9 */ public static function handle_oembed_content( $content = '' ) { if ( ! empty( $content ) && isset( $GLOBALS['wp_embed'] ) ) { add_filter( 'embed_oembed_html', array( 'ES_Common', 'handle_link_in_email_content' ), 10, 4 ); add_filter( 'embed_handler_html', array( 'ES_Common', 'handle_link_in_email_content' ), 10, 3 ); $content = $GLOBALS['wp_embed']->autoembed( $content ); remove_filter( 'embed_oembed_html', array( 'ES_Common', 'handle_link_in_email_content' ), 10, 4 ); remove_filter( 'embed_handler_html', array( 'ES_Common', 'handle_link_in_email_content' ), 10, 3 ); } return $content; } /** * Method to handle link in email content * * URL from {{POSTLINK-ONLY}} was being converted to oembed html if it is not wrapped inside tag's href attribute and is on a seperate line in ES template content * resulting in a link html for {{POSTLINK-ONLY}} instead of plain text link. * * Most email clients like GMail, Outlook do not support videos in the email. To handle it, we are replacing the WordPress's oembed generated HTML for video links to their respective thubmnail images which are then linked the original video URL. * * @param string $html HTML for current URL. * @param string $url Current URL. * @param array $attr Shortcode attribute. * @param int $post_ID Current post id. * * @return string $html HTML for current URL. * * @since 4.4.9 */ public static function handle_link_in_email_content( $html, $url, $attr, $post_ID = 0 ) { $post_link = ''; if ( ! empty( $post_ID ) ) { $post_link = get_permalink( $post_ID ); } // Check if current URL is same as current post's permalink. if ( ! empty( $post_link ) && $url === $post_link ) { // Convert URL HTML back to URL itself if it a current post URL. $html = $url; } else { if ( ! class_exists( 'WP_oEmbed' ) ) { require_once ABSPATH . 'wp-includes/class-wp-oembed.php'; } $oembed = new WP_oEmbed(); $provider = $oembed->get_provider( $url ); if ( ! empty( $provider ) ) { $oembed_response = $oembed->fetch( $provider, $url, $attr ); if ( is_object( $oembed_response ) && ! empty( $oembed_response->type ) && 'video' === $oembed_response->type && ! empty( $oembed_response->thumbnail_url ) ) { $thumbnail_url = $oembed_response->thumbnail_url; $title = $oembed_response->title; $provider_name = $oembed_response->provider_name; $play_icon_url = ''; switch ( $provider_name ) { case 'YouTube': $play_icon_url = ES_PLUGIN_URL . 'lite/public/images/youtube-play-button.png'; break; case 'Vimeo': $play_icon_url = ES_PLUGIN_URL . 'lite/public/images/vimeo-play-button.png'; break; default: $play_icon_url = ES_PLUGIN_URL . 'lite/public/images/default-play-button.png'; break; } ob_start(); $thumbnail_width = 'auto'; $thumbnail_height = 'auto'; if ( ! empty( $oembed_response->thumbnail_width ) && ! empty( $oembed_response->thumbnail_height ) ) { $thumbnail_width = $oembed_response->thumbnail_width . 'px'; $thumbnail_height = $oembed_response->thumbnail_height . 'px'; } elseif ( ! empty( $oembed_response->width ) && ! empty( $oembed_response->height ) ) { $thumbnail_width = $oembed_response->width . 'px'; $thumbnail_height = $oembed_response->height . 'px'; } ?>
__( 'Subscribed', 'email-subscribers' ), 'unconfirmed' => __( 'Unconfirmed', 'email-subscribers' ), 'unsubscribed' => __( 'Unsubscribed', 'email-subscribers' ), ); $statuses = apply_filters( 'ig_es_get_statuses_key_name_map', $statuses, $page ); if ( $reverse ) { $statuses = array_flip( $statuses ); } return $statuses; } /** * Prepare Statuses dropdown * * @param string $selected * @param string $default_label * * @return string * * @since 4.0.0 */ public static function prepare_statuses_dropdown_options( $selected = '', $default_label = '', $page = '' ) { if ( empty( $default_label ) ) { $default_label = __( 'Select Status', 'email-subscribers' ); } $default_status[0] = $default_label; $statuses = self::get_statuses_key_name_map(false, $page); $statuses = array_merge( $default_status, $statuses ); $dropdown = ''; foreach ( $statuses as $key => $status ) { $dropdown .= ''; } return $dropdown; } /** * Prepare status dropdown options * * @param $selected * * @return string * * @since 4.0.0 */ public static function prepare_status_dropdown_options( $selected ) { $statuses = array( '1' => __( 'Active', 'email-subscribers' ), '0' => __( 'Inactive', 'email-subscribers' ), ); $dropdown = ''; foreach ( $statuses as $key => $status ) { $dropdown .= '
'info', 'center' => true, 'box_shadow' => true, 'show_icon' => true, ); $info = wp_parse_args( $info, $default_args ); $type = $info['type']; $show_icon = $info['show_icon']; $is_center = $info['center']; $is_box_shadow = $info['box_shadow']; $div_class = 'ig-es-information-box'; if ( $is_center ) { $div_class .= ' ig-es-center'; } if ( $is_box_shadow ) { $div_class .= ' ig-es-box-shadow'; } if ( $type ) { $div_class .= ' ig-es-' . $type; } ?>
can_show_feedback_widget() ) { return; } $default_params = array( 'set_transient' => true, 'force' => false, 'show_once' => false, ); $params = wp_parse_args( $params, $default_params ); if ( ! empty( $params['event'] ) ) { $event = $feedback->event_prefix . $params['event']; $force = ! empty( $params['force'] ) ? $params['force'] : false; $can_show = false; if ( $force ) { $can_show = true; } else { if ( ! $feedback->is_event_transient_set( $event ) ) { $can_show = true; $feedback_data = $feedback->get_event_feedback_data( $feedback->plugin_abbr, $event ); if ( count( $feedback_data ) > 0 ) { $show_once = $params['show_once']; $feedback_data = array_reverse( $feedback_data ); $last_feedback_given_on = $feedback_data[0]['created_on']; // If event feedback given within 45 days or show event only once? // Don't show now if ( $show_once || ( strtotime( $last_feedback_given_on ) > strtotime( '-45 days' ) ) ) { $can_show = false; } } } } if ( $can_show ) { if ( 'star' === $params['type'] ) { $feedback->render_stars( $params ); } elseif ( 'emoji' === $params['type'] ) { $feedback->render_emoji( $params ); } elseif ( 'feedback' === $params['type'] ) { $feedback->render_general_feedback( $params ); } elseif ( 'fb' === $params['type'] ) { /** * We are not calling home for this event and we want to show * this Widget only once. So, we are storing feedback data now. */ $feedback->set_feedback_data( 'ig_es', $event ); $feedback->render_fb_widget( $params ); } elseif ( 'poll' === $params['type'] ) { $feedback->set_feedback_data( 'ig_es', $event ); $feedback->render_poll_widget( $params ); } } } } /** * Get all restricted settings which we can't share * * @return array * * @since 4.6.6 */ public static function get_restricted_settings() { return array( 'ig_es_admin_new_contact_email_content', 'ig_es_admin_emails', 'ig_es_admin_new_contact_email_subject', 'ig_es_admin_notices', 'ig_es_confirmation_mail_content', 'ig_es_confirmation_mail_subject', 'ig_es_coupons', 'ig_es_cron_admin_email', 'ig_es_cron_admin_email_subject', 'ig_es_cronurl', 'ig_es_current_version_date_details', 'ig_es_custom_admin_notice_bfcm_2019', 'ig_es_custom_admin_notice_covid_19', 'ig_es_custom_admin_notice_halloween_offer_2020', 'ig_es_db_update_history', 'ig_es_default_subscriber_imported', 'ig_es_feedback_data', 'ig_es_form_submission_success_message', 'ig_es_last_cron_run', 'ig_es_last_updated_blocked_domains', 'ig_es_mailer_settings', 'ig_es_ob_skip_email_receive_error', 'ig_es_offer_bfcm_done_2019', 'ig_es_offer_covid_19', 'ig_es_onboarding_test_campaign_error', 'ig_es_opt_in_consent_text', 'ig_es_optin_link', 'ig_es_optin_page', 'ig_es_send_email_action_response', 'ig_es_roles_and_capabilities', 'ig_es_send_email_action_response', 'ig_es_sent_report_content', 'ig_es_sent_report_subject', 'ig_es_set_widget', 'ig_es_show_opt_in_consent', 'ig_es_show_sync_tab', 'ig_es_subscription_error_messsage', 'ig_es_subscription_success_message', 'ig_es_sync_wp_users', 'ig_es_unsubscribe_error_message', 'ig_es_run_cron_on', 'ig_es_run_cron_time', 'ig_es_unsubscribe_link', 'ig_es_unsubscribe_link_content', 'ig_es_unsubscribe_page', 'ig_es_unsubscribe_success_message', 'ig_es_update_processed_tasks', 'ig_es_update_tasks_to_process', 'ig_es_welcome_email_content', 'ig_es_welcome_email_subject', 'ig_es_email_sent_data', 'ig_es_remote_gallery_items', ); } /** * Get coma(,) separated lists name based on list ids * * @param array $list_ids * * @return string * * @since 4.1.13 */ public static function prepare_list_name_by_ids( $list_ids = array() ) { $list_name = ''; if ( is_array( $list_ids ) && count( $list_ids ) > 0 ) { $lists_id_name_map = ES()->lists_db->get_list_id_name_map(); $lists_name = array(); foreach ( $list_ids as $list_id ) { if ( ! empty( $lists_id_name_map[ $list_id ] ) ) { $lists_name[] = $lists_id_name_map[ $list_id ]; } } $list_name = implode( ', ', $lists_name ); } return $list_name; } /** * Update Total Email Sent count * * @param int $sent_count Sent emails count * * @since 4.1.15 * * @since 4.7.5 Added $sent_count parameter */ public static function update_total_email_sent_count( $sent_count = 0 ) { $current_date = ig_es_get_current_date(); $current_hour = ig_es_get_current_hour(); $email_sent_data_option = 'email_sent_data'; // Get total emails sent in this hour $email_sent_data = self::get_ig_option( $email_sent_data_option, array() ); $total_emails_sent = 0; $data = array(); if ( is_array( $email_sent_data ) && ! empty( $email_sent_data[ $current_date ] ) && ! empty( $email_sent_data[ $current_date ][ $current_hour ] ) ) { $total_emails_sent = $email_sent_data[ $current_date ][ $current_hour ]; } // Add count for sent emails. $total_emails_sent += $sent_count; // We want to store only current hour data. $data[ $current_date ][ $current_hour ] = $total_emails_sent; self::set_ig_option( $email_sent_data_option, $data ); } /** * Check whether user has access to this page * * @param $page * * @return bool|mixed|void * * @since 4.2.3 */ public static function ig_es_can_access( $page ) { $user = wp_get_current_user(); if ( ! $user->exists() ) { return false; } $default_permission = 'manage_options'; $can_access = $user->has_cap( $default_permission ); // Is Admin? Have full access. if ( $can_access ) { return true; } // We are using this filter in ES Premium to check permission. return apply_filters( 'ig_es_can_access', $can_access, $page ); } /** * Get accessible submenus * * @return array|mixed|void * * @since 4.2.3 */ public static function ig_es_get_accessible_sub_menus() { $sub_menus = array(); $user = wp_get_current_user(); if ( ! $user->exists() ) { return $sub_menus; } $default_permission = 'manage_options'; $is_administrator = $user->has_cap( $default_permission ); // Is user administrator? User has access to all submenus if ( $is_administrator ) { $sub_menus = array( 'dashboard', 'workflows', 'audience', 'reports', 'logs', 'forms', 'campaigns', 'sequences', 'settings', 'ig_redirect', 'custom_fields', 'drag_drop_editor', 'gallery', 'template', ); return $sub_menus; } // We are using this in ES Premium $sub_menus = apply_filters( 'ig_es_accessible_sub_menus', $sub_menus ); return array_unique( $sub_menus ); } /** * Generate Hash * * @param $length * * @return false|string * * @since 4.2.4 */ public static function generate_hash( $length ) { $length = ( $length ) ? $length : 12; return substr( md5( uniqid() . uniqid() . wp_rand( $length, 64 ) ), 0, $length ); } /** * Get useful article links * * @return array * * @since 4.4.2 */ public static function get_useful_articles( $upsell = true ) { $articles_upsell = array(); $blog_articles = array( array( 'title' => __( 'Top 10 Tips on How to Build an Email List', 'email-subscribers' ), 'link' => 'https://www.icegram.com/email-list/', ), array( 'title' => __( 'Why are Your Email Unsubscribes Increasing and How to Fix Them?', 'email-subscribers' ), 'link' => 'https://www.icegram.com/unsubscribes/', ), array( 'title' => __( 'Balance Email Marketing and Social Media Marketing', 'email-subscribers' ), 'link' => 'https://www.icegram.com/email-marketing-and-social-media-marketing/', ), array( 'title' => __( 'Use social proof to grow blog traffic through email', 'email-subscribers' ), 'link' => 'https://www.icegram.com/social-proof/', ), array( 'title' => __( '5 Simple Tricks to Improve Email Marketing Campaign Results', 'email-subscribers' ), 'link' => 'https://www.icegram.com/email-marketing-campaign/', ), ); if ( $upsell ) { $pricing_page_url = admin_url( 'admin.php?page=es_pricing' ); $articles_upsell[] = array( 'title' => __( 'Icegram Express Secret Club', 'email-subscribers' ), 'link' => 'https://www.facebook.com/groups/2298909487017349/', 'label' => __( 'Join Now', 'email-subscribers' ), 'label_class' => 'bg-green-100 text-green-800', ); if ( ! ES()->is_premium() ) { $articles_upsell[] = array( 'title' => __( 'Unlock all premium features', 'email-subscribers' ), 'link' => $pricing_page_url, 'label' => __( '25% OFF', 'email-subscribers' ), 'label_class' => 'bg-green-100 text-green-800', ); } } $articles = array_merge( $blog_articles, $articles_upsell ); return $articles; } /** * Get utm tracking url * * @param array $utm_args * * @return mixed|string * * @since 4.4.5 */ public static function get_utm_tracking_url( $utm_args = array() ) { $url = ! empty( $utm_args['url'] ) ? $utm_args['url'] : 'https://icegram.com/email-subscribers-pricing/'; $utm_source = ! empty( $utm_args['utm_source'] ) ? $utm_args['utm_source'] : 'in_app'; $utm_medium = ! empty( $utm_args['utm_medium'] ) ? $utm_args['utm_medium'] : ''; $utm_campaign = ! empty( $utm_args['utm_campaign'] ) ? $utm_args['utm_campaign'] : 'es_upsell'; if ( ! empty( $utm_source ) ) { $url = add_query_arg( 'utm_source', $utm_source, $url ); } if ( ! empty( $utm_medium ) ) { $url = add_query_arg( 'utm_medium', $utm_medium, $url ); } if ( ! empty( $utm_campaign ) ) { $url = add_query_arg( 'utm_campaign', $utm_campaign, $url ); } return $url; } /** * Get Captcha setting * * @param $id null|int * @param $data array * * @return bool|mixed|void * * @since 4.4.7 */ public static function get_captcha_setting( $form_id = null, $data = array() ) { if ( ! empty( $form_id ) ) { $form_id = (int) $form_id; $form_data = ES()->forms_db->get_form_by_id( $form_id ); $settings = ig_es_get_data( $form_data, 'settings', array() ); if ( ! empty( $settings ) ) { $settings = maybe_unserialize( $settings ); if ( isset( $settings['captcha'] ) ) { return empty( $settings['captcha'] ) ? 'no' : $settings['captcha']; } } return get_option( 'ig_es_enable_captcha', 'no' ); } if ( ! isset( $data['captcha'] ) || empty( $data['captcha'] ) ) { $setting = get_option( 'ig_es_enable_captcha', 'no' ); } else { $setting = $data['captcha']; } return $setting; } public static function convert_date_to_wp_date( $date ) { $convert_date_format = get_option( 'date_format' ); $convert_time_format = get_option( 'time_format' ); return date_i18n( "$convert_date_format $convert_time_format", strtotime( $date ) ); } /** * Get next local midnight time * * @since 5.5.2 * * @return string $local_next_midnight_time next local midnight time */ public static function get_next_local_midnight_time() { $next_day_utc_time = time() + DAY_IN_SECONDS; $offset_in_seconds = self::get_timezone_offset_in_seconds(); $next_day_local_time = $next_day_utc_time + $offset_in_seconds; $next_day_local_date = date_i18n( 'Y-m-d H:i:s', $next_day_local_time ); $local_date_obj = new DateTime( $next_day_local_date ); $local_date_obj->setTime( 0, 0, 0 ); $local_next_midnight_time = $local_date_obj->getTimestamp(); return $local_next_midnight_time; } /** * Convert UTC time for local midnight time * * @since 5.5.2 * * @return string $utc_time_for_local_midnight UTC time local midnight time */ public static function get_utc_time_for_local_midnight_time() { $offset_in_seconds = self::get_timezone_offset_in_seconds(); $next_local_midnight_time = self::get_next_local_midnight_time(); $utc_time_for_local_midnight = $next_local_midnight_time - $offset_in_seconds; return $utc_time_for_local_midnight; } /** * Get site's timezone offset in seconds * * @since 5.5.2 * * @return int $offset_in_seconds */ public static function get_timezone_offset_in_seconds() { $offset = get_option( 'gmt_offset' ); $offset_in_seconds = $offset * HOUR_IN_SECONDS; return $offset_in_seconds; } /** * Method to convert emojis character into their equivalent HTML entity in the given string if conversion supported * else remove them * * @param string $string String with emojis characters. * * @return string $string Converted string with equivalent HTML entities * * @since 4.4.7 */ public static function handle_emoji_characters( $string = '' ) { if ( ! empty( $string ) ) { if ( function_exists( 'wp_encode_emoji' ) ) { $string = wp_encode_emoji( $string ); } else { $string = preg_replace( '%(?: \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3 | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15 | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16 )%xs', '', $string ); } } return $string; } /** * Get Campaign type * * @param bool $reverse * * @return array * * @since 4.4.8 */ public static function get_campaign_type_key_name_map( $reverse = false ) { $campaign_type = self::get_campaign_types(); if ( $reverse ) { $campaign_type = array_flip( $campaign_type ); } return $campaign_type; } /** * Get Campaign type * * @return array * * @since 4.6.1 */ public static function get_campaign_types( $disallowed_types = array() ) { $template_types = apply_filters( 'es_template_type', array() ); if ( ! empty( $disallowed_types ) ) { foreach ( $disallowed_types as $disallowed_type ) { if ( isset( $template_types[ $disallowed_type ] ) ) { unset( $template_types[ $disallowed_type ] ); } } } return $template_types; } /** * Prepare Campaign Status dropdown * * @param string $selected * @param string $default_label * * @return string * * @since 4.4.8 */ public static function prepare_campaign_type_dropdown_options( $selected = '', $default_label = '' ) { $campaign_type = self::get_campaign_type_key_name_map(); $dropdown = ''; foreach ( $campaign_type as $key => $type ) { $dropdown .= ''; foreach ( $statuses as $key => $status ) { $dropdown .= ''; foreach ( $statuses as $key => $status ) { $dropdown .= '