[
'name' => 'Address 1',
'type' => 1,
'mode' => 2,
'vmode' => 1,
'view' => 2,
'meta' => [],
],
'address-2' => [
'name' => 'Address 2',
'type' => 1,
'mode' => 2,
'vmode' => 1,
'view' => 2,
'meta' => []
],
'city' => [
'name' => 'City',
'type' => 1,
'mode' => 2,
'vmode' => 1,
'view' => 2,
'meta' => []
],
'postcode' => [
'name' => 'Pincode',
'type' => 1,
'mode' => 2,
'vmode' => 1,
'view' => 2,
'meta' => []
],
'company' => [
'name' => 'Company',
'type' => 1,
'mode' => 2,
'vmode' => 1,
'view' => 2,
'meta' => []
],
'gender' => [
'name' => 'Gender',
'type' => 4,
'mode' => 2,
'vmode' => 1,
'view' => 2,
'meta' => [ 'options' => [ 'Male', 'Female', 'Other' ] ]
],
'dob' => [
'name' => 'Date of Birth',
'type' => 7,
'mode' => 2,
'vmode' => 1,
'view' => 2,
'meta' => []
]
];
public static $stop_async_call = null;
public static function init() {
self::$date_format = self::bwfan_get_date_format();
self::$time_format = self::bwfan_get_time_format();
self::$admin_email = get_option( 'admin_email' );
self::$select2ajax_functions = array( 'get_subscription_product', 'get_membership_plans', 'get_coupon' );
register_deactivation_hook( BWFAN_PLUGIN_FILE, array( __CLASS__, 'deactivation' ) );
/** Loading WooFunnels core */
add_action( 'plugins_loaded', function () {
WooFunnel_Loader::include_core();
}, - 99 );
add_action( 'plugins_loaded', [ __CLASS__, 'set_dynamic_string' ], 0 );
add_filter( 'modify_set_data', array( __CLASS__, 'parse_default_merge_tags' ), 10, 1 );
add_action( 'bwfan_delete_order_meta_payment_failed', array( __CLASS__, 'delete_order_meta' ), 10, 1 );
add_filter( 'bwfan_select2_ajax_callable', array( __CLASS__, 'get_callable_object' ), 1, 2 );
add_action( 'admin_notices', array( __CLASS__, 'bwfan_run_cron_test' ) );
add_action( 'rest_api_init', array( __CLASS__, 'add_plugin_endpoint' ) );
/** showing consent text on checkout page */
add_action( 'wp', array( __CLASS__, 'display_marketing_optin_checkbox' ) );
add_filter( 'action_scheduler_queue_runner_batch_size', array( __CLASS__, 'ac_increase_queue_batch_size' ) );
add_filter( 'action_scheduler_queue_runner_time_limit', array( __CLASS__, 'ac_increase_max_execution_time' ) );
add_filter( 'cron_schedules', array( __CLASS__, 'make_custom_events_time' ) );
/** Action Scheduler custom table worker callback */
add_action( 'bwfan_run_queue', array( __CLASS__, 'run_as_ct_worker' ) );
add_action( 'action_scheduler_pre_init', array( __CLASS__, 'as_pre_init_cb' ) );
add_action( 'action_scheduler_pre_init', array( __CLASS__, 'as_pre_init_cli_cb' ) );
/** Action Scheduler custom table v2 worker callback */
add_action( 'bwfan_run_queue_v2', array( __CLASS__, 'run_as_ct_v2_worker' ) );
add_action( 'action_scheduler_pre_init', array( __CLASS__, 'as_pre_init_v2_cb' ), 11 );
add_action( 'action_scheduler_pre_init', array( __CLASS__, 'as_pre_init_cli_v2_cb' ), 12 );
/** Action Scheduler to delete engagement meta records from tools */
add_action( 'bwfan_delete_engagement_tracking_meta_tool_action', array( __CLASS__, 'delete_engagement_tracking_meta_tool_action' ) );
/** Enable WooFunnels Action Scheduler Data Store */
add_filter( 'enable_woofunnels_as_ds', '__return_true' );
/** Convert all active abandoned rows to abandoned */
add_action( 'bwfan_check_abandoned_carts', array( __CLASS__, 'check_for_abandoned_carts' ) );
/** Delete all the old abandoned cart rows and their queued tasks */
add_action( 'bwfan_delete_old_abandoned_carts', array( __CLASS__, 'delete_old_abandoned_carts' ) );
add_action( 'bwfan_mark_abandoned_lost_cart', array( __CLASS__, 'mark_abandoned_lost_cart' ) );
add_action( 'bwfan_delete_expired_autonami_coupons', array( __CLASS__, 'delete_expired_autonami_coupons' ) );
add_action( 'bwfan_get_sources_events', array( __CLASS__, 'merge_pro_events' ) );
add_action( 'woofunnels_woocommerce_thankyou', array( __CLASS__, 'hit_cron_to_run_tasks' ) );
/** Auto deploy coupon in the cart */
add_action( 'wp', array( __CLASS__, 'auto_apply_wc_coupon' ), 20 );
/** Handling when restoring abandoned cart */
add_action( 'bwfan_abandoned_cart_restored', array( __CLASS__, 'auto_apply_wc_coupon' ) );
/** update order meta marketing_status details */
add_action( 'woocommerce_checkout_order_created', array( __CLASS__, 'bwfan_update_order_user_consent' ) );
add_action( 'bwf_normalize_contact_meta_before_save', array( __CLASS__, 'save_marketing_status_for_user' ), 20, 2 );
/** save marketing status if order is failed */
add_action( 'woocommerce_order_status_failed', array( __CLASS__, 'woocommerce_order_status_failed' ), 999, 2 );
/**
* Hooked over action_scheduler_pre_init
* Initiating core action scheduler
*/
add_action( 'bwf_after_action_scheduler_load', array( __CLASS__, 'bwf_after_action_scheduler_load' ), 11 );
/**Update the execution time of v2 automations if delay time changed */
add_action( 'bwfan_delay_step_updated', [ __CLASS__, 'bwfan_delay_step_updated' ], 10, 1 );
add_action( 'bwfan_goal_step_updated', [ __CLASS__, 'bwfan_goal_step_updated' ], 10, 2 );
add_action( 'bwfan_lost_cart_triggered', [ __CLASS__, 'bwfan_lost_cart_triggered' ] );
add_action( 'bwfan_automation_step_deleted', [ __CLASS__, 'bwfan_automation_step_deleted' ], 10, 1 );
add_action( 'bwfan_store_automation_completed_ids', [ __CLASS__, 'bwfan_store_automation_completed_ids' ] );
add_action( 'bwfan_store_automation_active_ids', [ __CLASS__, 'bwfan_store_automation_active_ids' ] );
/** Automation contact bulk action */
add_action( 'bwfan_automation_contact_bulk_action', [ __CLASS__, 'bwfan_automation_contact_bulk_action' ], 10, 4 );
/** Bulk action on listing pages */
add_action( 'bwfan_bulk_action', [ __CLASS__, 'bwfan_bulk_action' ], 10, 3 );
add_action( 'bwfan_delete_expired_coupons', array( __CLASS__, 'delete_expired_dynamic_coupons' ) );
/** Update contact wp user id after a wp user is deleted */
add_action( 'delete_user', array( __CLASS__, 'update_contact_wp_id' ) );
add_action( 'bwfan_update_meta_automations_v2', [ __CLASS__, 'update_meta_automations_v2' ] );
add_action( 'bwfan_delete_logs', [ __CLASS__, 'delete_bwfan_logs' ] );
/** Bulk action for Automation contact listing */
add_action( 'bwfan_automation_all_contact_bulk_action', [ __CLASS__, 'bwfan_automation_all_contact_bulk_action' ], 10, 3 );
/** Update automation contact's step trail status */
add_action( 'bwfan_update_contact_trail', [ __CLASS__, 'bwfan_update_contact_trail' ] );
add_filter( 'fk_before_sending_order_status_change_async_request', [ __CLASS__, 'order_status_change' ], 10, 4 );
add_action( 'fk_order_status_change_async_capture', [ __CLASS__, 'order_status_change_async_capture' ] );
/** Cron 'every 8 hrs' schedule */
add_filter( 'cron_schedules', [ __CLASS__, 'add_schedules' ], 100 );
add_action( 'fka_clear_duplicate_actions', array( __CLASS__, 'remove_duplicate_actions' ) );
add_action( 'wffn_optin_form_submit', array( __CLASS__, 'set_uid_in_cookies' ), 10, 3 );
add_action( 'bwfan_run_event_queue', [ __CLASS__, 'bwfan_run_event_queue' ] );
add_action( 'bwfan_conversions_index', [ __CLASS__, 'bwfan_conversions_index' ] );
add_action( 'bwfan_run_midnight_cron', array( 'BWFAN_Table_Validation_Controller', 'get_table_validate_option' ) );
add_action( 'bwfan_run_midnight_cron', [ __CLASS__, 'schedule_notification' ] );
/** Enable cron check logging if enabled in setting */
add_filter( 'bwf_check_cron_schedule_logging', function () {
return self::is_log_enabled( 'bwfan_cron_check_logging' );
} );
/** Modify midnight cron action scheduler's execution time to store time */
$midnight_actions = [
'bwfan_run_midnight_cron',
'bwfan_delete_logs',
'bwfan_delete_expired_autonami_coupons',
'bwfan_mark_abandoned_lost_cart',
'bwfan_run_midnight_connectors_sync',
];
foreach ( $midnight_actions as $action ) {
add_filter( 'bwf_recurring_action_' . $action . '_execution_time', function ( $e_time ) {
return self::get_midnight_store_time();
} );
}
/** Add contact if not created */
add_action( 'user_register', [ __CLASS__, 'bwfan_register_user' ], 10, 1 );
add_action( 'bwfan_store_template_links', [ __CLASS__, 'bwfan_store_template_links' ] );
}
public static function display_marketing_optin_checkbox() {
/** check for woocommerce active **/
if ( ! function_exists( 'bwfan_is_woocommerce_active' ) || false === bwfan_is_woocommerce_active() ) {
return;
}
/** check for woocommerce checkout page **/
if ( ! is_checkout() && ! wp_doing_ajax() ) {
return;
}
$general_options = self::get_global_settings();
$wc_endpoint = filter_input( INPUT_GET, 'wc-ajax' );
if ( ! is_null( $wc_endpoint ) && ! wp_doing_ajax() ) {
return;
}
/** showing consent text on checkout page */
if ( isset( $general_options['bwfan_user_consent_position'] ) && 'below_term' === $general_options['bwfan_user_consent_position'] ) {
add_action( 'woocommerce_checkout_after_terms_and_conditions', function () {
self::add_user_consent_after_terms_and_conditions();
} );
} elseif ( isset( $general_options['bwfan_user_consent_position'] ) && 'below_phone' === $general_options['bwfan_user_consent_position'] ) {
/** Below Phone */
add_filter( 'woocommerce_form_field', function ( $field, $key, $args, $value ) {
if ( 'billing_phone' === $key ) {
$field_priority = $args['priority'] ? $args['priority'] : '';
$field .= self::add_user_consent_after_terms_and_conditions( true, $field_priority );
}
return $field;
}, 99, 4 );
} else {
/** Below Email */
add_filter( 'woocommerce_form_field', function ( $field, $key, $args, $value ) {
if ( 'billing_email' === $key ) {
$field_priority = $args['priority'] ? $args['priority'] : '';
$field .= self::add_user_consent_after_terms_and_conditions( true, $field_priority );
}
return $field;
}, 99, 4 );
}
}
public static function get_global_settings() {
$global_settings = get_option( 'bwfan_global_settings', array() );
$global_settings = self::override_non_changeable_settings( $global_settings );
$global_settings = wp_parse_args( $global_settings, self::get_default_global_settings( $global_settings ) );
return apply_filters( 'bwfan_get_global_settings', $global_settings );
}
/** Deleting from in-db settings, as those were old Shortcodes saved before the update */
public static function override_non_changeable_settings( $global_settings ) {
if ( ! is_array( $global_settings ) ) {
return $global_settings;
}
unset( $global_settings['bwfan_unsubscribe_button'] );
unset( $global_settings['bwfan_subscriber_recipient'] );
unset( $global_settings['bwfan_subscriber_name'] );
return $global_settings;
}
/**
* fetching the providers from the array
*
* @param $providers
* @param $default
*
* @return false|mixed|string
*/
public static function get_provider_value( $providers, $default = '' ) {
if ( ! empty( $default ) && isset( $providers[ $default ] ) ) {
return $default;
}
$providers = array_keys( $providers );
return end( $providers );
}
public static function get_default_global_settings( $global_settings = [] ) {
$email_settings = self::get_global_email_settings( $global_settings );
$defaults = array_replace( array(
'bwfan_ac_b_s' => 25,
'bwfan_ac_t_l' => 30,
'bwfan_unsubscribe_button' => "[wfan_unsubscribe_button label=__('Update my preference','wp-marketing-automations')]",
'bwfan_subscriber_recipient' => '[wfan_contact_email]',
'bwfan_subscriber_name' => '[wfan_contact_name]',
'bwfan_unsubscribe_email_label' => __( 'Unsubscribe', 'wp-marketing-automations' ),
'bwfan_unsubscribe_data_success' => __( 'Your subscription preference has been updated.', 'wp-marketing-automations' ),
'bwfan_email_service' => self::get_default_email_provider(),
'bwfan_sms_service' => self::get_default_sms_provider(),
'bwfan_shortener_service' => self::get_default_shortener_provider(),
'bwfan_whatsapp_service' => self::get_default_whatsapp_provider(),
'bwfan_sandbox_mode' => false,
'bwfan_make_logs' => 0,
'bwfan_ab_enable' => 0,
'bwfan_ab_exclude_users_cart_tracking' => 0,
'bwfan_ab_exclude_emails' => '',
'bwfan_ab_exclude_roles' => array(),
'bwfan_ab_init_wait_time' => 15,
'bwfan_disable_abandonment_days' => 15,
'bwfan_ab_email_consent' => 0,
'bwfan_ab_mark_lost_cart' => 15,
'bwfan_order_tracking_conversion' => 15,
'bwfan_ab_restore_cart_message_success' => '',
'bwfan_ab_restore_cart_message_failure' => __( 'Your cart could not be restored, it may have expired.', 'wp-marketing-automations' ),
// phpcs:ignore WordPress.WP.I18n.TextDomainMismatch, WordPress.WP.I18n.MissingTranslatorsComment
'bwfan_ab_email_consent_message' => sprintf( __( 'Your email and cart are saved so we can send you email reminders about this order. %s', 'wp-marketing-automations' ), '{{no_thanks label="' . __( 'No Thanks', 'wp-marketing-automations' ) . '"}}' ),
'bwfan_user_consent' => 0,
'bwfan_user_consent_message' => __( 'Keep me up to date on news and exclusive offers.', 'wp-marketing-automations' ),
'bwfan_user_consent_eu' => '1',
'bwfan_user_consent_non_eu' => '0',
'bwfan_delete_autonami_generated_coupons_time' => 1,
'bwfan_delete_engagement_tracking_meta' => 0,
'bwfan_user_consent_position' => 'below_term',
'bwfan_email_footer_setting' => '
{{business_name}}, {{business_address}} ' . __( 'Don\'t want to stay in the loop? We\'ll be sad to see you go, but you can click here to', 'wp-marketing-automations' ) . ' ' . __( 'unsubscribe', 'wp-marketing-automations' ) . '
',
'bwfan_sms_unsubscribe_text' => __( 'Reply STOP to unsubscribe', 'wp-marketing-automations' ),
'bwfan_bounce_select' => '',
'bwfan_unsubscribe_page' => '',
'bwfan_unsubscribe_from_all_label' => __( 'Unsubscribe from all Email Lists', 'wp-marketing-automations' ),
'bwfan_unsubscribe_from_all_description' => __( 'You will still receive important billing and transactional emails', 'wp-marketing-automations' ),
'after_confirmation_type' => 'show_message',
'bwfan_confirmation_message' => '' . __( 'Subscription Confirmed', 'wp-marketing-automations' ) . ' ' . __( 'Your subscription to our list has been confirmed.', 'wp-marketing-automations' ) . '
' . __( 'Thank you for subscribing!', 'wp-marketing-automations' ) . '
',
'bwfan_enable_notification' => 0,
'bwfan_contact_export_logging' => '',
'bwfan_contact_query_logging' => '',
'bwfan_webhook_received_logging' => '',
), $email_settings );
if ( self::is_whatsapp_services_enabled() ) {
$defaults['bwfan_whatsapp_gap_btw_message'] = 1;
$services = self::get_whatsapp_services();
if ( ! empty( $services ) ) {
$defaults['bwfan_primary_whats_app_service'] = [
[
'key' => $services[0]['value'],
'label' => $services[0]['label']
]
];
}
}
if ( true === apply_filters( 'bwfan_ab_delete_inactive_carts', false ) ) {
$defaults['bwfan_ab_remove_inactive_cart_time'] = 30;
}
return apply_filters( 'bwfan_default_global_settings', $defaults );
}
public static function get_global_email_settings( $global = [] ) {
$global_settings = array();
/** Email Settings */
if ( ! isset( $global['bwfan_email_from'] ) || empty( $global['bwfan_email_from'] ) ) {
if ( bwfan_is_woocommerce_active() ) {
$global_settings['bwfan_email_from'] = get_option( 'woocommerce_email_from_address' );
$global_settings['bwfan_email_from'] = sanitize_email( $global_settings['bwfan_email_from'] );
} else {
$global_settings['bwfan_email_from'] = sanitize_email( get_bloginfo( 'admin_email' ) );
}
} else {
$global_settings['bwfan_email_from'] = $global['bwfan_email_from'];
}
if ( ! isset( $global['bwfan_email_from_name'] ) || empty( $global['bwfan_email_from_name'] ) ) {
if ( bwfan_is_woocommerce_active() ) {
$global_settings['bwfan_email_from_name'] = get_option( 'woocommerce_email_from_name' );
$global_settings['bwfan_email_from_name'] = wp_specialchars_decode( esc_html( $global_settings['bwfan_email_from_name'] ), ENT_QUOTES );
} else {
$global_settings['bwfan_email_from_name'] = wp_specialchars_decode( esc_html( get_bloginfo( 'name' ) ), ENT_QUOTES );
}
} else {
$global_settings['bwfan_email_from_name'] = $global['bwfan_email_from_name'];
}
$global_settings['bwfan_email_reply_to'] = $global_settings['bwfan_email_from'];
$global_settings['bwfan_email_per_second_limit'] = 15;
$global_settings['bwfan_email_daily_limit'] = 10000;
return array(
'bwfan_email_from' => $global_settings['bwfan_email_from'],
'bwfan_email_from_name' => $global_settings['bwfan_email_from_name'],
'bwfan_email_reply_to' => $global_settings['bwfan_email_reply_to'],
'bwfan_email_per_second_limit' => $global_settings['bwfan_email_per_second_limit'],
'bwfan_email_daily_limit' => $global_settings['bwfan_email_daily_limit'],
);
}
/**
* fetching the default email provider
* @return false|mixed|string
*/
public static function get_default_email_provider() {
$default = apply_filters( 'bwfan_default_email_services', 'wp' );
$providers = self::get_email_services();
return self::get_provider_value( $providers, $default );
}
public static function get_email_services() {
$services = apply_filters( 'bwfan_email_services', array() );
return ! empty( $services ) ? $services : array();
}
/**
* fetching default sms provider
* @return false|mixed|string
*/
public static function get_default_sms_provider() {
$default = apply_filters( 'bwfan_default_sms_services', 'bwfco_twilio' );
$providers = self::get_sms_services();
return self::get_provider_value( $providers, $default );
}
public static function get_sms_services() {
$services = apply_filters( 'bwfan_sms_services', array() );
return ! empty( $services ) ? $services : array();
}
/**
* fetching default push notification provider
* @return false|mixed|string
*/
public static function get_default_push_provider() {
$default = apply_filters( 'bwfan_default_push_services', 'bwfco_pushengage' );
$providers = self::get_push_services();
return self::get_provider_value( $providers, $default );
}
public static function get_push_services() {
$services = apply_filters( 'bwfan_push_services', array() );
return ! empty( $services ) ? $services : array();
}
/**
* it fetches the default shortener provider
* @return int|string
*/
public static function get_default_shortener_provider() {
$default = apply_filters( 'bwfan_default_shortener_services', '' );
$providers = self::get_shortener_services();
return self::get_provider_value( $providers, $default );
}
/**
* it fetches the shortener services and also have the filter to add new shortener services
* @return array|void
*/
public static function get_shortener_services() {
$services = apply_filters( 'bwfan_shortener_services', array() );
return ! empty( $services ) ? $services : array();
}
/**
* fetching the default whatsapp service
*
* @return false|mixed|string
*/
public static function get_default_whatsapp_provider() {
$default = apply_filters( 'bwfan_default_whatsapp_services', '' );
$providers = self::get_whatsapp_services();
return self::get_provider_value( $providers, $default );
}
/**
* fetching all the whatsapp services available and active
*
* @return array|mixed|void
*/
public static function get_whatsapp_services() {
$services = apply_filters( 'bwfan_whatsapp_services', array() );
return ! empty( $services ) ? $services : array();
}
/**
* Check for whatsapp services
*
* @return bool
*/
public static function is_whatsapp_services_enabled() {
if ( ! bwfan_is_autonami_pro_active() || ! class_exists( 'WFCO_Autonami_Connectors_Core' ) || is_null( BWFCRM_Core()->conversation ) ) {
return false;
}
$services = self::get_whatsapp_services();;
if ( is_array( $services ) && count( $services ) > 0 ) {
return true;
}
return false;
}
public static function add_user_consent_after_terms_and_conditions( $return = false, $field_priority = '' ) {
$global_settings = self::get_global_settings();
$marketing_status = 0;
if ( empty( $global_settings['bwfan_user_consent'] ) ) {
$marketing_status = 1;
}
if ( empty( $marketing_status ) && is_user_logged_in() ) {
$user = wp_get_current_user();
$ins = WooFunnels_DB_Operations::get_instance();
$contact_row = $ins->get_contact_by_wpid( $user->ID );
if ( ! is_null( $contact_row ) && property_exists( $contact_row, 'status' ) ) {
$status = self::get_contact_status( $contact_row->status, $contact_row->email, $contact_row->contact_no );
/** Check contact's marketing status, email and sms status */
if ( 1 === absint( $status['status'] ) && 1 === absint( $status['email_status'] ) && 1 === absint( $status['sms_status'] ) ) {
$marketing_status = 1;
}
}
}
if ( 1 === $marketing_status ) {
if ( ! $return ) {
echo ' ';
return;
} else {
return ' ';
}
}
$country_code = self::maybe_get_user_country_code();
$tax_supported_countries = WC()->countries->get_european_union_countries();
$check = in_array( $country_code, $tax_supported_countries, true );
if ( true === $check ) {
/** EU country */
$checked = 'checked';
if ( empty( $global_settings['bwfan_user_consent_eu'] ) ) {
$checked = '';
}
} else {
/** Non EU country */
$checked = 'checked';
if ( empty( $global_settings['bwfan_user_consent_non_eu'] ) ) {
$checked = '';
}
}
$user_consent_message = self::get_user_consent_message_in_site_language( $global_settings );
if ( ! $return ) {
echo '';
echo '';
echo ' ';
echo wp_kses_post( $user_consent_message );
echo ' ';
echo '
';
} else {
$field_priority = ! empty( $field_priority ) ? 'data-priority="' . ( absint( $field_priority ) + 5 ) . '"' : '';
$return = '';
$return .= '';
$return .= ' ';
$return .= wp_kses_post( $user_consent_message );
$return .= ' ';
$return .= '
';
return $return;
}
}
/**
* getting checkout consent message in site language
*
* @param $global_settings
*
* @return mixed
*/
public static function get_user_consent_message_in_site_language( $global_settings ) {
$site_language = self::get_site_current_language();
$site_language = ! empty( $site_language ) ? $site_language : get_locale();
$message_index = 'bwfan_user_consent_message_' . $site_language;
return isset( $global_settings[ $message_index ] ) && ! empty( $global_settings[ $message_index ] ) ? $global_settings[ $message_index ] : $global_settings['bwfan_user_consent_message'];
}
public static function get_site_current_language() {
/** WPML */
if ( defined( 'ICL_SITEPRESS_VERSION' ) ) {
global $sitepress;
return $sitepress->get_current_language();
}
/** Polylang */
if ( function_exists( 'pll_the_languages' ) ) {
return pll_current_language( 'locale' );
}
/** TranslatePress **/
if ( bwfan_is_translatepress_active() ) {
global $TRP_LANGUAGE;
return $TRP_LANGUAGE;
}
/** Weglot */
if ( defined( 'BWFAN_VERSION' ) && version_compare( BWFAN_VERSION, '2.0.2', '>' ) && function_exists( 'bwfan_is_weglot_active' ) && bwfan_is_weglot_active() ) {
$request_url_service = weglot_get_request_url_service();
$lang_obj = $request_url_service->get_current_language();
$current_language = $lang_obj->getExternalCode();
$current_language = empty( $current_language ) ? $lang_obj->getInternalCode() : $current_language;
return $current_language;
}
}
/**
* may be get user country from woocommerce session
* @return array|mixed|string
*/
public static function maybe_get_user_country_code() {
if ( ! is_null( WC()->session ) ) {
$country_code = WC()->session->get( 'bwfan_user_checkout_country', '' );
if ( ! empty( $country_code ) ) {
return $country_code;
}
$country_code = self::get_user_country();
WC()->session->set( 'bwfan_user_checkout_country', $country_code );
return $country_code;
}
$country_code = self::get_user_country();
return $country_code;
}
/** get user country
* @return mixed
*/
public static function get_user_country() {
$user_location = WC_Geolocation::geolocate_ip();
$country_code = $user_location['country'];
return $country_code;
}
/**
* Restrict product link display for product layouts in emails
*
* @return mixed|void
*/
public static function disable_product_link() {
return apply_filters( 'bwfan_disable_product_link', false );
}
/**
* Restrict thumbnails display for product layouts in emails
*
* @return mixed|void
*/
public static function disable_product_thumbnail() {
return apply_filters( 'bwfan_disable_product_thumbnail', false );
}
/**
* @param DateTime $datetime
*/
public static function convert_to_gmt( $datetime ) {
$datetime->modify( '-' . self::get_timezone_offset() * HOUR_IN_SECONDS . ' seconds' );
}
public static function get_timezone_offset() {
$timezone = get_option( 'timezone_string' );
if ( $timezone ) {
$timezone_object = new DateTimeZone( $timezone );
return $timezone_object->getOffset( new DateTime( 'now' ) ) / HOUR_IN_SECONDS;
} else {
return floatval( get_option( 'gmt_offset', 0 ) );
}
}
public static function convert_to_site_time( $date ) {
return self::convert_from_gmt( $date );
}
/**
* @param $datetime DateTime
*
* @return mixed
*/
public static function convert_from_gmt( $datetime ) {
return $datetime->modify( '+' . self::get_timezone_offset() * HOUR_IN_SECONDS . ' seconds' );
}
/**
* @param $screen_type
*
* @return bool
*/
public static function is_load_admin_assets( $screen_type = 'single' ) {
$page = filter_input( INPUT_GET, 'page' );
if ( empty( $page ) ) {
return false;
}
if ( 'all' === $screen_type ) {
$is_autonami = ( false !== strpos( $page, 'autonami' ) );
if ( $page === 'autonami' || $is_autonami ) {
return true;
}
} elseif ( 'builder' === $screen_type ) {
if ( $page === 'autonami-automations' && filter_input( INPUT_GET, 'edit' ) > 0 ) {
return true;
}
} elseif ( 'all' === $screen_type || 'builder' === $screen_type ) {
if ( $page === 'autonami-automations' && filter_input( INPUT_GET, 'edit' ) > 0 ) {
return true;
}
} elseif ( 'all' === $screen_type || 'settings' === $screen_type ) {
if ( $page === 'autonami-settings' || false !== strpos( filter_input( INPUT_GET, 'path' ), 'settings' ) ) {
return true;
}
} elseif ( 'automation' === $screen_type ) {
if ( $page === 'autonami-automations' && filter_input( INPUT_GET, 'edit' ) > 0 ) {
return true;
}
} elseif ( 'recipe' === $screen_type ) {
if ( $page === 'autonami-automations' && filter_input( INPUT_GET, 'tab' ) === 'recipe' ) {
return true;
}
}
$screen = get_current_screen();
return apply_filters( 'bwfan_enqueue_scripts', false, $screen_type, $screen );
}
public static function array_flatten( $array ) {
if ( ! is_array( $array ) ) {
return false;
}
$result = iterator_to_array( new RecursiveIteratorIterator( new RecursiveArrayIterator( $array ) ), false );
return $result;
}
public static function pr( $arr ) {
echo '';
print_r( $arr ); //phpcs:ignore WordPress.PHP.DevelopmentFunctions
echo ' ';
}
public static function pc( $val1, $val2 = '' ) {
if ( ! class_exists( 'pc' ) ) {
return;
}
pc::debug( $val1, $val2 ); //phpcs:ignore WordPress.PHP.DevelopmentFunctions
}
/**
* Slug-ify the class name and remove underscores and convert it to filename
* Helper function for the auto-loading
*
* @param $class_name
*
* @return mixed|string
* @see BWFAN_Gateways::integration_autoload();
*/
public static function slugify_classname( $class_name ) {
$classname = sanitize_title( $class_name );
$classname = str_replace( '_', '-', $classname );
return $classname;
}
public static function maybe_convert_html_tag( $val ) {
if ( false === is_string( $val ) ) {
return $val;
}
$val = str_replace( '<', '<', $val );
$val = str_replace( '>', '>', $val );
return $val;
}
public static function string2hex( $string ) {
$hex = '';
for ( $i = 0; $i < strlen( $string ); $i ++ ) {
$hex .= dechex( ord( $string[ $i ] ) );
}
return $hex;
}
/**
* Return sidebar options on single automation screen.
*
* @return mixed|void
*/
public static function get_sidebar_menu() {
$sidebar_menu = array(
'20' => array(
'icon' => 'dashicons dashicons-networking',
'name' => __( 'Automation', 'wp-marketing-automations' ),
'key' => 'automation',
),
'50' => array(
'icon' => 'dashicons dashicons-admin-tools',
'name' => __( 'Tools', 'wp-marketing-automations' ),
'key' => 'tools',
),
);
return apply_filters( 'bwfan_builder_menu', $sidebar_menu );
}
/**
* Checks if the current page is autonami page or not.
*
* @return bool
*/
public static function is_autonami_page() {
if ( isset( $_GET['page'] ) && 'autonami-automations' === sanitize_text_field( $_GET['page'] ) ) { //phpcs:ignore WordPress.Security.NonceVerification
return true;
}
return false;
}
/**
* Remove autonami events on plugin deactivation.
*/
public static function deactivation() {
if ( bwf_has_action_scheduled( 'bwfan_run_queue' ) ) {
bwf_unschedule_actions( 'bwfan_run_queue' );
}
if ( bwf_has_action_scheduled( 'bwfan_check_abandoned_carts' ) ) {
bwf_unschedule_actions( 'bwfan_check_abandoned_carts' );
}
if ( bwf_has_action_scheduled( 'bwfan_delete_expired_autonami_coupons' ) ) {
bwf_unschedule_actions( 'bwfan_delete_expired_autonami_coupons' );
}
if ( bwf_has_action_scheduled( 'bwfan_mark_abandoned_lost_cart' ) ) {
bwf_unschedule_actions( 'bwfan_mark_abandoned_lost_cart' );
}
if ( bwf_has_action_scheduled( 'bwfan_delete_old_abandoned_carts' ) ) {
bwf_unschedule_actions( 'bwfan_delete_old_abandoned_carts' );
}
}
/**
* Send a remote call.
*
* @param $api_url
* @param $data
* @param string $method_type
*
* @return array|mixed|object|string|null
*/
public static function send_remote_call( $api_url, $data, $method_type = 'post' ) {
if ( 'get' === $method_type ) {
$httpPostRequest = self::http()->get( $api_url, array(
'body' => $data,
'sslverify' => false,
'timeout' => 30,
) );
} else {
$httpPostRequest = self::http()->post( $api_url, array(
'body' => $data,
'sslverify' => false,
'timeout' => 30,
) );
}
if ( isset( $httpPostRequest->errors ) ) {
$response = null;
} elseif ( isset( $httpPostRequest['body'] ) && '' !== $httpPostRequest['body'] ) {
$body = $httpPostRequest['body'];
$response = json_decode( $body, true );
} else {
$response = 'No result';
}
return $response;
}
public static function http() {
if ( null === self::$http ) {
self::$http = new WP_Http();
}
return self::$http;
}
/**
* Return all the merge tags from a string.
*
* @param $text
*
* @return array|null
*/
public static function get_merge_tags_from_text( $text ) {
$merge_tags = null;
$more_merge_tags = null;
if ( ! is_array( $text ) ) {
preg_match_all( '/\{{(.*?)\}}/', $text, $more_merge_tags );
}
if ( is_array( $more_merge_tags[1] ) && count( $more_merge_tags[1] ) > 0 ) {
$merge_tags = $more_merge_tags[1];
}
return $merge_tags;
}
/**
* Return the merge tags which will behave as array.
*
* @param $merge_tags
* @param $integration_merge_tags
* @param $action_data
*
* @return array
*/
public static function initial_parse_merge_tags( $merge_tags, $integration_merge_tags, $action_data ) {
$dynamic_array = array();
if ( ! is_array( $action_data ) || count( $action_data ) === 0 ) {
return $dynamic_array;
}
foreach ( $action_data as $key1 => $value1 ) {
if ( ! is_array( $value1 ) || count( $value1 ) === 0 ) {
$dynamic_array[ $key1 ] = $value1;
continue;
}
foreach ( $value1 as $key2 => $value2 ) {
if ( ! in_array( $key2, $merge_tags, true ) || ( ! is_array( $integration_merge_tags ) || ! in_array( $key2, $integration_merge_tags, true ) ) ) {
$dynamic_array[ $key2 ] = $value2;
continue;
}
if ( isset( $dynamic_array[ $key2 ] ) ) {
array_push( $dynamic_array[ $key2 ], $value2 );
} else {
$dynamic_array[ $key2 ] = array( $value2 );
}
}
}
return $dynamic_array;
}
public static function filter_tasks( $all_tasks, $all_tasks_meta ) {
$result = array();
foreach ( $all_tasks_meta as $value1 ) {
if ( isset( $value1['bwfan_task_id'] ) ) {
$id = $value1['bwfan_task_id'];
} elseif ( isset( $value1['bwfan_log_id'] ) ) {
$id = $value1['bwfan_log_id'];
}
if ( isset( $all_tasks[ $id ] ) ) {
$result['all_tasks'][ $id ] = array(
$all_tasks[ $id ]['integration_slug'] => $all_tasks[ $id ]['integration_action'],
);
if ( 'integration_data' === $value1['meta_key'] ) {
$meta = maybe_unserialize( $value1['meta_value'] );
$meta['automation_id'] = $all_tasks[ $id ]['automation_id'];
$result['all_tasks_meta'][ $id ] = $meta;
}
$result['all_tasks_status'][ $id ] = $all_tasks[ $id ]['status'];
$result['all_tasks_automation_id'][ $id ] = $all_tasks[ $id ]['automation_id'];
$result['all_tasks_attempts'][ $id ] = $all_tasks[ $id ]['attempts'];
}
}
return $result;
}
/**
* Remove backslashes from $_POST content of the automation.
*
* @param $posted_data
*
* @return array
*/
public static function remove_back_slash_from_automation( $posted_data ) {
if ( ! is_array( $posted_data ) || count( $posted_data ) === 0 ) {
return $posted_data;
}
foreach ( $posted_data as $key1 => $value1 ) {
if ( isset( $value1['ajax_data'] ) ) {
$posted_data[ $key1 ]['ajax_data'] = self::remove_backslashes( $value1['ajax_data'] );
}
if ( isset( $value1['data']['field_value'] ) && ! is_array( $value1['data']['field_value'] ) ) {
$posted_data[ $key1 ]['data']['field_value'] = self::remove_newlines( self::remove_backslashes( $value1['data']['field_value'] ) );
}
}
return $posted_data;
}
public static function remove_backslashes( $string ) {
return preg_replace( '/\\\\/', '', $string );
}
public static function remove_newlines( $string ) {
return trim( preg_replace( '/\s+/', ' ', $string ) );
}
/**
* Get all the merge tags of all the events.
*
* @param $all_sources
*
* @return array
*/
public static function get_all_events_merge_tags() {
$all_events_merge_tags = array();
$merge_tags = BWFAN_Core()->merge_tags->get_localize_tags_with_source();
$source_events = BWFAN_Core()->sources->get_events();
$merge_tags = self::get_v1_supported_mergetag( $merge_tags );
/**
* @var $event_object BWFAN_Event
*/
foreach ( $source_events as $event_key => $event_object ) {
$event_merge_tags = $event_object->get_merge_tag_groups();
if ( empty( $event_merge_tags ) ) {
continue;
}
$curr_event_merge_tags = array();
foreach ( $event_merge_tags as $head ) {
if ( ! isset( $merge_tags[ $head ] ) ) {
continue;
}
$curr_event_merge_tags[ $head ] = $merge_tags[ $head ];
}
$all_events_merge_tags[ $event_key ] = apply_filters( 'bwfan_default_merge_tags', $curr_event_merge_tags );
}
return $all_events_merge_tags;
}
/** get the supported v1 merge tag */
public static function get_v1_supported_mergetag( $all_merge_tags ) {
if ( empty( $all_merge_tags ) ) {
return $all_merge_tags;
}
/** Filter v1 merge tags */
foreach ( $all_merge_tags as $mergeGroup => $mergeTagList ) {
if ( empty( $mergeTagList ) ) {
continue;
}
$final_Arr = [];
foreach ( $mergeTagList as $mergeTagKey => $mergeTagData ) {
/** check if the merge tag not support v1 */
if ( isset( $mergeTagData['support_v1'] ) && empty( $mergeTagData['support_v1'] ) ) {
unset( $all_merge_tags[ $mergeGroup ][ $mergeTagKey ] );
continue;
}
$final_Arr[ $mergeTagKey ] = $mergeTagData;
}
if ( ! empty( $final_Arr ) ) {
$all_merge_tags[ $mergeGroup ] = $final_Arr;
}
}
return $all_merge_tags;
}
/**
* @param $all_sources
*
* @return array
*/
public static function get_all_events_rules() {
if ( ! bwfan_is_autonami_pro_active() ) {
return [];
}
$all_rules_groups = array();
$events = BWFAN_Core()->sources->get_events();
if ( empty( $events ) ) {
return $all_rules_groups;
}
/** Null check */
if ( ! is_object( BWFAN_Core()->rules ) || ! method_exists( BWFAN_Core()->rules, 'get_default_rule_groups' ) ) {
return $all_rules_groups;
}
/**
* @var $event BWFAN_Event
*/
foreach ( $events as $slug => $event ) {
$all_rules_groups[ $slug ] = array_merge( $event->get_rule_group(), BWFAN_Core()->rules->get_default_rule_groups() );
}
return $all_rules_groups;
}
public static function sort_automations( $all_automations ) {
$all_automations_temp = array();
$nice_names = array();
if ( is_array( $all_automations ) && count( $all_automations ) > 0 ) {
foreach ( $all_automations as $int_slug => $int_obj ) {
$nice_names[] = $int_obj->get_name();
}
asort( $nice_names );
foreach ( $nice_names as $int_nice_name ) {
foreach ( $all_automations as $int_slug => $int_obj ) {
if ( $int_nice_name === $int_obj->get_name() ) {
$all_automations_temp[ $int_slug ] = $int_obj;
}
}
}
$all_automations = $all_automations_temp;
}
return $all_automations;
}
/**
* Save integration data for a connector.
*
* @param $data
* @param $slug
* @param $status
*
* @return int
*/
public static function save_integration_data( $data, $slug, $status ) {
$new_task_data = array();
$new_task_data['last_sync'] = current_time( 'timestamp', 1 );
$new_task_data['integration_slug'] = $slug;
$new_task_data['api_data'] = maybe_serialize( $data );
$new_task_data['status'] = $status;
BWFAN_Model_Settings::insert( $new_task_data );
return BWFAN_Model_Settings::insert_id();
}
/**
* Update integration data for a connector.
*
* @param $data
* @param $id
*/
public static function update_integration_data( $data, $id ) {
$meta_data = array();
$meta_data['api_data'] = maybe_serialize( $data );
$meta_data['last_sync'] = current_time( 'timestamp', 1 );
$where = array(
'ID' => $id,
);
BWFAN_Model_Settings::update( $meta_data, $where );
}
public static function get_parsed_time( $wp_date_format, $logs ) {
$logs_temp = array();
$logs_temp[ date( 'Y-m-d H:i:s' ) ] = __( 'Error in generating logs', 'wp-marketing-automations' ); // phpcs:ignore WordPress.DateTime.RestrictedFunctions
if ( ! is_array( $logs ) || count( $logs ) === 0 ) {
return array_reverse( $logs_temp, true );
}
$logs_temp = array();
foreach ( $logs as $timestamp => $message ) {
$time = get_date_from_gmt( date( 'Y-m-d H:i:s', $timestamp ), $wp_date_format ); // phpcs:ignore WordPress.DateTime.RestrictedFunctions
if ( empty( $message ) ) {
$message = __( 'No response from API', 'wp-marketing-automations' );
} else {
$message = str_replace( "'", '', $message );
}
$logs_temp[ $time ] = $message;
}
return array_reverse( $logs_temp, true );
}
public static function string( $string ) {
return sanitize_text_field( $string );
}
public static function add_default_merge_tags( $event_merge_tags ) {
$default_merge_tags = self::get_default_merge_tags( false );
foreach ( $default_merge_tags as $merge_tag => $details ) {
$event_merge_tags[ $merge_tag ] = $details[0];
}
return $event_merge_tags;
}
public static function get_default_merge_tags( $load_values ) {
$current_date = null;
$current_time = null;
$current_date_time = null;
if ( $load_values ) {
$cdt = self::$date_format . ' ' . self::$time_format;
$ct = self::$time_format;
$cd = self::$date_format;
$current_date_time = get_date_from_gmt( date( 'Y-m-d H:i:s' ), $cdt ); // phpcs:ignore WordPress.DateTime.RestrictedFunctions
$current_time = get_date_from_gmt( date( 'H:i:s' ), $ct ); // phpcs:ignore WordPress.DateTime.RestrictedFunctions
$current_date = get_date_from_gmt( date( 'Y-m-d' ), $cd ); // phpcs:ignore WordPress.DateTime.RestrictedFunctions
}
$default_merge_tags = array(
'admin_email' => array( __( 'Admin email', 'wp-marketing-automations' ), self::$admin_email ),
'current_date' => array( __( 'Current date when task will be executed', 'wp-marketing-automations' ), $current_date ),
'current_time' => array( __( 'Current time when task will be executed', 'wp-marketing-automations' ), $current_time ),
'current_date_time' => array( __( 'Current date and time when task will be executed', 'wp-marketing-automations' ), $current_date_time ),
);
return apply_filters( 'bwfan_modify_default_merge_tags', $default_merge_tags );
}
public static function parse_default_merge_tags( $data, $recursive = false ) {
if ( ! is_array( $data ) || count( $data ) === 0 ) {
return $data;
}
$default_merge_tags_values = self::get_default_merge_tags( true );
/** *
* This function only decode two level array
*/
foreach ( $default_merge_tags_values as $merge_tag => $details ) {
foreach ( $data as $key1 => $value1 ) {
if ( in_array( gettype( $value1 ), array( 'int', 'boolean' ), true ) ) {
continue;
}
if ( is_array( $value1 ) ) {
if ( empty( $value1 ) ) {
continue;
}
foreach ( $value1 as $key2 => $value2 ) {
if ( is_array( $value2 ) ) {
$data[ $key1 ][ $key2 ] = $value2;
} else {
if ( false !== strpos( $value2, '{{' . $merge_tag . '}}' ) ) {
$data[ $key1 ][ $key2 ] = str_replace( '{{' . $merge_tag . '}}', $details[1], $value2 );
}
}
}
} else {
if ( is_object( $value1 ) ) { // ignore if the value is object type in case of leandash events
continue;
}
if ( $value1 && false !== strpos( $value1, '{{' . $merge_tag . '}}' ) ) {
$data[ $key1 ] = str_replace( '{{' . $merge_tag . '}}', $details[1], $value1 );
continue;
}
}
}
}
return $data;
}
public static function filter_actions_conditions( $selected_actions, $automation_details ) {
$automation_actions = $automation_details['actions'];
$automation_conditions = ( isset( $automation_details['condition'] ) ) ? $automation_details['condition'] : array();
$temp_actions = array();
$temp_conditions = array();
foreach ( $selected_actions as $single_indexes ) {
$single_ind = explode( '_', $single_indexes );
$group_id = $single_ind[0];
$child_id = $single_ind[1];
$temp_actions[ $group_id ][ $child_id ] = $automation_actions[ $group_id ][ $child_id ];
}
if ( is_array( $automation_conditions ) && count( $automation_conditions ) > 0 ) {
foreach ( $temp_actions as $group_id => $actions ) {
/** Checking if group id not present in the condition */
if ( ! isset( $automation_conditions[ $group_id ] ) ) {
continue;
}
/** Checking if actions empty */
if ( ! is_array( $actions ) || 0 === count( $actions ) ) {
continue;
}
/** Checking if action id condition not exist */
foreach ( $actions as $action_id => $action_data ) {
if ( ! isset( $automation_conditions[ $group_id ][ $action_id ] ) ) {
continue;
}
if ( ! is_array( $action_data ) ) {
continue;
}
$temp_conditions[ $group_id ][ $action_id ] = $action_data;
}
}
}
$automation_details['actions'] = $temp_actions;
$automation_details['condition'] = $temp_conditions;
return $automation_details;
}
/**
*
* Check for the user order count , if not found in the usermeta then fires wpdb query
*
* @param int $user_id
*
* @return int
* @since 2.7.1
*/
public static function get_customer_order_count( $user_id, $force = false ) {
global $wpdb;
$order_count = implode( "','", wc_get_order_types( 'order-count' ) );
$trashed_statuses = implode( "','", self::get_order_trashed_statuses() );
if ( BWF_WC_Compatibility::is_hpos_enabled() ) {
$query = $wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->prefix}wc_orders as orders LEFT JOIN {$wpdb->prefix}wc_orders_meta AS meta ON orders.id = meta.order_id WHERE meta.meta_key= '_customer_user' AND orders.type IN (%s) AND orders.status NOT IN (%s) AND meta.meta_value= %d", $order_count, $trashed_statuses, $user_id );
$count = $wpdb->get_var( $query ); //phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL
return empty( $wpdb->last_error ) && ! empty( $count ) ? intval( $count ) : 0;
}
$query = $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->posts as posts LEFT JOIN {$wpdb->postmeta} AS meta ON posts.ID = meta.post_id WHERE meta.meta_key= '_customer_user' AND posts.post_type IN (%s) AND posts.post_status NOT IN (%s) AND meta.meta_value= %d", $order_count, $trashed_statuses, $user_id );
$count = $wpdb->get_var( $query ); //phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL
if ( ! empty( $wpdb->last_error ) ) {
return 0;
}
return intval( $count );
}
public static function get_order_trashed_statuses() {
return apply_filters( 'bwfan_get_order_trashed_statuses', array( 'wc-cancelled', 'wc-refunded', 'wc-failed', 'trash', 'draft' ) );
}
public static function get_funnel_data( $funnel_id ) {
$data = array();
$data['funnel_id'] = $funnel_id;
$funnel_details = get_post( $funnel_id );
$data['funnel_name'] = $funnel_details->post_title;
return $data;
}
public static function get_offer_data( $offer_id ) {
$data = array();
$data['offer_id'] = $offer_id;
$offer_details = get_post( $offer_id );
$data['offer_name'] = $offer_details->post_title;
$data['offer_type'] = get_post_meta( $offer_id, '_offer_type', true );
return $data;
}
/**
* Return subscription products by searched term.
*
* @param $searched_term
*
* @return array
* @throws Exception
*/
public static function get_subscription_product( $searched_term ) {
$subscription_products = array();
$results = array();
$term = $searched_term;
$include_variations = true;
$data_store = WC_Data_Store::load( 'product' );
$ids = $data_store->search_products( $term, '', (bool) $include_variations );
$product_objects = array_filter( array_map( 'wc_get_product', $ids ), 'wc_products_array_filter_readable' );
foreach ( $product_objects as $product_object ) {
if ( WC_Subscriptions_Product::is_subscription( $product_object ) ) {
$results[] = array(
'id' => $product_object->get_id(),
'text' => rawurldecode( $product_object->get_formatted_name() ),
);
}
}
$subscription_products['results'] = $results;
return $subscription_products;
}
/**
* Get membership plans by searched term.
*
* @param $searched_term
*
* @return array
*/
public static function get_membership_plans( $searched_term ) {
$membership_plans = array();
$results = array();
$query_params = array(
'post_type' => 'wc_membership_plan',
'posts_per_page' => - 1,
);
if ( '' !== $searched_term ) {
$query_params['s'] = $searched_term;
}
$query = new WP_Query( $query_params );
if ( $query->found_posts > 0 ) {
foreach ( $query->posts as $post ) {
$results[] = array(
'id' => $post->ID,
'text' => $post->post_title,
);
}
}
$membership_plans['results'] = $results;
return $membership_plans;
}
/**
* Get membership names by membership ids.
*
* @param $membership_plans
*
* @return array
*/
public static function get_membership_pre_data( $membership_plans ) {
$plans = array();
if ( is_array( $membership_plans ) && count( $membership_plans ) > 0 ) {
foreach ( $membership_plans as $id ) {
$plan_name = get_the_title( $id );
$plans[ $id ] = $plan_name;
}
}
return $plans;
}
/**
* Get subscription names by subscription ids.
*
* @param $subscription_products
*
* @return array
*/
public static function get_subscription_pre_data( $subscription_products ) {
$products = array();
if ( is_array( $subscription_products ) && count( $subscription_products ) > 0 ) {
foreach ( $subscription_products as $id ) {
$product = wc_get_product( $id );
$product_name = $product->get_formatted_name();
$products[ $id ] = $product_name;
}
}
return $products;
}
public static function delete_order_meta( $order_id ) {
$order = wc_get_order( $order_id );
if ( ! $order instanceof WC_Order ) {
return;
}
$order->delete_meta_data( '_bwfan_poid' );
$order->delete_meta_data( '_bwfan_package' );
$order->delete_meta_data( '_bwfan_fun_id' );
$order->save();
}
public static function get_sorted_automations( $rows ) {
$result = array();
if ( is_array( $rows ) && count( $rows ) > 0 ) {
foreach ( $rows as $value1 ) {
$result[ $value1['ID'] ] = $value1;
}
}
return $result;
}
public static function get_callable_object( $is_empty, $data ) {
if ( in_array( 'get_' . $data['type'], self::$select2ajax_functions, true ) ) {
return array( __CLASS__, 'get_' . $data['type'] );
} else {
return $is_empty;
}
}
public static function get_product_image( $product, $size = 'shop_catalog', $only_url = false, $img_width = '' ) {
$image_id = $product->get_image_id();
$image_url = '';
if ( ! empty( $image_id ) ) {
$image_url = wp_get_attachment_image_url( $image_id, $size );
}
if ( empty( $image_url ) && function_exists( 'wc_placeholder_img_src' ) ) {
$image_url = wc_placeholder_img_src( $size );
}
/** Correcting the image URL if not an http link **/
if ( 'http' !== substr( $image_url, 0, 4 ) ) {
$image_url = site_url( $image_url );
}
if ( $only_url ) {
$image = $image_url;
} else {
$style = ! empty( $img_width ) ? "width='{$img_width}'" : '';
$image = ' ';
}
return $image;
}
/**
* @param $product WC_Product
*
* @return mixed
*/
public static function get_name( $product ) {
return $product->get_name();
}
/**
* @param $order WC_Order
*
* @return array
*/
public static function get_order_cross_sells( $order ) {
$cross_sells = array();
$in_order = array();
$items = $order->get_items();
foreach ( $items as $item ) {
$product = $item->get_product();
$in_order[] = self::is_variation( $product ) ? $product->get_parent_id() : $product->get_id();
$cross_sells = array_merge( $product->get_cross_sell_ids(), $cross_sells );
}
return array_diff( $cross_sells, $in_order );
}
public static function is_variation( $product ) {
return $product->is_type( array( 'variation', 'subscription_variation' ) );
}
/**
* @param $name
*
* @return mixed
*/
public static function get_cookie( $name ) {
return isset( $_COOKIE[ $name ] ) ? sanitize_text_field( $_COOKIE[ $name ] ) : false;
}
/**
* Clear a cookie.
*
* @param $name
*/
public static function clear_cookie( $name ) {
if ( isset( $_COOKIE[ $name ] ) ) {
self::set_cookie( $name, '', time() - HOUR_IN_SECONDS );
}
}
/**
* Set a cookie - wrapper for setcookie using WP constants.
*
* @param string $name Name of the cookie being set.
* @param string $value Value of the cookie.
* @param integer $expire Expiry of the cookie.
* @param bool $secure Whether the cookie should be served only over https.
* @param bool $httponly Whether the cookie is only accessible over HTTP, not scripting languages like JavaScript. @since 3.6.0.
*/
public static function set_cookie( $name, $value, $expire = 0, $secure = false, $httponly = false ) {
if ( self::is_cli() || self::is_cron() || self::is_rest() ) {
return;
}
if ( headers_sent() ) {
return;
}
setcookie( $name, $value, $expire, COOKIEPATH ? COOKIEPATH : '/', COOKIE_DOMAIN, $secure, apply_filters( 'bwfan_cookie_httponly', $httponly, $name, $value, $expire, $secure ) ); //phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.cookies_setcookie
}
/**
* Checks whether the current request is a WP CLI request
*
* @return bool
*/
public static function is_cli() {
if ( defined( 'WP_CLI' ) && WP_CLI ) {
return true;
}
return false;
}
/**
* Checks whether the current request is a WP cron request
*
* @return bool
*/
public static function is_cron() {
if ( defined( 'DOING_CRON' ) && true === DOING_CRON ) {
return true;
}
return false;
}
/**
* Checks whether the current request is a WP rest request
*
* @return bool
*/
public static function is_rest() {
if ( defined( 'REST_REQUEST' ) && true === REST_REQUEST ) {
return true;
}
return false;
}
public static function get_line_subtotal( $item ) {
return isset( $item['line_subtotal'] ) ? floatval( $item['line_subtotal'] ) : 0;
}
/**
* @return float
*/
public static function get_line_subtotal_tax( $item ) {
return isset( $item['line_subtotal_tax'] ) ? floatval( $item['line_subtotal_tax'] ) : 0;
}
public static function get_quantity( $item ) {
return isset( $item['quantity'] ) ? absint( $item['quantity'] ) : 0;
}
public static function price( $price, $currency = '' ) {
$args = array( 'currency' => $currency );
return wc_price( $price, $args );
}
/**
* Get those coupons which are user made only.
*
* @param $searched_term
*
* @return array
*/
public static function get_coupon( $searched_term ) {
$membership_plans = array();
$results = array();
$query_params = array(
'post_type' => 'shop_coupon',
'posts_per_page' => - 1,
'post_status' => 'publish',
'meta_query' => array(
array(
'key' => '_is_bwfan_coupon',
'compare' => 'NOT EXISTS',
),
),
);
if ( '' !== $searched_term ) {
$query_params['s'] = $searched_term;
}
$query = new WP_Query( $query_params );
if ( $query->found_posts > 0 ) {
foreach ( $query->posts as $post ) {
$results[] = array(
'id' => $post->ID,
'text' => $post->post_title,
);
}
}
$membership_plans['results'] = $results;
return $membership_plans;
}
public static function validate_action_date_before_save( $all_actions ) {
if ( ! is_array( $all_actions ) || 0 === count( $all_actions ) ) {
return false;
}
$modified_actions = $all_actions;
foreach ( $all_actions as $row_index => $row_actions ) {
if ( null === $row_actions ) {
continue;
}
if ( ! is_array( $row_actions ) || 0 === count( $row_actions ) ) {
$modified_actions[ $row_index ] = array();
continue;
}
foreach ( $row_actions as $action_index => $action_details ) {
if ( isset( $action_details['temp_action_slug'] ) && ! empty( $action_details['temp_action_slug'] ) ) {
$modified_actions[ $row_index ][ $action_index ]['temp_action_slug'] = '';
}
}
}
return $modified_actions;
}
/**
* Sort actions when automation is saved.
*
* @param $all_actions
*
* @return array
*/
public static function sort_actions( $all_actions ) {
if ( ! is_array( $all_actions ) || 0 === count( $all_actions ) ) {
return $all_actions;
}
foreach ( $all_actions as $row_index => $row_actions ) {
if ( null === $row_actions && ! is_array( $row_actions ) || 0 === count( $row_actions ) ) {
unset( $all_actions[ $row_index ] );
continue;
}
foreach ( $row_actions as $action_index => $action_details ) {
if ( ! is_array( $action_details ) || 0 === count( $action_details ) ) {
unset( $all_actions[ $row_index ][ $action_index ] );
}
}
}
return $all_actions;
}
/**
* Attach default merge tags to every event.
*
* @param $all_events_merge_tags
* @param $all_merge_tags
*
* @return array
*/
public static function attach_default_merge_to_events( $all_events_merge_tags, $all_merge_tags ) {
if ( ! is_array( $all_events_merge_tags ) || 0 === count( $all_events_merge_tags ) ) {
return $all_events_merge_tags;
}
foreach ( $all_events_merge_tags as $event_slug => $groups ) {
if ( ! is_array( $groups ) || 0 === count( $groups ) ) {
continue;
}
$all_events_merge_tags[ $event_slug ]['bwfan_default'] = $all_merge_tags['bwfan_default'];
}
return $all_events_merge_tags;
}
/**
* Get wc products by searched term.
*
* @param bool $term
* @param bool $include_variations
* @param bool $return
*
* @return mixed|void
*/
public static function product_search( $term = false, $include_variations = false, $return = false ) {
self::check_nonce();
if ( empty( $term ) ) {
if ( isset( $_POST['term'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
$term = stripslashes( sanitize_text_field( $_POST['term'] ) ); // phpcs:ignore WordPress.Security.NonceVerification
}
}
// if ( empty( $term ) ) {
// wp_die();
// }
$variations = true;
if ( true !== $include_variations ) {
$variations = false;
}
$ids = self::search_products( $term, $variations );
/**
* Products types that are allowed in the offers
*/
$product_objects = array_filter( array_map( 'wc_get_product', $ids ), 'wc_products_array_filter_editable' );
$products = array();
foreach ( $product_objects as $product_object ) {
if ( 'pending' === $product_object->get_status() ) {
continue;
}
$products[] = array(
'id' => $product_object->get_id(),
'text' => rawurldecode( self::get_formatted_product_name( $product_object ) ),
);
}
$data = apply_filters( 'bwfan_woocommerce_json_search_found_products', $products );
if ( true === $return ) {
return $data;
}
wp_send_json( $data );
}
/**
* Check nonce.
*/
public static function check_nonce() {
$nonce = ( isset( $_REQUEST['_wpnonce'] ) ) ? sanitize_text_field( $_REQUEST['_wpnonce'] ) : ''; //phpcs:ignore WordPress.Security.NonceVerification
$bwf_nonce = ( isset( $_REQUEST['bwf_nonce'] ) ) ? sanitize_text_field( $_REQUEST['bwf_nonce'] ) : '';//phpcs:ignore WordPress.Security.NonceVerification
if ( wp_verify_nonce( $bwf_nonce, 'bwf_secure_key' ) || wp_verify_nonce( $nonce, 'bwfan-action-admin' ) ) {
return;
}
/** check if current user has the permission or not */
$default_permissions = array( 'manage_options' );
$permissions = method_exists( 'BWFAN_Common', 'access_capabilities' ) ? BWFAN_Common::access_capabilities() : $default_permissions;
foreach ( $permissions as $permission ) {
if ( current_user_can( $permission ) ) {
return;
}
}
// This nonce is not valid.
$resp = array(
'msg' => __( 'Invalid request, security validation failed.', 'wp-marketing-automations' ),
'status' => false,
);
wp_send_json( $resp );
}
/**
* Get wc products by searched term.
*
* @param $term
* @param bool $include_variations
*
* @return array
*/
public static function search_products( $term, $include_variations = false, $limit = 10, $offset = 0 ) {
self::check_nonce();
global $wpdb;
$like_term = '%' . $wpdb->esc_like( $term ) . '%';
$post_statuses = current_user_can( 'edit_private_products' ) ? array(
'private',
'publish',
'draft',
) : array( 'publish', 'draft' );
$product_type = [ 'product' ];
if ( true === $include_variations ) {
$product_type[] = 'product_variation';
}
$query = $wpdb->prepare( "SELECT DISTINCT posts.ID FROM {$wpdb->posts} AS posts LEFT JOIN {$wpdb->wc_product_meta_lookup} AS wc_product_meta_lookup ON posts.ID = wc_product_meta_lookup.product_id WHERE (posts.post_title LIKE %s OR wc_product_meta_lookup.sku LIKE %s OR posts.ID LIKE %s) AND posts.post_status IN ('" . implode( "','", $post_statuses ) . "') AND posts.post_type IN ('" . implode( "','", $product_type ) . "') ORDER BY posts.post_parent ASC, posts.post_title ASC", $like_term, $like_term, $like_term ); //phpcs:ignore WordPress.DB.PreparedSQL,WordPress.DB.PreparedSQLPlaceholders
if ( ! empty( $limit ) ) {
$query .= " LIMIT %d, %d ";
$query = $wpdb->prepare( $query, $offset, $limit );// phpcs:ignore WordPress.DB.PreparedSQL
}
$product_ids = $wpdb->get_col( $query ); //phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL
if ( is_numeric( $term ) ) {
$post_id = absint( $term );
$post_type = get_post_type( $post_id );
if ( 'product_variation' === $post_type && $include_variations ) {
$product_ids[] = $post_id;
} elseif ( 'product' === $post_type ) {
$product_ids[] = $post_id;
}
$product_ids[] = wp_get_post_parent_id( $post_id );
}
return wp_parse_id_list( $product_ids );
}
public static function get_formatted_product_name( $product ) {
$formatted_variation_list = self::get_variation_attribute( $product );
$arguments = array();
if ( ! empty( $formatted_variation_list ) && count( $formatted_variation_list ) > 0 ) {
foreach ( $formatted_variation_list as $att => $att_val ) {
if ( '' === $att_val ) {
$att_val = __( 'any', 'wp-marketing-automations' );
}
$att = strtolower( $att );
$att_val = strtolower( $att_val );
$arguments[] = "$att: $att_val";
}
}
return sprintf( '%s (#%d)%s', strip_tags( $product->get_title() ), $product->get_id(), ( count( $arguments ) > 0 ) ? ' (' . implode( ',', $arguments ) . ')' : '' );
}
public static function get_variation_attribute( $variation ) {
$variation_attributes = array();
if ( is_a( $variation, 'WC_Product_Variation' ) ) {
$variation_attributes = $variation->get_attributes();
} else {
if ( is_array( $variation ) ) {
foreach ( $variation as $key => $value ) {
$variation_attributes[ str_replace( 'attribute_', '', $key ) ] = $value;
}
}
}
return ( $variation_attributes );
}
public static function array_equal( $a, $b ) {
return ( is_array( $a ) && is_array( $b ) && count( $a ) === count( $b ) && array_diff( $a, $b ) === array_diff( $b, $a ) ); //phpcs:ignore WordPress.PHP.StrictComparisons
}
public static function validate_string_multi( $actual_values, $compare_type, $expected_value ) {
if ( empty( $expected_value ) ) {
return false;
}
$actual_value = '';
// look for at least one item that validates the text match
foreach ( $actual_values as $coupon_code => $coupon_data ) {
$actual_value = is_string( $coupon_code ) ? $coupon_code : $coupon_data;
if ( self::validate_string( $actual_value, $compare_type, $expected_value ) ) {
return true;
}
}
return false;
}
/**
* @param $actual_value
* @param $compare_type
* @param $expected_value
*
* @return bool
*/
public static function validate_string( $actual_value, $compare_type, $expected_value ) {
// case insensitive
$actual_value = strtolower( (string) $actual_value );
$expected_value = strtolower( (string) $expected_value );
$return_status = false;
switch ( $compare_type ) {
case 'is':
$return_status = ( $actual_value === $expected_value );//phpcs:ignore WordPress.PHP.StrictComparisons
break;
case 'is_not':
$return_status = ( $actual_value !== $expected_value );//phpcs:ignore WordPress.PHP.StrictComparisons
break;
case 'contains':
$return_status = strstr( $actual_value, $expected_value ) !== false;
break;
case 'not_contains':
$return_status = strstr( $actual_value, $expected_value ) === false;
break;
case 'starts_with':
$length = strlen( $expected_value );
$return_status = substr( $actual_value, 0, $length ) === $expected_value;
break;
case 'ends_with':
$length = strlen( $expected_value );
if ( 0 === $length ) {
$return_status = true;
} else {
$return_status = substr( $actual_value, - $length ) === $expected_value;
}
break;
case 'blank':
$return_status = empty( $actual_value );
break;
case 'not_blank':
$return_status = ! empty( $actual_value );
break;
}
return $return_status;
}
public static function get_bwf_customer( $email, $wpid ) {
if ( function_exists( 'bwf_get_contact' ) ) {
$get_contact = bwf_get_contact( $wpid, $email );
return bwf_get_customer( $get_contact );
}
return null;
}
/**
* Run the check and update the status.
*/
public static function bwfan_run_cron_test( $forced = false ) {
if ( defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON ) {
$message = __( 'The DISABLE_WP_CRON constant is set to true . WP-Cron is disabled and will not run on it\'s own.', 'wp-marketing-automations' );
$url = rest_url( '/woofunnels/v1/worker' ) . '?' . time();
$message .= ' ' . __( 'Copy following URL and paste it in your Cpanel', 'wp-marketing-automations' );
$message .= '' . $url . ' ';
$current_version = BWFAN_VERSION;
$current_ver = str_replace( '.', '_', $current_version );
$version_key = 'bwfan_version_' . $current_ver;
$versionArr = array();
$versionArr[ $version_key ] = array(
'html' => $message,
'type' => 'wf_error',
);
$versionStatus = WooFunnels_Notifications::get_instance()->get_notification( $version_key, 'bwfan' );
if ( isset( $versionStatus['error'] ) && $versionStatus['error'] == $version_key . ' Key or Notification group may be Not Available.' ) { //phpcs:ignore WordPress.PHP.StrictComparisons
$notice_check_in_db = WooFunnels_Notifications::get_instance()->get_dismiss_notification_key( 'bwfan' );
if ( is_array( $notice_check_in_db ) && false === in_array( $version_key, $notice_check_in_db ) ) {//phpcs:ignore WordPress.PHP.StrictInArray
WooFunnels_Notifications::get_instance()->register_notification( $versionArr, 'bwfan' );
}
}
}
}
/**
* Returns the timestamp in the blog's time and format.
*/
public static function bwfan_get_datestring( $timestamp = '' ) {
if ( empty( $timestamp ) ) {
$timestamp = time();
}
return get_date_from_gmt( date( 'Y-m-d H:i:s', $timestamp ), get_option( 'date_format' ) . ' ' . get_option( 'time_format' ) ); // phpcs:ignore WordPress.DateTime.RestrictedFunctions
}
/**
* Get unique actions from a single automation.
*
* @param $automation_details
* @param $selected_actions
*
* @return array
*/
public static function get_automation_selected_action_slugs( $automation_details, $selected_actions ) {
$automation_actions = $automation_details['meta']['actions'];
$action_slugs = array();
foreach ( $selected_actions as $value1 ) {
$groups = explode( ',', $value1 );
foreach ( $groups as $group_actions ) {
$action_indexes = explode( '_', $group_actions );
$group_index = $action_indexes[0];
$action_index = $action_indexes[1];
$action = $automation_actions[ $group_index ][ $action_index ];
$action_slugs[] = $action['integration_slug'] . ':' . $action['action_slug'];
}
}
$action_slugs = array_unique( $action_slugs );
return $action_slugs;
}
public static function get_actions_filter_data() {
return self::get_all_actions_names();
}
/**
* Get all actions readable names with action slug
*
* @return array
*/
public static function get_all_actions_names() {
global $wpdb;
$filter_table = null;
$filtered_table_actions = null;
if ( ( isset( $_GET['tab'] ) && 'tasks' === sanitize_text_field( $_GET['tab'] ) ) ) { //phpcs:ignore WordPress.Security.NonceVerification
$filter_table = $wpdb->prefix . 'bwfan_tasks';
}
if ( ( isset( $_GET['tab'] ) && 'logs' === sanitize_text_field( $_GET['tab'] ) ) ) { //phpcs:ignore WordPress.Security.NonceVerification
$filter_table = $wpdb->prefix . 'bwfan_logs';
}
$task_status = ( isset( $_GET['status'] ) && '' !== $_GET['status'] ) ? sanitize_text_field( $_GET['status'] ) : 't_0'; //phpcs:ignore WordPress.Security.NonceVerification
if ( strpos( $task_status, '_' ) !== false ) {
$task_status = explode( '_', $task_status );
$task_status = intval( $task_status[1] );
} else {
$task_status = 0;
}
$params = array();
if ( ! is_null( $filter_table ) ) {
$query = 'SELECT DISTINCT(integration_action) as actions FROM ' . $filter_table;
if ( ! is_null( $task_status ) ) {
$query .= ' WHERE `status` = %d';
$params[] = $task_status;
}
$parsed_query = $wpdb->prepare( $query, $params ); // phpcs:ignore WordPress.DB.PreparedSQL
$distinct_actions = $wpdb->get_results( $parsed_query, ARRAY_A ); //phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL
if ( is_array( $distinct_actions ) && count( $distinct_actions ) > 0 ) {
foreach ( $distinct_actions as $values ) {
$filtered_table_actions[ $values['actions'] ] = $values['actions'];
}
}
}
$result = array();
$all_sources = BWFAN_Core()->integration->get_integrations();
$all_actions = BWFAN_Load_Integrations::get_all_integrations();
if ( is_array( $all_actions ) && count( $all_actions ) > 0 ) {
foreach ( $all_actions as $source_slug => $source_actions ) {
if ( ! is_array( $source_actions ) || 0 === count( $source_actions ) ) {
break;
}
foreach ( $source_actions as $actions_slug => $action_object ) {
if ( ! is_null( $filtered_table_actions ) && in_array( $actions_slug, $filtered_table_actions, true ) ) {
$result[ $actions_slug ] = $all_sources[ $source_slug ]->get_name() . ': ' . $action_object->get_name();
continue;
} elseif ( is_null( $filtered_table_actions ) ) {
$result[ $actions_slug ] = $all_sources[ $source_slug ]->get_name() . ': ' . $action_object->get_name();
}
}
}
}
ksort( $result );
return $result;
}
public static function modify_display_numbers( $value = false ) {
if ( false === $value ) {
return 0;
}
if ( 1000 > $value ) {
return $value;
}
return intval( $value / 1000 ) . 'k';
}
/**
* Get automations with title
*
* @return array
*/
public static function get_automations_filter_data() {
$result = array();
global $wpdb;
$automation_table = $wpdb->prefix . 'bwfan_automations';
$automation_meta_table = $wpdb->prefix . 'bwfan_automationmeta';
$params = array();
$query = 'SELECT am.`bwfan_automation_id`, am.`meta_value` ';
$query .= 'FROM ' . $automation_meta_table . ' AS am';
$query .= ' INNER JOIN ' . $automation_table . ' AS aut ON am.`bwfan_automation_id` = aut.`ID`';
$query .= ' WHERE 1=1';
$query .= ' AND am.`meta_key` = %s';
$params[] = 'title';
$parsed_query = $wpdb->prepare( $query, $params ); // phpcs:ignore WordPress.DB.PreparedSQL
$all_automations = $wpdb->get_results( $parsed_query, ARRAY_A ); //phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL
if ( false === is_array( $all_automations ) || 0 === count( $all_automations ) ) {
return $result;
}
foreach ( $all_automations as $details ) {
$result[ $details['bwfan_automation_id'] ] = $details['meta_value'];
}
return $result;
}
/**
* Increase the queue batch size while processing actions. default is 5.
*
* @param $batch_size
*
* @return mixed
*/
public static function ac_increase_queue_batch_size( $batch_size ) {
$global_settings = self::get_global_settings();
if ( isset( $global_settings['bwfan_ac_b_s'] ) && $global_settings['bwfan_ac_b_s'] > 0 ) {
$batch_size = intval( $global_settings['bwfan_ac_b_s'] );
}
return $batch_size;
}
/**
* Increase the maximum execution time while processing actions. default is 30 seconds.
*
* @param $max_timeout
*
* @return mixed
*/
public static function ac_increase_max_execution_time( $max_timeout ) {
$global_settings = self::get_global_settings();
if ( isset( $global_settings['bwfan_ac_t_l'] ) && $global_settings['bwfan_ac_t_l'] > 0 ) {
$max_timeout = intval( $global_settings['bwfan_ac_t_l'] );
}
return $max_timeout;
}
/**
* Make custom cron times for autonami events.
*
* @param $schedules
*
* @return mixed
*/
public static function make_custom_events_time( $schedules ) {
/** Don't add localization due to load textdomain error */
$schedules['bwfan_once_in_day'] = array(
'interval' => 86400,
'display' => 'Once in a day',
);
$schedules['bwfan_once_in_two_minutes'] = array(
'interval' => 120,
'display' => 'Once in 2 minutes',
);
$schedules['bwfan_every_minute'] = array(
'interval' => 60,
'display' => 'Every minute',
);
$schedules['bwfan_once_in_week'] = array(
'interval' => 604800,
'display' => 'Once in a week',
);
return $schedules;
}
/**
* Make a new endpoint which will receive the event data
*/
public static function add_plugin_endpoint() {
register_rest_route( 'autonami/v1', '/events', array(
'methods' => WP_REST_Server::CREATABLE,
'callback' => array( __CLASS__, 'capture_async_events' ),
'permission_callback' => '__return_true',
) );
register_rest_route( 'autonami/v1', '/worker', array(
'methods' => WP_REST_Server::CREATABLE,
'callback' => array( __CLASS__, 'run_worker_tasks' ),
'permission_callback' => '__return_true',
) );
register_rest_route( 'autonami/v1', '/autonami-cron', array(
'methods' => WP_REST_Server::READABLE,
'callback' => array( __CLASS__, 'run_autonami_cron_events' ),
'permission_callback' => '__return_true',
) );
register_rest_route( 'autonami/v1', '/delete-tasks', array(
'methods' => WP_REST_Server::CREATABLE,
'callback' => array( __CLASS__, 'delete_automation_tasks_by_unique_action_ids' ),
'permission_callback' => '__return_true',
) );
register_rest_route( 'autonami/v1', '/update-contact-automation', array(
'methods' => WP_REST_Server::CREATABLE,
'callback' => array( __CLASS__, 'update_contact_meta' ),
'permission_callback' => '__return_true',
) );
register_rest_route( 'autonami/v1', '/update-generated-increment', array(
'methods' => WP_REST_Server::CREATABLE,
'callback' => array( __CLASS__, 'update_generated_increment' ),
'permission_callback' => '__return_true',
) );
register_rest_route( 'autonami/v1', '/wc-add-to-cart', array(
'methods' => WP_REST_Server::CREATABLE,
'callback' => array( __CLASS__, 'wc_add_to_cart' ),
'permission_callback' => '__return_true',
) );
/** v2 autonami endpoint */
register_rest_route( 'autonami/v2', '/worker', array(
'methods' => WP_REST_Server::CREATABLE,
'callback' => array( __CLASS__, 'run_worker_tasks' ),
'permission_callback' => '__return_true',
) );
register_rest_route( 'autonami/v2', '/worker', array(
'methods' => WP_REST_Server::READABLE,
'callback' => array( __CLASS__, 'run_v2_worker_tasks' ),
'permission_callback' => '__return_true',
) );
}
/**
* Callback function for receiving the event data
*
* @param WP_REST_Request $request
*/
public static function capture_async_events( WP_REST_Request $request ) {
self::nocache_headers();
$post_parameters = $request->get_body_params();
self::event_advanced_logs( 'Event endpoint data received' );
self::event_advanced_logs( $post_parameters );
/** Check Unique key security */
$unique_key = get_option( 'bwfan_u_key', false );
if ( false === $unique_key || ! isset( $post_parameters['unique_key'] ) || $post_parameters['unique_key'] !== $unique_key ) {
return;
}
/** Delete row from automation events */
if ( isset( $post_parameters['a_e_id'] ) ) {
BWFAN_Model_Automation_Events::delete( $post_parameters['a_e_id'] );
}
self::capture_async_helper( $post_parameters );
BWFAN_Core()->logger->log( 'Automation Source Or Event data is not available, Data - ' . print_r( self::$events_async_data, true ), 'event_lifecycle' ); //phpcs:ignore WordPress.PHP.DevelopmentFunctions
wp_send_json( array(
'msg' => '',
'time' => time(),
) );
}
public static function capture_async_helper( $post_parameters = [], $wp_send_json = true ) {
if ( empty( $post_parameters ) ) {
return;
}
$resp = array();
if ( ( isset( $post_parameters['source'] ) && isset( $post_parameters['event'] ) ) && ( ! isset( $post_parameters['automation_id'] ) ) ) {
/** Set posted params to static property */
self::$events_async_data = $post_parameters;
$event_slug = $post_parameters['event'];
$event = BWFAN_Core()->sources->get_event( $event_slug );
$resp['msg'] = 'success';
/** Try to run v2 automations */
self::maybe_run_v2_automations( $event_slug, $post_parameters );
/** Check if the Event has active automations, used this check again for cases like Form Submissions trigger */
if ( ! is_null( $event ) && false !== $event->get_current_event_automations() ) {
try {
$event->capture_async_data();
} catch ( Exception $exception ) {
$resp['msg'] = $exception->getMessage();
}
}
if ( true === $wp_send_json ) {
wp_send_json( $resp );
}
}
}
/**
* Find v2 active automations for event and run
*
* @param $event_slug
*
* @return false|void
*/
public static function maybe_run_v2_automations( $event_slug, $post_parameters ) {
BWFAN_Core()->public->load_active_v2_automations( $event_slug );
/** @var BWFAN_Event $event */
$event = BWFAN_Core()->sources->get_event( $event_slug );
if ( ! $event instanceof BWFAN_Event ) {
return false;
}
/**
* Run Autonami async events
* Form submission, Automation goals, Normalize 3rd party tables
*/
self::extend_async_capture( $event, $post_parameters );
$automations = $event->get_automations_data( 2 );
if ( ! is_array( $automations ) || count( $automations ) === 0 ) {
BWFAN_Core()->logger->log( 'No v2 active automations found. Event - ' . $event->get_slug(), $event->log_type );
return false;
}
self::log_test_data( 'Found v2 automations. Event - ' . $event->get_slug() );
self::log_test_data( 'IDs: ' . implode( ', ', array_keys( $automations ) ) );
$any_automation_ran = false;
foreach ( $automations as $automation_id => $automation_data ) {
$automation_data = self::remove_extra_automation_data( $automation_data );
if ( ! empty( $post_parameters ) && is_array( $post_parameters ) ) {
$automation_data = array_merge( $automation_data, $post_parameters );
}
if ( empty( $automation_data ) ) {
continue;
}
if ( false === $event->validate_v2_event_settings( $automation_data ) ) {
continue;
}
$automation_data = $event->capture_v2_data( $automation_data );
if ( empty( $automation_data ) ) {
continue;
}
$event->global_data = $event->get_event_data( $automation_data );
/** For modify data */
$event->global_data = apply_filters( 'bwfan_modify_event_data', $event->global_data );
$event->event_data = $event->get_automation_event_data( $automation_data );
/** Don't extend locally */
$result = $event->handle_automation_run_v2( $automation_id, $automation_data );
/** Set last run automation contact id */
self::$last_automation_cid[ $automation_id ] = $result;
$any_automation_ran = $any_automation_ran || ! empty( $result );
}
return $any_automation_ran;
}
/**
* @param BWFAN_Event $event
* @param array $post_parameters
*/
public static function extend_async_capture( $event, $post_parameters ) {
/** Capture Async: Form Submission */
if ( isset( $post_parameters['is_form_submission'] ) && 1 === absint( $post_parameters['is_form_submission'] ) && bwfan_is_autonami_pro_active() ) {
try {
BWFCRM_Core()->forms->capture_async_form_submission();
} catch ( Error $e ) {
BWFAN_Common::log_test_data( $event->get_slug() . ' : Capture Async: Form Submission try catch failed. Error: ' . $e->getMessage(), 'extend_async_capture' );
}
}
/** Capture Async: Goal Controller */
if ( $event->is_goal() ) {
try {
BWFAN_Common::log_test_data( $event->get_slug() . ' is a goal', 'goal-check' );
BWFAN_Goal_Controller::capture_async_goal( $event, $post_parameters );
} catch ( Error $e ) {
BWFAN_Common::log_test_data( $event->get_slug() . ' : Goal execution try catch failed. Error: ' . $e->getMessage(), 'extend_async_capture' );
}
}
if ( $event->is_db_normalize() ) {
try {
if ( method_exists( $event, 'execute_normalization' ) ) {
$event->execute_normalization( $post_parameters );
}
} catch ( Error $e ) {
BWFAN_Common::log_test_data( $event->get_slug() . ' : Normalization method not found. Error: ' . $e->getMessage(), 'extend_async_capture' );
}
}
}
/**
* Aman testing purpose only
*
* @param $data
* @param $file
* @param $force
*
* @return void
*/
public static function log_test_data( $data, $file = 'v2-automations', $force = false ) {
if ( empty( $data ) ) {
return;
}
if ( true === $force ) {
add_filter( 'bwfan_before_making_logs', '__return_true' );
}
if ( is_array( $data ) ) {
BWFAN_Core()->logger->log( self::$dynamic_str, $file );
BWFAN_Core()->logger->log( print_r( $data, true ), $file ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions
return;
}
BWFAN_Core()->logger->log( self::$dynamic_str . ' - ' . $data, $file );
}
public static function log_l2_data( $data, $file = 'v2-automations', $force = false ) {
if ( empty( $data ) ) {
return;
}
$should_log = apply_filters( 'bwfan_log_level_2_logs', false );
if ( false === $should_log ) {
return;
}
if ( true === $force ) {
add_filter( 'bwfan_before_making_logs', '__return_true' );
}
if ( is_array( $data ) ) {
BWFAN_Core()->logger->log( print_r( $data, true ), $file ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions
return;
}
BWFAN_Core()->logger->log( $data, $file );
}
public static function remove_extra_automation_data( $automation_data ) {
if ( array_key_exists( 'goal', $automation_data ) ) {
unset( $automation_data['goal'] );
}
if ( array_key_exists( 'steps', $automation_data ) ) {
unset( $automation_data['steps'] );
}
if ( array_key_exists( 'links', $automation_data ) ) {
unset( $automation_data['links'] );
}
if ( array_key_exists( 'count', $automation_data ) ) {
unset( $automation_data['count'] );
}
if ( array_key_exists( 'requires_update', $automation_data ) ) {
unset( $automation_data['requires_update'] );
}
if ( array_key_exists( 'step_iteration_array', $automation_data ) ) {
unset( $automation_data['step_iteration_array'] );
}
if ( array_key_exists( 'unique_key', $automation_data ) ) {
unset( $automation_data['unique_key'] );
}
return $automation_data;
}
/**
* Callback function for running autonami tasks
*
* @param WP_REST_Request $request
*/
public static function run_worker_tasks( WP_REST_Request $request ) {
self::nocache_headers();
$post_parameters = $request->get_body_params();
if ( ! is_array( $post_parameters ) || ! isset( $post_parameters['worker'] ) ) {
return;
}
/**
* Check Unique key security
*/
$unique_key = get_option( 'bwfan_u_key', false );
if ( false === $unique_key || ! isset( $post_parameters['unique_key'] ) || $post_parameters['unique_key'] !== $unique_key ) {
return;
}
$v = ( isset( $_SERVER['REQUEST_URI'] ) && strpos( $_SERVER['REQUEST_URI'], 'autonami/v1/worker' ) !== false ) ? 1 : 2;// phpcs:ignore WordPress.Security.ValidatedSanitizedInput
self::event_advanced_logs( "V{$v} worker callback received" );
self::worker_as_run();
/** Logs */
$cron_check = self::is_log_enabled( 'bwfan_cron_check_logging' );
if ( true === $cron_check || ( defined( 'BWF_CHECK_CRON_SCHEDULE' ) && true === BWF_CHECK_CRON_SCHEDULE ) ) {
add_filter( 'bwf_logs_allowed', '__return_true', PHP_INT_MAX );
$logger_obj = BWF_Logger::get_instance();
$logger_obj->log( date_i18n( 'Y-m-d H:i:s' ) . ' - after worker run', 'fka-cron-check-v' . $v, 'autonami' );
}
$resp = array();
$resp['msg'] = 'success';
wp_send_json( $resp );
}
public static function worker_as_run() {
if ( ! class_exists( 'ActionScheduler_QueueRunner' ) ) {
return;
}
/** Check if Autonami is in sandbox mode */
if ( true === BWFAN_Common::is_sandbox_mode_active() ) {
return;
}
/** Modify Action Scheduler filters */
self::modify_as_filters();
$as_ins = ActionScheduler_QueueRunner::instance();
/** Run Action Scheduler worker */
$as_ins->run();
}
/**
* Check if sandbox is active or not
*
* @return bool
*/
public static function is_sandbox_mode_active() {
if ( defined( 'BWFAN_SANDBOX_MODE' ) && true === BWFAN_SANDBOX_MODE ) {
return true;
}
$global_settings = get_option( 'bwfan_global_settings', array() );
if ( empty( $global_settings ) || ! isset( $global_settings['bwfan_sandbox_mode'] ) ) {
return false;
}
if ( 1 === intval( $global_settings['bwfan_sandbox_mode'] ) ) {
return true;
}
return false;
}
public static function modify_as_filters() {
/** Remove all existing filters */
remove_all_filters( 'action_scheduler_queue_runner_time_limit' );
remove_all_filters( 'action_scheduler_queue_runner_batch_size' );
remove_all_filters( 'action_scheduler_queue_runner_concurrent_batches' );
remove_all_filters( 'action_scheduler_timeout_period' );
remove_all_filters( 'action_scheduler_cleanup_batch_size' );
remove_all_filters( 'action_scheduler_maximum_execution_time_likely_to_be_exceeded' );
remove_all_filters( 'action_scheduler_failure_period' );
/** Adding all filters for Autonami Action Scheduler only */
add_filter( 'action_scheduler_queue_runner_time_limit', function () {
$as_per_call_time = apply_filters( 'bwfan_as_per_call_time', 30 );
return intval( $as_per_call_time ) > 50 ? 50 : $as_per_call_time;
}, 999 );
add_filter( 'action_scheduler_queue_runner_batch_size', function () {
return apply_filters( 'bwfan_as_per_call_batch_size', 30 );
}, 999 );
add_filter( 'action_scheduler_queue_runner_concurrent_batches', function () {
return 5;
}, 999 );
add_filter( 'action_scheduler_timeout_period', function () {
return 300;
}, 999 );
add_filter( 'action_scheduler_cleanup_batch_size', function () {
return 20;
}, 999 );
add_filter( 'action_scheduler_maximum_execution_time_likely_to_be_exceeded', function ( $val, $ins, $processed_actions, $execution_time, $max_execution_time ) {
return ( $execution_time > $max_execution_time );
}, 99999, 5 );
add_filter( 'action_scheduler_failure_period', function () {
return 180;
}, 999 );
}
/**
* Check if cart abandonment is active or not
*
* @return bool
*/
public static function is_cart_abandonment_active() {
$global_settings = get_option( 'bwfan_global_settings', array() );
if ( empty( $global_settings ) || ! isset( $global_settings['bwfan_ab_enable'] ) || empty( $global_settings['bwfan_ab_enable'] ) ) {
return false;
}
return true;
}
/**
* action_scheduler_pre_init action hook
*/
public static function as_pre_init_cb() {
if ( ( ! isset( $_GET['rest_route'] ) || '/autonami/v1/worker' !== sanitize_text_field( $_GET['rest_route'] ) ) && false === strpos( $_SERVER['REQUEST_URI'], '/autonami/v1/worker' ) ) { //phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput
return;
}
if ( ! class_exists( 'BWFAN_AS_CT' ) ) {
return;
}
/** BWFAN_AS_CT instance */
$as_ct_ins = BWFAN_AS_CT::instance();
/** Set new AS CT data store */
$as_ct_ins->change_data_store();
self::$change_data_strore = true;
}
/**
* action_scheduler_pre_init action hook for version 2
*/
public static function as_pre_init_v2_cb() {
if ( ( ! isset( $_GET['rest_route'] ) || '/autonami/v2/worker' !== sanitize_text_field( $_GET['rest_route'] ) ) && false === strpos( $_SERVER['REQUEST_URI'], '/autonami/v2/worker' ) ) { //phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput
return;
}
if ( ! class_exists( 'BWFAN_AS_V2' ) ) {
return;
}
/** BWFAN_AS_V2 instance */
$ins = BWFAN_AS_V2::instance();
/** Unset orphaned claims */
$ins->unset_orphaned_claims();
/** Set new AS V2 data store */
$ins->change_data_store();
self::$change_data_strore = true;
}
/**
* action_scheduler_pre_init action hook for autonami cli
*/
public static function as_pre_init_cli_cb() {
global $argv;
if ( ! defined( 'WP_CLI' ) || ! WP_CLI ) {
return;
}
/**
* $argv holds arguments passed to script
* https://www.php.net/manual/en/reserved.variables.argv.php
*/
if ( empty( $argv ) ) {
WP_CLI::log( 'FunnelKit Automations WP CLI arguments not found.' );
return;
}
if ( ! isset( $argv[1] ) || 'autonami-tasks' !== $argv[1] ) {
return;
}
if ( ! isset( $argv[2] ) || 'run' !== $argv[2] ) {
return;
}
if ( ! class_exists( 'BWFAN_AS_CT' ) ) {
WP_CLI::log( 'BWFAN_AS_CT class not found.' );
}
/** BWFAN_AS_CT instance */
$as_ct_ins = BWFAN_AS_CT::instance();
/** Set new AS CT data store */
$as_ct_ins->change_data_store();
self::$change_data_strore = true;
}
/**
* action_scheduler_pre_init action hook for version 2 for autonami cli
*/
public static function as_pre_init_cli_v2_cb() {
global $argv;
if ( ! defined( 'WP_CLI' ) || ! WP_CLI ) {
return;
}
/**
* $argv holds arguments passed to script
* https://www.php.net/manual/en/reserved.variables.argv.php
*/
if ( empty( $argv ) ) {
WP_CLI::log( 'FunnelKit Automations V2 WP CLI arguments not found.' );
return;
}
if ( ! isset( $argv[1] ) || 'autonami-tasks' !== $argv[1] ) {
return;
}
if ( ! isset( $argv[2] ) || 'run' !== $argv[2] ) {
return;
}
if ( ! class_exists( 'BWFAN_AS_V2' ) ) {
WP_CLI::log( 'BWFAN_AS_V2 class not found.' );
}
/** BWFAN_AS_V2 instance */
$ins = BWFAN_AS_V2::instance();
/** Set new AS V2 data store */
$ins->change_data_store();
self::$change_data_strore = true;
}
/**
* This function is called when rest endpoint of cron is hit.
*
* @param WP_REST_Request $request
*/
public static function run_autonami_cron_events( WP_REST_Request $request ) {
self::nocache_headers();
$resp = array();
$resp['msg'] = 'success';
if ( isset( $_GET['debug'] ) && 'yes' === $_GET['debug'] ) { // phpcs:ignore WordPress.Security.NonceVerification
$resp['msg'] = 'connection established';
wp_send_json( $resp );
}
self::run_as_ct_worker();
wp_send_json( $resp );
}
/**
* 1 min worker callback
*/
public static function run_as_ct_worker() {
/** Maybe v1 automation not active */
if ( false === self::is_automation_v1_active() && bwf_has_action_scheduled( 'bwfan_run_queue' ) ) {
bwf_unschedule_actions( 'bwfan_run_queue' );
}
/** Check if a single task is available for execution */
if ( false === self::is_automation_v1_active() || false === BWFAN_Model_Tasks::maybe_tasks_available() ) {
return;
}
$url = rest_url( '/autonami/v1/worker' ) . '?' . time();
$body_data = array(
'worker' => true,
'unique_key' => get_option( 'bwfan_u_key', false ),
);
$args = bwf_get_remote_rest_args( $body_data );
wp_remote_post( $url, $args );
}
/**
* v2 automation 1 min worker callback
*
* @return void
*/
public static function run_as_ct_v2_worker() {
/** Advanced logs */
self::event_advanced_logs( 'V2 action callback' );
/** Logs */
$cron_check = self::is_log_enabled( 'bwfan_cron_check_logging' );
if ( true === $cron_check || ( defined( 'BWF_CHECK_CRON_SCHEDULE' ) && true === BWF_CHECK_CRON_SCHEDULE ) ) {
add_filter( 'bwf_logs_allowed', '__return_true', PHP_INT_MAX );
$logger_obj = BWF_Logger::get_instance();
$logger_obj->log( date_i18n( 'Y-m-d H:i:s' ) . ' - before worker hit', 'fka-cron-check-v2', 'autonami' );
}
/** Check if any contact in automation can proceed */
if ( false === BWFAN_Model_Automation_Contact::maybe_can_execute() ) {
return;
}
$url = rest_url( '/autonami/v2/worker' ) . '?' . time();
$body_data = array(
'worker' => true,
'unique_key' => get_option( 'bwfan_u_key', false ),
);
$args = bwf_get_remote_rest_args( $body_data );
$resp = wp_remote_post( $url, $args );
self::event_advanced_logs( 'V2 worker response' );
if ( is_wp_error( $resp ) ) {
self::event_advanced_logs( $resp->get_error_message() );
} elseif ( isset( $resp['body'] ) ) {
self::event_advanced_logs( $resp['body'] );
self::event_advanced_logs( $resp['response'] );
}
}
/**
* phpcs:ignore WordPress.Security.NonceVerification
* Return the html for tasks links on tasks listing page.
*
* @return string
*/
public static function get_link_options_for_tasks() {
$scheduled_count = BWFAN_Core()->tasks->fetch_tasks_count( 0, 0 );
/* translators: %d is the number of scheduled tasks */
$scheduled = sprintf( __( 'Scheduled (%d)', 'wp-marketing-automations' ), $scheduled_count );
$paused_count = BWFAN_Core()->tasks->fetch_tasks_count( 0, 1 );
/* translators: %d is the number of paused tasks */
$paused = sprintf( __( 'Paused (%d)', 'wp-marketing-automations' ), $paused_count );
$completed_count = BWFAN_Core()->logs->fetch_logs_count( 1 );
/* translators: %d is the number of completed tasks */
$completed = sprintf( __( 'Completed (%d)', 'wp-marketing-automations' ), $completed_count );
$failed_count = BWFAN_Core()->logs->fetch_logs_count( 0 );
/* translators: %d is the number of failed tasks */
$failed = sprintf( __( 'Failed (%d)', 'wp-marketing-automations' ), $failed_count );
$get_campaign_statuses = apply_filters( 'bwfan_admin_trigger_nav', array(
't_0' => $scheduled,
't_1' => $paused,
'l_1' => $completed,
'l_0' => $failed,
) );
$html = '';
$html_inside = array();
$current_status = 't_0';
if ( isset( $_GET['status'] ) && '' !== $_GET['status'] ) { //phpcs:ignore WordPress.Security.NonceVerification
$current_status = sanitize_text_field( $_GET['status'] );//phpcs:ignore WordPress.Security.NonceVerification
}
// For listing screen
$all_statuses = array(
't_0' => array(
'tab' => 'tasks',
),
't_1' => array(
'tab' => 'tasks',
),
'l_0' => array(
'tab' => 'logs',
),
'l_1' => array(
'tab' => 'logs',
),
);
foreach ( $get_campaign_statuses as $slug => $status ) {
$need_class = '';
if ( $slug === $current_status ) {
$need_class = 'current';
}
$args = array(
'status' => $slug,
);
$args['tab'] = $all_statuses[ $slug ]['tab'];
$url = add_query_arg( $args, admin_url( 'admin.php?page=autonami-automations' ) );
$html_inside[] = sprintf( '%s ', $url, $need_class, $status );
}
if ( is_array( $html_inside ) && count( $html_inside ) > 0 ) {
$html .= implode( '', $html_inside );
}
$html .= ' ';
return $html;
}
public static function get_logging_status() {
$global_settings = self::get_global_settings();
return ( isset( $global_settings['bwfan_make_logs'] ) && 1 === intval( $global_settings['bwfan_make_logs'] ) ) ? true : false;
}
/**
* Capture all the action ids of an automation and delete all its tasks except for completed tasks.
*
* @param WP_REST_Request $request
*/
public static function delete_automation_tasks_by_unique_action_ids( WP_REST_Request $request ) {
self::nocache_headers();
$post_parameters = $request->get_body_params();
if ( false === is_array( $post_parameters ) || 0 === count( $post_parameters ) ) {
return;
}
if ( ! isset( $post_parameters['automation_id'] ) || ! isset( $post_parameters['a_track_id'] ) || ! isset( $post_parameters['t_to_delete'] ) ) {
return;
}
/**
* Check Unique key security
*/
$unique_key = get_option( 'bwfan_u_key', false );
if ( false === $unique_key || ! isset( $post_parameters['unique_key'] ) || $post_parameters['unique_key'] !== $unique_key ) {
return;
}
$automation_id = sanitize_text_field( $post_parameters['automation_id'] );
$a_track_id = sanitize_text_field( $post_parameters['a_track_id'] );
$t_to_delete = $post_parameters['t_to_delete'];
$t_to_delete = self::is_json( $t_to_delete ) ? json_decode( $t_to_delete, true ) : $t_to_delete;
if ( false === is_array( $t_to_delete ) || 0 === count( $t_to_delete ) ) {
return;
}
foreach ( $t_to_delete as $key1 => $action_index ) {
$t_to_delete[ $key1 ] = $a_track_id . '_' . $action_index;
}
BWFAN_Core()->tasks->delete_by_index_ids( $automation_id, $t_to_delete );
BWFAN_Core()->logs->delete_by_index_ids( $automation_id, $t_to_delete );
}
/**
* Convert string/ json to array
*
* @param $value
*
* @return array
*/
public static function make_array( $value ) {
$value = self::is_json( $value ) ? json_decode( $value, true ) : $value;
return empty( $value ) || ! is_array( $value ) ? [] : $value;
}
/**
* Check if string is a json
*
* @param $string
*
* @return bool
*/
public static function is_json( $string ) {
if ( ! is_string( $string ) ) {
return false;
}
json_decode( $string );
return ( json_last_error() === JSON_ERROR_NONE );
}
/**
* Array unique and sort
*
* @param $value
*
* @return array|mixed
*/
public static function unique( $value ) {
if ( ! is_array( $value ) ) {
return $value;
}
$value = array_unique( $value );
sort( $value );
return $value;
}
/**
* Clean variables using sanitize_text_field. Arrays are cleaned recursively.
* Non-scalar values are ignored.
*
* @param string|array $var Data to sanitize.
*
* @return string|array
*/
public static function bwfan_clean( $var ) {
if ( is_array( $var ) ) {
return array_map( 'self::bwfan_clean', $var );
} else {
return is_scalar( $var ) ? sanitize_text_field( $var ) : $var;
}
}
/**
* Update contact automation table for current automation.
*
* @param WP_REST_Request $request
*/
public static function update_contact_meta( WP_REST_Request $request ) {
self::nocache_headers();
$post_parameters = $request->get_body_params();
if ( false === is_array( $post_parameters ) || 0 === count( $post_parameters ) ) {
return;
}
if ( ! isset( $post_parameters['automation_id'] ) || ! isset( $post_parameters['email'] ) || ! isset( $post_parameters['user_id'] ) ) {
return;
}
/**
* Check Unique key security
*/
$unique_key = get_option( 'bwfan_u_key', false );
if ( false === $unique_key || ! isset( $post_parameters['unique_key'] ) || $post_parameters['unique_key'] !== $unique_key ) {
return;
}
$automation_id = sanitize_text_field( $post_parameters['automation_id'] );
$email = sanitize_text_field( $post_parameters['email'] );
$user_id = sanitize_text_field( $post_parameters['user_id'] );
$contact_obj = bwf_get_contact( $user_id, $email );
$contact_id = $contact_obj->id;
if ( ! isset( $contact_id ) || empty( $contact_id ) ) {
return;
}
$data = array(
'contact_id' => $contact_id,
'automation_id' => $automation_id,
'time' => time(),
);
BWFAN_Model_Contact_Automations::insert( $data );
}
public static function update_generated_increment( WP_REST_Request $request ) {
self::nocache_headers();
$post_parameters = $request->get_body_params();
if ( false === is_array( $post_parameters ) || 0 === count( $post_parameters ) ) {
return;
}
if ( ! isset( $post_parameters['id'] ) ) {
return;
}
/**
* Check Unique key security
*/
$unique_key = get_option( 'bwfan_u_key', false );
if ( false === $unique_key || ! isset( $post_parameters['unique_key'] ) || $post_parameters['unique_key'] !== $unique_key ) {
return;
}
$date = date( 'Y-m-d' ); // phpcs:ignore WordPress.DateTime.RestrictedFunctions
/**
* All calculations are done via this row and the stats displayed are fetched from this row only.
*/
WFCO_Model_Report_views::update_data( $date, 0, 1 );
/**
* If AeroCheckout page
*
* This row is saved for future use
*/
if ( ! empty( $post_parameters['id'] ) ) {
WFCO_Model_Report_views::update_data( $date, $post_parameters['id'], 1 );
}
}
public static function wc_add_to_cart( WP_REST_Request $request ) {
self::nocache_headers();
$post_parameters = $request->get_body_params();
if ( false === is_array( $post_parameters ) || 0 === count( $post_parameters ) ) {
return;
}
if ( ! isset( $post_parameters['id'] ) || ! isset( $post_parameters['coupon_data'] ) || ! isset( $post_parameters['items'] ) || ! isset( $post_parameters['fees'] ) ) {
return;
}
/**
* Check Unique key security
*/
$unique_key = get_option( 'bwfan_u_key', false );
if ( false === $unique_key || ! isset( $post_parameters['unique_key'] ) || $post_parameters['unique_key'] !== $unique_key ) {
return;
}
$user_id = $post_parameters['id'];
$email = '';
$abandoned_obj = BWFAN_Abandoned_Cart::get_instance();
if ( ! empty( $post_parameters['fk_uid'] ) ) {
$uid = $post_parameters['fk_uid'];
$contact = new WooFunnels_Contact( '', '', '', '', $uid );
$email = $contact->get_email();
$user_id = $contact->get_wpid();
}
$coupon_data = $post_parameters['coupon_data'];
$items = $post_parameters['items'];
$fees = $post_parameters['fees'];
$cart_details = $abandoned_obj->get_cart_by_key( 'cookie_key', $post_parameters['bwfan_visitor'], '%s' );
$cart_details = empty( $cart_details ) ? $abandoned_obj->get_cart_by_key( 'email', $email, '%s' ) : $cart_details;
if ( ! empty( $email ) && empty( $cart_details ) ) {
self::create_abandoned_cart( array(
'user_id' => $user_id,
'email' => $email,
'coupons' => $coupon_data,
'items' => $items,
'fees' => $fees,
'cookie_key' => $post_parameters['bwfan_visitor'] ?? '',
) );
return;
}
/** If cart details is not found, then return */
if ( empty( $cart_details ) || ! isset( $cart_details['ID'] ) ) {
return;
}
$cart_details['coupons'] = $coupon_data;
$cart_details['items'] = $items;
$cart_details['fees'] = $fees;
$data = self::get_abandoned_totals( $cart_details );
$data['user_id'] = $user_id;
$data['last_modified'] = current_time( 'mysql', 1 );
/** If status lost and others */
$cart_status = isset( $cart_details['status'] ) ? intval( $cart_details['status'] ) : 0;
if ( in_array( $cart_status, array( 2, 3, 4 ), true ) ) {
$data['status'] = 0;
$data['created_time'] = current_time( 'mysql', 1 );
}
$where = array(
'ID' => $cart_details['ID'],
);
BWFAN_Model_Abandonedcarts::update( $data, $where );
}
private static function create_abandoned_cart( $data ) {
$customer = new WC_Customer( $data['user_id'] );
$checkout_data = array(
'fields' => array(
'billing_first_name' => $customer->get_billing_first_name(),
'billing_last_name' => $customer->get_billing_last_name(),
'billing_company' => $customer->get_billing_company(),
'billing_country' => $customer->get_billing_country(),
'billing_address_1' => $customer->get_billing_address_1(),
'billing_address_2' => $customer->get_billing_address_2(),
'billing_city' => $customer->get_billing_city(),
'billing_state' => $customer->get_billing_state(),
'billing_postcode' => $customer->get_billing_postcode(),
'billing_phone' => $customer->get_billing_phone(),
'billing_email' => $customer->get_billing_email(),
'shipping_first_name' => $customer->get_shipping_first_name(),
'shipping_last_name' => $customer->get_shipping_last_name(),
'shipping_company' => $customer->get_shipping_company(),
'shipping_country' => $customer->get_shipping_country(),
'shipping_address_1' => $customer->get_shipping_address_1(),
'shipping_address_2' => $customer->get_shipping_address_2(),
'shipping_city' => $customer->get_shipping_city(),
'shipping_state' => $customer->get_shipping_state(),
'shipping_postcode' => $customer->get_shipping_postcode(),
),
);
$data['status'] = 0;
$data['created_time'] = current_time( 'mysql', 1 );
$data['last_modified'] = current_time( 'mysql', 1 );
$data['token'] = self::create_token( 32 );
$data['checkout_data'] = wp_json_encode( $checkout_data );
$data['currency'] = get_woocommerce_currency();
$data = self::get_abandoned_totals( $data );
BWFAN_Model_Abandonedcarts::insert( $data );
}
public static function create_token( $length = 25 ) {
return wp_generate_password( $length, false );
}
private static function get_abandoned_totals( $data ) {
$coupon_data = $data['coupons'];
$items = $data['items'];
$fees = $data['fees'];
$calculated_total = 0;
foreach ( maybe_unserialize( $items ) as $item ) {
$line_subtotal_tax = isset( $item['line_subtotal_tax'] ) ? floatval( $item['line_subtotal_tax'] ) : 0;
$line_subtotal = isset( $item['line_subtotal'] ) ? floatval( $item['line_subtotal'] ) : 0;
$calculated_total += $line_subtotal + $line_subtotal_tax;
}
foreach ( maybe_unserialize( $coupon_data ) as $coupon ) {
$calculated_total -= $coupon['discount_incl_tax'];
}
foreach ( maybe_unserialize( $fees ) as $fee ) {
$calculated_total += ( $fee->total + $fee->tax );
}
$calculated_total = wc_format_decimal( $calculated_total, wc_get_price_decimals() );
$data['total'] = $calculated_total;
$data['total_base'] = BWF_Plugin_Compatibilities::get_fixed_currency_price_reverse( $calculated_total, get_woocommerce_currency() );
return $data;
}
/**
* Get human readable time format like 18 minutes 47 seconds ago
*
* @param $timestamp
* @param $date
*
* @return string
*/
public static function get_human_readable_time( $timestamp, $date ) {
$current_timestamp = gmdate( 'U' );
if ( $current_timestamp > $timestamp ) {
$schedule_display_string = '' . self::human_interval( gmdate( 'U' ) - $timestamp ) . __( ' ago', 'wp-marketing-automations' ) . ' ';
} else {
$schedule_display_string = '' . __( 'in ', 'wp-marketing-automations' ) . self::human_interval( $timestamp - gmdate( 'U' ) ) . ' ';
}
return $schedule_display_string;
}
public static function human_interval( $interval, $periods_to_include = 2 ) {
self::$time_periods = array(
array(
'seconds' => YEAR_IN_SECONDS,
'names' => _n_noop( '%s year', '%s years', 'wp-marketing-automations' ), // phpcs:ignore WordPress.WP.I18n.MissingTranslatorsComment
),
array(
'seconds' => MONTH_IN_SECONDS,
'names' => _n_noop( '%s month', '%s months', 'wp-marketing-automations' ), // phpcs:ignore WordPress.WP.I18n.MissingTranslatorsComment
),
array(
'seconds' => WEEK_IN_SECONDS,
'names' => _n_noop( '%s week', '%s weeks', 'wp-marketing-automations' ), // phpcs:ignore WordPress.WP.I18n.MissingTranslatorsComment
),
array(
'seconds' => DAY_IN_SECONDS,
'names' => _n_noop( '%s day', '%s days', 'wp-marketing-automations' ), // phpcs:ignore WordPress.WP.I18n.MissingTranslatorsComment
),
array(
'seconds' => HOUR_IN_SECONDS,
'names' => _n_noop( '%s hour', '%s hours', 'wp-marketing-automations' ), // phpcs:ignore WordPress.WP.I18n.MissingTranslatorsComment
),
array(
'seconds' => MINUTE_IN_SECONDS,
'names' => _n_noop( '%s minute', '%s minutes', 'wp-marketing-automations' ), // phpcs:ignore WordPress.WP.I18n.MissingTranslatorsComment
),
array(
'seconds' => 1,
'names' => _n_noop( '%s second', '%s seconds', 'wp-marketing-automations' ), // phpcs:ignore WordPress.WP.I18n.MissingTranslatorsComment
),
);
if ( $interval <= 0 ) {
return __( 'Now!', 'wp-marketing-automations' );
}
$output = '';
for ( $time_period_index = 0, $periods_included = 0, $seconds_remaining = $interval; $time_period_index < count( self::$time_periods ) && $seconds_remaining > 0 && $periods_included < $periods_to_include; $time_period_index ++ ) {
$periods_in_interval = floor( $seconds_remaining / self::$time_periods[ $time_period_index ]['seconds'] );
if ( $periods_in_interval > 0 ) {
if ( ! empty( $output ) ) {
$output .= ' ';
}
$output .= sprintf( _n( self::$time_periods[ $time_period_index ]['names'][0], self::$time_periods[ $time_period_index ]['names'][1], $periods_in_interval, 'wp-marketing-automations' ), $periods_in_interval ); //phpcs:ignore WordPress.WP.I18n.NonSingularStringLiteralPlural, WordPress.WP.I18n.NonSingularStringLiteralSingle
$seconds_remaining -= $periods_in_interval * self::$time_periods[ $time_period_index ]['seconds'];
$periods_included ++;
}
}
return $output;
}
/**
* Return seconds from 24 hr format.
*
* @param $str_time
*
* @return float|int
*/
public static function get_seconds_from_time_format( $str_time ) {
$hours = '';
$minutes = '';
$seconds = '';
sscanf( $str_time, '%d:%d:%d', $hours, $minutes, $seconds );
$time_seconds = ( isset( $hours ) && ! empty( $hours ) ) ? absint( $hours ) * 3600 + absint( $minutes ) * 60 + absint( $seconds ) : absint( $minutes ) * 60 + absint( $seconds );
return $time_seconds;
}
/**
* Get the nearest date.
*
* @param $actual_timestamp
* @param $days_selected
*
* @return false|int
*/
public static function get_nearest_date( $actual_timestamp, $days_selected ) {
$date_object = new DateTime( date( ( 'Y-m-d H:i:s' ), $actual_timestamp ) ); // phpcs:ignore WordPress.DateTime.RestrictedFunctions
for ( $h = 0; $h < 7; $h ++ ) {
if ( in_array( $date_object->format( "N" ), $days_selected ) ) {
return $date_object->getTimestamp();
}
$date_object->modify( '+1 days' );
}
return $actual_timestamp;
}
/**
* Find the closest matching date.
*
* @param $array
* @param $date
*
* @return mixed
*/
public static function find_closest( $array, $date ) {
$interval = array();
foreach ( $array as $day ) {
$interval[] = abs( strtotime( $date ) - strtotime( $day ) );
}
asort( $interval );
$closest = key( $interval );
return $array[ $closest ];
}
/**
* @param $ids
* @param $status
*/
public static function update_abandoned_rows( $ids, $status ) {
global $wpdb;
$automationCount = count( $ids );
$stringPlaceholders = array_fill( 0, $automationCount, '%s' );
$placeholdersautomation = implode( ', ', $stringPlaceholders );
$sql_query = "Update {table_name} Set status = $status WHERE ID IN ($placeholdersautomation)";
$sql_query = $wpdb->prepare( $sql_query, $ids );// phpcs:ignore WordPress.DB.PreparedSQL
BWFAN_Model_Abandonedcarts::get_results( $sql_query );
}
/**
* Delete all the tasks related to an abandoned cart row
*
* @param $abandoned_cart_id
*/
public static function delete_abandoned_cart_tasks( $abandoned_cart_id ) {
global $wpdb;
$meta_key = 'c_a_id';
$query = $wpdb->prepare( 'SELECT `bwfan_task_id` FROM {table_name} WHERE meta_key = %s AND meta_value = %s', $meta_key, $abandoned_cart_id );
$result = BWFAN_Model_Taskmeta::get_results( $query );
if ( ! is_array( $result ) || count( $result ) === 0 ) {
return;
}
$task_ids = array();
foreach ( $result as $value1 ) {
$task_ids[] = $value1['bwfan_task_id'];
}
BWFAN_Core()->tasks->delete_tasks( $task_ids );
}
/**
* This function checks for all the active carts. If last modified time of active carts exceeds the global cart timeout setting,
* then those carts will me made as abandoned.
*/
public static function check_for_abandoned_carts() {
if ( ! class_exists( 'WooCommerce' ) && bwf_has_action_scheduled( 'bwfan_check_abandoned_carts' ) ) {
bwf_unschedule_actions( 'bwfan_check_abandoned_carts' );
return;
}
$global_settings = self::get_global_settings();
if ( empty( $global_settings['bwfan_ab_enable'] ) ) {
return;
}
/** Maybe run */
if ( false === BWFAN_Model_Abandonedcarts::maybe_run( $global_settings['bwfan_ab_init_wait_time'] ) ) {
return;
}
$all_sources = BWFAN_Load_Sources::get_all_sources_obj();
$all_sources['wc']['ab_cart_abandoned']->load_hooks();
$all_sources['wc']['ab_cart_abandoned']->get_eligible_abandoned_rows();
}
/**
* Delete all the old abandoned rows from db table. This function runs once in a week.
*/
public static function delete_old_abandoned_carts() {
if ( false === apply_filters( 'bwfan_ab_delete_inactive_carts', false ) ) {
return;
}
global $wpdb;
$global_settings = self::get_global_settings();
$abandoned_time_in_days = absint( $global_settings['bwfan_ab_remove_inactive_cart_time'] ) * 1440;
$query = $wpdb->prepare( 'select T.ID from {table_name} T where TIMESTAMPDIFF(MINUTE,T.last_modified,UTC_TIMESTAMP) > %d', $abandoned_time_in_days );
$abandoned_carts = BWFAN_Model_Abandonedcarts::get_results( $query );
if ( ! is_array( $abandoned_carts ) || count( $abandoned_carts ) === 0 ) {
return;
}
$abandoned_cart_ids = array();
foreach ( $abandoned_carts as $value1 ) {
$abandoned_cart_ids[] = $value1['ID'];
}
$automationCount = count( $abandoned_cart_ids );
$stringPlaceholders = array_fill( 0, $automationCount, '%s' );
$placeholdersautomation = implode( ', ', $stringPlaceholders );
$sql_query = "Delete FROM {table_name} WHERE ID IN ($placeholdersautomation)";
$sql_query = $wpdb->prepare( $sql_query, $abandoned_cart_ids );// phpcs:ignore WordPress.DB.PreparedSQL
BWFAN_Model_Abandonedcarts::delete_multiple( $sql_query );
}
/**
* Scheduling recurring action for marking lost cart
*
* @return void
*/
public static function mark_abandoned_lost_cart() {
if ( ! class_exists( 'WooCommerce' ) && bwf_has_action_scheduled( 'bwfan_mark_abandoned_lost_cart' ) ) {
bwf_unschedule_actions( 'bwfan_mark_abandoned_lost_cart' );
return;
}
if ( ! bwf_has_action_scheduled( 'bwfan_lost_cart_triggered' ) ) {
bwf_schedule_recurring_action( time(), 120, 'bwfan_lost_cart_triggered' );
}
}
/**
* Mark cart lost action callback
*
* @return void
*/
public static function bwfan_lost_cart_triggered() {
global $wpdb;
$global_settings = self::get_global_settings();
$abandoned_time_in_days = absint( $global_settings['bwfan_ab_mark_lost_cart'] ) * 1440;
$start_time = time();
do {
/** Get carts to mark lost carts */
$query = "SELECT ID, email FROM {$wpdb->prefix}bwfan_abandonedcarts WHERE TIMESTAMPDIFF(MINUTE,last_modified,UTC_TIMESTAMP) > %d AND `status` != %d LIMIT %d";
$query = $wpdb->prepare( $query, $abandoned_time_in_days, 2, 10 );// phpcs:ignore WordPress.DB.PreparedSQL
$carts = $wpdb->get_results( $query, ARRAY_A ); //phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL
/** Un-schedule the action if no cart found */
if ( empty( $carts ) ) {
bwf_unschedule_actions( 'bwfan_lost_cart_triggered' );
return;
}
/** Add lost tags & lists */
self::add_lost_cart_tags( $carts );
$ids = array_column( $carts, 'ID' );
$stringPlaceholders = array_fill( 0, count( $ids ), '%d' );
$placeholder = implode( ', ', $stringPlaceholders );
/** Changing status recoverable into lost cart */
$wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->prefix}bwfan_abandonedcarts SET `status` = 2 WHERE ID IN ( $placeholder )", $ids ) ); //phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL, WordPress.DB.PreparedSQLPlaceholders
} while ( ( time() - $start_time ) > 10 );
}
/**
* Add tags and list to lost carts
*
* @param $carts
*
* @return void
*/
public static function add_lost_cart_tags( $carts ) {
if ( ! class_exists( 'BWFCRM_Contact' ) || ! is_array( $carts ) || 0 === count( $carts ) ) {
return;
}
if ( false === method_exists( 'BWFAN_Model_Terms', 'get_crm_term_ids' ) ) {
/** Pro version 2.4.4 or higher required */
return;
}
$global_settings = self::get_global_settings();
$lost_cart_tags = isset( $global_settings['bwfan_lostcart_tag_selector'] ) ? json_decode( $global_settings['bwfan_lostcart_tag_selector'], true ) : [];
$lost_cart_tags = BWFAN_Model_Terms::get_crm_term_ids( $lost_cart_tags, BWFCRM_Term_Type::$TAG );
$lost_cart_list = isset( $global_settings['bwfan_lostcart_list_selector'] ) ? $global_settings['bwfan_lostcart_list_selector'] : [];
$lost_cart_list = BWFAN_Model_Terms::get_crm_term_ids( $lost_cart_list, BWFCRM_Term_Type::$LIST );
/** If tags & lists are not set in setting */
if ( empty( $lost_cart_tags ) && empty( $lost_cart_list ) ) {
return;
}
foreach ( $carts as $cart ) {
$contact = new BWFCRM_Contact( $cart['email'] );
if ( ! $contact->is_contact_exists() ) {
continue;
}
if ( ! empty( $lost_cart_tags ) ) {
$contact->set_tags_v2( $lost_cart_tags );
}
if ( ! empty( $lost_cart_list ) ) {
$contact->set_lists_v2( $lost_cart_list );
}
$contact->save();
}
}
/**
* Delete all the old abandoned rows from db table. This function runs once in a week.
*/
public static function delete_expired_autonami_coupons() {
if ( ! class_exists( 'WooCommerce' ) && bwf_has_action_scheduled( 'bwfan_delete_expired_autonami_coupons' ) ) {
bwf_unschedule_actions( 'bwfan_delete_expired_autonami_coupons' );
return;
}
global $wpdb;
$global_settings = self::get_global_settings();
/** 1 day = 1440 minutes */
$coupon_time_in_days = absint( $global_settings['bwfan_delete_autonami_generated_coupons_time'] ) * 1440;
if ( ( 30 * 1440 ) < $coupon_time_in_days ) {
$coupon_time_in_days = 30 * 1440;
}
$query = $wpdb->prepare( "
SELECT m1.post_id as id
FROM {$wpdb->prefix}postmeta as m1
LEFT JOIN {$wpdb->prefix}postmeta as m2
ON m1.post_id = m2.post_id
LEFT JOIN {$wpdb->prefix}postmeta as m3
ON m1.post_id = m3.post_id
WHERE m1.meta_key = %s
AND m1.meta_value = %d
AND m2.meta_key = %s
AND TIMESTAMPDIFF(MINUTE,FROM_UNIXTIME(m2.meta_value),UTC_TIMESTAMP) > %d
AND m3.meta_key= %s
AND m3.meta_value <>''
", '_is_bwfan_coupon', 1, 'date_expires', $coupon_time_in_days, 'date_expires' );
$coupons = $wpdb->get_results( $query ); //phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL
if ( empty( $coupons ) ) {
return;
}
foreach ( $coupons as $coupon ) {
wp_delete_post( $coupon->id, true );
}
}
/**
* Get all the scheduled task of given automation ids and the contact email
*
* @param array $winback_automations
* @param string $email
*
* @return array
*/
public static function get_schedule_task_by_email( $winback_automations, $email ) {
global $wpdb;
$task_table_name = $wpdb->prefix . 'bwfan_tasks';
$task_meta_table_name = $wpdb->prefix . 'bwfan_taskmeta';
$tasks_results = array();
if ( empty( $winback_automations ) || empty( $email ) ) {
return $tasks_results;
}
foreach ( $winback_automations as $automation_id ) {
$query = $wpdb->prepare( "SELECT t.ID FROM $task_table_name AS t JOIN $task_meta_table_name AS tm ON t.ID=tm.bwfan_task_id WHERE t.automation_id = %d AND tm.meta_key='integration_data' AND tm.meta_value LIKE %s", $automation_id, '%' . $email . '%' );// phpcs:ignore WordPress.DB.PreparedSQL, WordPress.DB.PreparedSQLPlaceholders
$tasks_results[ $automation_id ] = $wpdb->get_results( $query, ARRAY_A ); //phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL
}
return $tasks_results;
}
/**
* Get all the scheduled tasks of given automation ids and the contact phone number
*
* @param $winback_automations
* @param $phone
*
* @return array
*/
public static function get_schedule_task_by_phone( $winback_automations, $phone ) {
global $wpdb;
$task_table_name = $wpdb->prefix . 'bwfan_tasks';
$task_meta_table_name = $wpdb->prefix . 'bwfan_taskmeta';
$tasks_results = array();
if ( empty( $winback_automations ) || empty( $phone ) ) {
return $tasks_results;
}
foreach ( $winback_automations as $automation_id ) {
$query = $wpdb->prepare( "SELECT t.ID FROM $task_table_name AS t JOIN $task_meta_table_name AS tm ON t.ID=tm.bwfan_task_id WHERE t.automation_id = %d AND tm.meta_key='integration_data' AND tm.meta_value LIKE %s", $automation_id, '%' . $phone . '%' );// phpcs:ignore WordPress.DB.PreparedSQL, WordPress.DB.PreparedSQLPlaceholders
$tasks_results[ $automation_id ] = $wpdb->get_results( $query, ARRAY_A ); //phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL
}
return $tasks_results;
}
public static function wc_get_cart_recovery_url( $token, $coupon = '', $lang = '', $data = [] ) {
$checkout_id = get_option( 'woocommerce_checkout_page_id' );
if ( isset( $data['aerocheckout_page_id'] ) && intval( $data['aerocheckout_page_id'] ) > 0 && 'publish' === get_post_status( $data['aerocheckout_page_id'] ) ) {
$is_global_checkout = $data['aero_data']['wfacp_is_checkout_override'] ?? false;
if ( empty( $is_global_checkout ) ) {
$checkout_id = $data['aerocheckout_page_id'];
}
}
/**
* Making checkout page compatible with the WPML
* Trying & getting the base language translation post to validate the checkout page
*/
$url = ! empty( $checkout_id ) ? self::get_permalink_by_language( $checkout_id, $lang ) : '';
if ( empty( $url ) ) {
$url = home_url();
}
$url = self::maybe_modify_recovery_link( $url, $data, $lang );
$url = add_query_arg( array(
'bwfan-ab-id' => $token,
), $url );
if ( ! empty( $coupon ) ) {
$url = add_query_arg( array(
'bwfan-coupon' => preg_replace( "/?[a-z0-9]{2,8};/i", "", $coupon ),
), $url );
}
return apply_filters( 'bwfan_abandoned_cart_restore_link', $url, $token, $coupon );
}
/**
* @param $post_id
* @param string $lang
*
* Get permalink by language
*
* @return false|mixed|string|void
*/
public static function get_permalink_by_language( $post_id, $lang = '' ) {
$url = get_permalink( $post_id );
$url = empty( $url ) ? home_url() : $url;
if ( defined( 'ICL_SITEPRESS_VERSION' ) ) {
global $sitepress;
$language_code = $sitepress->get_default_language();
if ( ! empty( $lang ) ) {
$language_code = $lang;
}
if ( version_compare( ICL_SITEPRESS_VERSION, '3.2' ) > 0 ) {
$post_id = apply_filters( 'wpml_object_id', $post_id, 'page', false, $language_code );
} else {
$post_id = wpml_object_id_filter( $post_id, 'page', false, $language_code );
}
$url = apply_filters( 'wpml_permalink', $url, $language_code );
}
/** in case of translatepress */
if ( bwfan_is_translatepress_active() ) {
$trp_settings = get_option( 'trp_settings' );
$language_code = $trp_settings['default-language'];
if ( ! empty( $lang ) ) {
$language_code = $lang;
}
$trp = TRP_Translate_Press::get_trp_instance();
$url_converter = $trp->get_component( 'url_converter' );
$url = $url_converter->get_url_for_language( $language_code, $url, '' );
}
/** for polylang language */
if ( function_exists( 'pll_current_language' ) ) {
$language_code = pll_default_language();
if ( ! empty( $lang ) ) {
$language_code = $lang;
}
$url = add_query_arg( array(
'lang' => $language_code,
), $url );
}
if ( function_exists( 'bwfan_is_weglot_active' ) && bwfan_is_weglot_active() ) {
$language_code = weglot_get_original_language();
if ( ! empty( $lang ) ) {
$language_code = $lang;
}
$site_url = home_url();
$url = str_replace( $site_url, $site_url . '/' . $language_code, $url );
}
/** For GTranslate */ //
if ( function_exists( 'bwfan_is_gtranslate_active' ) && bwfan_is_gtranslate_active() && ! empty( $lang ) ) {
$url = class_exists( 'BWFAN_Compatibility_With_GTRANSLATE' ) ? BWFAN_Compatibility_With_GTRANSLATE::get_translated_domain_url( $url, $lang ) : $url;
}
return $url;
}
public static function maybe_modify_recovery_link( $url, $data = [], $lang = '' ) {
/** for polylang language */
if ( function_exists( 'pll_current_language' ) ) {
return apply_filters( 'bwfan_modify_checkout_recovery_url_polylang', $url, $data, $lang );
}
return $url;
}
/**
* Get all the abandoned carts by email with status 1 and 2
*
* @param $email
*
* @return array|null|object|void
*/
public static function get_email_abandoned( $email ) {
if ( empty( $email ) ) {
return;
}
global $wpdb;
$abandoned_table = $wpdb->prefix . 'bwfan_abandonedcarts';
$abandoned_data = $wpdb->get_results( "select ID,last_modified from $abandoned_table where status in(1,2) and email='" . $email . "' order by last_modified limit 0,3", ARRAY_A ); //phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL, WordPress.DB.PreparedSQLPlaceholders
return $abandoned_data;
}
/**
* Set the status 3 i.e. aborted of the abandoned cart
*
* @param $abandoned_id
*/
public static function set_email_cart_aborted( $abandoned_id ) {
if ( empty( $abandoned_id ) ) {
return;
}
$data = [];
$data['status'] = 3;
$where = array(
'ID' => $abandoned_id,
);
BWFAN_Model_Abandonedcarts::update( $data, $where );
}
public static function merge_default_actions() {
$all_automations = self::get_default_connector();
$integrations = self::get_default_actions();
$default_data = array();
foreach ( $all_automations as $a_slug => $automation ) {
$nice_name = $automation['nice_name'];
if ( isset( $integrations[ $a_slug ] ) ) {
$actions = $integrations[ $a_slug ];
foreach ( $actions as $slug => $action ) {
if ( ! class_exists( 'bwfan_' . $slug ) || ! bwfan_is_autonami_pro_active() ) {
$default_data[ $nice_name ][ $slug ] = $action;
}
}
}
}
return empty( $default_data ) ? new stdClass() : $default_data;
}
public static function get_default_connector() {
return array(
'wc' => array(
'nice_name' => __( 'WooCommerce', 'wp-marketing-automations' ),
'slug' => 'wp_adv',
'connector_slug' => '',
'native_integration' => true,
),
'wp_adv' => array(
'nice_name' => __( 'WordPress Advanced', 'wp-marketing-automations' ),
'slug' => 'wp_adv',
'connector_slug' => '',
'native_integration' => true,
),
'activecampaign' => array(
'nice_name' => __( 'ActiveCampaign', 'wp-marketing-automations' ),
'slug' => 'activecampaign',
'connector_slug' => 'bwfco_activecampaign',
'native_integration' => false,
),
'drip' => array(
'nice_name' => __( 'Drip', 'wp-marketing-automations' ),
'slug' => 'drip',
'connector_slug' => 'bwfco_drip',
'native_integration' => false,
),
'google_sheets' => array(
'nice_name' => __( 'Google Sheets', 'wp-marketing-automations' ),
'slug' => 'google_sheets',
'connector_slug' => 'bwfco_google_sheets',
'native_integration' => false,
),
'slack' => array(
'nice_name' => __( 'Slack', 'wp-marketing-automations' ),
'slug' => 'slack',
'connector_slug' => 'bwfco_slack',
'native_integration' => false,
),
'zapier' => array(
'nice_name' => __( 'Zapier', 'wp-marketing-automations' ),
'slug' => 'zapier',
'connector_slug' => '',
'native_integration' => false,
),
);
}
public static function get_default_actions() {
return array(
'wc' => array(
'wc_change_order_status' => __( 'Change Order Status', 'wp-marketing-automations' ),
'wc_add_order_note' => __( 'Add Order Note', 'wp-marketing-automations' ),
'wc_remove_coupon' => __( 'Delete Coupon', 'wp-marketing-automations' ),
),
'activecampaign' => array(
'ac_create_contact' => __( 'Create Contact', 'wp-marketing-automations' ),
'ac_add_tag' => __( 'Add Tags', 'wp-marketing-automations' ),
'ac_rmv_tag' => __( 'Remove Tags', 'wp-marketing-automations' ),
'ac_add_to_automation' => __( 'Add Contact To Automation', 'wp-marketing-automations' ),
'ac_rmv_from_automation' => __( 'Remove Contact From Automation', 'wp-marketing-automations' ),
'ac_add_to_list' => __( 'Add Contact To List', 'wp-marketing-automations' ),
'ac_rmv_from_list' => __( 'Remove Contact From List', 'wp-marketing-automations' ),
'ac_create_abandoned_cart' => __( 'Create Abandoned Cart', 'wp-marketing-automations' ),
'ac_create_order' => __( 'Create Order', 'wp-marketing-automations' ),
'ac_create_deal' => __( 'Create Deal', 'wp-marketing-automations' ),
'ac_create_deal_note' => __( 'Create Deal Note', 'wp-marketing-automations' ),
'ac_update_deal' => __( 'Update Deal', 'wp-marketing-automations' ),
'ac_update_customfields' => __( 'Update Fields', 'wp-marketing-automations' ),
),
'drip' => array(
'dr_create_subscriber' => __( 'Create / Update Subscriber', 'wp-marketing-automations' ),
'dr_add_tags' => __( 'Add Tags', 'wp-marketing-automations' ),
'dr_rmv_tags' => __( 'Remove Tags', 'wp-marketing-automations' ),
'dr_add_to_campaign' => __( 'Add Subscriber to Campaign', 'wp-marketing-automations' ),
'dr_rmv_from_campaign' => __( 'Remove Subscriber from Campaign', 'wp-marketing-automations' ),
'dr_add_to_workflow' => __( 'Add Subscriber to Workflow', 'wp-marketing-automations' ),
'dr_rmv_from_workflow' => __( 'Remove Subscriber from Workflow', 'wp-marketing-automations' ),
'dr_add_cart' => __( 'Cart Activity', 'wp-marketing-automations' ),
'dr_add_order' => __( 'Add A New Order', 'wp-marketing-automations' ),
'dr_add_customfields' => __( 'Update Custom fields of Subscriber', 'wp-marketing-automations' ),
),
'convertkit' => array(
'ck_add_customfields' => __( 'Update Custom Fields', 'wp-marketing-automations' ),
'ck_add_tags' => __( 'Add Tags', 'wp-marketing-automations' ),
'ck_rmv_tags' => __( 'Remove Tags', 'wp-marketing-automations' ),
'ck_add_to_sequence' => __( 'Add Subscriber To Sequence', 'wp-marketing-automations' ),
'ck_rmv_from_sequence' => __( 'Remove Subscriber from Sequence', 'wp-marketing-automations' ),
'ck_add_order' => __( 'Create A New Purchase', 'wp-marketing-automations' ),
),
'google_sheets' => array(
'gs_insert_data' => __( 'Insert Row', 'wp-marketing-automations' ),
'gs_update_data' => __( 'Update Row', 'wp-marketing-automations' ),
),
'slack' => array(
'sl_message_user' => __( 'Sends a message to a user', 'wp-marketing-automations' ),
'sl_message' => __( 'Sends a message to a channel', 'wp-marketing-automations' ),
),
'zapier' => array(
'za_send_data' => __( 'Send data to zapier', 'wp-marketing-automations' ),
),
'twilio' => array(
'twilio_send_sms' => __( 'Send SMS', 'wp-marketing-automations' ),
),
'wp_adv' => array(
'wp_createuser' => __( 'Create User', 'wp-marketing-automations' ),
'wp_update_user_meta' => __( 'Update User Meta', 'wp-marketing-automations' ),
'wp_http_post' => __( 'HTTP Post', 'wp-marketing-automations' ),
'wp_custom_callback' => __( 'Custom Callback', 'wp-marketing-automations' ),
'wp_debug' => __( 'Debug', 'wp-marketing-automations' ),
),
);
}
public static function merge_pro_events( $events ) {
$default = self::default_events();
foreach ( $default as $slug => $data ) {
if ( ! class_exists( 'BWFAN_' . $slug ) || ! bwfan_is_autonami_pro_active() ) {
$source_type = $data['source_type'];
$events[ $source_type ]['events']['Upstroke'][ $slug ] = array(
'name' => $data['event_name'],
'available' => 'no',
);
}
}
return $events;
}
public static function default_events() {
return array();
return array(
'wf_offer_viewed' => array(
'source_type' => 'wc',
'event_name' => __( 'Offer Viewed', 'wp-marketing-automations' ),
'event_desc' => 'This automation would trigger when an offer is viewed by the user.',
'slug' => 'wf_offer_viewed',
'is_time_independent' => false,
'excluded_actions' => array(),
'event_saved_data' => array(),
'available' => 'no',
),
'wf_product_accepted' => array(
'source_type' => 'wc',
'event_name' => __( 'Offer Accepted', 'wp-marketing-automations' ),
'event_desc' => 'This automation would trigger when an upstroke offer is accepted by the user.',
'slug' => 'wf_product_accepted',
'is_time_independent' => false,
'excluded_actions' => array(),
'event_saved_data' => array(),
'available' => 'no',
),
'wf_offer_payment_failed' => array(
'source_type' => 'wc',
'event_name' => __( 'Offer Payment Failed', 'wp-marketing-automations' ),
'event_desc' => 'This automation would trigger when the payment is failed while accepting an offer.',
'slug' => 'wf_offer_payment_failed',
'is_time_independent' => false,
'excluded_actions' => array(),
'event_saved_data' => array(),
'available' => 'no',
),
'wf_offer_rejected' => array(
'source_type' => 'wc',
'event_name' => __( 'Offer Rejected', 'wp-marketing-automations' ),
'event_desc' => 'This automation would trigger when an offer is rejected by the user.',
'slug' => 'wf_offer_rejected',
'is_time_independent' => false,
'excluded_actions' => array(),
'event_saved_data' => array(),
'available' => 'no',
),
);
}
/**
* Get Autonami notifications only
*
* @return array
*/
public static function get_autonami_notifications() {
if ( ! class_exists( 'WooFunnels_Notifications' ) ) {
return array();
}
$notifications_list = WooFunnels_Notifications::get_instance()->get_all_notifications();
if ( ! is_array( $notifications_list ) || ! isset( $notifications_list['bwfan'] ) ) {
return array();
}
if ( ! is_array( $notifications_list['bwfan'] ) || count( $notifications_list['bwfan'] ) === 0 ) {
return array();
}
return array(
'bwfan' => $notifications_list['bwfan'],
);
}
/**
* Used as fallback to make sure all the tasks run on the thank you page
*/
public static function hit_cron_to_run_tasks() {
$url = rest_url( '/autonami/v1/autonami-cron' );
$args = bwf_get_remote_rest_args( array(), 'GET' );
wp_remote_post( $url, $args );
}
public static function add_ordinal_number_suffix( $num ) {
if ( ! in_array( ( $num % 100 ), array( 11, 12, 13 ), true ) ) {
switch ( $num % 10 ) {
// Handle 1st, 2nd, 3rd
case 1:
return $num . 'st';
case 2:
return $num . 'nd';
case 3:
return $num . 'rd';
}
}
return $num . 'th';
}
public static function bwfan_recipe_list_template() {
ob_start();
include plugin_dir_path( __FILE__ ) . 'bwfan-recipe-list-template.php';
return ob_get_clean();
}
public static function auto_apply_wc_coupon() {
if ( ! isset( $_GET['bwfan-coupon'] ) || empty( $_GET['bwfan-coupon'] ) ) { //phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput
return;
}
$coupon_code = $_GET['bwfan-coupon']; //phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput
if ( WC()->cart instanceof WC_Cart && ! empty( $coupon_code ) && ! WC()->cart->has_discount( $coupon_code ) ) {
/** Keep existing wc notices */
$wc_notices = wc_get_notices();
WC()->cart->add_discount( $coupon_code );
/** Add all old wc notices back */
WC()->session->set( 'wc_notices', $wc_notices );
}
}
public static function mark_automation_require_update( $automation_id, $state = true ) {
if ( empty( $automation_id ) ) {
return;
}
$meta_data = array(
'meta_value' => ( true === $state ) ? 1 : 0,
);
$where = array(
'bwfan_automation_id' => $automation_id,
'meta_key' => 'requires_update',
);
BWFAN_Model_Automationmeta::update( $meta_data, $where );
}
/**
* checking plugin dependency
*
* @param $plugin_depend
*
* @return array|bool
*/
public static function plugin_dependency_check( $plugin_depend ) {
if ( empty( $plugin_depend ) ) {
return true;
}
$plugin_error = array();
foreach ( $plugin_depend as $plugins ) {
$function_name = 'bwfan_is_' . $plugins . '_active';
/** checking if function exists */
if ( ! function_exists( $function_name ) ) {
continue;
}
if ( false === $function_name() ) {
$nice_name = self::plugin_dependency_nice_names( $plugins );
$plugin_error[] = "{$nice_name} plugin is not active.";
}
}
return empty( $plugin_error ) ? true : $plugin_error;
}
public static function plugin_dependency_nice_names( $slug ) {
switch ( $slug ) {
case 'woocommerce':
$slug = 'WooCommerce';
break;
case 'edd':
$slug = 'Easy Digital Downloads';
break;
case 'woocommerce_subscriptions':
$slug = 'WooCommerce Subscriptions';
break;
case 'woocommerce_membership':
$slug = 'WooCommerce Membership';
break;
case 'woofunnels_upstroke':
$slug = 'FunnelKit Upsells';
break;
case 'autonami_pro':
$slug = 'FunnelKit Automations Pro';
break;
case 'autonami_connector':
$slug = 'FunnelKit Automations Connectors';
break;
case 'affiliatewp':
$slug = 'AffiliateWP';
break;
}
return $slug;
}
/**
* Load Hooks after Action Scheduler is loaded
*/
public static function bwf_after_action_scheduler_load() {
/** Schedule WP cron event */
add_action( 'admin_init', array( __CLASS__, 'maybe_set_bwf_ct_worker' ) );
}
/**
* Register WP cron schedules
*
* @param $schedules
*
* @return void
*/
public static function add_schedules( $schedules ) {
$schedules['fka_eight_hours'] = [
'interval' => 28800,
'display' => 'Every Eight hours'
];
return $schedules;
}
/**
* Scheduling event with core callback
*/
public static function maybe_set_bwf_ct_worker() {
if ( ! wp_next_scheduled( 'bwf_as_run_queue' ) ) {
wp_schedule_event( time(), 'bwf_every_minute', 'bwf_as_run_queue' );
}
if ( ! wp_next_scheduled( 'fka_clear_duplicate_actions' ) ) {
wp_schedule_event( time(), 'fka_eight_hours', 'fka_clear_duplicate_actions' );
}
}
public static function hide_free_products_cart_order_items() {
return apply_filters( 'bwfan_items_display_hide_free_products', false );
}
/**
* Return if emogrifier library is supported.
*
* @return bool
* @since 3.5.0
*/
public static function supports_emogrifier() {
return class_exists( 'DOMDocument' ) && version_compare( PHP_VERSION, '5.5', '>=' );
}
public static function color_light_or_dark( $color, $dark = '#000000', $light = '#FFFFFF' ) {
return self::color_hex_is_light( $color ) ? $dark : $light;
}
public static function color_hex_is_light( $color ) {
$hex = str_replace( '#', '', $color );
$c_r = hexdec( substr( $hex, 0, 2 ) );
$c_g = hexdec( substr( $hex, 2, 2 ) );
$c_b = hexdec( substr( $hex, 4, 2 ) );
$brightness = ( ( $c_r * 299 ) + ( $c_g * 587 ) + ( $c_b * 114 ) ) / 1000;
return $brightness > 155;
}
public static function maybe_clear_cache() {
/**
* Clear WordPress cache
*/
if ( function_exists( 'wp_cache_flush' ) ) {
wp_cache_flush();
}
/**
* Checking if wp fastest cache installed
* Clear cache of wp fastest cache
*/
if ( class_exists( 'WpFastestCache' ) ) {
global $wp_fastest_cache;
if ( method_exists( $wp_fastest_cache, 'deleteCache' ) ) {
$wp_fastest_cache->deleteCache();
}
// clear all cache
if ( function_exists( 'wpfc_clear_all_cache' ) ) {
wpfc_clear_all_cache( true );
}
}
/**
* Checking if wp Autoptimize installed
* Clear cache of Autoptimize
*/
if ( class_exists( 'autoptimizeCache' ) ) {
autoptimizeCache::clearall();
}
/**
* Checking if W3Total Cache plugin activated.
* Clear cache of W3Total Cache plugin
*/
if ( function_exists( 'w3tc_flush_all' ) ) {
w3tc_flush_all();
}
}
/**
* Updating marketing_status in order meta
*
* @param $order
*
* @return void
*/
public static function bwfan_update_order_user_consent( $order ) {
$marketing_status = isset( $_POST['bwfan_user_consent'] ) ? absint( $_POST['bwfan_user_consent'] ) : 0; //phpcs:ignore WordPress.Security.NonceVerification
$order->update_meta_data( 'marketing_status', $marketing_status );
$order->save_meta_data();
}
/** updating contact marketing status
*
* @param WooFunnels_Contact $contact
* @param int $order_id
*/
public static function save_marketing_status_for_user( $contact, $order_id ) {
$order = wc_get_order( absint( $order_id ) );
if ( ! $order instanceof WC_Order ) {
return;
}
$marketing_status = $order->get_meta( 'marketing_status' );
if ( empty( $marketing_status ) ) {
return;
}
/** Below code will mark the contact subscribe as we get user consent from the checkout */
/** If unsubscribed rows found for the contact, then remove */
$has_unsubscribed = self::maybe_delete_unsubscribe_rows( $contact );
/** in case contact already subscribed and earlier not unsubscribe than return */
if ( 1 === intval( $contact->get_status() ) && false === $has_unsubscribed ) {
return;
}
/** Added filter to allow double optin and can still make the contact unverified in case of consent is checked */
$is_single_optin = apply_filters( 'bwfcrm_contact_enable_single_optin', true, $contact, $order, $marketing_status );
if ( false === $is_single_optin ) {
$contact->set_status( 0 );
$contact->save();
return;
}
/** Manually set the prop to trigger the subscribe event run in case it was unsubscribed earlier */
if ( true === $has_unsubscribed ) {
$contact->is_subscribed = true;
}
$contact->set_status( 1 );
$contact->save();
}
/**
* Save marketing status if order failed
*
* @param $order_id
* @param $order
*
* @return void
*/
public static function woocommerce_order_status_failed( $order_id, $order ) {
if ( ! $order instanceof WC_Order ) {
return;
}
$cid = $order->get_meta( '_woofunnel_cid' );
$contact = '';
if ( 0 === intval( $cid ) ) {
$contact = new WooFunnels_Contact( '', '', '', $cid );
}
/** Get contact object by email or user id */
if ( empty( $contact ) || empty( $contact->get_id() ) ) {
$contact = bwf_get_contact( $order->get_user_id(), $order->get_billing_email() );
}
if ( empty( $contact ) || empty( $contact->get_id() ) ) {
return;
}
self::save_marketing_status_for_user( $contact, $order_id );
}
public static function get_form_submit_events() {
return apply_filters( 'bwfan_get_form_submit_events', array( 'BWFAN_CF7_Form_Submit' ) );
}
/**
* Get automations by title for different versions
*
* @param $search
* @param $version
* @param $ids
* @param $limit
* @param $offset
*
* @return array|object|stdClass[]|null
*/
public static function get_automation_by_title( $search, $version = 0, $ids = [], $limit = 10, $offset = 0 ) {
global $wpdb;
/** Search all automation from v1 and v2 */
if ( 0 === absint( $version ) ) {
return self::search_automation_by_title( $search, $limit, $offset );
}
$query = '';
$id_query = '';
if ( ! empty( $ids ) ) {
$id_query = " AND ID IN(" . implode( ',', $ids ) . ") ";
}
$where = $wpdb->prepare( "AND v = %d ", $version );
switch ( absint( $version ) ) {
case 2 :
if ( ! empty( $search ) ) {
$where .= $wpdb->prepare( " AND title LIKE %s ", '%' . $search . '%' );
}
$query = "SELECT ID as id, title FROM {$wpdb->prefix}bwfan_automations WHERE 1=1 $where $id_query ORDER BY title ASC";
break;
case 1 :
if ( ! empty( $search ) ) {
$where .= $wpdb->prepare( " AND am.meta_value LIKE %s AND am.meta_key = 'title'", '%' . $search . '%' );
}
$query = "SELECT am.bwfan_automation_id AS id,am.meta_value AS title FROM {$wpdb->prefix}bwfan_automationmeta AS am WHERE 1=1 $where $id_query GROUP BY am.bwfan_automation_id ORDER BY am.meta_value ASC";
break;
}
if ( ! empty( $limit ) ) {
$query .= " LIMIT %d, %d";
$query = $wpdb->prepare( $query, $offset, $limit );// phpcs:ignore WordPress.DB.PreparedSQL
}
return ! empty( $query ) ? $wpdb->get_results( $query, ARRAY_A ) : []; //phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL
}
/**
* Get automations by title
*
* @param $search
* @param $limit
* @param $offset
*
* @return array|object|stdClass[]|null
*/
public static function search_automation_by_title( $search = '', $limit = 10, $offset = 0 ) {
global $wpdb;
$where = '';
/** Search automations by title form automation table */
if ( ! empty( $search ) ) {
$where = $wpdb->prepare( " WHERE title LIKE %s ", '%' . $search . '%' );
}
$query = "SELECT ID as id, title FROM {$wpdb->prefix}bwfan_automations $where ORDER BY title ASC";
if ( ! empty( $limit ) ) {
$query .= " LIMIT %d, %d";
$query = $wpdb->prepare( $query, $offset, $limit );// phpcs:ignore WordPress.DB.PreparedSQL
}
$automations = $wpdb->get_results( $query, ARRAY_A ); //phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL
/** Search automations by title form automation meta table */
if ( ! empty( $search ) ) {
$where = $wpdb->prepare( " WHERE am.meta_value LIKE %s AND am.meta_key = 'title'", '%' . $search . '%' );
}
$meta_query = "SELECT am.bwfan_automation_id AS id,am.meta_value AS title FROM {$wpdb->prefix}bwfan_automationmeta AS am $where GROUP BY am.bwfan_automation_id ORDER BY am.meta_value ASC";
if ( ! empty( $limit ) ) {
$meta_query .= " LIMIT %d, %d";
$meta_query = $wpdb->prepare( $meta_query, $offset, $limit );// phpcs:ignore WordPress.DB.PreparedSQL
}
$automation_meta = $wpdb->get_results( $meta_query, ARRAY_A ); //phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL
return array_merge( $automations, $automation_meta );
}
/**
* @param $search
* @param $offset
* @param $limit
*/
public static function get_unsubscribers( $search = '', $offset = 0, $limit = 25 ) {
global $wpdb;
$where = '';
$args = [];
/** Check for search unsubscriber */
if ( ! empty( $search ) ) {
$where = $wpdb->prepare( " WHERE `recipient` LIKE %s ", '%' . $search . '%' );
$args['recipient'] = array(
'operator' => '%s',
'value' => "%" . $search . "%",
);
}
/** Query to fetch unsubscribers data from DB */
$unsubscribers = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}bwfan_message_unsubscribe $where ORDER BY ID DESC LIMIT %d, %d ", $offset, $limit ) ); //phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL
if ( empty( $unsubscribers ) ) {
return array();
}
$found_posts = array();
$items = array();
foreach ( $unsubscribers as $unsubscriber ) {
$c_type = absint( $unsubscriber->c_type );
$oid = empty( $unsubscriber->automation_id ) ? 0 : absint( $unsubscriber->automation_id );
$otype = '';
$oname = '';
if ( 1 === $c_type ) {
$automation_meta = BWFAN_Core()->automations->get_automation_data_meta( $oid );
$oname = isset( $automation_meta['title'] ) && ! empty( $automation_meta['title'] ) ? $automation_meta['title'] : __( 'No Title', 'wp-marketing-automations' );
$otype = __( 'Automation', 'wp-marketing-automations' );
} elseif ( 2 === $c_type ) {
$broadcast = bwfan_is_autonami_pro_active() ? BWFAN_Model_Broadcast::get( $oid ) : array();
$oname = isset( $broadcast['title'] ) ? $broadcast['title'] : __( 'No Title', 'wp-marketing-automations' );
$otype = __( 'Broadcast', 'wp-marketing-automations' );
} elseif ( $c_type > 2 ) {
$otype = __( 'Manual', 'wp-marketing-automations' );
}
$items[] = array(
'id' => $unsubscriber->ID,
'recipient' => $unsubscriber->recipient,
'date' => date( self::get_date_format(), strtotime( $unsubscriber->c_date ) ),// phpcs:ignore WordPress.DateTime.RestrictedFunctions
'automation_id' => $oid,
'automation_name' => empty( $oname ) && empty( $otype ) ? '-' : ( empty( $oname ) ? $otype : "$otype: $oname" ),
'source_type' => $c_type,
);
}
$count = BWFAN_Model_Message_Unsubscribe::count( $args );
$found_posts['found_posts'] = empty( $count ) ? 0 : absint( $count );
$found_posts['items'] = $items;
return $found_posts;
}
public static function get_date_format() {
return self::bwfan_get_date_format() . ' ' . self::bwfan_get_time_format();
}
/** run global tools
*
* @param $tool_type
* @param $data
*
* @return array
*/
public static function run_global_tools( $tool_type, $data = [] ) {
global $wpdb;
$result = array();
switch ( $tool_type ) {
case 'run_all_tasks':
$result['msg'] = __( 'All queued tasks have been scheduled to run now', 'wp-marketing-automations' );
$all_tasks = BWFAN_Core()->tasks->get_all_tasks();
if ( ! is_array( $all_tasks ) || 0 === count( $all_tasks ) ) {
$result['msg'] = __( 'There are no tasks.', 'wp-marketing-automations' );
$result['status'] = false;
return $result;
}
$task_ids = array();
foreach ( $all_tasks as $task_id => $task_details ) { //phpcs:ignore WordPressVIPMinimum.Variables.VariableAnalysis
$task_ids[] = $task_id;
}
BWFAN_Core()->tasks->rescheduled_tasks( true, $task_ids );
break;
case 'delete_completed_tasks':
//phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
$logs = $wpdb->get_results( $wpdb->prepare( "
SELECT ID
FROM {$wpdb->prefix}bwfan_logs
WHERE `status` = %d
", 1 ) );
if ( ! empty( $logs ) ) {
$completed_tasks = array();
foreach ( $logs as $log ) {
$completed_tasks[] = $log->ID;
}
BWFAN_Core()->logs->delete_logs( $completed_tasks );
}
$result['msg'] = __( 'All completed tasks successfully deleted.', 'wp-marketing-automations' );
break;
case 'delete_failed_tasks':
//phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
$logs = $wpdb->get_results( $wpdb->prepare( "
SELECT ID
FROM {$wpdb->prefix}bwfan_logs
WHERE `status` = %d
", 0 ) );
if ( ! empty( $logs ) ) {
$failed_tasks = array();
foreach ( $logs as $log ) {
$failed_tasks[] = $log->ID;
}
BWFAN_Core()->logs->delete_logs( $failed_tasks );
}
$result['msg'] = __( 'All failed tasks successfully deleted.', 'wp-marketing-automations' );
break;
case 'delete_previous_logs_automation':
if ( false !== bwf_has_action_scheduled( 'bwfan_delete_older_logs' ) ) {
$result['msg'] = __( 'A process is already scheduled for deleting old logs of this automation', 'wp-marketing-automations' );
$result['status'] = false;
return $result;
}
$data_inputs = isset( $_POST['data_inputs'] ) ? json_decode( self::remove_backslashes( $_POST['data_inputs'] ), true ) : array(); //phpcs:ignore WordPress.Security.ValidatedSanitizedInput, WordPress.Security.NonceVerification
$automation_id = $data_inputs['automation_id'];
$result['msg'] = __( 'Process scheduled for deleting old logs of this automation', 'wp-marketing-automations' );
$data = array();
$data['days'] = apply_filters( 'bwfan_logs_days_deletion_limit', 15 );
$data['limit'] = apply_filters( 'bwfan_logs_days_deletion_count', 200 );
$data['automation_id'] = intval( $automation_id );
bwf_schedule_single_action( time(), 'bwfan_delete_older_logs', $data );
break;
case 'delete_expired_coupons':
if ( false !== bwf_has_action_scheduled( 'bwfan_delete_expired_coupons' ) ) {
$result['msg'] = __( 'A process is already scheduled for deleting expired Funnelkit Automation generated coupons', 'wp-marketing-automations' );
$result['status'] = false;
return $result;
}
$result['msg'] = __( 'Process scheduled for deleting expired Funnelkit Automation generated coupons', 'wp-marketing-automations' );
bwf_schedule_recurring_action( time(), 2, 'bwfan_delete_expired_coupons', array() );
break;
case 'delete_lost_carts':
//phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
$wpdb->query( $wpdb->prepare( "
DELETE
FROM {$wpdb->prefix}bwfan_abandonedcarts
WHERE `status` = %d
", 2 ) );
$result['msg'] = __( 'All lost carts successfully deleted.', 'wp-marketing-automations' );
break;
case 'delete_engagement_tracking_meta':
if ( false !== bwf_has_action_scheduled( 'bwfan_delete_engagement_tracking_meta_tool_action' ) ) {
$result['msg'] = __( 'A process is already scheduled to optimize the Engagement Tracking meta table', 'wp-marketing-automations' );
$result['status'] = false;
return $result;
}
global $wpdb;
$query = $wpdb->prepare( "SELECT ID FROM {$wpdb->prefix}bwfan_engagement_trackingmeta WHERE `meta_key` = %s LIMIT 1", 'merge_tags' );
$row_id = $wpdb->get_var( $query ); //phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL
if ( empty( $row_id ) ) {
$result['msg'] = __( 'No optimization is needed for the Engagement Tracking meta table', 'wp-marketing-automations' );
return $result;
}
bwf_schedule_recurring_action( time(), MINUTE_IN_SECONDS * 5, 'bwfan_delete_engagement_tracking_meta_tool_action' );
$result['msg'] = __( 'Process scheduled for Engagement Tracking meta table', 'wp-marketing-automations' );
break;
case 're_index_cart_orders_conversion':
if ( false !== bwf_has_action_scheduled( 'bwfan_reindex_cart_conversions_base_total' ) ) {
$result['msg'] = __( 'A process is already scheduled for re-indexing cart & conversion value', 'wp-marketing-automations' );
$result['status'] = false;
return $result;
}
$result['msg'] = __( 'Process scheduled for re-indexing cart & conversion value', 'wp-marketing-automations' );
bwf_options_update( 're_index_data_type', 'conversion' );
bwf_options_update( 'last_index_id', 0 );
bwf_schedule_recurring_action( time(), 60, 'bwfan_reindex_cart_conversions_base_total' );
break;
case 'bwfan_validate_db_tables':
$missing_tables = BWFAN_Table_Validation_Controller::check_missing_tables();
if ( isset( $missing_tables['error'] ) ) {
$result['msg'] = $missing_tables['error'];
break;
}
if ( empty( $missing_tables ) ) {
$result['msg'] = __( 'All required tables are present in the database.', 'wp-marketing-automations' );
bwf_options_update( 'bwfan_table_validation_error', 0 );
break;
}
$table_created = BWFAN_Table_Validation_Controller::create_missing_tables( $missing_tables );
$result['msg'] = $table_created === true ? __( 'The following tables were created: ', 'wp-marketing-automations' ) . implode( ', ', $missing_tables ) : __( 'Error while creating table', 'wp-marketing-automations' );
break;
case 'toggle_usage_tracking':
if ( isset( $data['value'] ) && true === $data['value'] ) {
WooFunnels_optIn_Manager::Allow_optin( true, 'FKA' );
} else {
WooFunnels_optIn_Manager::reset_optin();
}
$result['msg'] = __( 'Status Updated', 'wp-marketing-automations' );
$result['status'] = true;
break;
}
return $result;
}
/**
* Get setting schema
*
* @return mixed|null
* @throws Exception
*/
public static function get_setting_schema() {
if ( ! function_exists( 'get_editable_roles' ) ) {
require_once ABSPATH . 'wp-admin/includes/user.php';
}
$editable_roles = get_editable_roles();
$user_roles = array();
if ( $editable_roles ) {
foreach ( $editable_roles as $role => $details ) {
$name = translate_user_role( $details['name'] );
$user_roles[ $role ]['label'] = $name;
$user_roles[ $role ]['value'] = $role;
}
}
$user_roles = array_values( $user_roles );
/** SMS Service Providers */
$sms_options = self::get_sms_services();
$is_twilio_connected = ( is_array( $sms_options ) && isset( $sms_options['bwfco_twilio'] ) );
$sms_options = array_map( function ( $sms, $slug ) {
return array(
'label' => $sms,
'value' => $slug,
);
}, $sms_options, array_keys( $sms_options ) );
/** Email Service Providers */
$email_options = self::get_email_services();
$email_options = array_map( function ( $email, $slug ) {
return array(
'label' => $email,
'value' => $slug,
);
}, $email_options, array_keys( $email_options ) );
$show_fields = true;
if ( function_exists( 'bwfan_is_autonami_pro_active' ) && ! bwfan_is_autonami_pro_active() ) {
$show_fields = false;
}
$bounce_settings_schema = self::get_bounce_settings_schema();
$bounce_settings_schema = array_merge( $bounce_settings_schema, array(
array(
'id' => 'bwfan_email_per_second_limit',
'label' => __( 'Max Sending Limit (per sec)', 'wp-marketing-automations' ),
'type' => 'number',
"min" => '0',
'class' => 'bwfan_email_per_second_limit',
'placeholder' => '15',
'hint' => __( 'Enter maximum email sending limit. Note: This is an indicative limit and not the actual sending rate for Funnelkit Automation. ', 'wp-marketing-automations' ) . '' . __( 'The real sending rate would vary based on site configuration, plugin used and even SMTP API connection.', 'wp-marketing-automations' ) . ' ',
'required' => false,
'show' => $show_fields,
'toggler' => array(),
),
array(
'id' => 'bwfan_email_daily_limit',
'label' => __( 'Max Sending Limit (per day)', 'wp-marketing-automations' ),
'type' => 'number',
"min" => '0',
'class' => 'bwfan_email_daily_limit ',
'placeholder' => '10000',
'hint' => __( 'Set the maximum emails allowed per 24 hours. Once this limit is reached, sending pauses and resumes after the quota resets. This ensures manageable daily output and compliance with email provider policies.', 'wp-marketing-automations' ),
'required' => false,
'show' => $show_fields,
'toggler' => array(),
)
) );
$email_field = array(
array(
'id' => 'bwfan_email_from_name',
'label' => __( 'From Name', 'wp-marketing-automations' ),
'type' => 'text',
'class' => 'bwfan_email_from_name',
'placeholder' => __( 'Enter Name', 'wp-marketing-automations' ),
'hint' => __( 'Name that will be used to send emails', 'wp-marketing-automations' ),
'required' => false,
'toggler' => array(),
),
array(
'id' => 'bwfan_email_from',
'label' => __( 'From Email', 'wp-marketing-automations' ),
'type' => 'text',
'class' => 'bwfan_email_from',
'placeholder' => __( 'Enter Email', 'wp-marketing-automations' ),
'hint' => __( 'Valid email address that will be used to send emails', 'wp-marketing-automations' ),
'required' => false,
'toggler' => array(),
),
array(
'id' => 'bwfan_email_reply_to',
'label' => __( 'Reply To Email', 'wp-marketing-automations' ),
'type' => 'text',
'class' => 'bwfan_email_reply_to',
'placeholder' => __( 'Enter Email', 'wp-marketing-automations' ),
'hint' => __( 'Valid email address that will be used to receive replies', 'wp-marketing-automations' ),
'required' => false,
'toggler' => array(),
),
array(
'id' => 'bwfan_email_footer_setting',
'label' => __( 'Unsubscribe Text', 'wp-marketing-automations' ),
'type' => 'richeditor',
'class' => 'bwfan_setting_business_name',
'required' => false,
'wrap_before' => '' . __( 'Footer', 'wp-marketing-automations' ) . ' ',
'toggler' => array(),
// phpcs:ignore WordPress.WP.I18n.TextDomainMismatch, WordPress.WP.I18n.MissingTranslatorsComment, WordPress.WP.I18n.UnorderedPlaceholdersText
'hint' => sprintf( __( 'Anti-spam laws require you to put a physical address and an unsubscribe link at the bottom of every email. Use dynamic tags %s for Business Name, %s for Business Address and %s for Unsubscribe page link', 'wp-marketing-automations' ), '{{business_name}} ', '{{business_address}} ', '{{unsubscribe_link}} ' ),
),
);
if ( ! empty( $bounce_settings_schema ) ) {
$email_field = array_merge( $email_field, $bounce_settings_schema );
}
/** added email provider setting in case of multiple provider */
if ( count( $email_options ) > 1 ) {
$email_provider_schema = array(
array(
'id' => 'bwfan_email_service',
'label' => __( 'Default Email Provider', 'wp-marketing-automations' ),
'type' => 'select',
'class' => '',
'options' => $email_options,
'required' => false,
'multiple' => false,
'hint' => __( 'Select default provider for sending emails', 'wp-marketing-automations' ),
'toggler' => array(),
),
);
$email_field = array_merge( $email_field, $email_provider_schema );
}
$twilio_sms_unsubscribe_settings = [];
$twilio_sms_sort_url = [];
$unsubscribe_text = [];
$messaging_service_sid = [];
/** getting the twilio sms webhook link for unsubscribes in case connector and class exists */
if ( $is_twilio_connected ) {
if ( bwfan_is_autonami_connector_active() && class_exists( 'BWFAN_Twilio_Webhook_Setup' ) && method_exists( 'BWFAN_Twilio_Webhook_Setup', 'get_webhooks' ) ) {
$twilio_sms_unsub_instance = BWFAN_Twilio_Webhook_Setup::get_instance();
$twilio_webhook = $twilio_sms_unsub_instance->get_webhooks();
$webhook_link = ! empty( $twilio_webhook['link'] ) ? $twilio_webhook['link'] : '';
$twilio_sms_unsubscribe_settings = array(
'id' => 'bwfan_sms_webhook_twilio',
'label' => __( 'Webhook URL', 'wp-marketing-automations' ),
'type' => 'copier',
'class' => 'bwfan_sms_webhook_twilio',
'hint' => __( "Paste this URL into your Twilio's settings to send requests. Learn more on how to set up.", 'wp-marketing-automations' ),
'required' => false,
'copy_text' => $webhook_link,
'wrap_before' => '' . __( 'Twilio Settings', 'wp-marketing-automations' ) . ' ',
);
if ( true === apply_filters( 'bwfan_enable_twilio_advanced_settings', false ) ) {
$twilio_sms_sort_url = array(
'id' => 'bwfan_twilio_shorten_url',
'label' => __( 'Enable URL Shortening', 'wp-marketing-automations' ),
'type' => 'checkbox',
'checkboxlabel' => __( "Twilio's native URL shortening", 'wp-marketing-automations' ),
'hint' => __( "Enable URL shortening by Twilio. Click here to understand more.", "wp-marketing-automations" ),
'required' => false,
);
$messaging_service_sid = array(
'id' => 'bwfan_twilio_messaging_service_sid',
'label' => __( 'Messaging Service ID', 'wp-marketing-automations' ),
'type' => 'text',
'hint' => __( "Messaging Service ID is required for shortening.", 'wp-marketing-automations' ),
'required' => false,
'toggler' => array(
'fields' => array(
array(
'id' => 'bwfan_twilio_shorten_url',
'value' => true,
),
),
'relation' => 'OR',
),
);
}
}
$unsubscribe_text = array(
'id' => 'bwfan_sms_unsubscribe_text',
'label' => __( 'Unsubscribe Text', 'wp-marketing-automations' ),
'type' => 'text',
'class' => 'bwfan_sms_unsubscribe_text',
'placeholder' => __( 'Enter Unsubscribe Text', 'wp-marketing-automations' ),
'required' => true,
'disabled' => method_exists( 'BWFCRM_Common', 'get_sms_provider_slug' ) && ! empty( BWFCRM_Common::get_sms_provider_slug() ) ? false : true,
'isProSetting' => true,
);
}
$sms_fields = array(
$twilio_sms_unsubscribe_settings,
$twilio_sms_sort_url,
$unsubscribe_text,
$messaging_service_sid,
array(
'id' => 'bwfan_disable_sms_tracking',
'label' => __( 'Disable Click Tracking', 'wp-marketing-automations' ),
'type' => 'checkbox',
'checkboxlabel' => __( 'Disable Click Tracking for all SMS Broadcasts and Automations', 'wp-marketing-automations' ),
'hint' => __( 'Click tracking adds special variables to the URL that increases the SMS character limit. Enable this setting to reduce the character limit. Note: Funnelkit Automation cannot track conversion rate if click tracking is disabled.', 'wp-marketing-automations' ),
'class' => 'bwfan_disable_sms_tracking',
'required' => false,
),
);
/** added email provider setting in case of multiple provider */
if ( count( $sms_options ) > 1 ) {
$sms_provider_schema = array(
array(
'id' => 'bwfan_sms_service',
'label' => __( 'Default SMS Provider', 'wp-marketing-automations' ),
'type' => 'select',
'class' => '',
'options' => $sms_options,
'required' => false,
'multiple' => false,
'hint' => __( 'Select default provider for sending SMS', 'wp-marketing-automations' ),
'toggler' => array(),
),
);
$sms_fields = array_merge( $sms_fields, $sms_provider_schema );
}
$general_fields = [];
if ( is_multisite() ) {
/**
* Check if sitewide installed, if yes then get the plugin info from primary site
*/
$active_plugins = get_site_option( 'active_sitewide_plugins', array() );
if ( is_array( $active_plugins ) && ( in_array( BWFAN_PLUGIN_BASENAME, apply_filters( 'active_plugins', $active_plugins ), true ) || array_key_exists( BWFAN_PLUGIN_BASENAME, apply_filters( 'active_plugins', $active_plugins ) ) ) && ! is_main_site() ) {
$main_site_id = 1; // Main site ID in Multisite
$main_site_admin_url = get_site_url( $main_site_id, 'wp-admin/admin.php?page=autonami&path=/settings' );
$general_fields[] = array(
'id' => 'no_license',
'type' => 'multisitenotice',
'linkButton' => esc_url( $main_site_admin_url ),
'label' => __( 'FunnelKit Automations Pro', 'wp-marketing-automations' ),
'msg' => __( 'Manage your FunnelKit Automations Pro license centrally from the main site of your multisite network. Simply head there to manage. ', 'wp-marketing-automations' ),
'wrap_before' => '' . __( 'License', 'wp-marketing-automations' ) . ' ',
'hint' => '',
);
} else {
$general_fields[] = array(
'id' => 'autonami_pro',
'label' => __( 'FunnelKit Automations Pro', 'wp-marketing-automations' ),
'type' => 'license',
'license' => self::get_pro_license( false ),
'wrap_before' => '' . __( 'License', 'wp-marketing-automations' ) . ' ',
'toggler' => array(),
);
if ( true === bwfan_is_autonami_pro_active() && true === bwfan_is_autonami_connector_active() ) {
$general_fields[] = array(
'id' => 'autonami_connector',
'label' => __( 'FunnelKit Automations Connectors', 'wp-marketing-automations' ),
'type' => 'license',
'isConnectorField' => true,
'license' => self::get_connector_license( false ),
'toggler' => array(),
);
}
}
} else {
$general_fields[] = array(
'id' => 'autonami_pro',
'label' => __( 'FunnelKit Automations Pro', 'wp-marketing-automations' ),
'type' => 'license',
'license' => self::get_pro_license( false ),
'wrap_before' => '' . __( 'License', 'wp-marketing-automations' ) . ' ',
'toggler' => array(),
);
if ( true === bwfan_is_autonami_pro_active() && true === bwfan_is_autonami_connector_active() ) {
$general_fields[] = array(
'id' => 'autonami_connector',
'label' => __( 'FunnelKit Automations Connectors', 'wp-marketing-automations' ),
'type' => 'license',
'isConnectorField' => true,
'license' => self::get_connector_license( false ),
'toggler' => array(),
);
}
}
$general_fields[] = array(
'id' => 'bwfan_setting_business_name',
'label' => __( 'Business Name', 'wp-marketing-automations' ),
'type' => 'text',
'class' => 'bwfan_setting_business_name',
'placeholder' => __( 'Enter Business Name', 'wp-marketing-automations' ),
'hint' => '',
'required' => true,
'wrap_before' => '' . __( 'Business Details', 'wp-marketing-automations' ) . ' ' . __( 'Anti-spam laws require you to put a physical address at the bottom of every email where you can be reached.', 'wp-marketing-automations' ) . '
',
'toggler' => array(),
);
$general_fields[] = array(
'id' => 'bwfan_setting_business_address',
'label' => __( 'Business Address', 'wp-marketing-automations' ),
'type' => 'text',
'class' => 'bwfan_setting_business_address',
'placeholder' => __( 'Enter Business Address', 'wp-marketing-automations' ),
'hint' => '',
'required' => true,
'toggler' => array(),
);
$checkout_consent_fields = [];
$ab_email_consent_message_fields = [];
$checkout_consent_fields[] = array(
'id' => 'bwfan_user_consent_message',
'label' => __( 'Text', 'wp-marketing-automations' ),
'type' => 'textarea',
'class' => '',
'required' => true,
'toggler' => array(
'fields' => array(
array(
'id' => 'bwfan_user_consent',
'value' => true,
),
),
'relation' => 'OR',
),
);
$ab_email_consent_message_fields[] = array(
'id' => 'bwfan_ab_email_consent_message',
'type' => 'textarea',
'label' => 'Text',
'class' => 'bwfan_ab_email_consent_message',
'required' => true,
'hint' => __( "Use merge tag {{no_thanks label='No Thanks'}} to let users opt out of cart tracking.", 'wp-marketing-automations' ),
'toggler' => array(
'fields' => array(
array(
'id' => 'bwfan_ab_enable',
'value' => true,
),
array(
'id' => 'bwfan_ab_email_consent',
'value' => true,
),
),
'relation' => 'AND',
),
);
if ( bwfan_is_autonami_pro_active() && method_exists( 'BWFAN_PRO_Common', 'get_language_settings' ) ) {
$language_data = BWFAN_PRO_Common::get_language_settings();
if ( is_array( $language_data ) && isset( $language_data['lang_options'] ) && ! empty( $language_data['lang_options'] ) ) {
$default_language = strval( get_locale() );
/** Change default language field label */
$checkout_consent_fields[0]['label'] = __( 'Text (Default)', 'wp-marketing-automations' );
foreach ( $language_data['lang_options'] as $lang_slug => $lang_name ) {
if ( $default_language === strval( $lang_slug ) ) {
continue;
}
$checkout_consent_fields[] = array(
'id' => 'bwfan_user_consent_message_' . $lang_slug,
'label' => sprintf( __( 'Text (%s)', 'wp-marketing-automations' ), $lang_name ), // phpcs:ignore WordPress.WP.I18n.MissingTranslatorsComment
'type' => 'textarea',
'class' => '',
'required' => false,
'toggler' => array(
'fields' => array(
array(
'id' => 'bwfan_user_consent',
'value' => true,
),
),
'relation' => 'OR',
),
);
$ab_email_consent_message_fields[] = array(
'id' => 'bwfan_ab_email_consent_message_' . $lang_slug,
'type' => 'textarea',
'class' => 'bwfan_ab_email_consent_message',
'required' => false,
'hint' => '( ' . $lang_name . ' ) ' . __( "Use merge tag {{no_thanks label='No Thanks'}} to let users opt out of cart tracking.", 'wp-marketing-automations' ),
'toggler' => array(
'fields' => array(
array(
'id' => 'bwfan_ab_enable',
'value' => true,
),
array(
'id' => 'bwfan_ab_email_consent',
'value' => true,
),
),
'relation' => 'AND',
),
);
}
}
}
$engagement_meta_record_delete = [];
if ( bwfan_is_autonami_pro_active() && method_exists( 'BWFAN_PRO_Common', 'delete_engagement_tracking_meta' ) ) {
$engagement_meta_record_delete = array(
'id' => 'bwfan_delete_engagement_tracking_meta',
'label' => __( 'Delete Engagement Tracking meta records (in days)', 'wp-marketing-automations' ),
'type' => 'number',
"min" => '0',
'class' => 'bwfan_delete_engagement_tracking_meta',
'placeholder' => '0',
'wrap_before' => '' . __( 'Engagement Tracking Meta Records', 'wp-marketing-automations' ) . ' ',
'hint' => __( 'Optimizing WordPress by cleaning up engagement tracking meta records.', 'wp-marketing-automations' ),
'required' => false,
'toggler' => array(),
);
}
$twilio_webhook_log_data = [];
if ( class_exists( 'BWFCO_Twilio' ) && BWFAN_Core()->connectors->is_connected( 'bwfco_twilio' ) ) {
$twilio_webhook_log_data = array(
'id' => 'bwfan_twilio_webhook_received_logging',
'type' => 'checkbox',
'label' => ' ',
'checkboxlabel' => __( 'Enable Logs for Twilio SMS Received event automation', 'wp-marketing-automations' ),
'hint' => __( "It logs the received data on a 'Twilio SMS Received' automation. Logs are captured in file named fka-twilio-sms-webhooks-xxx ", 'wp-marketing-automations' ),
'class' => 'bwfan_make_logs',
'required' => false,
'wrap_before' => '',
'isProField' => true,
'toggler' => array(
'fields' => array(
array(
'id' => 'bwfan_advance_logs',
'value' => true,
),
),
),
);
}
$short_url_log_data = [];
if ( ! empty( self::get_shortener_services() ) ) {
$short_url_log_data = array(
'id' => 'bwfan_short_url_response_log',
'type' => 'checkbox',
'label' => ' ',
'checkboxlabel' => __( 'Enable Logs for Shortener URL Service', 'wp-marketing-automations' ),
'hint' => __( "It logs the received data on a 'URL Shortening' operation. Logs are captured in a file named fka-short-url-response-xxx ", 'wp-marketing-automations' ),
'class' => 'bwfan_make_logs',
'required' => false,
'wrap_before' => '',
'isProField' => true,
'toggler' => array(
'fields' => array(
array(
'id' => 'bwfan_advance_logs',
'value' => true,
),
),
),
);
}
$settings = array(
array(
'key' => 'general',
'label' => __( 'General', 'wp-marketing-automations' ),
'heading' => 'General Settings',
'tabs' => array(
array(
'key' => 'general',
'label' => __( 'General', 'wp-marketing-automations' ),
'heading' => __( 'General', 'wp-marketing-automations' ),
'fields' => $general_fields,
),
array(
'key' => 'emails',
'label' => __( 'Email', 'wp-marketing-automations' ),
'heading' => __( 'Email Settings', 'wp-marketing-automations' ),
'fields' => $email_field,
),
array(
'key' => 'sms',
'label' => __( 'SMS', 'wp-marketing-automations' ),
'heading' => __( 'SMS Settings', 'wp-marketing-automations' ),
"showSection" => bwfan_is_autonami_pro_active(),
'fields' => $sms_fields,
),
array(
"key" => 'whatsapp',
"label" => __( 'WhatsApp', 'wp-marketing-automations' ),
"heading" => __( 'WhatsApp', 'wp-marketing-automations' ),
"showSection" => bwfan_is_autonami_pro_active() ? BWFAN_Core()->conversation->is_whatsapp_service_available() : false,
'fields' => self::get_whatsapp_services_fields(),
),
array(
"key" => 'abandonment',
"label" => __( 'Cart', 'wp-marketing-automations' ),
"heading" => __( 'Cart', 'wp-marketing-automations' ),
"isWooSection" => true,
"fields" => array_merge( array(
array(
'id' => 'bwfan_ab_enable',
'label' => __( 'Enable Cart Tracking', 'wp-marketing-automations' ),
'type' => 'checkbox',
'checkboxlabel' => __( "Enable to live capture buyer's email & cart details", 'wp-marketing-automations' ),
'class' => 'bwfan_ab_enable',
'required' => false,
'toggler' => array(),
),
array(
'id' => 'bwfan_ab_init_wait_time',
'label' => __( 'Wait Period (minutes)', 'wp-marketing-automations' ),
'type' => 'number',
'class' => '',
'placeholder' => '15',
"min" => '0',
'hint' => __( 'Wait for a given time before the cart is marked as Recoverable', 'wp-marketing-automations' ),
'required' => false,
'toggler' => array(
'fields' => array(
array(
'id' => 'bwfan_ab_enable',
'value' => true,
),
),
'relation' => 'OR',
),
),
array(
'id' => 'bwfan_disable_abandonment_days',
'label' => __( 'Cool Off Period (days)', 'wp-marketing-automations' ),
'type' => 'number',
'class' => '',
'placeholder' => '15',
"min" => '0',
'required' => false,
'hint' => __( 'Exclude customers from cart abandonment tracking if the order was placed days ago (recommended 15 days)', 'wp-marketing-automations' ),
'toggler' => array(
'fields' => array(
array(
'id' => 'bwfan_ab_enable',
'value' => true,
),
),
'relation' => 'OR',
),
),
array(
'id' => 'bwfan_ab_mark_lost_cart',
'label' => __( 'Lost Cart (days)', 'wp-marketing-automations' ),
'type' => 'number',
'class' => '',
'placeholder' => '15',
"min" => '0',
'required' => false,
'hint' => __( 'Mark the user as Lost if the order is not made within the given days', 'wp-marketing-automations' ),
'toggler' => array(
'fields' => array(
array(
'id' => 'bwfan_ab_enable',
'value' => true,
),
),
'relation' => 'OR',
),
),
array(
'id' => 'bwfan_ab_email_consent',
'label' => __( 'Notice', 'wp-marketing-automations' ),
'type' => 'checkbox',
'checkboxlabel' => __( 'When entering email addresses, inform customers that their email and cart data are saved to send abandonment reminders', 'wp-marketing-automations' ),
'class' => 'bwfan_ab_email_consent',
'required' => false,
'wrap_before' => '' . __( 'GDPR Consent', 'wp-marketing-automations' ) . ' ',
'toggler' => array(
'fields' => array(
array(
'id' => 'bwfan_ab_enable',
'value' => true,
),
),
'relation' => 'OR',
),
)
), $ab_email_consent_message_fields, array(
array(
'id' => 'bwfan_ab_tag_selector',
'label' => __( 'Add Tag', 'wp-marketing-automations' ),
'type' => 'tagselector',
'class' => '',
'placeholder' => '',
'required' => false,
'isProField' => true,
'wrap_before' => '' . __( 'Cart is Abandoned', 'wp-marketing-automations' ) . ' ',
'hint' => __( 'The selected tag(s) will be added when cart is abandoned. The tag(s) will be automatically removed when cart recovers', 'wp-marketing-automations' ),
'toggler' => array(
'fields' => array(
array(
'id' => 'bwfan_ab_enable',
'value' => true,
),
),
'relation' => 'AND',
),
),
array(
'id' => 'bwfan_ab_list_selector',
'label' => __( 'Add list', 'wp-marketing-automations' ),
"type" => 'search',
'autocompleter' => 'lists',
"allowFreeTextSearch" => false,
'required' => false,
'isProField' => true,
'wrap_before' => '',
'hint' => __( 'The selected lists(s) will be added when cart is abandoned. The list(s) will be automatically removed when cart recovers', 'wp-marketing-automations' ),
'toggler' => array(
'fields' => array(
array(
'id' => 'bwfan_ab_enable',
'value' => true,
),
),
'relation' => 'AND',
),
),
array(
'id' => 'bwfan_lostcart_tag_selector',
'label' => __( 'Add Tag', 'wp-marketing-automations' ),
'type' => 'tagselector',
'class' => '',
'placeholder' => '',
'required' => false,
'isProField' => true,
'wrap_before' => '' . __( 'Cart is Lost', 'wp-marketing-automations' ) . ' ',
'hint' => __( 'The selected tag(s) will be added when cart is lost. The tag(s) will be automatically removed when cart recovers', 'wp-marketing-automations' ),
'toggler' => array(
'fields' => array(
array(
'id' => 'bwfan_ab_enable',
'value' => true,
),
),
'relation' => 'AND',
),
),
array(
'id' => 'bwfan_lostcart_list_selector',
'label' => __( 'Add list', 'wp-marketing-automations' ),
"type" => 'search',
'autocompleter' => 'lists',
"allowFreeTextSearch" => false,
'required' => false,
'isProField' => true,
'wrap_before' => '',
'hint' => __( 'The selected lists(s) will be added when cart is lost. The list(s) will be automatically removed when cart recovers', 'wp-marketing-automations' ),
'toggler' => array(
'fields' => array(
array(
'id' => 'bwfan_ab_enable',
'value' => true,
),
),
'relation' => 'AND',
),
),
array(
'id' => 'bwfan_ab_exclude_users_cart_tracking',
'label' => __( 'Exclude User Roles', 'wp-marketing-automations' ),
'type' => 'checkbox',
'checkboxlabel' => __( 'Exclude user roles from cart tracking', 'wp-marketing-automations' ),
'class' => 'bwfan_ab_exclude_users_cart_tracking',
'required' => false,
'toggler' => array(
'fields' => array(
array(
'id' => 'bwfan_ab_enable',
'value' => true,
),
),
'relation' => 'OR',
),
),
array(
'id' => 'bwfan_ab_exclude_roles',
'type' => 'select',
'class' => '',
'options' => $user_roles,
'required' => false,
'inlineTags' => false,
'multiple' => true,
'placeholder' => 'Select',
'hint' => __( 'Carts for selected user roles will not be tracked', 'wp-marketing-automations' ),
'toggler' => array(
'fields' => array(
array(
'id' => 'bwfan_ab_enable',
'value' => true,
),
array(
'id' => 'bwfan_ab_exclude_users_cart_tracking',
'value' => true,
),
),
'relation' => 'AND',
),
),
array(
'id' => 'bwfan_ab_exclude_emails',
'label' => __( 'Emails', 'wp-marketing-automations' ),
'type' => 'textarea',
'class' => '',
'required' => false,
'wrap_before' => '' . __( 'Blacklist Emails', 'wp-marketing-automations' ) . ' ',
'hint' => __( 'Enter emails, domains or partials to exclude from cart abandonment tracking separated by comma(,) or in new line
You can add full emails (i.e. foo@example.com) or domains (i.e. domain.com), or partials (i.e. john)', 'wp-marketing-automations' ),
'toggler' => array(
'fields' => array(
array(
'id' => 'bwfan_ab_enable',
'value' => true,
),
),
'relation' => 'AND',
),
),
array(
'id' => 'bwfan_ab_restore_cart_message_success',
'label' => __( 'Cart Success Notice', 'wp-marketing-automations' ),
'type' => 'text',
'class' => '',
'placeholder' => '',
'wrap_before' => '' . __( 'Checkout Notice', 'wp-marketing-automations' ) . ' ',
'required' => false,
'hint' => __( "Notice when cart is successfully restored. Leave blank in case you don't want to show a notice.", 'wp-marketing-automations' ),
'toggler' => array(
'fields' => array(
array(
'id' => 'bwfan_ab_enable',
'value' => true,
),
),
'relation' => 'OR',
),
),
array(
'id' => 'bwfan_ab_restore_cart_message_failure',
'label' => __( 'Cart Failure Notice', 'wp-marketing-automations' ),
'type' => 'text',
'class' => '',
'placeholder' => '',
'required' => false,
'hint' => __( "Notice when cart fails to restore. Leave blank in case you don't want to show a notice.", 'wp-marketing-automations' ),
'toggler' => array(
'fields' => array(
array(
'id' => 'bwfan_ab_enable',
'value' => true,
),
),
'relation' => 'OR',
),
)
) ),
),
/*
array(
"key" => 'conversion',
"label" => 'Conversions', // label is used for left side tab item
"heading" => 'Conversions',
"fields" => [
array(
"id" => 'bwfan_order_tracking_conversion',
"label" => __( 'Order Tracking Conversion', 'wp-marketing-automations' ),
"type" => 'number',
"class" => 'bwfan_order_tracking_conversion',
"placeholder" => "Days to track order",
"hint" => __( "Days to Track order details for conversion.", 'wp-marketing-automations' ),
"required" => false,
"toggler" => array(),
),
],
),*/
array(
'key' => 'optin',
'label' => __( 'Checkout Consent', 'wp-marketing-automations' ),
'heading' => __( 'Checkout Consent', 'wp-marketing-automations' ),
'isWooSection' => true,
'fields' => array_merge( array(
array(
'id' => 'bwfan_user_consent',
'label' => __( 'Enable Marketing Consent', 'wp-marketing-automations' ),
'type' => 'checkbox',
'checkboxlabel' => __( 'Enable an optin on checkout to ask for the consent of marketing emails.', 'wp-marketing-automations' ),
'hint' => __( 'Note: For logged in users, this field would not be visible to Contacts if they are subscribed', 'wp-marketing-automations' ),
'class' => 'bwfan_user_consent',
'required' => false,
'wrap_before' => '',
'toggler' => array(),
)
), $checkout_consent_fields, array(
array(
'id' => 'bwfan_user_consent_position',
'label' => __( 'Consent Field Position', 'wp-marketing-automations' ),
'type' => 'select',
'multiple' => false,
'class' => 'bwfan_user_consent_position',
'options' => array(
array(
'value' => 'below_term',
'label' => __( 'Below Terms & Condition', 'wp-marketing-automations' ),
),
array(
'value' => 'below_email',
'label' => __( 'Below Email Field', 'wp-marketing-automations' ),
),
array(
'value' => 'below_phone',
'label' => __( 'Below Phone Field', 'wp-marketing-automations' ),
),
),
'required' => false,
'toggler' => array(
'fields' => array(
array(
'id' => 'bwfan_user_consent',
'value' => true,
),
),
'relation' => 'OR',
),
),
array(
'id' => 'bwfan_user_consent_eu',
'label' => __( 'EU Contacts', 'wp-marketing-automations' ),
'type' => 'select',
'multiple' => false,
'class' => 'bwfan_user_consent_eu',
'options' => array(
array(
'value' => '1',
'label' => __( 'Checked', 'wp-marketing-automations' ),
),
array(
'value' => '0',
'label' => __( 'Unchecked', 'wp-marketing-automations' ),
),
),
'required' => false,
'hint' => __( 'EU contacts are determined by their IP address. To respect GDPR, keep it unchecked.', 'wp-marketing-automations' ),
'wrap_before' => '' . __( 'Consent Checked Behaviour', 'wp-marketing-automations' ) . ' ',
'toggler' => array(
'fields' => array(
array(
'id' => 'bwfan_user_consent',
'value' => true,
),
),
'relation' => 'OR',
),
),
array(
'id' => 'bwfan_user_consent_non_eu',
'label' => __( 'Non-EU Contacts', 'wp-marketing-automations' ),
'type' => 'select',
'multiple' => false,
'class' => 'bwfan_user_consent_non_eu',
'options' => array(
array(
'value' => '1',
'label' => __( 'Checked', 'wp-marketing-automations' ),
),
array(
'value' => '0',
'label' => __( 'Unchecked', 'wp-marketing-automations' ),
),
),
'required' => false,
'toggler' => array(
'fields' => array(
array(
'id' => 'bwfan_user_consent',
'value' => true,
),
),
'relation' => 'OR',
),
)
) ),
),
array(
'key' => 'subscribe-page',
'label' => __( 'Subscribe Page', 'wp-marketing-automations' ),
'heading' => __( 'Subscribe Page', 'wp-marketing-automations' ),
'fields' => array_merge( array(
array(
'id' => 'bwfan_unsubscribe_page',
'label' => __( 'Page', 'wp-marketing-automations' ),
'type' => 'ajax',
'multiple' => false,
'class' => 'bwfan-unsubscribe-page',
'options' => array(),
'required' => true,
'hint' => self::get_unsubscribe_page_hint_text(),
'validation' => self::is_unsubscribe_page_valid(),
'ajax_cb' => 'bwfan_select_unsubscribe_page',
'toggler' => array(),
),
), self::get_lists_preference_schema(), array(
array(
'id' => 'bwfan_unsubscribe_from_all_label',
'label' => __( 'Unsubscribe All Lists Label', 'wp-marketing-automations' ),
'type' => 'text',
'class' => 'bwfan_unsubscribe_from_all_label',
'placeholder' => '',
'required' => false,
'hint' => __( 'Label for Unsubscribe from all list option', 'wp-marketing-automations' ),
),
array(
'id' => 'bwfan_unsubscribe_from_all_description',
'label' => __( 'Unsubscribe All Lists Description', 'wp-marketing-automations' ),
'type' => 'text',
'class' => 'bwfan_unsubscribe_from_all_description',
'placeholder' => '',
'required' => false,
'hint' => __( 'Description for Unsubscribe from all list option', 'wp-marketing-automations' ),
),
array(
'id' => 'bwfan_unsubscribe_data_success',
'label' => __( 'Text', 'wp-marketing-automations' ),
'type' => 'text',
'class' => 'bwfan_unsubscribe_data_success',
'placeholder' => '',
'required' => false,
'wrap_before' => '' . __( 'Confirmation Message', 'wp-marketing-automations' ) . ' ',
'hint' => __( 'Confirmation message when lists subscription is updated', 'wp-marketing-automations' ),
'toggler' => array(),
),
) ),
),
array(
'key' => 'double-optin',
'label' => __( 'Double Opt-in', 'wp-marketing-automations' ),
'heading' => __( 'Double Opt-in', 'wp-marketing-automations' ),
'isProSection' => true,
'fields' => array(
array(
'id' => 'after_confirmation_type',
'label' => __( 'After Confirmation Type', 'wp-marketing-automations' ),
'type' => 'radio',
'options' => [
[
'label' => __( "Show Message", 'wp-marketing-automations' ),
'value' => 'show_message',
'tooltip' => ""
],
[
'label' => __( "Redirect to an URL", 'wp-marketing-automations' ),
'value' => 'redirect',
'tooltip' => ""
]
],
'hint' => __( "Please Select what will happen after contact clicked on subscribe link", 'wp-marketing-automations' ),
'class' => 'bwfan_confirmation_type',
'required' => false,
'wrap_before' => '',
),
array(
'id' => 'bwfan_confirmation_message',
'label' => __( 'After Confirmation Message', 'wp-marketing-automations' ),
'type' => 'richeditor',
'class' => 'bwfan_confirmation_message',
'required' => false,
'wrap_before' => ' ',
'hint' => '',
'toggler' => array(
'fields' => array(
array(
'id' => 'after_confirmation_type',
'value' => 'show_message',
)
),
'relation' => 'OR',
),
),
array(
'id' => 'bwfan_confirmation_redirect_url',
'label' => __( 'Redirect URL', 'wp-marketing-automations' ),
'type' => 'text',
'class' => 'bwfan_confirmation_redirect_url',
'placeholder' => 'Redirect URL',
'required' => false,
'hint' => __( 'Please provide redirect URL after contact confirmation', 'wp-marketing-automations' ),
'toggler' => array(
'fields' => array(
array(
'id' => 'after_confirmation_type',
'value' => 'redirect',
)
),
'relation' => 'OR',
),
),
),
),
array(
'key' => 'advanced',
'label' => __( 'Advanced', 'wp-marketing-automations' ),
'heading' => __( 'Advanced', 'wp-marketing-automations' ),
'fields' => array(
array(
'id' => 'bwfan_sandbox_mode',
'label' => __( 'Sandbox Mode', 'wp-marketing-automations' ),
'type' => 'checkbox',
'checkboxlabel' => __( 'Enable Sandbox Mode', 'wp-marketing-automations' ),
'hint' => __( "Automations and Broadcasts will not run or trigger for any contacts while this mode is active.", 'wp-marketing-automations' ),
'class' => 'bwfan_sandbox_mode',
'required' => false,
'wrap_before' => '',
'toggler' => array(),
),
array(
'id' => 'bwfan_delete_autonami_generated_coupons_time',
'label' => __( 'Delete Expired Coupons (in days)', 'wp-marketing-automations' ),
'type' => 'number',
"min" => '0',
'class' => 'bwfan_delete_autonami_generated_coupons_time',
'placeholder' => '1',
'isWooField' => true,
'isProField' => true,
'wrap_before' => '' . __( 'WooCommerce Coupons', 'wp-marketing-automations' ) . ' ',
'hint' => __( 'Delete personalized coupons after expiry', 'wp-marketing-automations' ),
'required' => false,
'toggler' => array(),
),
$engagement_meta_record_delete,
array(
'id' => 'debug_notice',
'type' => 'notice',
'class' => '',
'status' => 'warning',
'message' => __( 'It is highly recommended to disable logging once troubleshooting is complete.', 'wp-marketing-automations' ),
'wrap_before' => '' . __( 'Debug Logs (For Developers)', 'wp-marketing-automations' ) . ' ',
'dismiss' => false,
'required' => false,
'toggler' => array(),
),
array(
'id' => 'bwfan_make_logs',
'label' => __( 'Basic Logging', 'wp-marketing-automations' ),
'type' => 'checkbox',
'checkboxlabel' => __( 'Enable Basic Logs', 'wp-marketing-automations' ),
'hint' => __( 'These are basic operational logs. Logs will be saved on path Funnelkit Automation > Settings > Logs . Disable this settings after debugging is finished.', 'wp-marketing-automations' ),
'class' => 'bwfan_make_logs',
'required' => false,
'toggler' => array(),
),
array(
'id' => 'bwfan_advance_logs',
'label' => __( 'Advance Logging', 'wp-marketing-automations' ),
'type' => 'checkbox',
'checkboxlabel' => __( 'Enable Advanced Logs', 'wp-marketing-automations' ),
'hint' => __( 'These are advanced logs for deeper troubleshooting for specific modules. Logs will be saved on path Funnelkit Automation > Settings > Logs . Disable this settings after debugging is finished.', 'wp-marketing-automations' ),
'class' => 'bwfan_make_logs',
'required' => false,
'wrap_before' => '',
'toggler' => array(),
),
array(
'id' => 'bwfan_cron_check_logging',
'type' => 'checkbox',
'label' => ' ',
'checkboxlabel' => __( 'Enable Logs for Cron Execution Time', 'wp-marketing-automations' ),
'hint' => __( "It logs the execution time of FunnelKit Automation worker. Logs are captured in file named fka-cron-check-xxx ", 'wp-marketing-automations' ),
'class' => 'bwfan_make_logs',
'required' => false,
'wrap_before' => '',
'toggler' => array(
'fields' => array(
array(
'id' => 'bwfan_advance_logs',
'value' => true,
),
),
),
),
array(
'id' => 'bwfan_end_point_logging',
'type' => 'checkbox',
'label' => ' ',
'checkboxlabel' => __( "Enable Logs for Event JSON endpoint", "wp-marketing-automations" ),
'hint' => __( "It logs the payload and response of the call. Logs are captured in file named fka-event-endpoint-check-xxx ", 'wp-marketing-automations' ),
'class' => 'bwfan_make_logs',
'required' => false,
'wrap_before' => '',
'toggler' => array(
'fields' => array(
array(
'id' => 'bwfan_advance_logs',
'value' => true,
),
),
),
),
array(
'id' => 'bwfan_step_logging',
'label' => ' ',
'type' => 'checkbox',
'checkboxlabel' => __( 'Enable Logs for Automation Steps', 'wp-marketing-automations' ),
'hint' => __( "It logs step by step execution in Automation. Logs are captured in file named fka-automation-step-id-xxx ", 'wp-marketing-automations' ),
'class' => 'bwfan_make_logs',
'required' => false,
'wrap_before' => '',
'toggler' => array(
'fields' => array(
array(
'id' => 'bwfan_advance_logs',
'value' => true,
),
),
),
),
array(
'id' => 'bwfan_broadcast_logging',
'type' => 'checkbox',
'label' => ' ',
'checkboxlabel' => __( 'Enable Logs for Broadcast', 'wp-marketing-automations' ),
'hint' => __( "It logs step by step execution in Broadcast. Logs are captured in file named fka-broadcast-xxx ", 'wp-marketing-automations' ),
'class' => 'bwfan_make_logs',
'required' => false,
'wrap_before' => '',
'isProField' => true,
'toggler' => array(
'fields' => array(
array(
'id' => 'bwfan_advance_logs',
'value' => true,
),
),
),
),
array(
'id' => 'bwfan_bulk_action_logging',
'type' => 'checkbox',
'label' => ' ',
'checkboxlabel' => __( 'Enable Logs for Bulk Actions', 'wp-marketing-automations' ),
'hint' => __( "It logs step by step execution in Bulk Action. Logs are captured in file named fka-bulk-action-xxx ", "wp-marketing-automations" ),
'class' => 'bwfan_make_logs',
'required' => false,
'wrap_before' => '',
'isProField' => true,
'toggler' => array(
'fields' => array(
array(
'id' => 'bwfan_advance_logs',
'value' => true,
),
),
),
),
array(
'id' => 'bwfan_contact_export_logging',
'type' => 'checkbox',
'label' => ' ',
'checkboxlabel' => __( 'Enable Logs for Contact Export Process', 'wp-marketing-automations' ),
'hint' => __( "It logs step by step execution in Contact Export. Logs are captured in file named fka-contact-export-xxx ", 'wp-marketing-automations' ),
'class' => 'bwfan_make_logs',
'required' => false,
'wrap_before' => '',
'isProField' => true,
'toggler' => array(
'fields' => array(
array(
'id' => 'bwfan_advance_logs',
'value' => true,
),
),
),
),
array(
'id' => 'bwfan_contact_query_logging',
'type' => 'checkbox',
'label' => ' ',
'checkboxlabel' => __( 'Enable Logs for Contact Query', 'wp-marketing-automations' ),
'hint' => __( "It logs the contact fetching query and time spent in fetching the data. Logs are captured in file named fka-contacts-query-xxx ", 'wp-marketing-automations' ),
'class' => 'bwfan_make_logs',
'required' => false,
'wrap_before' => '',
'isProField' => true,
'toggler' => array(
'fields' => array(
array(
'id' => 'bwfan_advance_logs',
'value' => true,
),
),
),
),
array(
'id' => 'bwfan_email_bounce_logging',
'type' => 'checkbox',
'label' => ' ',
'checkboxlabel' => __( 'Enable Logs for Email Bounce Webhook', 'wp-marketing-automations' ),
'hint' => __( "It logs the received data from email service provider related to bounce and complaint. Logs are captured in file named fka-email-webhook-request-xxx ", 'wp-marketing-automations' ),
'class' => 'bwfan_make_logs',
'required' => false,
'wrap_before' => '',
'isProField' => true,
'toggler' => array(
'fields' => array(
array(
'id' => 'bwfan_advance_logs',
'value' => true,
),
),
),
),
array(
'id' => 'bwfan_webhook_received_logging',
'type' => 'checkbox',
'label' => ' ',
'checkboxlabel' => __( 'Enable Logs for Webhook Received event automation', 'wp-marketing-automations' ),
'hint' => __( "It logs the received data on a 'Webhook Received' automation. Logs are captured in file named fka-webhook-logs-xxx ", 'wp-marketing-automations' ),
'class' => 'bwfan_make_logs',
'required' => false,
'wrap_before' => '',
'isProField' => true,
'toggler' => array(
'fields' => array(
array(
'id' => 'bwfan_advance_logs',
'value' => true,
),
),
),
),
$twilio_webhook_log_data,
$short_url_log_data
),
),
array(
'key' => 'unsubscribers',
'label' => __( 'Unsubscribers', 'wp-marketing-automations' ),
'fields' => [
array(
'id' => 'bwfan_unsubscribers',
'type' => 'bwfan_unsubscribers',
),
],
),
array(
'key' => 'tools',
'label' => __( 'Tools', 'wp-marketing-automations' ),
'heading' => __( 'Tools', 'wp-marketing-automations' ),
'tabs' => [
[
'key' => 'tools',
'label' => __( 'Tools', 'wp-marketing-automations' ),
'heading' => __( 'Tools', 'wp-marketing-automations' ),
'fields' => [
array(
'id' => 'bwfan_tools',
'type' => 'bwfan_tools',
),
],
],
[
'key' => 'logs',
'label' => __( 'Logs', 'wp-marketing-automations' ),
'heading' => __( 'Logs', 'wp-marketing-automations' ),
'fields' => [
array(
'id' => 'bwfan_logs',
'type' => 'bwfan_logs',
),
],
],
],
),
array(
'key' => 'notifications',
'label' => 'Notifications', // label is used for left side tab item
'heading' => 'Notifications',
'fields' => self::get_notification_settings_schema(),
),
),
),
);
return apply_filters( 'bwfan_admin_settings_schema', $settings );
}
public static function get_select_options( $type = 'hour' ) {
$options = [];
switch ( $type ) {
case 'hour':
for ( $i = 1; $i <= 12; $i ++ ) {
$options[] = [
'value' => sprintf( "%02d", $i ),
'label' => sprintf( "%02d", $i ),
];
}
break;
case 'minute':
for ( $i = 0; $i <= 59; $i ++ ) {
$options[] = [
'value' => sprintf( "%02d", $i ),
'label' => sprintf( "%02d", $i ),
];
}
break;
}
return $options;
}
public static function get_notification_settings_schema() {
return [
[
'id' => 'bwfan_enable_notification',
'label' => __( 'Enable Email Performance Summary', 'wp-marketing-automations' ),
'class' => 'bwf-tooglecontrol-settings',
'type' => 'toggle',
],
[
'id' => 'bwf_notification_frequency',
'label' => __( 'Frequency', 'wp-marketing-automations' ),
'type' => 'checkbox_grid',
'class' => '',
'placeholder' => '',
'required' => false,
'options' => [
'weekly' => __( 'Weekly', 'wp-marketing-automations' ),
'monthly' => __( 'Monthly', 'wp-marketing-automations' ),
],
'hint' => __( 'Emails will be skipped if there are no metrics to show', 'wp-marketing-automations' ),
'toggler' => array(
'fields' => array(
array(
'id' => 'bwfan_enable_notification',
'value' => true,
)
),
'relation' => 'AND',
),
],
array(
'id' => 'bwf_notification_user_selector',
'label' => __( 'Users', 'wp-marketing-automations' ),
"type" => 'search',
'autocompleter' => 'users',
"allowFreeTextSearch" => false,
'required' => false,
'wrap_before' => '',
'toggler' => array(
'fields' => array(
array(
'id' => 'bwfan_enable_notification',
'value' => true,
),
),
'relation' => 'AND',
),
),
array(
'id' => 'bwfan_external_user',
'label' => __( 'Other Recipient', 'wp-marketing-automations' ),
'type' => 'addrecipient',
'class' => '',
'hint' => __( 'If no users or recipients are added, the email summary will be sent to the site admin.', 'wp-marketing-automations' ),
'required' => false,
'toggler' => array(
'fields' => array(
array(
'id' => 'bwfan_enable_notification',
'value' => true,
),
),
'relation' => 'AND',
),
),
[
'id' => 'bwfan_notification_time',
'type' => 'expression',
'expression' => " {{hours/}} {{minutes /}} {{ampm /}}",
'label' => __( 'Send Time', 'wp-marketing-automations' ),
'fields' => [
[
"id" => 'hours',
"label" => '',
"type" => 'select',
"options" => self::get_select_options( 'hour' ),
"class" => 'bwf-wid-90',
"placeholder" => "HH",
"description" => "",
"required" => false,
],
[
"id" => 'minutes',
"label" => '',
"type" => 'select',
"options" => self::get_select_options( 'minute' ),
"class" => 'bwf-wid-90',
"placeholder" => "MM",
"description" => "",
"required" => false,
],
[
'id' => 'ampm',
'type' => 'select',
"class" => 'bwf-wid-90',
'label' => '',
'placeholder' => __( 'Select', 'wp-marketing-automations' ),
'options' => [
[
'value' => 'am',
'label' => __( 'AM', 'wp-marketing-automations' ),
],
[
'value' => 'pm',
'label' => __( 'PM', 'wp-marketing-automations' ),
]
],
]
],
"description" => "",
'toggler' => array(
'fields' => array(
array(
'id' => 'bwfan_enable_notification',
'value' => true,
),
),
'relation' => 'AND',
),
],
array(
'id' => 'send_test_mail',
'type' => 'testmail',
'label' => '',
'class' => 'bwf-position-test-mail-bottom',
'toggler' => array(
'fields' => array(
array(
'id' => 'bwfan_enable_notification',
'value' => true,
),
),
'relation' => 'AND',
),
)
];
}
public static function get_bounce_settings_schema() {
if ( ! bwfan_is_autonami_pro_active() ) {
return array(
array(
'id' => 'bwfan_enable_bounce_handling',
'label' => __( 'Bounce Tracking', 'wp-marketing-automations' ),
'type' => 'checkbox',
'checkboxlabel' => __( 'Enable to capture bounced emails from the email service and mark Contact as Bounced', 'wp-marketing-automations' ),
'class' => 'bwfan_user_consent',
'required' => false,
'wrap_before' => '' . __( 'Email Service Provider', 'wp-marketing-automations' ) . ' ',
'disabled' => true,
'isProSetting' => true,
),
);
}
$bounce_settings = bwfan_is_autonami_pro_active() ? BWFCRM_Core()->email_webhooks->get_webhooks() : array();
$bounce_options = array(
array(
'label' => __( 'Select Email Service', 'wp-marketing-automations' ),
'value' => '',
),
);
$bounce_settings_schema = ! empty( $bounce_settings ) ? array_map( function ( $webhook, $slug ) use ( &$bounce_options ) {
if ( empty( $slug ) || empty( $webhook ) || ! is_array( $webhook ) ) {
return false;
}
$bounce_options[] = array(
'label' => $webhook['name'],
'value' => strtolower( $webhook['name'] ),
);
return array(
'id' => 'bwfan_email_webhook_' . $slug,
'type' => 'copier',
'class' => 'bwfan_email_webhook',
// phpcs:ignore WordPress.WP.I18n.MissingTranslatorsComment
'hint' => sprintf( __( "Paste this URL into your %s's Webhook settings to enable Bounce Handling", 'wp-marketing-automations' ), $webhook['name'] ),
'required' => false,
'copy_text' => $webhook['link'],
'toggler' => array(
'fields' => array(
array(
'id' => 'bwfan_bounce_select',
'value' => strtolower( $webhook['name'] ),
),
array(
'id' => 'bwfan_enable_bounce_handling',
'value' => true,
),
),
'relation' => 'AND',
),
);
}, $bounce_settings, array_keys( $bounce_settings ) ) : array();
$bounce_settings_schema = array_merge( array(
array(
'id' => 'bwfan_enable_bounce_handling',
'label' => __( 'Bounce Tracking', 'wp-marketing-automations' ),
'type' => 'checkbox',
'checkboxlabel' => __( 'Enable to capture bounced emails from the email service and mark Contact as Bounced', 'wp-marketing-automations' ),
'class' => 'bwfan_user_consent',
'required' => false,
'wrap_before' => '' . __( 'Email Service Provider', 'wp-marketing-automations' ) . ' ',
),
array(
'id' => 'bwfan_bounce_select',
'type' => 'select',
'class' => '',
'options' => $bounce_options,
'required' => false,
'multiple' => false,
'toggler' => array(
'fields' => array(
array(
'id' => 'bwfan_enable_bounce_handling',
'value' => true,
),
),
'relation' => 'AND',
),
),
), $bounce_settings_schema );
return is_array( $bounce_settings_schema ) ? array_filter( $bounce_settings_schema ) : array();
}
public static function get_pro_license( $onlyKey = true ) {
$bwf_licenses = get_option( 'woofunnels_plugins_info', false );
if ( is_multisite() ) {
$active_plugins = get_site_option( 'active_sitewide_plugins', array() );
if ( is_array( $active_plugins ) && ( in_array( BWFAN_PLUGIN_BASENAME, apply_filters( 'active_plugins', $active_plugins ), true ) || array_key_exists( BWFAN_PLUGIN_BASENAME, apply_filters( 'active_plugins', $active_plugins ) ) ) && ! is_main_site() ) {
$bwf_licenses = get_blog_option( get_network()->site_id, 'woofunnels_plugins_info', [] );
}
}
if ( ! defined( 'BWFAN_PRO_ENCODE' ) || empty( $bwf_licenses ) || ! is_array( $bwf_licenses ) ) {
return false;
}
if ( isset( $bwf_licenses[ BWFAN_PRO_ENCODE ] ) && isset( $bwf_licenses[ BWFAN_PRO_ENCODE ]['activated'] ) && $bwf_licenses[ BWFAN_PRO_ENCODE ]['activated'] ) {
if ( $onlyKey ) {
return $bwf_licenses[ BWFAN_PRO_ENCODE ]['data_extra']['api_key'];
} else {
$license_data = [
'manually_deactivated' => isset( $bwf_licenses[ BWFAN_PRO_ENCODE ]['manually_deactivated'] ) ? 1 : 0,
];
if ( isset( $bwf_licenses[ BWFAN_PRO_ENCODE ]['data_extra']['api_key'] ) ) {
$license_data['api_key'] = 'xxxxxxxxxxxxxxxxxxxxxxxxxx' . substr( $bwf_licenses[ BWFAN_PRO_ENCODE ]['data_extra']['api_key'], - 6 );
}
if ( isset( $bwf_licenses[ BWFAN_PRO_ENCODE ]['data_extra']['expires'] ) ) {
$license_data['expires'] = $bwf_licenses[ BWFAN_PRO_ENCODE ]['data_extra']['expires'];
}
return $license_data;
}
}
$plugin_sha = sha1( plugin_basename( 'wp-marketing-automations-pro/wp-marketing-automations-pro.php' ) );
if ( ! $onlyKey && $plugin_sha !== BWFAN_PRO_ENCODE ) {
return [
'error_msg' => __( 'It appears that the original plugin folder has been renamed. Please restore the folder to its original name or reinstall the plugin to activate the license.', 'wp-marketing-automations' )
];
}
return false;
}
/**
* @return array
*/
public static function get_lk_data() {
if ( ! is_null( self::$c_lk_d ) ) {
return self::$c_lk_d;
}
$arr = [ 's' => 0, 'e' => '' ];
if ( ! bwfan_is_autonami_pro_active() ) {
self::$c_lk_d = $arr;
return self::$c_lk_d;
}
$arr['s'] = 1;
if ( is_multisite() ) {
$active_plugins = get_site_option( 'active_sitewide_plugins', array() );
if ( is_array( $active_plugins ) && ( in_array( BWFAN_PLUGIN_BASENAME, apply_filters( 'active_plugins', $active_plugins ), true ) || array_key_exists( BWFAN_PLUGIN_BASENAME, apply_filters( 'active_plugins', $active_plugins ) ) ) && ! is_main_site() ) {
$l_data = get_blog_option( get_network()->site_id, 'woofunnels_plugins_info', [] );
} else {
$l_data = get_option( 'woofunnels_plugins_info', false );
}
} else {
$l_data = get_option( 'woofunnels_plugins_info', false );
}
if ( ! defined( 'BWFAN_PRO_ENCODE' ) || empty( $l_data ) || ! is_array( $l_data ) || ! isset( $l_data[ BWFAN_PRO_ENCODE ] ) || ! isset( $l_data[ BWFAN_PRO_ENCODE ]['activated'] ) || 1 !== intval( $l_data[ BWFAN_PRO_ENCODE ]['activated'] ) ) {
$arr['ad'] = bwf_options_get( 'fka_psd' );
self::$c_lk_d = $arr;
return self::$c_lk_d;
}
$arr['s'] = 2;
$arr['e'] = $l_data[ BWFAN_PRO_ENCODE ]['data_extra']['expires'];
self::$c_lk_d = $arr;
return self::$c_lk_d;
}
public static function get_connector_license( $onlyKey = true ) {
$bwf_licenses = get_option( 'woofunnels_plugins_info', false );
if ( empty( $bwf_licenses ) || ! is_array( $bwf_licenses ) ) {
return false;
}
if ( isset( $bwf_licenses[ WFCO_AUTONAMI_CONNECTORS_ENCODE ] ) && isset( $bwf_licenses[ WFCO_AUTONAMI_CONNECTORS_ENCODE ]['activated'] ) && $bwf_licenses[ WFCO_AUTONAMI_CONNECTORS_ENCODE ]['activated'] ) {
if ( $onlyKey ) {
return $bwf_licenses[ WFCO_AUTONAMI_CONNECTORS_ENCODE ]['data_extra']['api_key'];
} else {
$license_data = [
'manually_deactivated' => isset( $bwf_licenses[ WFCO_AUTONAMI_CONNECTORS_ENCODE ]['manually_deactivated'] ) ? 1 : 0,
];
if ( isset( $bwf_licenses[ WFCO_AUTONAMI_CONNECTORS_ENCODE ]['data_extra']['api_key'] ) ) {
$license_data['api_key'] = 'xxxxxxxxxxxxxxxxxxxxxxxxxx' . substr( $bwf_licenses[ WFCO_AUTONAMI_CONNECTORS_ENCODE ]['data_extra']['api_key'], - 6 );
}
if ( isset( $bwf_licenses[ WFCO_AUTONAMI_CONNECTORS_ENCODE ]['data_extra']['expires'] ) ) {
$license_data['expires'] = $bwf_licenses[ WFCO_AUTONAMI_CONNECTORS_ENCODE ]['data_extra']['expires'];
}
return $license_data;
}
}
$plugin_sha = sha1( plugin_basename( 'wp-marketing-automations-connectors/wp-marketing-automations-connectors.php' ) );
if ( ! $onlyKey && $plugin_sha !== WFCO_AUTONAMI_CONNECTORS_ENCODE ) {
return [
'error_msg' => __( 'It appears that the original plugin folder has been renamed. Please restore the folder to its original name or reinstall the plugin to activate the license.', 'wp-marketing-automations' )
];
}
return false;
}
/**
* Get settings fields for whatsapp services
*
* @return array|array[]
*/
public static function get_whatsapp_services_fields() {
$fields = array();
if ( bwfan_is_autonami_pro_active() && class_exists( 'WFCO_Autonami_Connectors_Core' ) ) {
$services = self::get_whatsapp_services();
$additional_fields = apply_filters( 'bwfan_whatsapp_services_additional_fields', array(), $services );
if ( count( $services ) > 0 ) {
if ( count( $services ) > 1 ) {
$fields[] = array(
"id" => 'bwfan_primary_whats_app_service',
"label" => __( 'Select Service', 'wp-marketing-automations' ),
"type" => 'select',
"class" => '',
"options" => $services,
"required" => false,
"multiple" => false,
"toggler" => array(),
);
}
$fields = array_merge( $fields, array(
array(
"id" => 'bwfan_whatsapp_gap_btw_message',
"label" => __( 'Time Between Each Message (secs)', 'wp-marketing-automations' ),
"type" => 'number',
"min" => '0',
"class" => 'bwfan_whatsapp_gap_btw_message',
"placeholder" => '1',
"hint" => __( "The time gap between messages in seconds", 'wp-marketing-automations' ),
"required" => false,
"autocomplete" => 'off',
"toggler" => array(),
),
) );
if ( ! empty( $additional_fields ) ) {
$fields = array_merge( $fields, $additional_fields );
}
} else {
$fields = array(
array(
'id' => 'whatsapp_notice',
'type' => 'notice',
'class' => '',
'status' => 'error',
'message' => __( 'WhatsApp service is not configured yet.', 'wp-marketing-automations' ),
'dismiss' => false,
'required' => false,
'toggler' => array(),
),
array(
'id' => 'redirect_button',
'label' => __( 'Click to configure Whatsapp Connector', 'wp-marketing-automations' ),
'type' => 'redirect_button',
'redirect_url' => ( 'admin.php?page=autonami&path=/connectors' ),
'class' => '',
'newtab' => '_self',
'btntype' => 'secondary',
'required' => false,
'toggler' => array(),
)
);
}
}
return $fields;
}
/**
* Returns unsubscribe page hint text
*
* @return string
*/
public static function get_unsubscribe_page_hint_text() {
$page_url = '';
$html = '';
$setting = self::get_global_settings();
if ( isset( $setting['bwfan_unsubscribe_page'] ) && ! empty( $setting['bwfan_unsubscribe_page'] ) ) {
$page_url = get_edit_post_link( $setting['bwfan_unsubscribe_page'] );
}
if ( $page_url ) {
$html = '' . __( 'Click here', 'wp-marketing-automations' ) . ' ' . __( 'to edit the page.', 'wp-marketing-automations' ) . ' ';
}
// $html .= __( 'Use shortcodes [wfan_contact_name] for contact\'s name', 'wp-marketing-automations' ) . ', ' . __( '[wfan_contact_firstname] for contact\'s first name', 'wp-marketing-automations' ) . ', ' . __( '[wfan_contact_lastname] for contact\'s last name', 'wp-marketing-automations' ) . ', ' . __( '[wfan_contact_email] for contact\'s email', 'wp-marketing-automations' ) . ' and ' . __( '[wfan_unsubscribe_button label=\'Update my preference\'] for the unsubscribe button.', 'wp-marketing-automations' );
$html .= sprintf( __( "Use shortcodes %s for contact's name, %s for contact's first name, %s for contact's last name', %s for contact's email and %s for the unsubscribe button.", 'wp-marketing-automations' ), '[wfan_contact_name] ', '[wfan_contact_firstname] ', '[wfan_contact_lastname] ', '[wfan_contact_email] ', "[wfan_unsubscribe_button label='" . __( 'Update my preference', 'wp-marketing-automations' ) . "'] " ); // phpcs:ignore WordPress.WP.I18n.MissingTranslatorsComment, WordPress.WP.I18n.UnorderedPlaceholdersText
return $html;
}
/**
* Validate subscribe page and its content
*
* @return array
*/
public static function is_unsubscribe_page_valid() {
$arr = [ 'status' => 0, 'message' => '' ];
$setting = self::get_global_settings();
/** Check if unsubscribe page is set */
if ( ! isset( $setting['bwfan_unsubscribe_page'] ) || empty( $setting['bwfan_unsubscribe_page'] ) ) {
return $arr;
}
$post = get_post( $setting['bwfan_unsubscribe_page'] );
if ( ! $post instanceof WP_Post ) {
return [
'status' => 3,
'message' => __( 'Unsubscribe Page Not Found.', 'wp-marketing-automations' ),
];
}
// Checking if page is not publish
if ( 'publish' !== $post->post_status ) {
return [
'status' => 3,
'message' => __( 'The unsubscribe page must be published and accessible to all users.', 'wp-marketing-automations' ),
];
}
/** Fetch Breakdance content if active */
$content = bwfan_is_breakdance_active() ? self::get_breakdance_content( $post->ID ) : '';
$content = empty( $content ) ? $post->post_content : $content;
/** Check for required shortcodes */
$has_shortcode = has_shortcode( $content, 'wfan_unsubscribe_button' ) || has_shortcode( $content, 'bwfan_unsubscribe_button' ) || strpos( $content, 'id="bwfan_unsubscribe"' ) !== false;
if ( empty( $content ) || ! $has_shortcode ) {
return [
'status' => 2,
'message' => __( 'The selected unsubscribe page doesn\'t contain the required shortcode. Please add.', 'wp-marketing-automations' ),
];
}
return [ 'status' => 1, 'message' => '' ]; // success
}
/**
* Get the Breakdance post content
*
* @param $page_id
*
* @return string
*/
public static function get_breakdance_content( $page_id ) {
if ( empty( $page_id ) ) {
return '';
}
$data = get_post_meta( $page_id, '_breakdance_data', true );
if ( empty( $data ) ) {
return '';
}
$decoded_data = json_decode( $data, true );
$tree_json = $decoded_data['tree_json_string'] ?? '';
if ( empty( $tree_json ) ) {
return '';
}
$tree_data = json_decode( $tree_json, true );
return ! empty( $tree_data['root']['children'] ) ? self::extract_shortcodes_from_breakdance( $tree_data['root']['children'] ) : '';
}
/**
* Extract shortcodes from Breakdance JSON tree.
*
* @param array $children
*
* @return string
*/
private static function extract_shortcodes_from_breakdance( $children ) {
$shortcodes = '';
foreach ( $children as $child ) {
if ( isset( $child['data']['type'] ) && $child['data']['type'] === 'EssentialElements\\Shortcode' ) {
$shortcodes .= $child['data']['properties']['content']['shortcode']['full_shortcode'] ?? '';
}
if ( ! empty( $child['children'] ) ) {
$shortcodes .= self::extract_shortcodes_from_breakdance( $child['children'] );
}
}
return $shortcodes;
}
public static function get_lists_preference_schema() {
if ( ! bwfan_is_autonami_pro_active() ) {
return array();
}
return array(
array(
'id' => 'bwfan_unsubscribe_lists_enable',
'label' => __( 'Manage Lists', 'wp-marketing-automations' ),
'type' => 'checkbox',
'checkboxlabel' => __( 'Allow contacts to manage their lists', 'wp-marketing-automations' ),
'class' => 'bwfan_unsubscribe_lists_enable',
'wrap_before' => '' . __( 'List Management', 'wp-marketing-automations' ) . ' ',
'required' => false,
),
array(
'id' => 'bwfan_unsubscribe_public_lists',
'label' => __( 'Select Lists', 'wp-marketing-automations' ),
'type' => 'checkbox_grid',
'hint' => __( 'The selected lists will be shown to contacts for managing their preferences', 'wp-marketing-automations' ),
'class' => 'bwfan_unsubscribe_public_lists',
'options' => self::get_lists_for_preferences(),
'required' => false,
'toggler' => array(
'fields' => array(
array(
'id' => 'bwfan_unsubscribe_lists_enable',
'value' => true,
),
),
),
),
array(
'id' => 'bwfan_unsubscribe_lists_visibility',
'label' => __( 'Filter List', 'wp-marketing-automations' ),
'type' => 'checkbox',
'checkboxlabel' => __( 'Show contact their subscribed lists', 'wp-marketing-automations' ),
'hint' => __( 'If unchecked all the selected lists will be available to contacts', 'wp-marketing-automations' ),
'class' => 'bwfan_unsubscribe_lists_visibility',
'required' => false,
'toggler' => array(
'fields' => array(
array(
'id' => 'bwfan_unsubscribe_lists_enable',
'value' => true,
),
),
),
),
);
}
public static function get_lists_for_preferences() {
if ( ! bwfan_is_autonami_pro_active() ) {
return array();
}
$lists = BWFAN_Model_Terms::get_all( BWFCRM_Term_Type::$LIST );
if ( empty( $lists ) ) {
return array();
}
$lists_array = array();
foreach ( $lists as $list ) {
if ( empty( $list['name'] ) ) {
continue;
}
$lists_array[ $list['ID'] ] = $list['name'];
}
return $lists_array;
}
/**
* checking if all table created or not
*/
public static function checking_all_tables_exists() {
global $wpdb;
$result = true;
$not_created_tables = array();
$mytables = $wpdb->get_results( 'SHOW TABLES', ARRAY_A ); //phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
$tables_array = empty( $mytables ) ? [] : array_column( $mytables, 'Tables_in_' . $wpdb->dbname );
$automations_table_array = self::get_tables_array();
foreach ( $automations_table_array as $table ) {
if ( ! in_array( $table, $tables_array, true ) ) {
$not_created_tables[] = $table;
}
}
if ( ! empty( $not_created_tables ) ) {
return $not_created_tables;
}
return $result;
}
/** return all autonami tables
*
* @return mixed|void
*/
public static function get_tables_array() {
global $wpdb;
$automations_table_array = apply_filters( 'bwfan_automation_tables', array(
$wpdb->prefix . 'bwfan_automations',
$wpdb->prefix . 'bwfan_automationmeta',
$wpdb->prefix . 'bwfan_tasks',
$wpdb->prefix . 'bwfan_taskmeta',
$wpdb->prefix . 'bwfan_task_claim',
$wpdb->prefix . 'bwfan_logs',
$wpdb->prefix . 'bwfan_logmeta',
$wpdb->prefix . 'bwfan_message_unsubscribe',
$wpdb->prefix . 'bwfan_contact_automations',
$wpdb->prefix . 'bwfan_abandonedcarts',
) );
sort( $automations_table_array );
return $automations_table_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,
);
}
/** maybe create abandoned cart if enable
*
* @param $active_abandoned_cart
*/
public static function maybe_create_abandoned_contact( $active_abandoned_cart ) {
$global_settings = self::get_global_settings();
$abandoned_tag = isset( $global_settings['bwfan_ab_tag_selector'] ) ? json_decode( $global_settings['bwfan_ab_tag_selector'], true ) : [];
$abandoned_list = isset( $global_settings['bwfan_ab_list_selector'] ) && is_array( $global_settings['bwfan_ab_list_selector'] ) ? $global_settings['bwfan_ab_list_selector'] : [];
$abandoned_tag = array_map( function ( $tag ) {
$tag['value'] = ! isset( $tag['value'] ) && isset( $tag['name'] ) ? $tag['name'] : '';
unset( $tag['name'] );
return $tag;
}, $abandoned_tag );
$abandoned_list = array_map( function ( $list ) {
$list['value'] = ! isset( $list['value'] ) && isset( $list['name'] ) ? $list['name'] : '';
unset( $list['name'] );
return $list;
}, $abandoned_list );
if ( ! isset( $active_abandoned_cart['ID'] ) || empty( $active_abandoned_cart['ID'] ) ) {
return;
}
$abandoned_id = $active_abandoned_cart['ID'];
$abandoned_data = BWFAN_Model_Abandonedcarts::get( $abandoned_id );
if ( ! is_array( $abandoned_data ) ) {
return;
}
$abandoned_user_id = $active_abandoned_cart['user_id'];
$abandoned_email = $abandoned_data['email'];
if ( empty( $abandoned_email ) ) {
return;
}
if ( empty( $abandoned_user_id ) ) {
$abandoned_user_id = 0;
}
$contact = bwf_get_contact( $abandoned_user_id, $abandoned_email );
if ( $contact instanceof WooFunnels_Contact && $contact->get_id() > 0 ) {
$bwfcrm_contact = new BWFCRM_Contact( $contact ); // getting bwfcrm_contact object to add tags
if ( ! empty( $abandoned_tag ) ) {
$bwfcrm_contact->add_tags( $abandoned_tag );
}
if ( ! empty( $abandoned_list ) ) {
$bwfcrm_contact->add_lists( $abandoned_list );
}
}
if ( $abandoned_user_id > 0 ) {
$wp_user = get_user_by( 'id', $abandoned_user_id );
$abandoned_email = $wp_user->user_email;
}
$abandoned_checkout_data = json_decode( $abandoned_data['checkout_data'], true );
$pushengage_token = $abandoned_checkout_data['pushengage_token'] ?? '';
$bwf_contact = new WooFunnels_Contact( $abandoned_user_id, $abandoned_email );
if ( ! empty( $abandoned_user_id ) ) {
$bwf_contact->set_wpid( $abandoned_user_id );
}
$f_name = self::get_field_with_fallback( $abandoned_checkout_data, 'first_name' );
$l_name = self::get_field_with_fallback( $abandoned_checkout_data, 'last_name' );
$contact_no = self::get_field_with_fallback( $abandoned_checkout_data, 'phone' );
$state = self::get_field_with_fallback( $abandoned_checkout_data, 'state' );
$country = self::get_field_with_fallback( $abandoned_checkout_data, 'country' );
$address_1 = self::get_field_with_fallback( $abandoned_checkout_data, 'address_1' );
$address_2 = self::get_field_with_fallback( $abandoned_checkout_data, 'address_2' );
$city = self::get_field_with_fallback( $abandoned_checkout_data, 'city' );
$postcode = self::get_field_with_fallback( $abandoned_checkout_data, 'postcode' );
$timezone = $abandoned_checkout_data['fields']['timezone'] ?? '';
if ( ! empty( $f_name ) ) {
$bwf_contact->set_f_name( $f_name );
}
if ( ! empty( $l_name ) ) {
$bwf_contact->set_l_name( $l_name );
}
if ( ! empty( $contact_no ) ) {
$bwf_contact->set_contact_no( $contact_no );
}
if ( ! empty( $timezone ) ) {
$bwf_contact->set_timezone( $timezone );
}
if ( ! empty( $state ) ) {
$bwf_contact->set_state( $state );
}
if ( ! empty( $country ) ) {
$bwf_contact->set_country( $country );
}
$bwf_contact->save();
$bwfcrm_contact = new BWFCRM_Contact( $bwf_contact ); // getting bwfcrm_contact object to add tags
if ( ! empty( $address_1 ) ) {
$bwfcrm_contact->set_field_by_slug( 'address-1', $address_1 );
}
if ( ! empty( $address_2 ) ) {
$bwfcrm_contact->set_field_by_slug( 'address-2', $address_2 );
}
if ( ! empty( $city ) ) {
$bwfcrm_contact->set_field_by_slug( 'city', $city );
}
if ( ! empty( $postcode ) ) {
$bwfcrm_contact->set_field_by_slug( 'postcode', $postcode );
}
if ( ! empty( $pushengage_token ) ) {
$subs_tokens = $bwfcrm_contact->get_field_by_slug( 'push-engage-token' );
$subs_tokens = json_decode( $subs_tokens, true );
if ( empty( $subs_tokens ) || ! is_array( $subs_tokens ) ) {
$subs_tokens = array();
}
if ( empty( $subs_tokens ) || ! in_array( $pushengage_token, $subs_tokens, true ) ) {
$subs_tokens[] = $pushengage_token;
$bwfcrm_contact->set_field_by_slug( 'push-engage-token', wp_json_encode( $subs_tokens ) );
}
}
$year = (int) ( $abandoned_checkout_data['fields']['dob_fields']['bwfan_birthday_date_yy'] ?? 0 );
$month = (int) ( $abandoned_checkout_data['fields']['dob_fields']['bwfan_birthday_date_mm'] ?? 0 );
$day = (int) ( $abandoned_checkout_data['fields']['dob_fields']['bwfan_birthday_date_dd'] ?? 0 );
$dob = '';
if ( $year >= 1900 && $year <= 2100 && $month >= 1 && $month <= 12 && $day >= 1 && $day <= 31 && checkdate( $month, $day, $year ) ) {
$dob = sprintf( '%04d-%02d-%02d', $year, $month, $day );
}
if ( ! empty( $dob ) ) {
$bwfcrm_contact->set_field_by_slug( 'dob', $dob );
}
$bwfcrm_contact->save();
if ( ! empty( $city ) || ! empty( $address_1 ) || ! empty( $address_2 ) || ! empty( $postcode ) || ! empty( $pushengage_token ) || ! empty( $dob ) ) {
$bwfcrm_contact->save_fields();
}
}
/**
* Get field value of checkout form field with fallback to shipping if billing is not available
*
* @param $cart_data
* @param $key
*
* @return mixed|string
*/
public static function get_field_with_fallback( $cart_data, $key ) {
if ( empty( $cart_data ) || ! is_array( $cart_data ) || empty( $key ) ) {
return '';
}
$value = $cart_data['fields'][ 'billing_' . $key ] ?? '';
if ( ! empty( $value ) ) {
return $value;
}
return $cart_data['fields'][ 'shipping_' . $key ] ?? '';
}
/**
* remove abandoned cart tags on cart recovered
*
* @param $order
*/
public static function bwfan_remove_abandoned_cart_tags( $order ) {
if ( ! $order instanceof WC_Order ) {
return;
}
/** If pro not found */
if ( ! bwfan_is_autonami_pro_active() || ! class_exists( 'BWFCRM_Contact' ) ) {
return;
}
$global_settings = self::get_global_settings();
$removed_abandoned_tags = isset( $global_settings['bwfan_ab_tag_selector'] ) ? json_decode( $global_settings['bwfan_ab_tag_selector'], true ) : [];
$removed_abandoned_list = isset( $global_settings['bwfan_ab_list_selector'] ) ? $global_settings['bwfan_ab_list_selector'] : [];
if ( empty( $removed_abandoned_tags ) && empty( $removed_abandoned_list ) ) {
return;
}
$remove_tag_data = $remove_list_data = array();
if ( ! empty( $removed_abandoned_tags ) ) {
foreach ( $removed_abandoned_tags as $remove_tag ) {
$tag_id = $remove_tag['id'];
if ( 0 === absint( $tag_id ) && bwfan_is_autonami_pro_active() ) {
$tag_id = empty( $remove_tag['id'] ) ? BWFCRM_Term::get_terms( 1, [], $remove_tag['name'], 0, 0, ARRAY_A, 'exact' ) : $remove_tag['id'];
}
$remove_tag_data[] = is_array( $tag_id ) && isset( $tag_id[0]['ID'] ) ? $tag_id[0]['ID'] : $tag_id;
}
}
if ( ! empty( $removed_abandoned_list ) ) {
foreach ( $removed_abandoned_list as $remove_tag ) {
$remove_list_data[] = $remove_tag['id'];
}
}
$cid = $order->get_meta( '_woofunnel_cid' );
if ( empty( $cid ) ) {
return;
}
$bwfcrm_contact = new BWFCRM_Contact( $cid );
if ( ! $bwfcrm_contact->is_contact_exists() ) {
return;
}
if ( ! empty( $remove_tag_data ) ) {
$bwfcrm_contact->remove_tags( $remove_tag_data );
}
if ( ! empty( $remove_list_data ) ) {
$bwfcrm_contact->remove_lists( $remove_list_data );
}
$bwfcrm_contact->save();
}
public static function get_carts_count() {
$recoverable_count = BWFAN_Recoverable_Carts::get_abandoned_carts( '', '', '', '', '', true );
$recovered_count = BWFAN_Recoverable_Carts::get_recovered_carts( '', '', '', true );
$lost_carts = BWFAN_Recoverable_Carts::get_abandoned_carts( '', '', '', '', 2, true );
return [
'carts_recoverable' => absint( $recoverable_count['total_count'] ) > 0 ? absint( $recoverable_count['total_count'] ) : 0,
'carts_recovered' => absint( $recovered_count['total_count'] ) > 0 ? absint( $recovered_count['total_count'] ) : 0,
'carts_lost' => absint( $lost_carts['total_count'] ) > 0 ? absint( $lost_carts['total_count'] ) : 0,
];
}
public static function get_automation_data_count( $version = 1 ) {
$automation_count = self::get_all_automations( '', 'all', 0, 0, true, $version );
$active = self::get_all_automations( '', '1', 0, 0, true, $version );
$inactive = absint( $automation_count['total_records'] ) - absint( $active['total_records'] );
if ( 2 === intval( $version ) ) {
return [
'automations' => absint( $automation_count['total_records'] ),
'contact_activity' => absint( BWFAN_Model_Automation_Contact::get_active_count( '', 2, '', '' ) ),
'status_count' => [
'active' => absint( $active['total_records'] ),
'inactive' => $inactive,
]
];
}
$scheduled_count = BWFAN_Core()->tasks->fetch_tasks_count( 0, 0 );
$paused_count = BWFAN_Core()->tasks->fetch_tasks_count( 0, 1 );
$completed_count = BWFAN_Core()->logs->fetch_logs_count( 1 );
$failed_count = BWFAN_Core()->logs->fetch_logs_count( 0 );
$task_history_count = $scheduled_count + $paused_count + $completed_count + $failed_count;
return [
'automations' => absint( $automation_count['total_records'] ),
'contact_activity' => absint( BWFAN_Model_Automation_Contact::get_active_count( '', 2, '', '' ) ),
'status_count' => [
'active' => absint( $active['total_records'] ),
'inactive' => $inactive,
],
'task_history' => $task_history_count
];
}
/** get all automations data for the api
*
* @param string $status
* @param int $offset
* @param int $limit
*
* @return array
*/
public static function get_all_automations( $search, $status = 'all', $offset = 0, $limit = 25, $only_count = false, $version = 0 ) {
global $wpdb;
$automations_table = $wpdb->prefix . 'bwfan_automations';
$base_query = array();
$count_query = array();
$base_query[] = "SELECT distinct a.* FROM $automations_table as a LEFT JOIN {$wpdb->prefix}bwfan_automationmeta as am ON a.ID = am.bwfan_automation_id where 1=1 ";
$count_query[] = "SELECT count(DISTINCT a.ID) FROM $automations_table as a LEFT JOIN {$wpdb->prefix}bwfan_automationmeta as am ON a.ID = am.bwfan_automation_id where 1=1 ";
if ( ! empty( $search ) && $only_count === false ) {
$search = "%$search%";
if ( 2 === absint( $version ) ) {
$search_query = $wpdb->prepare( " AND a.title LIKE %s", $search );
} else {
$search_query = $wpdb->prepare( " AND am.meta_key='title' AND am.meta_value like %s", $search );
}
$base_query[] = $search_query;
$count_query[] = $search_query;
}
if ( intval( $version ) !== 0 ) {
$version_query = $wpdb->prepare( ' AND a.v = %d ', $version );
$base_query[] = $version_query;
$count_query[] = $version_query;
}
if ( $status !== 'all' ) {
$status_query = $wpdb->prepare( ' AND a.status = %d', $status );
$base_query[] = $status_query;
$count_query[] = $status_query;
}
$base_query[] = $wpdb->prepare( ' ORDER BY a.ID DESC LIMIT %d OFFSET %d', $limit, $offset );
if ( $only_count === false ) {
$all_automations = self::get_db_cache_data( implode( ' ', $base_query ) );
if ( false === $all_automations ) {
$all_automations = $wpdb->get_results( implode( ' ', $base_query ), ARRAY_A ); //phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL
self::set_db_cache_data( implode( ' ', $base_query ), $all_automations );
}
}
$overall_total = self::get_db_cache_data( implode( ' ', $count_query ) );
if ( false === $overall_total ) {
$overall_total = $wpdb->get_var( implode( ' ', $count_query ) ); //phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL
self::set_db_cache_data( implode( ' ', $count_query ), $overall_total );
}
if ( $only_count === true ) {
return array(
'automations' => array(),
'total_records' => $overall_total,
);
}
if ( empty( $all_automations ) ) {
return array(
'automations' => array(),
'total_records' => 0,
);
}
$final_automation_data = array();
$date_format = self::get_date_format();
$automation_ids = array_map( function ( $all_automation ) {
return isset( $all_automation['ID'] ) ? absint( $all_automation['ID'] ) : false;
}, $all_automations );
$automation_ids = array_filter( $automation_ids, 'intval' );
$stringPlaceholders = array_fill( 0, count( $automation_ids ), '%d' );
$stringPlaceholders = implode( ', ', $stringPlaceholders );
/** Get all automation revenue total if pro active */
$conversion_data = array();
$query = $wpdb->prepare( "SELECT bwc.oid, count(bwc.ID) as conversions, SUM(bwc.wctotal) as revenue FROM {$wpdb->prefix}bwfan_conversions as bwc JOIN {$wpdb->prefix}posts as p ON bwc.wcid=p.ID WHERE bwc.oid IN ( $stringPlaceholders ) AND bwc.otype=1 GROUP BY bwc.oid", $automation_ids );// phpcs:ignore WordPress.DB.PreparedSQL, WordPress.DB.PreparedSQLPlaceholders
$conversions = self::get_db_cache_data( $query );
if ( false === $conversions ) {
$conversions = $wpdb->get_results( $query, ARRAY_A ); //phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL
self::set_db_cache_data( $query, $conversions );
}
foreach ( $conversions as $conversion ) {
if ( absint( $conversion['oid'] ) ) {
$conversion_data[ absint( $conversion['oid'] ) ] = $conversion;
}
}
$automations_meta = BWFAN_Model_Automationmeta::get_automations_meta( $automation_ids );
foreach ( $all_automations as $automation ) {
$id = absint( $automation['ID'] );
$automation_actions = isset( $automations_meta[ $id ]['actions'] ) ? self::get_automation_actions( $automations_meta[ $id ]['actions'] ) : array();
$source = self::get_automation_source_name( $automation['source'] );
$event = self::get_automation_event_name( $automation['event'] );
$run_count = ( isset( $automations_meta[ $id ]['run_count'] ) ) ? $automations_meta[ $id ]['run_count'] : 0;
$data = array(
'id' => $id,
'source' => empty( $source ) ? __( 'Not Found', 'wp-marketing-automations' ) : $source,
'last_update' => isset( $automations_meta[ $id ]['m_date'] ) ? get_date_from_gmt( $automations_meta[ $id ]['m_date'], $date_format ) : '',
'name' => 2 === absint( $automation['v'] ) && isset( $automation['title'] ) ? $automation['title'] : ( isset( $automations_meta[ $id ]['title'] ) ? $automations_meta[ $id ]['title'] : '' ),
'event' => $event,
'status' => $automation['status'],
'priority' => $automation['priority'],
'automation_actions' => $automation_actions,
'run_count' => $run_count,
'conversions' => 0,
'revenue' => 0,
'migrated' => isset( $automations_meta[ $id ]['v1_migrate'] ) ? true : false,
'v' => isset( $automation['v'] ) ? $automation['v'] : 1,
);
if ( isset( $conversion_data[ $id ] ) ) {
$data = array_replace( $data, $conversion_data[ $id ] );
}
$final_automation_data[ $id ] = $data;
}
return array(
'automations' => ! empty( $final_automation_data ) && is_array( $final_automation_data ) ? array_values( $final_automation_data ) : array(),
'total_records' => ! empty( $overall_total ) ? absint( $overall_total ) : 0,
);
}
/**
* @param $automation_actions
*
* @return array
*/
public static function get_automation_actions( $automation_actions ) {
$actions = array();
if ( empty( $automation_actions ) ) {
return array();
}
$integration_data = $automation_actions;
$unique_actions = BWFAN_Core()->automations->get_unique_automation_actions( $integration_data );
foreach ( $unique_actions as $action => $integration ) {
$action_obj = BWFAN_Core()->integration->get_action( $action );
$integration_obj = BWFAN_Core()->integration->get_integration( $integration );
if ( $integration_obj instanceof BWFAN_Integration && $action_obj instanceof BWFAN_Action ) {
$nice_name = $integration_obj->get_name();
$actions[ $nice_name ][] = $action_obj->get_name();
} else {
$integration_name = self::get_entity_nice_name( 'integration', $integration );
$action_name = self::get_entity_nice_name( 'action', $action );
if ( ! empty( $integration_name ) && ! empty( $action_name ) ) {
$actions[ $integration_name ][] = $action_name;
}
}
}
return $actions;
}
public static function get_entity_nice_name( $key = 'source', $slug = 'wc' ) {
$nice_names = self::get_default_event_action_names();
if ( empty( $key ) || empty( $slug ) ) {
return '';
}
if ( ! isset( $nice_names[ $key ] ) || ! isset( $nice_names[ $key ][ $slug ] ) ) {
return '';
}
return $nice_names[ $key ][ $slug ];
}
/**
* Return Sources, Events, Integrations, Actions nice names.
* Useful when respective entity not exist but data as task or automation available.
*
* @return array
*/
public static function get_default_event_action_names() {
return array(
'source' => array(
'wc' => __( 'WooCommerce', 'wp-marketing-automations' ),
'wp' => __( 'WordPress', 'wp-marketing-automations' ),
'wcs' => __( 'WooCommerce Subscription', 'wp-marketing-automations' ),
'upstroke' => __( 'UpStroke', 'wp-marketing-automations' ),
'activecampaign' => __( 'Active Campaign', 'wp-marketing-automations' ),
'drip' => __( 'Drip', 'wp-marketing-automations' ),
'affwp' => __( 'AffiliateWp', 'wp-marketing-automations' ),
'gf' => __( 'Gravity Forms', 'wp-marketing-automations' ),
),
'event' => array(
'wc_comment_post' => __( 'New Review', 'wp-marketing-automations' ),
'wc_new_order' => __( 'Order Created', 'wp-marketing-automations' ),
'wc_order_note_added' => __( 'Order Note Added', 'wp-marketing-automations' ),
'wc_order_status_change' => __( 'Order Status Changed', 'wp-marketing-automations' ),
'wc_product_purchased' => __( 'Order Created - Per Item', 'wp-marketing-automations' ),
'wc_product_refunded' => __( 'Order Item Refunded', 'wp-marketing-automations' ),
'wc_product_stock_reduced' => __( 'Order Item Stock Reduced', 'wp-marketing-automations' ),
'wc_customer_win_back' => __( 'Customer Win Back', 'wp-marketing-automations' ),
'ab_cart_abandoned' => __( 'Cart Abandoned', 'wp-marketing-automations' ),
'ab_cart_recovered' => __( 'Cart Recovered', 'wp-marketing-automations' ),
'wp_user_creation' => __( 'User Creation', 'wp-marketing-automations' ),
'wp_user_login' => __( 'User Login', 'wp-marketing-automations' ),
'ac_webhook_received' => __( 'Webhook Received', 'wp-marketing-automations' ),
'drip_webhook_received' => __( 'Webhook Received', 'wp-marketing-automations' ),
'upstroke_funnel_ended' => __( 'Funnel Ended', 'wp-marketing-automations' ),
'upstroke_offer_viewed' => __( 'Offer Viewed', 'wp-marketing-automations' ),
'upstroke_product_accepted' => __( 'Offer Accepted', 'wp-marketing-automations' ),
'upstroke_offer_rejected' => __( 'Offer Rejected', 'wp-marketing-automations' ),
'upstroke_offer_payment_failed' => __( 'Offer Payment Failed', 'wp-marketing-automations' ),
'wcs_created' => __( 'Subscriptions Created', 'wp-marketing-automations' ),
'wcs_status_changed' => __( 'Subscriptions Status Changed', 'wp-marketing-automations' ),
'wcs_trial_end' => __( 'Subscriptions Trial End', 'wp-marketing-automations' ),
'wcs_before_renewal' => __( 'Subscriptions Before Renewal', 'wp-marketing-automations' ),
'wcs_before_end' => __( 'Subscriptions Before End', 'wp-marketing-automations' ),
'wcs_renewal_payment_complete' => __( 'Subscriptions Renewal Payment Complete', 'wp-marketing-automations' ),
'wcs_renewal_payment_failed' => __( 'Subscriptions Renewal Payment Failed', 'wp-marketing-automations' ),
'wcs_card_expiry' => __( 'Customer Before Card Expiry', 'wp-marketing-automations' ),
'affwp_affiliate_report' => __( 'Affiliate Digests', 'wp-marketing-automations' ),
'affwp_application_approved' => __( 'Application Approved', 'wp-marketing-automations' ),
'affwp_application_rejected' => __( 'Application Rejected', 'wp-marketing-automations' ),
'affwp_makes_sale' => __( 'Affiliate Makes A Sale', 'wp-marketing-automations' ),
'affwp_referral_rejected' => __( 'Referral Rejected', 'wp-marketing-automations' ),
'affwp_signup' => __( 'Application Sign Up', 'wp-marketing-automations' ),
'gf_form_submit' => __( 'Form Submits', 'wp-marketing-automations' ),
),
'integration' => array(
'wc' => __( 'WooCommerce', 'wp-marketing-automations' ),
'wp' => __( 'WordPress', 'wp-marketing-automations' ),
'wp_adv' => __( 'WordPress Advanced', 'wp-marketing-automations' ),
'zapier' => __( 'Zapier', 'wp-marketing-automations' ),
'activecampaign' => __( 'ActiveCampaign', 'wp-marketing-automations' ),
'convertkit' => __( 'Kit ( Formerly ConvertKit )', 'wp-marketing-automations' ),
'drip' => __( 'Drip', 'wp-marketing-automations' ),
'slack' => __( 'Slack', 'wp-marketing-automations' ),
'twilio' => __( 'Twilio', 'wp-marketing-automations' ),
'whatsapp' => __( 'Whatsapp', 'wp-marketing-automations' ),
'google_sheets' => __( 'Google Sheets', 'wp-marketing-automations' ),
),
'action' => array(
'wc_create_coupon' => __( 'Create Coupon', 'wp-marketing-automations' ),
'wc_add_order_note' => __( 'Add Order Note', 'wp-marketing-automations' ),
'wc_change_order_status' => __( 'Change Order Status', 'wp-marketing-automations' ),
'wc_remove_coupon' => __( 'Delete Coupon', 'wp-marketing-automations' ),
'wp_sendemail' => __( 'Send Email', 'wp-marketing-automations' ),
'za_send_data' => __( 'Send Data To Zapier', 'wp-marketing-automations' ),
'wp_custom_callback' => __( 'Custom Callback', 'wp-marketing-automations' ),
'wp_debug' => __( 'Debug', 'wp-marketing-automations' ),
'wp_http_post' => __( 'HTTP Post', 'wp-marketing-automations' ),
'wp_createuser' => __( 'Create User', 'wp-marketing-automations' ),
'wp_update_user_meta' => __( 'Update User Meta', 'wp-marketing-automations' ),
'ac_add_tag' => __( 'Add Tags', 'wp-marketing-automations' ),
'ac_add_to_automation' => __( 'Add Contact To Automation', 'wp-marketing-automations' ),
'ac_add_to_list' => __( 'Add Contact To List', 'wp-marketing-automations' ),
'ac_create_abandoned_cart' => __( 'Create Abandoned Cart', 'wp-marketing-automations' ),
'ac_create_deal_note' => __( 'Create Deal Note', 'wp-marketing-automations' ),
'ac_create_deal' => __( 'Create Deal', 'wp-marketing-automations' ),
'ac_create_order' => __( 'Create Order', 'wp-marketing-automations' ),
'ac_rmv_from_automation' => __( 'End Automation', 'wp-marketing-automations' ),
'ac_rmv_from_list' => __( 'Remove Contact From List', 'wp-marketing-automations' ),
'ac_rmv_tag' => __( 'Remove Tags', 'wp-marketing-automations' ),
'ac_update_customfields' => __( 'Update Fields', 'wp-marketing-automations' ),
'ac_update_deal' => __( 'Update Deal', 'wp-marketing-automations' ),
'ck_add_customfields' => __( 'Update Custom Fields', 'wp-marketing-automations' ),
'ck_add_order' => __( 'Create A New Purchase', 'wp-marketing-automations' ),
'ck_add_tags' => __( 'Add Tags', 'wp-marketing-automations' ),
'ck_add_to_sequence' => __( 'Add Subscriber To Sequence', 'wp-marketing-automations' ),
'ck_rmv_from_sequence' => __( 'Remove Subscriber from Sequence', 'wp-marketing-automations' ),
'ck_rmv_tags' => __( 'Remove Tags', 'wp-marketing-automations' ),
'dr_add_cart' => __( 'Cart Activity', 'wp-marketing-automations' ),
'dr_add_customfields' => __( 'Update Custom fields of Subscriber', 'wp-marketing-automations' ),
'dr_add_order' => __( 'Add A New Order', 'wp-marketing-automations' ),
'dr_add_tags' => __( 'Add Tags', 'wp-marketing-automations' ),
'dr_add_to_campaign' => __( 'Add Subscriber to Campaign', 'wp-marketing-automations' ),
'dr_add_to_workflow' => __( 'Add Subscriber to Workflow', 'wp-marketing-automations' ),
'dr_rmv_from_campaign' => __( 'Remove Subscriber from Campaign', 'wp-marketing-automations' ),
'dr_rmv_from_workflow' => __( 'Remove Subscriber from Workflow', 'wp-marketing-automations' ),
'dr_rmv_tags' => __( 'Remove Tags', 'wp-marketing-automations' ),
'sl_message_user' => __( 'Sends a message to a user', 'wp-marketing-automations' ),
'sl_message' => __( 'Sends a message to a channel', 'wp-marketing-automations' ),
'twilio_send_sms' => __( 'Send SMS', 'wp-marketing-automations' ),
'gs_insert_data' => __( 'Insert Row', 'wp-marketing-automations' ),
'gs_update_data' => __( 'Update Row', 'wp-marketing-automations' ),
'wcs_change_subscription_status' => __( 'Change Subscription Status', 'wp-marketing-automations' ),
'wcs_send_subscription_invoice' => __( 'Send Subscription Invoice', 'wp-marketing-automations' ),
'affwp_change_affiliate_rate' => __( 'Change Affiliate Rate', 'wp-marketing-automations' ),
'affwp_change_referral_status' => __( 'Change Referral Status', 'wp-marketing-automations' ),
),
);
}
/**
* Get automation source name using source_slug
*
* @param $source
*
* @return mixed|string
*/
public static function get_automation_source_name( $source ) {
if ( empty( $source ) ) {
return '';
}
$single_source = BWFAN_Core()->sources->get_source( $source );
if ( $single_source instanceof BWFAN_Source ) {
return $single_source->get_name();
}
return self::get_entity_nice_name( 'source', $source );
}
/**
* Get automation event name using event_slug
*
* @param $event
*
* @return mixed|string
*/
public static function get_automation_event_name( $event ) {
if ( empty( $event ) ) {
return '';
}
$single_event = BWFAN_Core()->sources->get_event( $event );
if ( $single_event instanceof BWFAN_Event ) {
return $single_event->get_name();
}
return self::get_entity_nice_name( 'event', $event );
}
public static function automation_status_count( $aid, $status_aids, $counts ) {
$aid_index = array_search( $aid, $status_aids );
if ( false === $aid_index ) {
return 0;
}
return isset( $counts[ $aid_index ] ) ? $counts[ $aid_index ] : 0;
}
/**
* @param $automation_id
* @param $automation_tasks
*
* @return array
*/
public static function get_automation_task_details( $automation_id, $automation_tasks ) {
$output = array();
foreach ( $automation_tasks as $key => $count ) {
$output[] = array(
'count' => absint( $count ),
'name' => ucfirst( $key ),
);
}
return $output;
}
/**
* Skip child order
*
* @param $id int order id
*
* @return bool
*/
public static function bwf_check_to_skip_child_order( $id ) {
return ( apply_filters( 'bwf_skip_sub_order', false ) && wp_get_post_parent_id( $id ) );
}
/**
* Remove action for without instance method class found and return object of class
*
* @param $hook
* @param $cls
* @param $function
*
* @return mixed|string|null
*/
public static function remove_actions( $hook, $cls, $function = '' ) {
global $wp_filter;
$object = null;
if ( class_exists( $cls ) && isset( $wp_filter[ $hook ] ) && ( $wp_filter[ $hook ] instanceof WP_Hook ) ) {
$hooks = $wp_filter[ $hook ]->callbacks;
foreach ( $hooks as $priority => $reference ) {
if ( is_array( $reference ) && count( $reference ) > 0 ) {
foreach ( $reference as $index => $calls ) {
if ( isset( $calls['function'] ) && is_array( $calls['function'] ) && count( $calls['function'] ) > 0 ) {
if ( is_object( $calls['function'][0] ) ) {
$cls_name = get_class( $calls['function'][0] );
if ( $cls_name == $cls && $calls['function'][1] == $function ) {
$object = $calls['function'][0];
unset( $wp_filter[ $hook ]->callbacks[ $priority ][ $index ] );
}
} elseif ( $index == $cls . '::' . $function ) {
// For Static Classess
$object = $cls;
unset( $wp_filter[ $hook ]->callbacks[ $priority ][ $cls . '::' . $function ] );
}
}
}
}
}
} elseif ( function_exists( $cls ) && isset( $wp_filter[ $hook ] ) && ( $wp_filter[ $hook ] instanceof WP_Hook ) ) {
$hooks = $wp_filter[ $hook ]->callbacks;
foreach ( $hooks as $priority => $reference ) {
if ( is_array( $reference ) && count( $reference ) > 0 ) {
foreach ( $reference as $index => $calls ) {
$remove = false;
if ( $index == $cls ) {
$remove = true;
} elseif ( isset( $calls['function'] ) && $cls == $calls['function'] ) {
$remove = true;
}
if ( true == $remove ) {
unset( $wp_filter[ $hook ]->callbacks[ $priority ][ $cls ] );
}
}
}
}
}
return $object;
}
/**
* Get all possible merge tags from the given string
*
* @param $str
*
* @return array
*/
public static function fetch_merge_tags( $str ) {
/** Remove all style tags and their content */
$pattern = '/', $string );
$shortcode_head = '[bwfan_';
$stripped_merge_tags = array();
foreach ( $elements as $element ) {
$strings = explode( '', $html, 1 );
return $html;
}
private static function mergeDuplicateMediaQueries( $style ) {
// Extract all media queries and their rules
$mediaQueries = [];
$change_resolution = apply_filters( 'bwfan_change_media_query_resolution', '' );
preg_match_all( '/@media[^{]+\{([\s\S]*?)\}}/i', $style, $mediaMatches );
foreach ( $mediaMatches[0] as $mediaQuery ) {
// Split the media query and its rules
$parts = explode( '{', $mediaQuery, 2 );
$query = trim( $parts[0] );
$rules = trim( $parts[1] );
if ( ! empty( $change_resolution ) && intval( $change_resolution ) > 0 ) {
// Update screen sizes from 768px to 480px
$query = preg_replace( '/(\(max-width:\s*)768px(\s*\))/i', '${1}' . $change_resolution . 'px${2}', $query );
}
// Store rules in the mediaQueries array
if ( ! isset( $mediaQueries[ $query ] ) ) {
$mediaQueries[ $query ] = [];
}
if ( str_ends_with( $rules, '}' ) ) {
// Remove the last character (brace) from the string
$rules = substr( $rules, 0, - 1 );
}
$mediaQueries[ $query ][] = $rules;
}
// Combine the media query rules into a single string
$combinedCSS = '';
foreach ( $mediaQueries as $query => $rules ) {
$combinedCSS .= "{$query} { " . implode( ' ', $rules ) . " }\n";
}
// Remove all media queries from the style
$style = preg_replace( '/@media[^{]*{([^{}]*{[^{}]*})*[^{}]*}/', '', $style );
return $style . " " . $combinedCSS;
}
/**
* Callback function for running v2 automation
*
* @param $request
*
* @return void
*/
public static function run_v2_worker_tasks( $request = '' ) {
self::event_advanced_logs( "V2 worker callback received" );
self::worker_as_run();
/** Logs */
$cron_check = self::is_log_enabled( 'bwfan_cron_check_logging' );
if ( true === $cron_check || ( defined( 'BWF_CHECK_CRON_SCHEDULE' ) && true === BWF_CHECK_CRON_SCHEDULE ) ) {
add_filter( 'bwf_logs_allowed', '__return_true', PHP_INT_MAX );
$logger_obj = BWF_Logger::get_instance();
$logger_obj->log( date_i18n( 'Y-m-d H:i:s' ) . ' - after worker run', 'fka-cron-check-v2', 'autonami' );
}
wp_send_json( [
'msg' => 'success',
'time' => date_i18n( 'Y-m-d H:i:s' ),
'datastore' => get_class( ActionScheduler_Store::instance() ),
] );
}
/**
* Validate redirect link by domain
*
* @param $link
* @param $l_hash
* @param $engagement_data
*
* @return mixed|string|null
*/
public static function validate_target_link( $link = '', $l_hash = '', $engagement_data = [] ) {
/** Validate target link if all links not saved and l_hash empty */
if ( empty( get_option( 'bwfan_all_link_saved' ) ) && empty( $l_hash ) ) {
return self::validate_old_target_link( $link, $engagement_data );
}
/** Checking by cleaned url */
$cleaned_url = BWFAN_Core()->conversation->get_cleaned_url( $link );
/** Checking by l_hash & clean url */
if ( ! empty( $l_hash ) ) {
$is_link_exists = BWFAN_Model_Links::is_link_hash_exists( $cleaned_url, $l_hash );
// if link entry not found return home url
if ( empty( $is_link_exists ) ) {
do_action( 'bwfan_invalid_tracking_link', $link );
return home_url();
}
BWFAN_Email_Conversations::$link_id = $is_link_exists;
return $link;
}
/** Checking by link exist in links table */
$is_link_exists = BWFAN_Model_Links::get_link_id_by_tid( $cleaned_url, $engagement_data[0] ?? [] );
if ( ! empty( $is_link_exists ) ) {
BWFAN_Email_Conversations::$link_id = $is_link_exists;
return $link;
}
/** If site url and redirect url host are same */
try {
$link_host = wp_parse_url( urldecode( $link ), PHP_URL_HOST );
$site_url = home_url();
$site_url_host = wp_parse_url( $site_url, PHP_URL_HOST );
} catch ( Error|Exception $e ) {
return $link;
}
if ( $link_host !== $site_url_host ) {
do_action( 'bwfan_invalid_tracking_link', $link );
return home_url();
}
return $link;
}
/**
* Validate old target link if link is not saved
*
* @param $link
* @param $e_data
*
* @return mixed|string|null
*/
public static function validate_old_target_link( $link, $e_data = [] ) {
try {
$link_host = wp_parse_url( urldecode( $link ), PHP_URL_HOST );
$site_url = home_url();
$site_url_host = wp_parse_url( $site_url, PHP_URL_HOST );
} catch ( Error|Exception $e ) {
return $link;
}
/** Checking by cleaned url */
$cleaned_url = BWFAN_Core()->conversation->get_cleaned_url( urldecode( $link ) );
BWFAN_Email_Conversations::$link_id = BWFAN_Model_Links::get_link_id_by_tid( $cleaned_url, $e_data[0] );
/** If site url and redirect url host are same */
if ( $link_host === $site_url_host ) {
return $link;
}
/** Allowed domains */
$allowed_domains = apply_filters( 'bwfan_allowed_redirect_domains', [] );
if ( empty( $allowed_domains ) ) {
return $link;
}
/** Filter valid domains */
$allowed_domains = array_filter( array_map( function ( $domain ) {
return ! empty( $domain ) && is_string( $domain ) ? wp_parse_url( $domain, PHP_URL_HOST ) : false;
}, $allowed_domains ) );
return in_array( $link_host, $allowed_domains, true ) ? $link : $site_url;
}
/**
* Store links
*
* @return void
*/
public static function bwfan_store_template_links() {
$last_id = intval( get_option( 'bwfan_template_links' ) );
BWFAN_Common::log_test_data( 'Template link store process start', 'fk-store-link', true );
global $wpdb;
$email_regex = BWFAN_Common::get_regex_pattern();
$sms_whatsapp_regex = BWFAN_Common::get_regex_pattern( 3 );
$start_time = time();
while ( ( time() - $start_time ) < 15 ) {
$query = "SELECT et.`oid`,et.`sid`,et.`type`,et.`mode`,t.`ID`,t.`template` FROM {$wpdb->prefix}bwfan_templates AS t JOIN {$wpdb->prefix}bwfan_engagement_tracking AS et ON t.`ID`=et.`tid` WHERE tid > $last_id GROUP BY tid LIMIT 20";
$templates = $wpdb->get_results( $query, ARRAY_A ); //phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL
if ( empty( $templates ) ) {
bwf_unschedule_actions( 'bwfan_store_template_links' );
delete_option( 'bwfan_template_links' );
update_option( 'bwfan_all_link_saved', true, true );
BWFAN_Common::log_test_data( 'Template link store process complete', 'fk-store-link', true );
break;
}
$template_ids = array_column( $templates, 'ID' );
BWFAN_Common::log_test_data( 'Template ids :' . implode( ',', $template_ids ), 'fk-store-link', true );
foreach ( $templates as $template ) {
$mode = intval( $template['mode'] );
$mode = $mode === BWFAN_Email_Conversations::$MODE_EMAIL ? 'email' : ( $mode === BWFAN_Email_Conversations::$MODE_SMS ? 'sms' : 'whatsapp' );
$regex_pattern = ( $mode === 'email' ) ? $email_regex : $sms_whatsapp_regex;
preg_replace_callback( $regex_pattern, function ( $matches ) use ( $mode, $template ) {
/** According to Href (1) regex, URL is at 1 index. And for Link (3) Regex, 0 index. */
$url = 'email' !== $mode ? $matches[0] : $matches[1];
BWFAN_Common::log_test_data( 'id:' . $template['ID'] . ' URL: ' . $url, 'fk-store-link', true );
if ( BWFAN_Common::is_exclude_url( $url ) ) {
BWFAN_Common::log_test_data( 'exclude url', 'fk-store-link', true );
return $matches[0];
}
/** Exclude click tracking for unsubscribe link and view email browser link*/
if ( false !== strpos( $url, 'bwfan-action=unsubscribe' ) || false !== strpos( $url, 'bwfan-action=view_in_browser' ) ) {
BWFAN_Common::log_test_data( 'unsubscribe or view url', 'fk-store-link', true );
return 'email' !== $mode ? $url : str_replace( $matches[1], $url, $matches[0] );
}
$data = [
'type' => $template['type'],
'oid' => $template['oid'],
'step_id' => $template['sid'],
'template_id' => $template['ID'],
];
/** Save link in DB */
BWFAN_Core()->conversation->get_link_hash( $url, $data );
return 'email' !== $mode ? $url : str_replace( $matches[1], $url, $matches[0] );
}, $template['template'] );
$last_id = $template['ID'];
}
BWFAN_Common::log_test_data( 'Last process template id :' . $last_id, 'fk-store-link', true );
update_option( 'bwfan_template_links', $last_id );
}
BWFAN_Common::log_test_data( 'Template link store process end :', 'fk-store-link', true );
}
/**
* Get mail replace string
*
* @return array
*/
public static function get_mail_replace_string() {
if ( defined( 'BWFAN_PRO_VERSION' ) && version_compare( BWFAN_PRO_VERSION, '3.5.2', '<=' ) ) {
return [];
}
return [
'http-equiv' => md5( 'http-equiv' ),
];
}
/**
* Create contact if not created
*
* @param $user_id
*
* @return void
*/
public static function bwfan_register_user( $user_id ) {
if ( did_action( 'woocommerce_before_checkout_process' ) ) {
return;
}
if ( class_exists( 'WooFunnels_DB_Updater' ) ) {
$db_updater = WooFunnels_DB_Updater::get_instance();
if ( is_object( $db_updater ) && method_exists( $db_updater, 'do_profile_update_async_call' ) ) {
$db_updater->do_profile_update_async_call( $user_id );
define( 'BWF_DISABLE_CONTACT_PROFILE_UPDATE', 1 );
}
}
}
/**
* @return string
*
*/
public static function get_wc_tax_label_if_displayed() {
if ( ! wc_tax_enabled() ) {
return '';
}
$tax_display_mode = get_option( 'woocommerce_tax_display_cart' );
$prices_include_tax = wc_prices_include_tax();
if ( $tax_display_mode === 'incl' && ! $prices_include_tax ) {
return WC()->countries->inc_tax_or_vat();
}
if ( $tax_display_mode === 'excl' && $prices_include_tax ) {
return WC()->countries->ex_tax_or_vat();
}
return '';
}
/**
* If constant define then get contact email by user id
*
* @param $user_id
* @param $contact_id
*
* @return string
*/
public static function get_contact_email( $user_id = 0, $contact_id = 0 ) {
if ( ! defined( 'BWFAN_GET_CONTACT_EMAIL' ) || true !== BWFAN_GET_CONTACT_EMAIL || ( empty( $user_id ) && empty( $contact_id ) ) ) {
return '';
}
$contact = new WooFunnels_Contact( $user_id, '', '', $contact_id );
return $contact->get_id() > 0 ? $contact->get_email() : '';
}
/**
* Check language support
*
* @return bool
*/
public static function should_skip_language_support() {
if ( ! function_exists( 'icl_get_languages' ) && ! function_exists( 'pll_the_languages' ) && ( ! function_exists( 'bwfan_is_translatepress_active' ) || ! bwfan_is_translatepress_active() ) && ( ! function_exists( 'bwfan_is_weglot_active' ) || ! bwfan_is_weglot_active() ) && ( ! function_exists( 'bwfan_is_gtranslate_active' ) || ! bwfan_is_gtranslate_active() ) ) {
return true;
}
return false;
}
/**
* Get wp terms id and name array from ids, static query
*
* @param $term_ids
*
* @return array|object|stdClass[]|null
*/
public static function get_wp_term( $term_ids ) {
if ( empty( $term_ids ) ) {
return [];
}
global $wpdb;
$placeholder = array_fill( 0, count( $term_ids ), '%d' );
$placeholder = implode( ', ', $placeholder );
$query = "SELECT `term_id` AS `id`,`name` FROM {$wpdb->prefix}terms WHERE `term_id` IN ($placeholder)";
//phpcs:ignore WordPress.DB.PreparedSQL
$query = $wpdb->prepare( $query, $term_ids );
//phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL
return $wpdb->get_results( $query, ARRAY_A );
}
/**
* Get product names and id from ids, static query
*
* @param $product_ids
*
* @return array|object|stdClass[]|null
*/
public static function get_products_name( $product_ids ) {
if ( empty( $product_ids ) ) {
return [];
}
global $wpdb;
$placeholder = array_fill( 0, count( $product_ids ), '%d' );
$placeholder = implode( ', ', $placeholder );
$query = "SELECT `ID` AS `id`, `post_title` AS `name`, `post_parent` FROM {$wpdb->prefix}posts WHERE `ID` IN ($placeholder)";
//phpcs:ignore WordPress.DB.PreparedSQL
$query = $wpdb->prepare( $query, $product_ids );
//phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL
return $wpdb->get_results( $query, ARRAY_A );
}
/**
* Check server memory limit.
* Using 75% max
*
* @return bool
*/
public static function memory_exceeded() {
$memory_limit = self::get_memory_limit() * 0.9;
$current_memory = memory_get_usage( true );
return ( $current_memory >= $memory_limit );
}
/**
* Get the memory limit in bytes.
* If the memory limit is set to -1 or 'unlimited', it will return 32GB.
*
* @return int|mixed
*/
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 );
}
/**
* Converts a shorthand byte value to an integer byte value.
*
* @param $value
*
* @return int|mixed
*/
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 );
}
/**
* Get a list of attach actions/filters hook
*
* @param $hook
*
* @return array
* @throws ReflectionException
*/
final public static function get_list_of_attach_actions( $hook ) {
global $wp_filter;
if ( ! isset( $wp_filter[ $hook ] ) || ! $wp_filter[ $hook ] instanceof WP_Hook ) {
return [];
}
$output = [];
$hooks = $wp_filter[ $hook ]->callbacks;
foreach ( $hooks as $priority => $reference ) {
if ( ! is_array( $reference ) || 0 === count( $reference ) ) {
continue;
}
foreach ( $reference as $index => $calls ) {
if ( isset( $calls['function'] ) && is_array( $calls['function'] ) && count( $calls['function'] ) > 0 ) {
if ( is_object( $calls['function'][0] ) ) {
$cls_name = get_class( $calls['function'][0] );
$output[] = [
'type' => 'class',
'class' => $cls_name,
'function' => $calls['function'][1],
'class_path' => self::get_class_path( $cls_name ),
'index' => $index,
'priority' => $priority,
];
} else {
$output[] = [
'type' => 'static_class',
'class' => $calls['function'][0],
'function' => $calls['function'][1],
'class_path' => self::get_class_path( $calls['function'][0] ),
'index' => $index,
'priority' => $priority,
];
}
} else {
$output[] = [
'type' => 'function',
'function' => $calls['function'],
'function_path' => self::get_function_path( $calls['function'] ),
'index' => $index,
'priority' => $priority,
];
}
}
}
return $output;
}
/**
* Get a class path
*
* @param $class
*
* @return string
* @throws ReflectionException
*/
public static function get_class_path( $class = 'BWFAN_Core' ) {
$reflector = new ReflectionClass( $class );
$file_name = $reflector->getFileName();
return dirname( $file_name );
}
/**
* Get a function path
*
* @param $function
*
* @return array|string|string[]
*/
public static function get_function_path( $function = '' ) {
if ( empty( $function ) ) {
return '';
}
try {
$reflector = new ReflectionFunction( $function );
$file_name = $reflector->getFileName();
$directory = dirname( $file_name );
if ( defined( 'WP_CONTENT_DIR' ) ) {
$directory = str_replace( WP_CONTENT_DIR, '', $directory );
}
} catch ( ReflectionException $exception ) {
$directory = $exception->getMessage();
}
return $directory;
}
/**
* Check if the site's default language is RTL (right-to-left)
* Unlike WordPress's is_rtl() function which checks current user's language in backend,
* this function checks the site's default language setting
*
* @return bool True if site language is RTL, false otherwise
*/
public static function is_site_rtl() {
// Get the site's default locale
$site_locale = get_locale();
// List of RTL language codes
$rtl_locales = array(
'ar', // Arabic
'ary', // Moroccan Arabic
'azb', // South Azerbaijani
'ckb', // Central Kurdish (Sorani)
'dv', // Dhivehi
'fa', // Persian/Farsi
'he', // Hebrew
'ku', // Kurdish
'ps', // Pashto
'sd', // Sindhi
'ug', // Uighur
'ur', // Urdu
'yi', // Yiddish
);
// Allow filtering of RTL locales for flexibility
$rtl_locales = apply_filters( 'bwfan_rtl_locales', $rtl_locales );
// Extract the language code from locale (e.g., 'ar_SA' becomes 'ar')
$language_code = substr( $site_locale, 0, 2 );
// Check if the language code is in the RTL list
$is_rtl = in_array( $language_code, $rtl_locales, true );
// Allow filtering of the final RTL result for complete flexibility
return apply_filters( 'bwfan_is_site_rtl', $is_rtl, $site_locale, $language_code );
}
}