'billing_address_1', 'address-2' => 'billing_address_2', 'city' => 'billing_city', 'state' => 'billing_state', 'postcode' => 'billing_postcode', 'country' => 'billing_country', ); public static $captured_email_failed_message = null; public static function init() { add_action( 'bwf_before_migrate_contact_save', array( __CLASS__, 'migrate_bwf_contact' ), 10, 2 ); add_action( 'bwf_normalize_contact_meta_before_save', array( __CLASS__, 'update_contact_crm_fields' ), 10, 3 ); add_action( 'wp_login', array( __CLASS__, 'save_last_login' ), 9, 2 ); add_action( 'profile_update', array( __CLASS__, 'update_contact_fields' ), 10, 2 ); add_action( 'updated_user_meta', array( __CLASS__, 'mark_updated_address_fields' ), 10, 4 ); add_filter( 'bwf_before_profile_update_contact_sync', [ __CLASS__, 'profile_update_contact_sync' ], 10, 1 ); add_action( 'bwfan_delete_unsubscriber', array( __CLASS__, 'maybe_subscribe_contact' ), 10, 1 ); add_filter( 'bwfan_modify_engagement_body_preview', array( __CLASS__, 'add_style_in_engagement_body_preview' ), 10, 2 ); add_filter( 'bwfan_weekly_mail_status_section', [ __CLASS__, 'bwfan_weekly_mail_status_section' ] ); /** Save contact's last sent field */ add_action( 'bwfan_broadcast_last_sent', array( __CLASS__, 'update_last_sent' ), 10, 2 ); /** Change the old Export\Import log files name */ add_action( 'bwfcrm_change_log_file_name', array( __CLASS__, 'bwfcrm_change_log_file_name' ) ); add_action( 'wp_mail_failed', array( __CLASS__, 'email_failed' ) ); } /** * Checks the status * * @return array * @throws DateMalformedStringException */ public static function bwfan_weekly_mail_status_section( $arr = [] ) { $data = BWFAN_Common::get_lk_data(); $s = isset( $data['s'] ) ? $data['s'] : 0; $e = isset( $data['e'] ) ? $data['e'] : ''; $ad = isset( $data['ad'] ) ? $data['ad'] : ''; $upgrade_link = BWFAN_Common::get_fk_site_links(); $upgrade_link = isset( $upgrade_link['upgrade'] ) ? $upgrade_link['upgrade'] : ''; $upgrade_link = add_query_arg( [ 'utm_campaign' => 'FKA+Pro+Notification' ], $upgrade_link ); if ( $s === 2 ) { if ( $e === '' ) { return []; } $n = new DateTime(); $ed = new DateTime( $e ); if ( $n > $ed ) { $diff = $n->diff( $ed )->days; if ( $diff < 1 ) { $ed->modify( '+1 days' ); $link = add_query_arg( [ 'utm_medium' => 'Renew+Now+Grace' ], $upgrade_link ); $date = date_i18n( 'd F, Y', $ed->getTimestamp() ); return [ 'content' => sprintf( __( "Your FunnelKit Automations license grace period will expire on %s. Please renew to get uninterrupted service.", 'wp-marketing-automations-pro' ), $date ), 'link' => $link, 'link_text' => __( 'Renew Now', 'wp-marketing-automations-pro' ), 'background_color' => '#FEF7E8', 'button_color' => '#FFC65C', 'button_text_color' => '#000000', ]; } $link = add_query_arg( [ 'utm_medium' => 'Renew+Now+Expired' ], $upgrade_link ); return [ 'content' => sprintf( __( "Your FunnelKit Automations %s. Please renew to get uninterrupted service.", 'wp-marketing-automations-pro' ), '' . __( 'license has been expired', 'wp-marketing-automations-pro' ) . '' ), 'link' => $link, 'link_text' => __( 'Renew Now', 'wp-marketing-automations-pro' ), 'background_color' => '#FFE9E9', 'button_color' => '#E15334', 'button_text_color' => '#ffffff', ]; } return []; } if ( $s === 1 ) { if ( $ad !== '' ) { $n = new DateTime(); $adDate = new DateTime( $ad ); $diff = $n->diff( $adDate )->days; if ( $diff < 1 ) { $adDate->modify( '+1 days' ); $link = add_query_arg( [ 'utm_medium' => 'Get+License+Grace' ], $upgrade_link ); $date = date_i18n( 'd F, Y', $adDate->getTimestamp() ); return [ 'content' => sprintf( __( "Your FunnelKit Automations license grace period will expire on %s. Activate license to get uninterrupted service.", 'wp-marketing-automations-pro' ), $date ), 'link' => $link, 'link_text' => __( 'Get License', 'wp-marketing-automations-pro' ), 'background_color' => '#FEF7E8', 'button_color' => '#FFC65C', 'button_text_color' => '#000000', ]; } } $link = add_query_arg( [ 'utm_medium' => 'Get+License+Inactive' ], $upgrade_link ); return [ 'content' => __( "Your FunnelKit Automations license is not active. Please renew to get uninterrupted service.", 'wp-marketing-automations-pro' ), 'link' => $link, 'link_text' => __( 'Get License Now', 'wp-marketing-automations-pro' ), 'background_color' => '#FEF7E8', 'button_color' => '#FFC65C', 'button_text_color' => '#000000', ]; } return []; } public static function profile_update_contact_sync( $contact ) { $contact = new BWFCRM_Contact( $contact ); if ( $contact->is_contact_exists() ) { add_filter( 'bwf_profile_update_contact_sync_field', function ( $bwf_contact, $key, $value ) use ( $contact ) { $contact->contact = $bwf_contact; $contact->set_field_by_slug( $key, $value ); return $contact->contact; }, 10, 3 ); add_filter( 'bwf_after_profile_update_contact_sync', function ( $bwf_contact ) use ( $contact ) { $contact->contact = $bwf_contact; $contact->save_fields(); return $contact->contact; }, 10, 1 ); } return $contact->contact; } /** Update Address fields on WP User update * * @param int $user_id * @param WP_User $user_data */ public static function update_contact_fields( $user_id, $user_data ) { /** Check if Old User Data valid */ if ( ! $user_data instanceof WP_User || ! is_email( $user_data->user_email ) ) { self::$_user_address_meta_updated = array(); return; } /** Check if there is a contact */ $contact = new BWFCRM_Contact( $user_data->user_email ); if ( ! $contact->is_contact_exists() ) { self::$_user_address_meta_updated = array(); return; } /** Check whether new email update required or address needed update */ $new_email = self::maybe_get_new_user_email( $user_id, $user_data->user_email ); if ( empty( self::$_user_address_meta_updated ) && empty( $new_email ) ) { self::$_user_address_meta_updated = array(); return; } $fields_updated = false; foreach ( self::$_user_address_meta_updated as $meta_key => $meta_value ) { $crm_key = array_search( $meta_key, self::$contact_wp_user_address_fields, true ); if ( empty( $crm_key ) ) { continue; } if ( 'state' === $crm_key ) { $contact->contact->set_state( $meta_value ); continue; } if ( 'country' === $crm_key ) { $contact->contact->set_country( $meta_value ); continue; } $contact->set_field_by_slug( $crm_key, $meta_value ); $fields_updated = true; } /** Update the email, if Profile email got updated */ if ( ! empty( $new_email ) ) { $contact->contact->set_email( $new_email ); } if ( $fields_updated ) { $contact->save_fields(); } $contact->contact->set_last_modified( current_time( 'mysql', 1 ) ); $contact->save(); } public static function mark_updated_address_fields( $meta_id, $object_id, $meta_key, $_meta_value ) { $address_meta_keys = array_values( self::$contact_wp_user_address_fields ); if ( in_array( $meta_key, $address_meta_keys, true ) ) { self::$_user_address_meta_updated[ $meta_key ] = $_meta_value; } } /** * Contact Indexing * * @param $bwf_contact * @param $order */ public static function migrate_bwf_contact( $bwf_contact, $order ) { $crm_contact = new BWFCRM_Contact( $bwf_contact ); if ( ! $crm_contact->is_contact_exists() ) { return; } $address_1 = $bwf_contact->get_meta( 'address_1', false ); $address_2 = $bwf_contact->get_meta( 'address_2', false ); $postcode = $bwf_contact->get_meta( 'postcode', false ); $company = $bwf_contact->get_meta( 'company', false ); $city = $bwf_contact->get_meta( 'city', false ); ! empty( $address_1 ) && $crm_contact->set_address_1( $address_1 ); ! empty( $address_2 ) && $crm_contact->set_address_2( $address_2 ); ! empty( $postcode ) && $crm_contact->set_postcode( $postcode ); ! empty( $company ) && $crm_contact->set_company( $company ); ! empty( $city ) && $crm_contact->set_city( $city ); if ( $order instanceof WC_Order ) { self::get_set_customer_fields( $crm_contact, $order->get_id(), $order ); } } /** * Update Contact Fields * * @param $bwf_contact * @param $order_id * @param $order WC_Order */ public static function update_contact_crm_fields( $bwf_contact, $order_id, $order ) { $crm_contact = new BWFCRM_Contact( $bwf_contact ); if ( ! $crm_contact->is_contact_exists() ) { return; } self::get_set_customer_fields( $crm_contact, $order_id, $order ); } /** * Get customer billing details and save in Contact Fields * Helper function * * @param $crm_contact BWFCRM_Contact * @param $order_id * @param $order WC_Order */ public static function get_set_customer_fields( $crm_contact, $order_id, $order ) { if ( ! $order instanceof WC_Order ) { $order = wc_get_order( $order_id ); if ( ! $order instanceof WC_Order ) { return; } } $address_1 = $order->get_billing_address_1(); $address_2 = $order->get_billing_address_2(); $postcode = $order->get_billing_postcode(); $company = $order->get_billing_company(); $city = $order->get_billing_city(); if ( true === WooFunnels_DB_Updater::$indexing ) { ( empty( $crm_contact->get_address_1() ) && ! empty( $address_1 ) ) && $crm_contact->set_address_1( $address_1 ); ( empty( $crm_contact->get_address_2() ) && ! empty( $address_2 ) ) && $crm_contact->set_address_2( $address_2 ); ( empty( $crm_contact->get_postcode() ) && ! empty( $postcode ) ) && $crm_contact->set_postcode( $postcode ); ( empty( $crm_contact->get_company() ) && ! empty( $company ) ) && $crm_contact->set_company( $company ); ( empty( $crm_contact->get_city() ) && ! empty( $city ) ) && $crm_contact->set_city( $city ); $crm_contact->save_fields(); return; } if ( apply_filters( 'bwfan_maybe_save_blank_value', false ) ) { $crm_contact->set_address_1( $address_1 ); $crm_contact->set_address_2( $address_2 ); $crm_contact->set_postcode( $postcode ); $crm_contact->set_company( $company ); $crm_contact->set_city( $city ); $crm_contact->save_fields(); return; } ! empty( $address_1 ) && $crm_contact->set_address_1( $address_1 ); ! empty( $address_2 ) && $crm_contact->set_address_2( $address_2 ); ! empty( $postcode ) && $crm_contact->set_postcode( $postcode ); ! empty( $company ) && $crm_contact->set_company( $company ); ! empty( $city ) && $crm_contact->set_city( $city ); $crm_contact->save_fields(); } /** * Get Format for Error Response * * @param $error_array * @param string $message * @param int $response_code * * @return array */ public static function format_error_response( $error_array, $message = '', $response_code = 500 ) { return array( 'code' => $response_code, 'message' => $message, 'error' => $error_array, ); } /** * Get Format for Success Response * * @param $result_array * @param string $message * @param int $response_code * * @return array */ public static function format_success_response( $result_array, $message = '', $response_code = 200 ) { return array( 'code' => $response_code, 'message' => $message, 'result' => $result_array, ); } /** * @param string $message * @param array $data * @param int $code * * @return WP_Error */ public static function crm_error( $message = '', $data = array(), $code = 500 ) { $wp_error = new WP_Error( $code, $message ); if ( ! empty( $data ) ) { $wp_error->add_data( $data ); } return $wp_error; } public static function get_store_aov() { global $wpdb; $sql = "SELECT count(`order_id`) as `orders`, SUM(`total_sales`) as `total` FROM {$wpdb->prefix}wc_order_stats WHERE `status` NOT IN('wc-failed', 'wc-pending', 'wc-cancelled', 'wc-refunded') "; $result = $wpdb->get_results( $sql, ARRAY_A ); //phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $aov = 0; if ( isset( $result[0]['orders'] ) && ! empty( $result[0]['orders'] ) && isset( $result[0]['total'] ) && ! empty( $result[0]['total'] ) ) { $aov = ( floatval( $result[0]['total'] ) / absint( $result[0]['orders'] ) ); } return $aov; } /** * * function to get term by type tag=0 and list=1 **/ public static function get_term_by_type( $type ) { global $wpdb; $query = "Select * from {table_name} where type='" . $type . "'"; $all_terms = BWFAN_Model_Terms::get_results( $query ); $all_term = array(); foreach ( $all_terms as $term_key => $term ) { $all_term[ $term['ID'] ] = $term['name']; } return $all_term; } /** * function to get all the lists **/ public static function get_all_lists() { $query = "Select ID,name from {table_name} where type='2'"; $lists = BWFAN_Model_Terms::get_results( $query ); $list_data = array(); if ( empty( $lists ) ) { return $list_data; } foreach ( $lists as $key => $list ) { $list_data[ $list['ID'] ] = $list['name']; } return $list_data; } public static function is_crm_page() { return isset( $_GET['page'] ) && ( 'bwf-broadcasts' === $_GET['page'] || 'bwfcrm-contacts' === $_GET['page'] ); } public static function get_memory_limit() { if ( function_exists( 'ini_get' ) ) { $memory_limit = ini_get( 'memory_limit' ); } else { $memory_limit = '128M'; // Sensible default, and minimum required by WooCommerce } if ( ! $memory_limit || - 1 === $memory_limit || '-1' === $memory_limit ) { // Unlimited, set to 32GB. $memory_limit = '32G'; } return self::convert_hr_to_bytes( $memory_limit ); } public static function convert_hr_to_bytes( $value ) { if ( function_exists( 'wp_convert_hr_to_bytes' ) ) { return wp_convert_hr_to_bytes( $value ); } $value = strtolower( trim( $value ) ); $bytes = (int) $value; if ( false !== strpos( $value, 'g' ) ) { $bytes *= GB_IN_BYTES; } elseif ( false !== strpos( $value, 'm' ) ) { $bytes *= MB_IN_BYTES; } elseif ( false !== strpos( $value, 'k' ) ) { $bytes *= KB_IN_BYTES; } // Deal with large (float) values which run into the maximum integer size. return min( $bytes, PHP_INT_MAX ); } public static function memory_exceeded() { $memory_limit = self::get_memory_limit() * 0.9; $current_memory = memory_get_usage( true ); return $current_memory >= $memory_limit; } public static function reschedule_broadcast_action() { if ( bwf_has_action_scheduled( 'bwfcrm_broadcast_run_queue' ) ) { bwf_unschedule_actions( 'bwfcrm_broadcast_run_queue' ); } bwf_schedule_recurring_action( time(), 60, 'bwfcrm_broadcast_run_queue', array(), 'bwfcrm' ); self::ping_woofunnels_worker(); } public static function ping_woofunnels_worker() { $url = rest_url( '/woofunnels/v1/worker' ) . '?' . time(); $args = array( 'method' => 'GET', 'body' => array(), 'timeout' => 0.01, 'sslverify' => false, ); wp_remote_post( $url, $args ); } /** * @param $user_login * @param $user WP_USER * * @return void */ public static function save_last_login( $user_login = false, $user = false ) { $user = self::get_user( $user_login, $user ); if ( empty( $user ) || ! $user instanceof WP_User ) { return; } $contact = new WooFunnels_Contact( '', $user->user_email ); if ( empty( $contact->get_id() ) ) { return; } /** Set contact uid in cookie */ if ( ! empty( $contact->get_uid() ) ) { BWFAN_Common::set_cookie( '_fk_contact_uid', $contact->get_uid(), time() + 10 * 365 * 24 * 60 * 60 ); } /** Save last login */ add_action( 'shutdown', function () use ( $contact ) { $field_id = BWFCRM_Fields::get_field_id_by_slug( 'last-login' ); if ( empty( $field_id ) ) { return; } BWF_Model_Contact_Fields::update( [ 'f' . $field_id => current_time( 'mysql' ) ], array( 'cid' => $contact->get_id() ) ); } ); } public static function get_user( $user_login = false, $user = false ) { if ( method_exists( 'BWFAN_Common', 'get_user' ) ) { /** Checks if function exists in lite */ return BWFAN_Common::get_user( $user_login, $user ); } if ( ! empty( $user ) && $user instanceof WP_User ) { return $user; } if ( ! empty( $user_login ) ) { $user = get_user_by( 'login', $user_login ); if ( false === $user ) { $user = get_user_by( 'email', $user_login ); } if ( ! empty( $user ) && $user instanceof WP_User ) { return $user; } } if ( is_user_logged_in() ) { return wp_get_current_user(); } return false; } public static function get_contact_by_email_or_phone( $email_or_phone ) { global $wpdb; $sql = $wpdb->prepare( "SELECT * from {$wpdb->prefix}bwf_contact WHERE email=%s OR contact_no=%s LIMIT 0,1", $email_or_phone, $email_or_phone ); $contact = $wpdb->get_row( $sql, ARRAY_A ); //phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching if ( empty( $contact ) ) { return false; } $contact = new BWFCRM_Contact( $contact ); if ( ! $contact->is_contact_exists() ) { return false; } return $contact; } public static function send_sms( $args ) { /** Make sure there is atleast 1 active connector */ $active_services = BWFAN_Common::get_sms_services(); if ( empty( $active_services ) ) { return new WP_Error( 'connector_not_found', __( 'No active SMS service (connector) available.', 'wp-marketing-automations-pro' ) ); } // fetching provider for test sms $provider = isset( $args['sms_provider'] ) ? $args['sms_provider'] : ''; if ( empty( $provider ) ) { $global_settings = BWFAN_Common::get_global_settings(); $provider = isset( $global_settings['bwfan_sms_service'] ) && ! empty( $global_settings['bwfan_sms_service'] ) ? $global_settings['bwfan_sms_service'] : BWFAN_Common::get_default_sms_provider(); } /** If no provider selected OR selected provider is not within active providers, then select default provider */ if ( empty( $provider ) || ! isset( $active_services[ $provider ] ) ) { $provider = BWFAN_Common::get_default_sms_provider(); } $provider = explode( 'bwfco_', $provider ); $provider = isset( $provider[1] ) ? $provider[1] : ''; $provider = ! empty( $provider ) ? BWFAN_Core()->integration->get_integration( $provider ) : ''; if ( ! $provider instanceof BWFAN_Integration || ! method_exists( $provider, 'send_message' ) ) { return new WP_Error( 'connector_not_found', __( 'Connector Integration not found', 'wp-marketing-automations-pro' ) ); } return $provider->send_message( $args ); } public static function get_sms_provider_integration() { /** Make sure there is atleast 1 active connector */ $active_services = BWFAN_Common::get_sms_services(); if ( empty( $active_services ) ) { return new WP_Error( 'connector_not_found', __( 'No active SMS service (connector) available.', 'wp-marketing-automations-pro' ) ); } $global_settings = BWFAN_Common::get_global_settings(); $provider = isset( $global_settings['bwfan_sms_service'] ) && ! empty( $global_settings['bwfan_sms_service'] ) ? $global_settings['bwfan_sms_service'] : BWFAN_Common::get_default_sms_provider(); /** If no provider selected OR selected provider is not within active providers, then select default provider */ if ( empty( $provider ) || ! isset( $active_services[ $provider ] ) ) { $provider = BWFAN_Common::get_default_sms_provider(); } $provider = explode( 'bwfco_', $provider ); $provider = isset( $provider[1] ) ? $provider[1] : ''; $provider = ! empty( $provider ) ? BWFAN_Core()->integration->get_integration( $provider ) : ''; if ( ! $provider instanceof BWFAN_Integration || ! method_exists( $provider, 'send_message' ) ) { return new WP_Error( 'connector_not_found', __( 'Connector Integration not found', 'wp-marketing-automations-pro' ) ); } return $provider; } public static function get_sms_provider_slug() { $provider = BWFCRM_Common::get_sms_provider_integration(); if ( is_wp_error( $provider ) ) { return false; } return $provider->get_connector_slug(); } /** * Remove filter before sending mail */ public static function bwf_remove_filter_before_wp_mail() { remove_all_filters( 'wp_mail_from' ); remove_all_filters( 'pre_wp_mail' ); remove_all_filters( 'wp_mail_from_name' ); remove_all_filters( 'wp_mail_content_type' ); remove_all_filters( 'wp_mail_charset' ); } /** update contact email on update of user email * * @param $user_id * @param $old_user_data */ public static function maybe_get_new_user_email( $user_id, $old_user_email ) { $user = get_userdata( $user_id ); $new_user_email = $user->user_email; if ( $new_user_email === $old_user_email ) { return false; } $new_email_contact = new BWFCRM_contact( $new_user_email ); if ( $new_email_contact->is_contact_exists() ) { return false; } return $new_user_email; } /** * Trigger contact subscribed event when deleting unsubscribes from list * * @param $data */ public static function maybe_subscribe_contact( $data ) { global $wpdb; /** @var BWFCRM_Contact $contact */ $contact = self::get_contact_by_email_or_phone( $data['recipient'] ); if ( ! $contact->is_contact_exists() ) { return; } /** If contact status 0(unverified) and 2(bounced) */ if ( 1 !== absint( $contact->contact->get_status() ) ) { return; } $search = $contact->contact->get_email(); if ( is_email( $data['recipient'] ) ) { $search = $contact->contact->get_contact_no(); } /** Get unsubscribe ids if contact's email or phone available in unsubscribe table*/ $query = $wpdb->prepare( "SELECT ID FROM {$wpdb->prefix}bwfan_message_unsubscribe WHERE recipient=%s", $search ); $unsubscribed = $wpdb->get_results( $query, ARRAY_A ); //phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching if ( count( $unsubscribed ) > 0 ) { return; } if ( ! did_action( 'bwfcrm_after_contact_subscribed' ) ) { do_action( 'bwfcrm_after_contact_subscribed', $contact->contact ); } } public static function emogrify_rich_text( $email_body ) { $email_body = self::add_body_attrs( $email_body ); BWFCRM_Core()->conversation->include_email_merge_tags_templates(); ob_start(); include BWFAN_PLUGIN_DIR . '/templates/email-styles.php'; $css = ob_get_clean(); $email_body = self::emogrifier_parsed_output( $css, $email_body ); return $email_body; } public static function emogrify_html( $email_body ) { $email_body = self::add_body_attrs( $email_body ); BWFCRM_Core()->conversation->include_email_merge_tags_templates(); ob_start(); include BWFAN_PLUGIN_DIR . '/templates/email-editor-styles.php'; $css = ob_get_clean(); $email_body = self::emogrifier_parsed_output( $css, $email_body ); return $email_body; } public static function emogrifier_parsed_output( $css, $email_body ) { if ( empty( $email_body ) || empty( $css ) ) { return $email_body; } if ( ! BWFAN_Common::supports_emogrifier() ) { $email_body = '' . $email_body; return $email_body; } $emogrifier_class = '\\BWF_Pelago\\Emogrifier'; if ( ! class_exists( $emogrifier_class ) ) { include_once BWFAN_PLUGIN_DIR . '/libraries/class-emogrifier.php'; } try { /** @var \BWF_Pelago\Emogrifier $emogrifier */ $emogrifier = new $emogrifier_class( $email_body, $css ); $email_body = $emogrifier->emogrify(); } catch ( Exception $e ) { BWFAN_Core()->logger->log( $e->getMessage(), 'send_email_emogrifier' ); } return $email_body; } public static function add_body_attrs( $content ) { $has_body = stripos( $content, '