Files
roi-theme/wp-content/plugins/wp-marketing-automations/includes/class-bwfcrm-contacts.php
root a22573bf0b Commit inicial - WordPress Análisis de Precios Unitarios
- WordPress core y plugins
- Tema Twenty Twenty-Four configurado
- Plugin allow-unfiltered-html.php simplificado
- .gitignore configurado para excluir wp-config.php y uploads

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-03 21:04:30 -06:00

2935 lines
92 KiB
PHP
Executable File

<?php
/**
* Contact Controller Class
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( ! class_exists( 'BWFCRM_Contact' ) && BWFAN_Common::is_pro_3_0() ) {
/**
* Class BWFCRM_Contact
*/
class BWFCRM_Contact {
/** @var WooFunnels_Contact $contact */
public $contact = null;
public $customer = null;
public $fields = array();
public $already_exists = true;
public $task_localized = array();
public $was_unsubscribed = false;
public static $STATUS_NOT_OPTED_IN = 0;
public static $STATUS_OPTED_IN = 1;
public static $STATUS_BOUNCED = 2;
public static $STATUS_SOFT_BOUNCED = 4;
public static $STATUS_COMPLAINT = 5;
public static $DISPLAY_STATUS_SUBSCRIBED = 1;
public static $DISPLAY_STATUS_UNSUBSCRIBED = 2;
public static $DISPLAY_STATUS_UNVERIFIED = 3;
public static $DISPLAY_STATUS_BOUNCED = 4;
public static $DISPLAY_STATUS_SOFT_BOUNCED = 5;
public static $DISPLAY_STATUS_COMPLAINT = 6;
public $unsubscribe_date = null;
/** Temporary terms storage for hooks firing */
public $assigned_tags = array();
public $assigned_lists = array();
public $removed_tags = array();
public $removed_lists = array();
/**
* Constructor
*
* @param $contact - WooFunnels_Contact instance | Contact db row data | cid | email
* @param false $force_create
* @param array $create_contact_args
* @param bool $update_fields
*/
public function __construct( $contact, $force_create = false, $create_contact_args = array(), $update_fields = true ) {
if ( $contact instanceof WooFunnels_Contact ) {
$this->contact = $contact;
$this->fill_fields_data( $update_fields );
return;
}
/** Contact row data */
if ( is_array( $contact ) && isset( $contact['id'] ) ) {
$this->create_obj_from_db_row( $contact );
if ( class_exists( 'WooCommerce' ) && isset( $contact['customer_id'] ) && ! empty( $contact['customer_id'] ) ) {
$this->customer = $this->fill_customer_from_array( $contact );
}
$this->fill_fields_data( $update_fields );
return;
}
/** Contact ID */
if ( is_numeric( $contact ) && absint( $contact ) > 0 ) {
$this->contact = new WooFunnels_Contact( '', '', '', $contact );
$this->fill_fields_data( $update_fields );
return;
}
/** Email given */
if ( is_email( $contact ) ) {
$this->contact = new WooFunnels_Contact( '', $contact );
if ( $this->contact->get_id() > 0 ) {
$this->fill_fields_data( $update_fields );
return;
}
( true === $force_create ) && $this->create_contact( $contact, $create_contact_args );
}
}
/**
* This populates the contact fields data
*
* @param bool $override
*/
public function fill_fields_data( $override = true ) {
if ( false === $override ) {
return;
}
if ( false === $this->is_contact_exists() ) {
return;
}
$fields = BWF_Model_Contact_Fields::get_contact_fields( $this->contact->get_id() );
if ( empty( $fields ) && ! is_array( $fields ) ) {
return;
}
$all_fields_type = BWFAN_Model_Fields::get_field_types();
$all_fields_type = array_filter( $all_fields_type, function ( $field ) {
return intval( $field['type'] ) === BWFCRM_Fields::$TYPE_DATE;
} );
if ( is_array( $all_fields_type ) && count( $all_fields_type ) > 0 ) {
$all_fields_type = array_column( $all_fields_type, 'ID' );
$all_fields_type = array_map( 'intval', $all_fields_type );
}
foreach ( $fields as $key => $value ) {
if ( false === strpos( $key, 'f' ) ) {
continue;
}
$field_id = str_replace( 'f', '', $key );
/** Check date value is valid or not */
if ( in_array( intval( $field_id ), $all_fields_type, true ) ) {
$value = $this->validate_date( $value ) ? $value : '';
}
$this->fields[ $field_id ] = maybe_unserialize( $value );
}
unset( $field_id );
unset( $fields );
}
public function validate_date( $value ) {
$date = $value !== null ? DateTime::createFromFormat( "Y-m-d", $value ) : '';
return ( $date && ( $date->format( "Y-m-d" ) === $value ) );
}
public function set_fields( $meta ) {
if ( empty( $meta ) || ! is_array( $meta ) ) {
return;
}
foreach ( $meta as $key => $item ) {
if ( ! is_numeric( $key ) ) {
unset( $meta[ $key ] );
}
}
$this->fields = array_replace( $this->fields, $meta );
}
/** This method will convert the retrieved DB Rows into BWFCRM_Contact objects */
public function create_obj_from_db_row( $db_row ) {
$contact = new WooFunnels_Contact();
/** Set cache if not set */
$cached = $contact->get_cache_obj( 'cid', absint( $db_row['id'] ) );
if ( false === $cached ) {
$contact->set_cache_object( 'cid', absint( $db_row['id'] ), (object) $db_row );
}
unset( $contact );
$this->contact = new WooFunnels_Contact( '', '', '', absint( $db_row['id'] ) );
/** Extract fields data */
if ( isset( $db_row['meta'] ) && is_array( $db_row['meta'] ) && count( $db_row['meta'] ) > 0 ) {
$this->set_fields( $db_row['meta'] );
}
}
/** This method will convert the retrieved DB Rows into BWFCRM_Contact objects */
public function fill_customer_from_array( $contact_db ) {
$customer = new WooFunnels_Customer( new WooFunnels_Contact( null, null ) );
if ( ! is_array( $contact_db ) || ! isset( $contact_db['customer_id'] ) ) {
return $customer;
}
/** Add Basic Details */
$customer->set_id( absint( $contact_db['customer_id'] ) );
( isset( $contact_db['l_order_date'] ) ) && $customer->set_l_order_date( $contact_db['l_order_date'] );
( isset( $contact_db['f_order_date'] ) ) && $customer->set_f_order_date( $contact_db['f_order_date'] );
( isset( $contact_db['total_order_count'] ) ) && $customer->set_total_order_count( absint( $contact_db['total_order_count'] ) );
( isset( $contact_db['total_order_value'] ) ) && $customer->set_total_order_value( $contact_db['total_order_value'] );
( isset( $contact_db['purchased_products'] ) ) && $customer->set_purchased_products( $contact_db['purchased_products'] );
( isset( $contact_db['purchased_products_cats'] ) ) && $customer->set_purchased_products_cats( $contact_db['purchased_products_cats'] );
( isset( $contact_db['purchased_products_tags'] ) ) && $customer->set_purchased_products_tags( $contact_db['purchased_products_tags'] );
( isset( $contact_db['used_coupons'] ) ) && $customer->set_used_coupons( $contact_db['used_coupons'] );
( isset( $contact_db['aov'] ) ) && $customer->set_aov( $contact_db['aov'] );
return $customer;
}
public function create_contact( $email, $args ) {
if ( ! is_email( $email ) || ! is_array( $args ) ) {
return false;
}
$contact = new WooFunnels_Contact( 0, $email );
! empty( $email ) && $contact->set_email( $email );
! empty( $args['f_name'] ) && $contact->set_f_name( $args['f_name'] );
! empty( $args['l_name'] ) && $contact->set_l_name( $args['l_name'] );
! empty( $args['state'] ) && $contact->set_state( $args['state'] );
! empty( $args['country'] ) && $contact->set_country( $args['country'] );
! empty( $args['contact_no'] ) && $contact->set_contact_no( $args['contact_no'] );
! empty( $args['timezone'] ) && $contact->set_timezone( $args['timezone'] );
isset( $args['status'] ) && $contact->set_status( absint( $args['status'] ) );
! empty( $args['wp_id'] ) && $contact->set_wpid( absint( $args['wp_id'] ) );
! empty( $args['source'] ) && $contact->set_source( $args['source'] );
! empty( $args['points'] ) && $contact->set_points( absint( $args['points'] ) );
! empty( $args['tags'] ) && $contact->set_tags( $args['tags'] );
! empty( $args['lists'] ) && $contact->set_lists( $args['lists'] );
$contact->set_type( 'lead' );
$creation_date = ! empty( $args['creation_date'] ) ? self::get_date_value( $args['creation_date'], 'Y-m-d H:i:s' ) : '';
! empty( $creation_date ) && $contact->set_creation_date( $creation_date );
// if ( ! empty( $contact->get_id() ) ) {
// $contact_id = $contact->get_id();
// ! empty( $args['f_name'] ) && $this->fire_hook_field_updated( 'f_name', $args['f_name'], '', $contact_id );
// ! empty( $args['l_name'] ) && $this->fire_hook_field_updated( 'l_name', $args['l_name'], '', $contact_id );
// ! empty( $args['state'] ) && $this->fire_hook_field_updated( 'state', $args['state'], '', $contact_id );
// ! empty( $args['country'] ) && $this->fire_hook_field_updated( 'country', $args['country'], '', $contact_id );
// ! empty( $args['contact_no'] ) && $this->fire_hook_field_updated( 'contact_no', $args['contact_no'], '', $contact_id );
// }
$disable_subscribe_event = false;
if ( isset( $args['disable_events'] ) && true === $args['disable_events'] ) {
$disable_subscribe_event = true;
unset( $args['disable_events'] );
}
unset( $args['f_name'] );
unset( $args['l_name'] );
unset( $args['contact_no'] );
unset( $args['state'] );
unset( $args['country'] );
unset( $args['creation_date'] );
unset( $args['timezone'] );
unset( $args['status'] );
unset( $args['source'] );
unset( $args['points'] );
unset( $args['wp_id'] );
/** Update Meta */
if ( is_array( $args ) && ! empty( $args ) ) {
/** Update Meta */
$this->set_fields( $args );
}
$this->contact = $contact;
if ( $disable_subscribe_event && isset( $this->contact->is_subscribed ) ) {
$this->contact->is_subscribed = false;
}
$this->save();
$this->already_exists = false;
$this->save_fields();
return $contact->get_id();
}
public function get_array( $slim_data = false, $get_wc_data = false, $get_wcs_data = false, $get_offer_data = false, $get_abandoned_data = false ) {
if ( ! $this->is_contact_exists() ) {
return array();
}
$meta = $this->fields;
$contact_array = array(
'id' => $this->contact->get_id(),
'wpid' => $this->contact->get_wpid(),
'email' => $this->contact->get_email(),
'f_name' => $this->contact->get_f_name(),
'l_name' => $this->contact->get_l_name(),
'contact_no' => $this->contact->get_contact_no(),
'state' => $this->contact->get_state(),
'country' => $this->contact->get_country(),
'creation_date' => ! empty( $this->contact->get_creation_date() ) ? $this->contact->get_creation_date() : '',
'timezone' => $this->contact->get_timezone(),
'fields' => $meta,
'last_modified' => ! empty( $this->contact->get_last_modified() ) ? $this->contact->get_last_modified() : '',
'unsubscribed' => false,
'source' => $this->contact->get_source(),
'type' => $this->contact->get_type(),
'status' => $this->contact->get_status(),
);
if ( isset( $contact_array['country'] ) && ! empty( $contact_array['country'] ) && function_exists( 'WC' ) && isset( WC()->countries ) ) {
$contact_array['country_formatted'] = isset( WC()->countries->get_countries()[ $contact_array['country'] ] ) ? html_entity_decode( WC()->countries->get_countries()[ $contact_array['country'] ] ) : '';
}
if ( false === $slim_data ) {
$contact_array['tags'] = $this->get_all_tags();
$contact_array['lists'] = $this->get_all_lists();
} else {
$contact_array['tags'] = $this->get_tags();
$contact_array['lists'] = $this->get_lists();
}
if ( class_exists( 'WooCommerce' ) && true === $get_wc_data ) {
$contact_array['wc'] = $this->get_customer_as_array( $slim_data );
}
/** getting subscription details of the contact */
if ( class_exists( 'WC_Subscriptions' ) && true === $get_wcs_data && false === $slim_data ) {
$contact_array['wcs'] = $this->get_wcs_as_array();
}
/** getting offer details of the contact */
if ( true === $get_offer_data && false === $slim_data ) {
$contact_array['offer'] = $this->get_offer_as_array();
}
/** get cart abandoned data only when cart is enable */
if ( class_exists( 'WooCommerce' ) && true === $get_abandoned_data && false === $slim_data ) {
$cart_enabled = true;
$global_settings = BWFAN_Common::get_global_settings();
if ( empty( $global_settings['bwfan_ab_enable'] ) ) {
$cart_enabled = false;
}
if ( true === $cart_enabled ) {
$contact_array['abandoned'] = $this->get_last_abandoned();
}
}
/** Status whether the contact is Subscribed, Unsubscribed, Bounced or Unverified */
if ( false === $slim_data ) {
$contact_array['display_status'] = $this->get_display_status();
}
if ( false === $slim_data && ! empty( $this->unsubscribe_date ) ) {
$contact_array['unsubscribe_date'] = $this->unsubscribe_date;
$contact_array['status'] = 3;
$contact_array['unsubscribed'] = true;
}
/** Get Contact Engagement data */
if ( false === $slim_data ) {
$contact_array['last_sent'] = $this->get_field_by_slug( 'last-sent' );
$contact_array['last_open'] = $this->get_field_by_slug( 'last-open' );
$contact_array['last_click'] = $this->get_field_by_slug( 'last-click' );
$contact_array['last_login'] = $this->get_field_by_slug( 'last-login' );
/** Get User Roles */
$user_id = absint( $this->contact->get_wpid() );
$user = $user_id > 0 ? get_user_by( 'id', $user_id ) : null;
if ( $user instanceof WP_User ) {
$contact_array['roles'] = array_values( $user->roles );
}
}
if ( false === $slim_data ) {
$contact_array['link_triggers'] = $this->get_all_link_triggers();
}
return apply_filters( 'bwfan_single_contact_get_array', $contact_array, $this, $slim_data );
}
public function get_all_tags() {
$tags = $this->get_tags();
if ( empty( $tags ) ) {
return array();
}
$all_tags = BWFCRM_Tag::get_tags( $tags );
if ( $this->show_contact_terms_by_name() ) {
usort( $all_tags, $this->sort_by_field( 'name' ) );
}
return $all_tags;
}
public function get_all_lists() {
$lists = $this->get_lists();
if ( empty( $lists ) ) {
return array();
}
$all_lists = BWFCRM_Lists::get_lists( $lists );
if ( $this->show_contact_terms_by_name() ) {
usort( $all_lists, $this->sort_by_field( 'name' ) );
}
return $all_lists;
}
/**
* Get link triggers full data
*
* @return array|mixed
*/
public function get_all_link_triggers() {
if ( ! bwfan_is_autonami_pro_active() ) {
return [];
}
$links = $this->get_link_triggers();
if ( empty( $links ) ) {
return array();
}
$data = BWFAN_Model_Link_Triggers::get_link_triggers( '', '', 0, 0, false, $links );
if ( isset( $data['links'] ) ) {
if ( $this->show_contact_terms_by_name() ) {
usort( $data['links'], $this->sort_by_field( 'title' ) );
}
return $data['links'];
}
return array();
}
public function show_contact_terms_by_name() {
if ( ! is_null( BWFAN_Common::$show_tags_list_by_name ) ) {
return BWFAN_Common::$show_tags_list_by_name;
}
BWFAN_Common::$show_tags_list_by_name = apply_filters( 'bwfan_contact_show_terms_by_name', false );
return BWFAN_Common::$show_tags_list_by_name;
}
public function sort_by_field( $field ) {
return function ( $a, $b ) use ( $field ) {
return strcmp( $a[ $field ], $b[ $field ] );
};
}
public function get_customer_as_array( $slim_data = false ) {
if ( ! class_exists( 'WooCommerce' ) ) {
return [];
}
if ( ! $this->is_customer_exists() && class_exists( 'WooCommerce' ) ) {
if ( ! $this->is_contact_exists() ) {
return array();
} else {
$this->customer = bwf_get_customer( $this->contact );
}
}
$purchased_products = array_unique( $this->customer->get_purchased_products() );
$wc_data = array(
'id' => $this->customer->get_id(),
'l_order_date' => $this->customer->get_l_order_date(),
'f_order_date' => $this->customer->get_f_order_date(),
'aov' => $this->customer->get_aov(),
'total_order_count' => $this->customer->get_total_order_count(),
'total_order_value' => $this->customer->get_total_order_value(),
'total_purchased_items' => is_array( $purchased_products ) && ! empty( $purchased_products ) ? count( $purchased_products ) : 0,
);
if ( true === $slim_data ) {
return $wc_data;
}
/** Get Purchased Products titles */
$purchased_products = BWFAN_Common::get_products_name( $purchased_products );
$purchased_products = array_map( function ( $product ) {
return [
'id' => ! empty( $product['post_parent'] ) ? $product['post_parent'] : $product['id'],
'name' => wp_strip_all_tags( $product['name'] )
];
}, $purchased_products );
$wc_data['purchased_products'] = array_values( array_filter( $purchased_products ) );
/** Get Purchased Products Cats & Tags */
$purchased_products_cats = array_unique( $this->customer->get_purchased_products_cats() );
$purchased_products_tags = array_unique( $this->customer->get_purchased_products_tags() );
$terms = BWFAN_Common::get_wp_term( array_merge( $purchased_products_cats, $purchased_products_tags ) );
$purchased_products_cats = array_filter( $terms, function ( $tags ) use ( $purchased_products_cats ) {
return in_array( intval( $tags['id'] ), $purchased_products_cats, true );
} );
$purchased_products_tags = array_filter( $terms, function ( $tags ) use ( $purchased_products_tags ) {
return in_array( intval( $tags['id'] ), $purchased_products_tags, true );
} );
$purchased_products_cats = array_values( $purchased_products_cats );
$purchased_products_tags = array_values( $purchased_products_tags );
$wc_data['purchased_products_cats'] = $purchased_products_cats;
$wc_data['purchased_products_tags'] = $purchased_products_tags;
/** Coupons and AOV data */
$wc_data['used_coupons'] = $this->customer->get_used_coupons();
$wc_data['aov_store'] = BWFAN_Common::get_store_aov();
if ( $this->customer->get_total_order_count() !== 0 ) {
$wc_data['aov_contact'] = $this->customer->get_aov();
} else {
$wc_data['aov_contact'] = 0;
}
/** Tags and Lists */
return $wc_data;
}
/** get subscriptions details of contact
*
* @return array
*/
public function get_wcs_as_array() {
if ( ! bwfan_is_autonami_pro_active() ) {
return [];
}
$contact_wpid = $this->contact->get_wpid();
if ( 0 === absint( $contact_wpid ) ) {
return array();
}
$user_total_renewal = 0;
$user_total_renewal_amount = 0;
$user_renewal_dates = array();
$user_next_renewal_date = '';
$user_next_renewal_amount = 0;
$user_active_subscriptions = 0;
$user_inactive_subscriptions = 0;
$user_subscriptions = array();
if ( function_exists( 'wcs_get_users_subscriptions' ) ) {
$user_subscriptions = wcs_get_users_subscriptions( $contact_wpid );
}
if ( empty( $user_subscriptions ) ) {
return array();
}
foreach ( $user_subscriptions as $subscription_id => $subscriptions ) {
if ( 'active' === $subscriptions->get_status() ) {
$user_active_subscriptions ++;
$user_next_renewal_date = $subscriptions->get_date( 'next_payment' );
if ( ! empty( $user_next_renewal_date ) ) {
$user_renewal_dates[ $subscription_id ] = $user_next_renewal_date;
}
$user_renewal_order = $subscriptions->get_related_orders( 'ids', array( 'renewal', 'resubscribe' ) );
} else {
$user_inactive_subscriptions ++;
}
}
/** getting contact total renewal and total renewal amount */
if ( ! empty( $user_renewal_order ) ) {
$paid_statuses = wc_get_is_paid_statuses();
foreach ( $user_renewal_order as $order_id ) {
$order = wc_get_order( $order_id );
if ( ! $order instanceof WC_ORDER || ! $order->has_status( $paid_statuses ) ) {
continue;
}
$user_total_renewal ++;
$order_total = BWF_Plugin_Compatibilities::get_fixed_currency_price_reverse( $order->get_total(), BWF_WC_Compatibility::get_order_currency( $order ) );
$user_total_renewal_amount += $order_total;
}
}
/** getting contact next renewal date and next renewal amount */
if ( ! empty( $user_renewal_dates ) ) {
uasort( $user_renewal_dates, function ( $date1, $date2 ) {
return ( strtotime( $date1 ) <=> strtotime( $date2 ) );
} );
foreach ( $user_renewal_dates as $subscription_id => $subscription_dates ) {
$subscription = wcs_get_subscription( $subscription_id );
if ( ! $subscription instanceof WC_Subscription ) {
break;
}
$user_next_renewal_amount = self::get_next_renewal_amount( $subscription );
$user_next_renewal_date = $subscription_dates;
break;
}
}
$user_subscriptions_data['active_subscriptions'] = $user_active_subscriptions;
$user_subscriptions_data['inactive_subscriptions'] = $user_inactive_subscriptions;
$user_subscriptions_data['next_renewal_date'] = $user_next_renewal_date;
$user_subscriptions_data['next_renewal_amount'] = $user_next_renewal_amount;
$user_subscriptions_data['total_renewal_count'] = $user_total_renewal;
$user_subscriptions_data['total_renewal_amount'] = number_format( $user_total_renewal_amount, 2 );
return $user_subscriptions_data;
}
/** get offers details of contact
*
* @return mixed
*/
public function get_offer_as_array() {
$contact_id = $this->contact->get_id();
$contact_offer_data['upsell'] = array();
$contact_offer_data['bump'] = array();
$contact_offer_data['checkout'] = array();
$contact_offer_data['optin'] = array();
/** checking oder bump activated */
if ( class_exists( 'WFOB_Core' ) && bwfan_is_woocommerce_active() ) {
$contact_offer_data['bump'] = BWFCRM_Model_Contact::get_bump_details( $contact_id );
}
/** checking oder bump activated */
if ( class_exists( 'WFACP_Core' ) && bwfan_is_woocommerce_active() ) {
$contact_offer_data['checkout'] = BWFCRM_Model_Contact::get_checkout_details( $contact_id );
}
/** checking optin activated */
if ( function_exists( 'WFOPP_Core' ) ) {
$contact_offer_data['optin'] = BWFCRM_Model_Contact::get_optin_details( $contact_id );
}
/** checking upstroke activated */
if ( class_exists( 'WFOCU_Core' ) && bwfan_is_woocommerce_active() ) {
$contact_offer_data['upsell'] = BWFCRM_Model_Contact::get_upstroke_details( $contact_id );
}
return $contact_offer_data;
}
/**
* @param $subscription WC_Subscription
*
* @return mixed
*/
public static function get_next_renewal_amount( $subscription ) {
$order_total = 0;
if ( $subscription->get_total() > 0 && '' !== $subscription->get_billing_period() && ! $subscription->is_one_payment() ) {
$order_total = BWF_Plugin_Compatibilities::get_fixed_currency_price_reverse( $subscription->get_total(), $subscription->get_currency() );
}
return $order_total;
}
/**
* Create WP User
*
* @param $email
* @param string $first_name
* @param string $last_name
* @param string $password
*
* @return int|WP_Error
*/
public function create_wp_user( $email, $first_name = '', $last_name = '', $password = '', $notify_new_user = false ) {
if ( ! is_email( $email ) ) {
return BWFAN_Common::crm_error( __( 'Can\'t create WP User as provided email is not valid', 'wp-marketing-automations' ) );
}
$user = new WP_User();
$user->user_email = $email;
$user->user_login = $email;
$user->first_name = $first_name;
$user->last_name = $last_name;
$user->user_pass = ! empty( $password ) ? $password : wp_generate_password();
$user_id = wp_insert_user( $user );
if ( ! $user_id instanceof WP_Error && true === $notify_new_user ) {
wp_send_new_user_notifications( $user_id, 'user' );
}
return $user_id;
}
public function is_contact_exists() {
return $this->contact instanceof WooFunnels_Contact && $this->contact->get_id() > 0;
}
public function is_customer_exists() {
return $this->customer instanceof WooFunnels_Customer && $this->customer->get_id() > 0;
}
public function get_id() {
return absint( $this->contact->get_id() );
}
/**
* @return array|array[]|BWFCRM_Lists[]|BWFCRM_Tag[]|BWFCRM_Term[]
*/
public function get_tags() {
$tags = $this->contact->get_tags();
if ( ! is_array( $tags ) || empty( $tags ) ) {
return array();
}
return $tags;
}
/**
* @return array|array[]|BWFCRM_Lists[]|BWFCRM_Term[]
*/
public function get_lists() {
$lists = $this->contact->get_lists();
if ( ! is_array( $lists ) || empty( $lists ) ) {
return array();
}
return $lists;
}
/**
* Get link triggers IDs
*
* @return mixed|string
*/
public function get_link_triggers() {
$links = $this->get_field_by_slug( 'link-trigger-click' );
$links = json_decode( $links, true );
return $links;
}
/**
* @param $tags
* @param bool $use_cache
* @param bool $stop_hooks
*
* @return BWFCRM_Term[]|WP_Error
*/
public function add_tags( $tags, $use_cache = false, $stop_hooks = false, $return_skipped = false ) {
if ( ! $this->is_contact_exists() ) {
return BWFAN_Common::crm_error( __( 'Contact doesn\'t exists', 'wp-marketing-automations' ) );
}
$tags = $this->set_tags( $tags, $use_cache, $stop_hooks, $return_skipped );
if ( false === $tags ) {
return BWFAN_Common::crm_error( __( 'Provided tags are empty / invalid', 'wp-marketing-automations' ) );
}
$this->save();
return $tags;
}
public function set_tags( $tags, $use_cache = false, $stop_hooks = false, $return_skipped = false ) {
if ( ! is_array( $tags ) || empty( $tags ) ) {
return false;
}
$tags = BWFCRM_Term::get_or_create_terms( $tags, BWFCRM_Term_Type::$TAG, true, false, $use_cache );
$old_tags = $this->get_tags();
/** Newly Assigned Tags IDs */
$tag_ids = array_filter( array_map( function ( $tag ) use ( $old_tags ) {
return in_array( $tag->get_id(), $old_tags ) ? false : $tag->get_id();
}, $tags ) );
$new_tags = array_values( array_unique( array_merge( $old_tags, $tag_ids ) ) );
$this->contact->set_tags( $new_tags );
/** To trigger automations we need to have contact save (ie need to get ID) */
if ( empty( $this->get_id() ) && false === $stop_hooks ) {
$this->contact->save();
}
$assigned_tags = array();
$skipped = array();
foreach ( $tags as $tag ) {
if ( ! in_array( $tag->get_id(), $tag_ids, true ) ) {
$skipped[] = $tag;
continue;
}
$assigned_tags[] = $tag;
}
if ( false === $stop_hooks && count( $assigned_tags ) > 0 ) {
$this->assigned_tags = $assigned_tags;
}
if ( true === $return_skipped ) {
return [
'skipped' => $skipped,
'assigned' => $assigned_tags
];
}
return $assigned_tags;
}
/**
* Set tags on a contact but don't save
* Run automations conditional - default run
* Version 2
* Tags array contains term id only
*
* @param $tags
* @param $stop_hooks
*
* @return array|bool
*/
public function set_tags_v2( $tags = [], $stop_hooks = false ) {
$this->assigned_tags = [];
if ( ! is_array( $tags ) || empty( $tags ) ) {
return false;
}
$old_tags = $this->get_tags();
/** Newly Assigned Tags IDs */
$new_tags = array_diff( $tags, $old_tags );
sort( $new_tags );
if ( empty( $new_tags ) ) {
/** No tag to update */
return true;
}
$all_tags = array_values( array_unique( array_merge( $old_tags, $new_tags ) ) );
/** Save tags on a contact */
$this->contact->set_tags( $all_tags );
if ( false === $stop_hooks && count( $new_tags ) > 0 ) {
$this->assigned_tags = BWFAN_Model_Terms::get_term_objects( $new_tags );
}
return $all_tags;
}
public function remove_tags( $tags ) {
if ( ! $this->is_contact_exists() ) {
return array();
}
if ( ! is_array( $tags ) || empty( $tags ) ) {
return array();
}
/** get contact tags from db */
$applied_tags = $this->get_tags();
$removed_tags = array();
/** remove tags from the contact $tag */
foreach ( $tags as $tag ) {
if ( ! is_string( $tag ) && ! is_numeric( $tag ) ) {
BWFAN_Common::log_test_data( 'contact id: ' . $this->get_id(), 'remove_tags', true );
BWFAN_Common::log_test_data( $tags, 'remove_tags', true );
BWFAN_Common::log_test_data( wp_debug_backtrace_summary(), 'remove_tags', true );
continue;
}
$list_key = array_search( strval( $tag ), $applied_tags );
if ( false === $list_key ) {
continue;
}
unset( $applied_tags[ $list_key ] );
$removed_tags[] = $tag;
}
$diff_array = array_diff( $this->get_tags(), $applied_tags );
if ( ! empty( $diff_array ) ) {
$this->contact->set_tags( array_values( $applied_tags ) );
}
if ( count( $removed_tags ) > 0 ) {
$this->removed_tags = $removed_tags;
}
return $removed_tags;
}
public function add_lists( $lists, $use_cache = false, $stop_hooks = false, $return_skipped = false ) {
if ( ! $this->is_contact_exists() ) {
return BWFAN_Common::crm_error( __( 'Contact doesn\'t exists', 'wp-marketing-automations' ) );
}
$lists = $this->set_lists( $lists, $use_cache, $stop_hooks, $return_skipped );
if ( false === $lists ) {
return BWFAN_Common::crm_error( __( 'Provided lists are empty / invalid', 'wp-marketing-automations' ) );
}
$this->save();
return $lists;
}
public function set_lists( $lists, $use_cache = false, $stop_hooks = false, $return_skipped = false ) {
if ( ! is_array( $lists ) || empty( $lists ) ) {
return false;
}
/** @var BWFCRM_Lists[] $lists */
$lists = BWFCRM_Term::get_or_create_terms( $lists, BWFCRM_Term_Type::$LIST, true, false, $use_cache );
$old_lists = $this->get_lists();
/** Newly Assigned List IDs */
$list_ids = array_filter( array_map( function ( $list ) use ( $old_lists ) {
return in_array( $list->get_id(), $old_lists ) ? false : $list->get_id();
}, $lists ) );
$new_lists = array_values( array_unique( array_merge( $old_lists, $list_ids ) ) );
$this->contact->set_lists( $new_lists );
/** To trigger automations we need to have contact save (ie need to get ID) */
if ( empty( $this->get_id() ) && false === $stop_hooks ) {
$this->contact->save();
}
$assigned_lists = array();
$skipped = array();
foreach ( $lists as $list ) {
if ( ! in_array( $list->get_id(), $list_ids, true ) ) {
$skipped[] = $list;
continue;
}
$assigned_lists[] = $list;
}
if ( false === $stop_hooks && count( $assigned_lists ) > 0 ) {
$this->assigned_lists = $assigned_lists;
}
if ( true === $return_skipped ) {
return [
'skipped' => $skipped,
'assigned' => $assigned_lists
];
}
return $assigned_lists;
}
/**
* Set lists on a contact but don't save
* Run automations conditional - default run
* Version 2
* Lists array contains term id only
*
* @param $lists
* @param $stop_hooks
*
* @return array|bool
*/
public function set_lists_v2( $lists, $stop_hooks = false ) {
$this->assigned_lists = [];
if ( ! is_array( $lists ) || empty( $lists ) ) {
return false;
}
$old_lists = $this->get_lists();
/** Newly Assigned Tags IDs */
$new_lists = array_diff( $lists, $old_lists );
sort( $new_lists );
if ( empty( $new_lists ) ) {
/** No list to update */
return true;
}
$all_lists = array_values( array_unique( array_merge( $old_lists, $new_lists ) ) );
/** Save lists on a contact */
$this->contact->set_lists( $all_lists );
if ( false === $stop_hooks && count( $new_lists ) > 0 ) {
$this->assigned_lists = BWFAN_Model_Terms::get_term_objects( $new_lists );
}
return $all_lists;
}
public static function get_contacts( $search, $offset, $limit, $filters = array(), $additional_info = array(), $return_type = ARRAY_N, $update_fields = false ) {
ob_start();
/** Send WC Data */
$wc_data_send = is_array( $additional_info ) && isset( $additional_info['customer_data'] ) && true === $additional_info['customer_data'];
$grab_totals = is_array( $additional_info ) && isset( $additional_info['grab_totals'] ) && true === $additional_info['grab_totals'];
$exclude_unsubs_lists = is_array( $additional_info ) && isset( $additional_info['exclude_unsubs_lists'] ) && true === $additional_info['exclude_unsubs_lists'];
/** Unsubscribed Lists Filter Handling */
if ( $exclude_unsubs_lists ) {
$filters = bwfan_is_autonami_pro_active() ? BWFCRM_Filters::maybe_add_unsubscribe_lists_filter( $filters ) : [];
}
$filter_match = isset( $filters['match'] ) && ! empty( $filters['match'] ) ? $filters['match'] : 'all';
$filter_match = ( 'any' === $filter_match ? ' OR ' : ' AND ' );
$filters = bwfan_is_autonami_pro_active() ? BWFCRM_Filters::_normalize_input_filters( $filters ) : [];
/** Get Contacts from DB */
$contacts = BWFCRM_Model_Contact::get_contacts( $search, $limit, $offset, $filters, $additional_info, $filter_match );
/** Return WP_Error in-case any WP_Error */
if ( is_wp_error( $contacts ) ) {
return $contacts;
}
/** Return Empty array on non-array or empty content */
if ( ! is_array( $contacts ) || empty( $contacts ) ) {
return array(
'contacts' => array(),
);
}
$total_count = $contacts['total'];
$contacts = $contacts['contacts'];
/** Prepare the output */
$contact_details = array();
foreach ( $contacts as $contact_db ) {
$contact = new BWFCRM_Contact( $contact_db, false, array(), $update_fields );
if ( ! $contact->is_contact_exists() ) {
continue;
}
/** Return data is requested format */
if ( ARRAY_N === $return_type ) {
$contact_details[] = $contact->get_array( true, $wc_data_send );
} elseif ( ARRAY_A === $return_type ) {
$contact_details[ $contact_db['id'] ] = $contact->get_array( true, $wc_data_send );
} else {
$contact_details[] = $contact;
}
}
if ( in_array( $return_type, array( ARRAY_A, ARRAY_N ) ) ) {
$contact_details = self::add_terms_to_contacts_details( $contact_details );
}
ob_end_flush();
$return_data = array(
'contacts' => $contact_details,
);
if ( true === $grab_totals ) {
$return_data['total_count'] = $total_count;
}
return $return_data;
}
public static function add_terms_to_contacts_details( $contact_details ) {
if ( ! is_array( $contact_details ) || empty( $contact_details ) ) {
return $contact_details;
}
$contact_tags = array();
$contact_lists = array();
foreach ( $contact_details as $contact ) {
if ( ! is_array( $contact ) || ( ! isset( $contact['tags'] ) && ! isset( $contact['lists'] ) ) ) {
continue;
}
if ( isset( $contact['tags'] ) && ! empty( $contact['tags'] ) ) {
if ( is_array( $contact['tags'] ) ) {
$contact_tags[ absint( $contact['id'] ) ] = array_map( 'absint', $contact['tags'] );
}
}
if ( isset( $contact['lists'] ) && ! empty( $contact['lists'] ) ) {
if ( is_array( $contact['lists'] ) ) {
$contact_lists[ absint( $contact['id'] ) ] = array_map( 'absint', $contact['lists'] );
}
}
}
$tags = ! empty( $contact_tags ) ? call_user_func_array( 'array_merge', $contact_tags ) : array();
$lists = ! empty( $contact_lists ) ? call_user_func_array( 'array_merge', $contact_lists ) : array();
$terms = array_map( 'absint', array_merge( $tags, $lists ) );
$terms = BWFAN_Model_Terms::get_terms( 0, 0, 0, '', $terms );
$terms_with_keys = array();
foreach ( $terms as $term ) {
if ( ! is_array( $term ) || ! isset( $term['ID'] ) ) {
continue;
}
$terms_with_keys[ absint( $term['ID'] ) ] = $term;
}
$contact_details = array_map( function ( $contact ) use ( $terms_with_keys, $contact_tags, $contact_lists ) {
if ( ! is_array( $contact ) || ! isset( $contact['id'] ) ) {
return false;
}
$contact_id = absint( $contact['id'] );
$contact['tags'] = array();
if ( isset( $contact_tags[ $contact_id ] ) && is_array( $contact_tags[ $contact_id ] ) ) {
$tags = $contact_tags[ $contact_id ];
foreach ( $tags as $tag_id ) {
if ( ! isset( $terms_with_keys[ $tag_id ] ) || ! is_array( $terms_with_keys[ $tag_id ] ) || $terms_with_keys[ $tag_id ]['type'] != 1 ) {
continue;
}
$contact['tags'][] = $terms_with_keys[ $tag_id ];
}
}
$contact['lists'] = array();
if ( isset( $contact_lists[ $contact_id ] ) && is_array( $contact_lists[ $contact_id ] ) ) {
$lists = $contact_lists[ $contact_id ];
foreach ( $lists as $list_id ) {
if ( ! isset( $terms_with_keys[ $list_id ] ) || ! is_array( $terms_with_keys[ $list_id ] ) || $terms_with_keys[ $list_id ]['type'] != 2 ) {
continue;
}
$contact['lists'][] = $terms_with_keys[ $list_id ];
}
}
return $contact;
}, $contact_details );
return array_filter( $contact_details );
}
public function get_conversations( $mode, $offset = 0, $limit = 0 ) {
if ( ! class_exists( 'BWFAN_Email_Conversations' ) || ! isset( BWFAN_Core()->conversations ) || ! BWFAN_Core()->conversations instanceof BWFAN_Email_Conversations ) {
return BWFAN_Common::crm_error( 'Conversations module not found' );
}
return BWFAN_Core()->conversations->get_conversations_by_cid( $this->get_id(), $mode, $offset, $limit );
}
public function get_conversation_email( $con_id = 0 ) {
if ( ! class_exists( 'BWFAN_Email_Conversations' ) || ! isset( BWFAN_Core()->conversations ) || ! BWFAN_Core()->conversations instanceof BWFAN_Email_Conversations ) {
return BWFAN_Common::crm_error( 'Conversations module not found' );
}
if ( ! empty( $con_id ) ) {
return BWFAN_Core()->conversations->get_conversation_email( $con_id );
}
$cons = BWFAN_Model_Engagement_Tracking::get_conversations_by_cid( $this->get_id(), 0 );
if ( ! is_array( $cons ) || empty( $cons ) || ! is_array( $cons[0] ) || ! isset( $cons[0]['ID'] ) ) {
return BWFAN_Common::crm_error( 'No Conversation for this email found' );
}
return BWFAN_Core()->conversations->get_conversation_email( $cons[0]['ID'] );
}
public function get_conversations_total( $mode ) {
return BWFAN_Model_Engagement_Tracking::get_total_engagements( $this->get_id(), $mode );
}
public function remove_lists( $lists ) {
if ( ! $this->is_contact_exists() ) {
return BWFAN_Common::crm_error( __( 'Contact doesn\'t exists', 'wp-marketing-automations' ) );
}
if ( ! is_array( $lists ) || empty( $lists ) ) {
return BWFAN_Common::crm_error( __( 'Provided Lists are empty / invalid', 'wp-marketing-automations' ) );
}
$applied_lists = $this->get_lists();
$removed_lists = array();
/** remove lists from the contact $lists */
foreach ( $lists as $list ) {
$list_key = array_search( $list, $applied_lists );
if ( false === $list_key ) {
continue;
}
$removed_lists[] = $list;
unset( $applied_lists[ $list_key ] );
}
$diff_array = array_diff( $this->get_lists(), $applied_lists );
if ( ! empty( $diff_array ) ) {
$this->contact->set_lists( array_values( $applied_lists ) );
$this->contact->save();
}
if ( count( $removed_lists ) > 0 ) {
$this->removed_lists = $removed_lists;
}
return $removed_lists;
}
/**
* Update/add custom field to contact meta
*
* @param $fields
*
* @return bool
*/
public function update_custom_fields( $fields ) {
if ( empty( $fields ) ) {
return false;
}
return false !== $this->update( $fields );
}
/**
* update contact info
*/
public function update_contact( $contact_details ) {
$this->contact->db_operations->update_contact( $contact_details );
}
/**
* Improved Update
*
* @param $args
*
* @return mixed|WooFunnels_Contact|null
*/
public function update( $args ) {
if ( ! $this->is_contact_exists() || ! is_array( $args ) ) {
return false;
}
$result = $this->set_data( $args );
if ( false === $result ) {
return false;
}
$this->save();
if ( true === $result['fields_changed'] ) {
$this->save_fields();
}
/** Fire hooks on field update */ // isset( $args['f_name'] ) && ( $f_name !== $args['f_name'] ) && $this->fire_hook_field_updated( 'f_name', $args['f_name'], $f_name, $this->get_id() );
// isset( $args['l_name'] ) && ( $l_name !== $args['l_name'] ) && $this->fire_hook_field_updated( 'l_name', $args['l_name'], $l_name, $this->get_id() );
// isset( $args['state'] ) && ( $state !== $args['state'] ) && $this->fire_hook_field_updated( 'state', $args['state'], $state, $this->get_id() );
// isset( $args['country'] ) && ( $country !== $args['country'] ) && $this->fire_hook_field_updated( 'country', $args['country'], $country, $this->get_id() );
// isset( $args['contact_no'] ) && ( $contact_no !== $args['contact_no'] ) && $this->fire_hook_field_updated( 'contact_no', $args['contact_no'], $contact_no, $this->get_id() );
return $this->contact;
}
public function set_data( $args, $cid = 0 ) {
if ( empty( $args ) || ! is_array( $args ) ) {
return false;
}
if ( ! $this->contact instanceof WooFunnels_Contact ) {
if ( ! empty( $cid ) ) {
$bwf_contacts = BWF_Contacts::get_instance();
$this->contact = $bwf_contacts->get_contact_by( 'id', absint( $cid ) );
} else {
$email = isset( $args['email'] ) && is_email( $args['email'] ) ? $args['email'] : null;
$this->contact = new WooFunnels_Contact( 0, $email );
}
}
// if ( ! is_email( $this->contact->email ) ) {
// $email = isset( $args['email'] ) && is_email( $args['email'] ) ? $args['email'] : null;
// $this->contact->set_email( $email );
// }
$contact_cols = array( 'email', 'f_name', 'l_name', 'state', 'country', 'contact_no', 'timezone', 'creation_date' );
$this->contact->blank_values_update = true;
foreach ( $contact_cols as $cols ) {
if ( ! isset( $args[ $cols ] ) ) {
continue;
}
$value = $args[ $cols ];
/** Get formatted creation date */
if ( 'creation_date' === $cols ) {
$value = self::get_date_value( $args['creation_date'], 'Y-m-d H:i:s' );
}
/** Get country code */
if ( function_exists( 'bwf_get_countries_data' ) && 'country' === $cols && strlen( $value ) > 2 ) {
$countries = bwf_get_countries_data();
$country = in_array( ucwords( $value ), $countries ) ? array_search( ucwords( $value ), $countries ) : false;
$value = ! empty( $country ) ? $country : '';
if ( empty( $value ) ) {
continue;
}
}
call_user_func_array( array( $this->contact, 'set_' . $cols ), array( $value ) );
}
$this->contact->blank_values_update = false;
$old_status = absint( $this->contact->get_status() );
if ( isset( $args['status'] ) ) {
$new_status = absint( $args['status'] );
$this->contact->set_status( $new_status );
/** If old and new status are same, but contact was unsubscribed, then he/she is subscribed now */
if ( 1 === $old_status && 1 === $new_status && true === $this->was_unsubscribed ) {
$this->contact->is_subscribed = true;
}
}
/** If Disable Events, then turn is_subscribed = false */
if ( isset( $args['disable_events'] ) && true === $args['disable_events'] && isset( $this->contact->is_subscribed ) ) {
$this->contact->is_subscribed = false;
}
if ( isset( $args['wp_id'] ) ) {
! empty( $args['wp_id'] ) && $this->contact->set_wpid( absint( $args['wp_id'] ) );
}
if ( isset( $args['points'] ) ) {
! empty( $args['points'] ) && $this->contact->set_points( absint( $args['points'] ) );
}
$contact_cols = array( 'email', 'f_name', 'l_name', 'contact_no', 'state', 'country', 'creation_date', 'timezone', 'status', 'source', 'points', 'wp_id', 'disable_events' );
foreach ( $contact_cols as $cols ) {
if ( isset( $args[ $cols ] ) ) {
unset( $args[ $cols ] );
}
}
/** Update Meta */
$fields_changed = false;
if ( ! empty( $args ) ) {
$this->set_fields( $args );
$fields_changed = true;
}
return array( 'fields_changed' => $fields_changed );
}
public function fire_hook_field_updated( $field_id, $new_value, $old_value, $contact_id ) {
/**
* $field_id - Field ID
* $new_value - Field New Value
* $old_value - Field Old Value
* $contact_id - Contact ID
*/
do_action( 'bwfcrm_contact_field_updated', $field_id, $new_value, $old_value, $contact_id );
}
public function save_fields() {
$contact_id = $this->get_id();
if ( ! is_array( $this->fields ) || 0 === count( $this->fields ) ) {
return;
}
$contact_field = BWF_Model_Contact_Fields::get_contact_field_by_id( $contact_id );
$field_ids = array_keys( $this->fields );
$field_ids = implode( ',', $field_ids );
$field_types_db = BWFAN_Model_Fields::get_results( 'SELECT ID, type, meta FROM {table_name} WHERE ID IN (' . $field_ids . ')' );
$field_types = array();
$field_meta = array();
foreach ( $field_types_db as $type ) {
$field_types[ absint( $type['ID'] ) ] = absint( $type['type'] );
$field_meta[ absint( $type['ID'] ) ] = json_decode( $type['meta'], true );
}
$field_array = array();
$format = [];
foreach ( $this->fields as $field_id => $field_value ) {
$field_value = is_string( $field_value ) ? trim( $field_value ) : $field_value;
/** Checkbox, Radio and Select field values alter */
$allowed_types = array(
BWFCRM_Fields::$TYPE_CHECKBOX,
BWFCRM_Fields::$TYPE_RADIO,
BWFCRM_Fields::$TYPE_SELECT
);
if ( isset( $field_types[ $field_id ] ) && in_array( $field_types[ $field_id ], $allowed_types, true ) ) {
$field_value = $this->get_field_values( $field_value, $field_meta[ $field_id ], $field_types[ $field_id ] );
$field_array[ 'f' . $field_id ] = $field_value;
$format[] = '%s';
continue;
}
if ( is_array( $field_value ) ) {
continue;
}
/** Date field */
if ( isset( $field_types[ $field_id ] ) && ( absint( $field_types[ $field_id ] ) === BWFCRM_Fields::$TYPE_DATE ) ) {
/** If date field value is empty */
if ( empty( $field_value ) ) {
$field_array[ 'f' . $field_id ] = null;
$format[] = '%s';
continue;
}
$field_value = self::get_date_value( $field_value );
}
/** Else fields case */
$field_array[ 'f' . $field_id ] = $field_value;
$format[] = '%s';
}
if ( empty( $contact_field ) || ! is_array( $contact_field ) ) {
$data = array_replace( array( 'cid' => $contact_id ), $field_array );
BWF_Model_Contact_Fields::insert_ignore( $data, array_merge( [ '%d' ], $format ) );
return;
}
BWF_Model_Contact_Fields::update( $field_array, array( 'cid' => $contact_id ) );
// foreach ( $field_array as $field => $field_value ) {
// $field_id = explode( 'f', $field )[1];
// $this->fire_hook_field_updated( $field_id, $field_value, $this->fields[ $field_id ], $contact_id );
// }
}
private function get_field_values( $values, $meta, $field_type ) {
if ( empty( $values ) ) {
return $values;
}
$options = isset( $meta['options'] ) ? $meta['options'] : [];
$json_values = ! is_array( $values ) ? json_decode( $values, true ) : $values;
if ( null === $json_values && ! is_array( $values ) ) {
$values = ( $field_type === BWFCRM_Fields::$TYPE_CHECKBOX ) ? array_map( 'trim', explode( ',', $values ) ) : [ $values ];
} else {
$values = is_array( $json_values ) ? $json_values : [ $json_values ];
}
$strtolower_options = array_map( function ( $option ) {
return strtolower( $option );
}, $options );
$strtolower_values = array_map( function ( $value ) {
return strtolower( $value );
}, $values );
$new_values = array_intersect( $strtolower_values, $strtolower_options );
if ( empty( $new_values ) ) {
return '';
}
/** get option value */
$new_values = array_map( function ( $new_value ) use ( $strtolower_options, $options ) {
$option_key = array_search( $new_value, $strtolower_options );
return isset( $options[ $option_key ] ) ? $options[ $option_key ] : '';
}, $new_values );
/** return value for radio and dropdown field */
if ( $field_type !== BWFCRM_Fields::$TYPE_CHECKBOX ) {
return isset( $new_values[0] ) ? $new_values[0] : '';
}
sort( $new_values );
/** return values for checkbox field */
return wp_json_encode( $new_values, JSON_UNESCAPED_UNICODE );
}
/**
* Return always a date
* If supplied date value is empty then returns the current date
*
* @param $value
* @param $format
*
* @return mixed|string|void
*/
public static function get_date_value( $value = '', $format = 'Y-m-d' ) {
if ( empty( $value ) ) {
return '';
}
$value = trim( apply_filters( 'bwfan_modify_date_before_formatting', $value, $format ) );
$value = ( strpos( $value, "/" ) !== false ) ? str_replace( "/", "-", $value ) : $value;
try {
/** Could be timestamp */
if ( is_numeric( $value ) && ( strtotime( date( 'd-m-Y H:i:s', $value ) ) === (int) $value ) ) {
/** Valid timestamp */
return date( $format, $value );
}
$new = new DateTime( $value, wp_timezone() );
} catch ( Error $e ) {
return '';
} catch ( Exception $e ) {
return '';
}
if ( ! $new instanceof DateTime ) {
return '';
}
return apply_filters( 'bwfan_contact_date_field_value', $new->format( $format ), $value, $format );
}
/**
* @param $offset
* @param $limit
* @param $active
*
* @return array
*/
public function get_subscriptions( $offset = 0, $limit = 10, $active = false ) {
if ( ! $this->is_contact_exists() || ! bwfan_is_woocommerce_subscriptions_active() ) {
return array();
}
$customer_id = $this->contact->get_wpid();
if ( empty( $customer_id ) ) {
$user = get_user_by( 'email', $this->contact->get_wpid() );
if ( ! $user instanceof WP_User ) {
return array();
}
$customer_id = $user->ID;
}
$args = array(
'subscriptions_per_page' => empty( $offset ) && empty( $limit ) ? - 1 : absint( $limit ),
'offset' => absint( $offset ),
'customer_id' => absint( $customer_id ),
'subscription_status' => true === $active ? array( 'active' ) : array( 'any' ),
);
return wcs_get_subscriptions( $args );
}
public function get_orders( $offset = 0, $limit = - 1 ) {
$limit_query = '';
if ( $limit > 0 ) {
$limit_query = " LIMIT $offset, $limit";
}
global $wpdb;
$query = $wpdb->prepare( "SELECT {$wpdb->posts}.ID FROM {$wpdb->posts}
WHERE {$wpdb->posts}.post_type = %s AND {$wpdb->posts}.ID in (SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key = '_woofunnel_cid' AND meta_value = %d )
ORDER BY {$wpdb->posts}.post_date DESC $limit_query", 'shop_order', $this->get_id() );
if ( method_exists( 'BWF_WC_Compatibility', 'is_hpos_enabled' ) && BWF_WC_Compatibility::is_hpos_enabled() ) {
$order_table = $wpdb->prefix . 'wc_orders';
$order_meta_table = $wpdb->prefix . 'wc_orders_meta';
$query = "SELECT ot.id FROM {$order_table} AS ot JOIN {$order_meta_table} AS otm ON ot.id = otm.order_id WHERE otm.meta_key = '_woofunnel_cid' AND ot.type = 'shop_order' AND otm.meta_value = %d ORDER BY ot.id DESC $limit_query";
}
$contact_orders = $wpdb->get_col( $wpdb->prepare( $query, $this->get_id() ) ); //phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
if ( empty( $contact_orders ) ) {
return array();
}
return $contact_orders;
}
/**
* @param int $offset
* @param int $limit
*
* @return array
*/
public function get_orders_array( $offset = 0, $limit = 10 ) {
if ( ! $this->is_contact_exists() ) {
return array();
}
$contact_orders = $this->get_orders( $offset, $limit );
$contact_order_data = array();
$co_id = 0;
foreach ( $contact_orders as $order ) {
$order = is_numeric( $order ) ? wc_get_order( $order ) : $order;
if ( ! $order instanceof WC_Order ) {
continue;
}
$status = $order->get_status();
$status = wc_get_order_status_name( $status );
$contact_order_data['orders'][ $co_id ]['id'] = $order->get_id();
$order_date = $order->get_date_created();
$contact_order_data['orders'][ $co_id ]['date'] = ( $order_date instanceof WC_DateTime ) ? ( $order_date->date( 'Y-m-d H:i:s' ) ) : '';
$contact_order_data['orders'][ $co_id ]['status'] = $status;
$contact_order_data['orders'][ $co_id ]['first_name'] = $order->get_billing_first_name();
$contact_order_data['orders'][ $co_id ]['last_name'] = $order->get_billing_last_name();
$contact_order_data['orders'][ $co_id ]['total'] = $order->get_total();
$contact_order_data['orders'][ $co_id ]['item_count'] = $order->get_item_count();
$order_items = $order->get_items();
$contact_order_data['orders'][ $co_id ]['items'] = [];
foreach ( $order_items as $item ) {
$product_id = $item->get_product_id(); // the Product id
$contact_order_data['orders'][ $co_id ]['items'][ $product_id ] = $item->get_name();
}
$co_id ++;
}
return $contact_order_data;
}
public function get_orders_count() {
$contact_orders_ids = $this->get_orders();
return count( $contact_orders_ids );
}
/**
* @param $offset
* @param $limit
*
* @return array
*/
public function get_subscriptions_array( $offset = 0, $limit = 10 ) {
if ( ! bwfan_is_autonami_pro_active() ) {
return [];
}
$contact_subscriptions = self::get_subscriptions( $offset, $limit );
if ( empty( $contact_subscriptions ) ) {
return array();
}
$contact_subscription_data = array();
$co_id = 0;
$wcs_statuses = wcs_get_subscription_statuses();
foreach ( $contact_subscriptions as $subscriptions ) {
if ( ! $subscriptions instanceof WC_Subscription ) {
continue;
}
$contact_subscription_data['subscriptions'][ $co_id ]['id'] = $subscriptions->get_id();
$subscriptions_date = $subscriptions->get_date_created();
$contact_subscription_data['subscriptions'][ $co_id ]['date'] = ( $subscriptions_date instanceof WC_DateTime ) ? ( $subscriptions_date->date( 'Y-m-d H:i:s' ) ) : '';
$contact_subscription_data['subscriptions'][ $co_id ]['status'] = $wcs_statuses[ 'wc-' . $subscriptions->get_status() ];
$contact_subscription_data['subscriptions'][ $co_id ]['status_arr'] = [
'label' => $wcs_statuses[ 'wc-' . $subscriptions->get_status() ],
'value' => 'wc-' . $subscriptions->get_status()
];
$contact_subscription_data['subscriptions'][ $co_id ]['first_name'] = $subscriptions->get_billing_first_name();
$contact_subscription_data['subscriptions'][ $co_id ]['last_name'] = $subscriptions->get_billing_last_name();
$contact_subscription_data['subscriptions'][ $co_id ]['total'] = BWF_Plugin_Compatibilities::get_fixed_currency_price_reverse( $subscriptions->get_total(), $subscriptions->get_currency() );
$contact_subscription_data['subscriptions'][ $co_id ]['item_count'] = $subscriptions->get_item_count();
$contact_subscription_data['subscriptions'][ $co_id ]['next_renewal_date'] = $subscriptions->get_date( 'next_payment' );
$user_renewal_order = $subscriptions->get_related_orders( 'ids', array( 'renewal', 'resubscribe' ) );
$contact_subscription_data['subscriptions'][ $co_id ]['total_renewal'] = BWFAN_Common::get_paid_orders_count( $user_renewal_order );
$subscriptions_items = $subscriptions->get_items();
foreach ( $subscriptions_items as $item ) {
$product_id = $item->get_product_id(); // the Product id
$variation_id = $item->get_variation_id();
if ( ! empty( $variation_id ) ) {
$contact_subscription_data['subscriptions'][ $co_id ]['items'][ $variation_id ] = $item->get_name();
} else {
$contact_subscription_data['subscriptions'][ $co_id ]['items'][ $product_id ] = $item->get_name();
}
}
$co_id ++;
}
return $contact_subscription_data;
}
public function get_total_subscriptions() {
if ( ! $this->is_contact_exists() || ! bwfan_is_woocommerce_subscriptions_active() ) {
return 0;
}
$customer_id = $this->contact->get_wpid();
if ( empty( $customer_id ) ) {
$user = get_user_by( 'email', $this->contact->get_wpid() );
if ( ! $user instanceof WP_User ) {
return 0;
}
$customer_id = $user->ID;
}
$subs = WCS_Customer_Store::instance()->get_users_subscription_ids( absint( $customer_id ) );
return is_array( $subs ) ? count( $subs ) : 0;
}
/**
* @return array
*/
public function get_automation_array() {
$db_automations = BWFCRM_Model_Contact::get_automations( $this->get_id() );
$contact_automation_data = array();
foreach ( $db_automations as $a_key => $contact_automation ) {
$automation_id = $contact_automation['automation_id'];
$contact_automation_data[ $a_key ]['aid'] = $contact_automation['automation_id'];
$contact_automation_data[ $a_key ]['run_time'] = date( 'F j, Y', $contact_automation['time'] );
$automation_title = BWFAN_Model_Automationmeta::get_meta( $automation_id, 'title' );
$contact_automation_data[ $a_key ]['name'] = false === $automation_title ? 'No Title' : $automation_title;
}
return array_filter( array_values( $contact_automation_data ) );
}
/**
* @return array
*/
public function get_tasks_array() {
$automations_obj = new BWFCRM_Automations();
return $automations_obj->get_contact_tasks( $this->get_id() );
}
public function get_carts_array() {
$automations_obj = new BWFCRM_Automations();
$contact_email = $this->contact->get_email();
$automation_obj = new BWFCRM_Automations();
$contact_carts = $automations_obj->get_contact_carts( $contact_email );
$contact_recovered_carts = self::get_carts_recovered_array();
$contact_carts = array_merge( $contact_carts, $contact_recovered_carts );
uasort( $contact_carts, function ( $item1, $item2 ) {
return strtotime( $item2['created_time'] ) - strtotime( $item1['created_time'] );
} );
$contact_carts = array_filter( array_values( $contact_carts ) );
foreach ( $contact_carts as $cart_key => $cart ) {
$contact_carts[ $cart_key ]['created_time'] = $automation_obj->get_abandoned_time( $cart['created_time'] );
}
return $contact_carts;
}
/**
* @return mixed
*/
public function get_carts_lost_array() {
$automations_obj = new BWFCRM_Automations();
$contact_email = $this->contact->get_email();
return $automations_obj->get_contact_lost_carts( $contact_email );
}
/**
* @return mixed
*/
public function get_carts_abandoned_array() {
$automations_obj = new BWFCRM_Automations();
$contact_email = $this->contact->get_email();
return $automations_obj->get_contact_abandoned_carts( $contact_email );
}
/**
* @return mixed
*/
public function get_carts_recovered_array() {
$recovered_cart = self::get_contact_recovered_carts();
if ( empty( $recovered_cart ) ) {
return array();
}
$recovered_order = array();
foreach ( $recovered_cart as $rec_key => $cart_recover ) {
$order = wc_get_order( $cart_recover['ID'] );
if ( ! $order instanceof WC_Order ) {
continue;
}
$products = array();
$order_items = $order->get_items();
foreach ( $order_items as $product ) {
$products[] = $product->get_name();
}
$recovered_order[ $rec_key ]['order_id'] = $order->get_id();
$recovered_order[ $rec_key ]['phone'] = $order->get_billing_phone();
$recovered_order[ $rec_key ]['email'] = $order->get_billing_email();
$recovered_order[ $rec_key ]['username'] = trim( $order->get_billing_first_name() . ' ' . $order->get_billing_last_name() );
$recovered_order[ $rec_key ]['total'] = $order->get_total();
$recovered_order[ $rec_key ]['items'] = implode( ',', $products );
$recovered_order[ $rec_key ]['created_time'] = $order->get_date_created()->date( 'Y-m-d H:i:s' );
$recovered_order[ $rec_key ]['status'] = 'Recovered';
}
return $recovered_order;
}
public function get_contact_recovered_carts() {
$automations_obj = new BWFAN_Abandoned_Cart();
$contact_email = $this->contact->get_email();
return $automations_obj->get_contact_recovered_carts( $contact_email );
}
/**
* @param $notes
*
* @return false|int
*/
public function add_note_to_contact( $notes ) {
$user_id = get_current_user_id();
$notes_data['cid'] = $this->get_id();
$notes_data['title'] = isset( $notes['title'] ) ? $notes['title'] : '';
$notes_data['body'] = isset( $notes['body'] ) ? $notes['body'] : '';
$notes_data['created_by'] = isset( $notes['created_by'] ) ? $notes['created_by'] : $user_id;
$notes_data['created_date'] = current_time( 'mysql', 1 );
$notes_data['date_time'] = isset( $notes['date_time'] ) ? date( 'Y-m-d H:i:s', strtotime( $notes['date_time'] ) ) : current_time( 'mysql', 1 );
$notes_data['type'] = isset( $notes['type'] ) ? $notes['type'] : 'general';
$notes_data['private'] = isset( $notes['private'] ) ? $notes['private'] : 0;
BWFAN_Model_Contact_Note::insert( $notes_data );
$contact_note_id = BWFAN_Model_Contact_Note::insert_id();
if ( empty( $contact_note_id ) ) {
return false;
}
/** Create conversation in case admin optin while adding contact note */
if ( isset( $notes['private'] ) && 1 === absint( $notes['private'] ) ) {
$this->send_note_conversation( $contact_note_id, $notes_data );
}
/** Update last modified */
$this->save_last_modified();
return $contact_note_id;
}
/**
* @return bool
*/
public function delete_notes( $note_id ) {
return BWFCRM_Model_Contact::delete_notes( $this->get_id(), $note_id );
}
/**
* @param int $offset
* @param int $limit
*
* @return array
*/
public function get_contact_notes_array( $offset = 0, $limit = 0 ) {
$contact_notes = self::get_contact_notes( $offset, $limit );
if ( empty( $contact_notes ) ) {
return array();
}
return array_map( function ( $contact_note ) {
if ( isset( $contact_note['created_by'] ) ) {
$created_user_data = get_userdata( $contact_note['created_by'] );
$created_user_name = ! $created_user_data instanceof WP_USer ? '' : $created_user_data->first_name . ' ' . $created_user_data->last_name;
$contact_note['created_username'] = $created_user_name;
}
if ( isset( $contact_note['modified_by'] ) ) {
$modified_user_data = get_userdata( $contact_note['modified_by'] );
$modified_user_name = ! $modified_user_data instanceof WP_USer ? '' : $modified_user_data->first_name . ' ' . $modified_user_data->last_name;
$contact_note['modified_username'] = $modified_user_name;
}
if ( isset( $contact_note['created_date'] ) && ! empty( $contact_note['created_date'] ) ) {
$contact_note['created_date'] = get_date_from_gmt( $contact_note['created_date'] );
}
if ( isset( $contact_note['date_time'] ) && ! empty( $contact_note['date_time'] ) ) {
$contact_note['date_time'] = get_date_from_gmt( $contact_note['date_time'] );
}
if ( isset( $contact_note['body'] ) && ! empty( $contact_note['body'] ) ) {
$action_object = BWFAN_Core()->integration->get_action( 'wp_sendemail' );
$contact_note['body'] = $action_object->email_content_v2( [
'body' => $contact_note['body'],
'template' => 1,
] );
$dom = new DOMDocument;
$dom->loadHTML( $contact_note['body'] );
$bodies = $dom->getElementsByTagName( 'body' );
assert( $bodies->length === 1 );
$contact_note['body'] = str_replace( 'id="body_content"', 'class="note-body"', $dom->saveHTML( $bodies->item( 0 ) ) );
}
return $contact_note;
}, $contact_notes );
}
public function get_contact_notes( $offset = 0, $limit = 0 ) {
return BWFAN_Model_Contact_Note::get_contact_notes( $this->get_id(), $offset, $limit );
}
/**
* @param $notes
* @param $note_id
*
* @return bool|int
*/
public function update_contact_note( $notes, $note_id ) {
$notes_data = array();
if ( ! empty( $notes['title'] ) ) {
$notes_data['title'] = $notes['title'];
}
if ( ! empty( $notes['created_by'] ) ) {
$notes_data['created_by'] = $notes['created_by'];
}
if ( ! empty( $notes['body'] ) ) {
$notes_data['body'] = $notes['body'];
}
if ( ! empty( $notes['date_time'] ) ) {
$notes_data['date_time'] = date( 'Y-m-d H:i:s', strtotime( $notes['date_time'] ) );
}
if ( ! empty( $notes['type'] ) ) {
$notes_data['type'] = $notes['type'];
}
$notes_data['modified_by'] = $notes['modified_by'];
$notes_data['modified_date'] = current_time( 'mysql', 1 );
$notes_data['cid'] = $this->get_id();
/** Update last modified */
$this->save_last_modified();
return BWFAN_Model_Contact_Note::update_contact_note( $this->get_id(), $notes_data, $note_id );
}
/**
* @return array
*/
public function get_basic_array( $context = '' ) {
if ( ! $this->is_contact_exists() ) {
return array();
}
$contact_array = array(
'id' => $this->contact->get_id(),
'first_name' => $this->contact->get_f_name(),
'last_name' => $this->contact->get_l_name(),
'email' => $this->contact->get_email(),
);
if ( 'terms' === $context ) {
$contact_array['tags'] = $this->get_tags();
$contact_array['lists'] = $this->get_lists();
}
return $contact_array;
}
/**
* @return array
*/
public function get_contact_funnels_array() {
$contact_funnels = self::get_contact_funnels();
return $contact_funnels;
}
/**
* @return array
*/
public function get_contact_funnels() {
$contact_id = $this->get_id();
$funnel_object = new BWFAN_Funnels();
return $funnel_object->get_contact_funnels( $contact_id );
}
public function get_contact_checkout_array() {
$contact_id = $this->get_id();
$funnel_object = new BWFAN_Funnels();
return $funnel_object->get_contact_checkout( $contact_id );
}
public function get_contact_order_bump_array() {
$contact_id = $this->get_id();
$funnel_object = new BWFAN_Funnels();
return $funnel_object->get_contact_bump( $contact_id );
}
public function get_contact_optin_array() {
$contact_id = $this->get_id();
$funnel_object = new BWFAN_Funnels();
return $funnel_object->get_contact_optin( $contact_id );
}
public function get_contact_upsell_array() {
$contact_id = $this->get_id();
$funnel_object = new BWFAN_Funnels();
return $funnel_object->get_contact_upsell( $contact_id );
}
/** adding conversation for contact notes */
public function send_note_conversation( $note_id, $note_data ) {
/** @var $global_email_settings BWFAN_Common settings */
$global_email_settings = BWFAN_Common::get_global_settings();
$email = $this->contact->get_email();
$message = BWFAN_Common::decode_merge_tags( wpautop( $note_data['body'] ) );
$author_id = get_current_user_id();
/** Create Engagement */
$conversation = BWFAN_Core()->conversation->create_campaign_conversation( $this, $note_id, 0, $author_id, BWFAN_Email_Conversations::$MODE_EMAIL, true, array(
'subject' => $note_data['title'],
'template' => $message,
), BWFAN_Email_Conversations::$TYPE_NOTE );
$conversation_id = isset( $conversation['conversation_id'] ) ? $conversation['conversation_id'] : 0;
if ( class_exists( 'BWFAN_Message' ) ) {
$message_obj = new BWFAN_Message();
$message_obj->set_message( 0, $conversation_id, $note_data['title'], $message );
$message_obj->save();
}
$from_email = $global_email_settings['bwfan_email_from'];
$from_name = $global_email_settings['bwfan_email_from_name'];
$reply_to_email = $global_email_settings['bwfan_email_reply_to'];
$headers = array();
$headers[] = 'MIME-Version: 1.0';
if ( ! empty( $from_name ) && ! empty( $from_email ) ) {
$headers[] = 'From: ' . $from_name . ' <' . $from_email . '>';
}
$headers[] = 'Content-type:text/html;charset=UTF-8';
if ( ! empty( $reply_to_email ) ) {
$headers[] = 'Reply-To: ' . $reply_to_email;
}
/** Set unsubscribe link in header */
$unsubscribe_link = BWFAN_Common::get_unsubscribe_link( [ 'uid' => $this->contact->get_uid() ] );
if ( ! empty( $unsubscribe_link ) ) {
$headers[] = "List-Unsubscribe: <$unsubscribe_link>";
$headers[] = "List-Unsubscribe-Post: List-Unsubscribe=One-Click";
}
$email_subject = BWFAN_Core()->conversation->prepare_email_subject( $note_data['title'], array() );
try {
BWFAN_Core()->conversation->engagement_type = BWFAN_Email_Conversations::$TYPE_NOTE;
$email_body = BWFAN_Core()->conversation->prepare_email_body( $conversation['conversation_id'], $note_data['cid'], $conversation['hash_code'], 'rich', $message );
} catch ( Error $e ) {
BWFAN_Core()->conversation->fail_the_conversation( $conversation_id, $e->getMessage() );
return false;
}
$headers = apply_filters( 'bwfan_email_headers', $headers );
/** Removed wp mail filters */
BWFAN_Common::bwf_remove_filter_before_wp_mail();
$send_email = wp_mail( $email, $email_subject, $email_body, $headers );
if ( ! $send_email ) {
BWFAN_Core()->conversation->fail_the_conversation( $conversation_id, __( 'Email not sent', 'wp-marketing-automations' ) );
return false;
}
/** Save the time of last sent engagement **/
$data = array( 'cid' => $this->contact->get_id() );
BWFAN_Conversation::save_last_sent_engagement( $data );
return BWFAN_Core()->conversation->update_conversation_status( $conversation_id, BWFAN_Email_Conversations::$STATUS_SEND );
}
/** getting mail error while sending email
*
* @return array|false
*/
public function maybe_get_failed_mail_error() {
global $phpmailer;
if ( ! class_exists( '\WPMailSMTP\MailCatcher' ) ) {
return false;
}
if ( ! ( $phpmailer instanceof \WPMailSMTP\MailCatcher ) ) {
return false;
}
$debug_log = get_option( 'wp_mail_smtp_debug', false );
if ( empty( $debug_log ) || ! is_array( $debug_log ) ) {
return false;
}
return array( 'message' => $debug_log[0] );
}
public function check_contact_unsubscribed( $single_row = true ) {
$email = $this->contact->get_email();
$contact_no = $this->contact->get_contact_no();
$data = array(
'recipient' => array( $email, $contact_no ),
);
return BWFAN_Model_Message_Unsubscribe::get_message_unsubscribe_row( $data, $single_row );
}
/**
* @return mixed
*/
public function get_last_abandoned() {
$automations_obj = new BWFAN_Abandoned_Cart();
$contact_email = $this->contact->get_email();
return $automations_obj->get_last_abandoned_cart( $contact_email );
}
/**
* @param $offset
* @param $limit
* @param $additional_info
*
* @return array[]
*/
public static function get_recent_contacts( $offset, $limit, $additional_info ) {
$wc_data_send = is_array( $additional_info ) && isset( $additional_info['customer_data'] ) && true === $additional_info['customer_data'];
$contacts = BWFCRM_Model_Contact::get_recent_contacts( $limit, $offset, $wc_data_send );
$total_count = $contacts['total'];
$contacts = $contacts['contacts'];
/** Prepare the output */
$contact_details = array();
foreach ( $contacts as $contact_db ) {
$contact = new BWFCRM_Contact( $contact_db, false );
if ( ! $contact->is_contact_exists() ) {
continue;
}
/** Return data is requested format */
$contact_details[] = $contact->get_array( true, $wc_data_send );
}
$return_data = array(
'contacts' => $contact_details,
);
$return_data['total_count'] = $total_count;
return $return_data;
}
/**
* @param $limit
* @param $offset
* @param $additional_info
*
* @return array[]
*/
public static function get_recent_unsubscribers( $limit, $offset, $additional_info ) {
$wc_data_send = is_array( $additional_info ) && isset( $additional_info['customer_data'] ) && true === $additional_info['customer_data'];
$contacts = BWFCRM_Model_Contact::get_recent_unsubscribers( $limit, $offset, $wc_data_send );
$total_count = $contacts['total'];
$contacts = $contacts['contacts'];
/** Prepare the output */
$contact_details = array();
foreach ( $contacts as $contact_db ) {
$contact = new BWFCRM_Contact( $contact_db, false );
if ( ! $contact->is_contact_exists() ) {
continue;
}
/** Return data is requested format */
$contact_details[] = $contact->get_array( true, $wc_data_send );
}
$return_data = array(
'contacts' => $contact_details,
);
$return_data['total_count'] = $total_count;
return $return_data;
}
/**
* @param $limit
* @param $offset
* @param $additional_info
*
* @return array[]
*/
public static function get_recent_abandoned( $limit, $offset, $additional_info ) {
$wc_data_send = is_array( $additional_info ) && isset( $additional_info['customer_data'] ) && true === $additional_info['customer_data'];
$contacts = BWFCRM_Model_Contact::get_recent_abandoned( $limit, $offset, $wc_data_send );
$total_count = $contacts['total'];
$contacts = $contacts['contacts'];
/** Prepare the output */
$contact_details = array();
foreach ( $contacts as $contact_db ) {
$contact = new BWFCRM_Contact( $contact_db, false );
if ( ! $contact->is_contact_exists() ) {
continue;
}
/** Return data is requested format */
$contact_details[] = $contact->get_array( true, $wc_data_send );
}
$return_data = array(
'contacts' => $contact_details,
);
$return_data['total_count'] = $total_count;
return $return_data;
}
public function save_last_modified() {
BWFCRM_Model_Contact::save_last_modified( $this->get_id() );
}
public function get_field_by_slug( $slug ) {
if ( empty( $this->fields ) || ! is_array( $this->fields ) ) {
return '';
}
$db_row = BWFAN_Model_Fields::get_field_by_slug( $slug );
if ( ! is_array( $db_row ) || ! isset( $db_row['ID'] ) ) {
return '';
}
$meta_id = absint( $db_row['ID'] );
return isset( $this->fields[ $meta_id ] ) ? $this->fields[ $meta_id ] : '';
}
public function set_field_by_slug( $slug, $value ) {
if ( empty( $this->fields ) || ! is_array( $this->fields ) ) {
$this->fields = array();
}
$db_row = BWFAN_Model_Fields::get_field_by_slug( $slug );
if ( ! is_array( $db_row ) || ! isset( $db_row['ID'] ) ) {
return false;
}
$meta_id = absint( $db_row['ID'] );
$this->fields[ $meta_id ] = $value;
return true;
}
public function get_address_1() {
return $this->get_field_by_slug( 'address-1' );
}
public function get_address_2() {
return $this->get_field_by_slug( 'address-2' );
}
public function get_city() {
return $this->get_field_by_slug( 'city' );
}
public function get_postcode() {
return $this->get_field_by_slug( 'postcode' );
}
public function get_company() {
return $this->get_field_by_slug( 'company' );
}
public function get_dob() {
return $this->get_field_by_slug( 'dob' );
}
public function get_gender() {
return $this->get_field_by_slug( 'gender' );
}
public function set_address_1( $value ) {
$this->set_field_by_slug( 'address-1', $value );
}
public function set_address_2( $value ) {
$this->set_field_by_slug( 'address-2', $value );
}
public function set_city( $value ) {
$this->set_field_by_slug( 'city', $value );
}
public function set_postcode( $value ) {
$this->set_field_by_slug( 'postcode', $value );
}
public function set_company( $value ) {
$this->set_field_by_slug( 'company', $value );
}
public function set_gender( $value ) {
$this->set_field_by_slug( 'gender', $value );
}
public function set_dob( $value ) {
$this->set_field_by_slug( 'dob', $value );
}
public function get_display_status() {
if ( ! $this->is_contact_exists() ) {
return BWFAN_Common::crm_error( __( 'Contact not valid', 'wp-marketing-automations' ) );
}
$status = absint( $this->contact->get_status() );
$is_unsubscribed = $this->check_contact_unsubscribed();
$this->unsubscribe_date = ! empty( $is_unsubscribed['c_date'] ) ? $is_unsubscribed['c_date'] : '';
$is_unsubscribed = is_array( $is_unsubscribed ) && count( $is_unsubscribed ) > 0;
if ( $is_unsubscribed ) {
return self::$DISPLAY_STATUS_UNSUBSCRIBED;
}
if ( self::$STATUS_BOUNCED === $status ) {
return self::$DISPLAY_STATUS_BOUNCED;
}
if ( self::$STATUS_SOFT_BOUNCED === $status ) {
return self::$DISPLAY_STATUS_SOFT_BOUNCED;
}
if ( self::$STATUS_COMPLAINT === $status ) {
return self::$DISPLAY_STATUS_COMPLAINT;
}
if ( self::$STATUS_NOT_OPTED_IN === $status ) {
return self::$DISPLAY_STATUS_UNVERIFIED;
}
return self::$DISPLAY_STATUS_SUBSCRIBED;
}
public function resubscribe( $stop_hooks = false ) {
if ( ! $this->is_contact_exists() ) {
return false;
}
$to_be_deleted = array( $this->contact->get_email() );
if ( ! empty( $this->contact->get_contact_no() ) ) {
$to_be_deleted[] = $this->contact->get_contact_no();
}
$is_unverified = 0 === absint( $this->contact->get_status() );
$is_unsubscribed = ! empty( $this->check_contact_unsubscribed() );
$is_not_subscribed = $is_unverified || $is_unsubscribed;
$verified = $this->verify();
$deleted = BWFAN_Model_Message_Unsubscribe::delete_unsubscribers( $to_be_deleted );
$return = $deleted && $verified;
if ( $is_not_subscribed && ! $stop_hooks ) {
do_action( 'bwfcrm_after_contact_subscribed', $this->contact );
}
$this->remove_soft_bounce_limit();
return $return;
}
public function unsubscribe( $stop_hooks = false ) {
if ( ! $this->is_contact_exists() ) {
return false;
}
$this->remove_soft_bounce_limit();
if ( ! empty( $this->check_contact_unsubscribed() ) ) {
return true;
}
$to_be_added = array( $this->contact->get_email() );
if ( ! empty( $this->contact->get_contact_no() ) ) {
$to_be_added[] = $this->contact->get_contact_no();
}
return BWFAN_Model_Message_Unsubscribe::add_unsubscribers( $to_be_added, 0, 0, $stop_hooks );
}
public function remove_unsubscribe_status() {
if ( ! $this->is_contact_exists() ) {
return false;
}
/** If there are not any entries in Unsubscribe Table, return */
if ( empty( $this->check_contact_unsubscribed() ) ) {
return true;
}
/** Simply delete the entries */
$to_be_deleted = array( $this->contact->get_email() );
if ( ! empty( $this->contact->get_contact_no() ) ) {
$to_be_deleted[] = $this->contact->get_contact_no();
}
BWFAN_Model_Message_Unsubscribe::delete_unsubscribers( $to_be_deleted );
$this->was_unsubscribed = true;
return true;
}
public function verify() {
if ( ! $this->is_contact_exists() ) {
return false;
}
$this->contact->set_last_modified( current_time( 'mysql', 1 ) );
$this->contact->set_status( 1 );
$this->save();
return true;
}
public function unverify() {
if ( ! $this->is_contact_exists() ) {
return false;
}
/** Remove data from unsubscribe table */
$this->remove_unsubscribe_status();
$this->contact->set_status( 0 );
$this->contact->set_last_modified( current_time( 'mysql', 1 ) );
$this->save();
return true;
}
/**
* Returns contacts fields
*
* @param array $fields
*
* @return array
*/
public function get_contact_info_by_fields( $fields = array() ) {
$data = array();
if ( empty( $fields ) ) {
return array();
}
$arr1 = array(
'f_name',
'l_name',
'email',
'contact_no',
'country',
'state',
'creation_date',
);
$arr2 = array(
'tags',
'lists',
);
$arr3 = array(
'last-open',
'last-click',
'last-login',
'company',
'gender',
'dob',
'address-1',
'address-2',
'city',
'postcode',
);
$arr4 = array(
'total_order_count',
'total_order_value',
'f_order_date',
'l_order_date',
'purchased_products',
'purchased_products_cats',
'purchased_products_tags',
'used_coupons',
);
$arr5 = array(
'has_purchased',
'has_used_any_coupons',
'l_order_days',
'f_order_days',
'creation_days',
'aov'
);
$customer_data = $this->get_customer_as_array( false );
foreach ( $fields as $ed ) {
$fieldVal = '';
if ( in_array( $ed, $arr1 ) ) {
$field = 'get_' . $ed;
$fieldVal = $this->contact->$field();
} elseif ( in_array( $ed, $arr2 ) ) {
$field = 'get_all_' . $ed;
$fieldVal = $this->$field();
if ( is_array( $fieldVal ) ) {
$value = array();
foreach ( $fieldVal as $val ) {
$value[] = $val['name'];
}
$fieldVal = implode( ',', $value );
}
} elseif ( in_array( $ed, $arr3 ) ) {
$fieldVal = $this->get_field_by_slug( $ed );
} elseif ( strpos( $ed, 'bwf_cf' ) !== false ) {
$fieldId = str_replace( 'bwf_cf', '', $ed );
$fieldVal = isset( $this->fields[ $fieldId ] ) ? $this->fields[ $fieldId ] : '';
} elseif ( in_array( $ed, $arr4 ) && $this->customer ) {
$fieldVal = isset( $customer_data[ $ed ] ) ? $customer_data[ $ed ] : '';
if ( is_array( $fieldVal ) ) {
$value = array();
foreach ( $fieldVal as $val ) {
if ( isset( $val['name'] ) ) {
$value[] = $val['name'];
} else {
$value[] = $val;
}
}
$fieldVal = implode( ',', $value );
}
} elseif ( in_array( $ed, $arr5 ) ) {
switch ( $ed ) {
case 'has_purchased':
$fieldVal = intval( $customer_data['total_order_count'] ) > 0;
break;
case 'has_used_any_coupons':
$fieldVal = count( $customer_data['used_coupons'] ) > 0;
break;
case 'l_order_days':
$fieldVal = 0;
if ( isset( $customer_data['l_order_date'] ) ) {
$fieldVal = self::get_creation_days( self::get_date_value( $customer_data['l_order_date'], 'Y-m-d H:i:s' ) );
}
break;
case 'f_order_days':
$fieldVal = 0;
if ( isset( $customer_data['f_order_date'] ) ) {
$fieldVal = self::get_creation_days( self::get_date_value( $customer_data['f_order_date'], 'Y-m-d H:i:s' ) );
}
break;
case 'creation_days':
$fieldVal = self::get_creation_days( self::get_date_value( $this->contact->get_creation_date(), 'Y-m-d H:i:s' ) );
break;
case 'aov' :
$fieldVal = wc_format_decimal( $customer_data['aov'], wc_get_price_decimals() );
}
} elseif ( 'status' === $ed ) {
$fieldVal = $this->get_marketing_status();
}
$data[] = apply_filters( 'bwfan_get_contact_field_by_slug', $fieldVal, $ed, $this );
}
return $data;
}
/**
* Get days difference in two dates
*/
public static function get_creation_days( $start ) {
if ( ! strtotime( $start ) || strtotime( $start ) < 0 ) {
return 0;
}
$start = strtotime( $start );
$end = current_time( 'timestamp', 1 );
return floor( abs( $end - $start ) / 86400 );
}
public function save() {
if ( ! $this->contact instanceof WooFunnels_Contact ) {
return false;
}
$this->contact->set_last_modified( current_time( 'mysql', 1 ) );
$this->contact->save();
/** Fire Tags added */
if ( ! empty( $this->assigned_tags ) ) {
$assigned_tags = $this->assigned_tags;
$this->assigned_tags = array();
do_action( 'bwfan_tags_added_to_contact', $assigned_tags, $this );
}
/** Fire Tags removed */
if ( ! empty( $this->removed_tags ) ) {
$removed_tags = $this->removed_tags;
$this->removed_tags = array();
do_action( 'bwfan_tags_removed_from_contact', $removed_tags, $this );
}
/** Fire Lists added */
if ( ! empty( $this->assigned_lists ) ) {
$assigned_lists = $this->assigned_lists;
$this->assigned_lists = array();
do_action( 'bwfan_contact_added_to_lists', $assigned_lists, $this );
}
/** Fire Lists removed */
if ( ! empty( $this->removed_lists ) ) {
$removed_lists = $this->removed_lists;
$this->removed_lists = array();
do_action( 'bwfan_contact_removed_from_lists', $removed_lists, $this );
}
return true;
}
/**
* Get Contacts by Audience id or name
* Check if contact is in or not in audience
*
* @param $audience
* @param string $search
* @param int $contact_id
*
* @return array|array[]|string
*/
public static function get_contacts_by_audience( $audience, $search = '', $contact_id = 0 ) {
if ( empty( $audience ) ) {
return [];
}
if ( is_numeric( $audience ) ) {
/** Get audience by id */
$audience = new BWFCRM_Audience( absint( $audience ) );
$audience_data = ! empty( $audience ) ? $audience->get_array() : [];
} else {
/** Get audience by name */
$audience_data = BWFAN_Model_Terms::get_term_by_name( $audience, 3 );
}
/** Return if no audience data found */
if ( empty( $audience_data ) || ! isset( $audience_data['data'] ) ) {
return [];
}
$data = json_decode( $audience_data['data'], true );
/** Return if no filters found in audience */
if ( empty( $data ) || ! isset( $data['filters'] ) ) {
return [];
}
$filters = $data['filters'];
if ( ! empty( $contact_id ) ) {
$filters['contact_id_is'] = absint( $contact_id );
}
return self::get_contacts( $search, 0, 1, $filters );
}
/**
* Mark contact unverified
*
* @return bool
*/
public function mark_as_unverified() {
if ( ! $this->is_contact_exists() ) {
return false;
}
/** Remove data from unsubscribe table */
$this->remove_unsubscribe_data();
$this->contact->set_status( self::$STATUS_NOT_OPTED_IN );
$this->contact->set_last_modified( current_time( 'mysql', 1 ) );
$this->save();
$this->remove_soft_bounce_limit();
return true;
}
/**
* Mark contact bounced
*
* @param $stop_hooks
*
* @return bool
*/
public function mark_as_bounced( $stop_hooks = false ) {
if ( ! $this->is_contact_exists() ) {
return false;
}
/** Check if already bounced */
$is_already_bounced = null;
if ( false === $stop_hooks ) {
$is_already_bounced = self::$STATUS_BOUNCED === absint( $this->contact->get_status() );
}
/** Remove data from unsubscribe table */
$this->remove_unsubscribe_data();
/** save last status in contact meta */
$this->save_last_status();
$this->contact->set_status( self::$STATUS_BOUNCED );
$this->contact->set_last_modified( current_time( 'mysql', 1 ) );
$this->save();
$this->contact->save_meta();
$this->remove_soft_bounce_limit();
/** Run action if contact earlier has a different status */
if ( false === $is_already_bounced && ! $stop_hooks ) {
do_action( 'bwfcrm_after_contact_bounced', $this->contact );
}
return true;
}
/**
* Mark contact soft bounced
*
* @param $stop_hooks
*
* @return array|bool
*/
public function mark_as_soft_bounced( $stop_hooks = false ) {
if ( ! $this->is_contact_exists() ) {
return false;
}
$soft_bounce_limit = apply_filters( 'bwfan_contact_soft_bounce_limit', 3 );
$soft_bounce_limit = empty( $soft_bounce_limit ) ? 1 : intval( $soft_bounce_limit );
$soft_bounce_count = $this->contact->get_meta( 'soft_bounce_count' );
$soft_bounce_count = empty( $soft_bounce_count ) ? 0 : intval( $soft_bounce_count );
if ( $soft_bounce_count >= $soft_bounce_limit ) {
/** Soft bounce limit reached, mark contact bounced */
/** Remove data from unsubscribe table */
$this->remove_unsubscribe_data();
$this->save_last_status();
$this->contact->set_status( self::$STATUS_BOUNCED );
$this->contact->set_last_modified( current_time( 'mysql', 1 ) );
$this->save();
/** Run action if contact has a different status */
if ( ! $stop_hooks ) {
do_action( 'bwfcrm_after_contact_bounced', $this->contact );
}
$count = ( $soft_bounce_count > 1 ) ? "($soft_bounce_count times)" : 'once';
$soft_bounce_count ++;
$this->contact->set_meta( 'soft_bounce_count', $soft_bounce_count );
$this->contact->save_meta();
return [
'message' => __( "Status change to bounce as contact already soft bounce", "wp-marketing-automations" ) . " $count",
];
}
/** Remove data from unsubscribe table */
$this->remove_unsubscribe_data();
/** Mark contact soft bounced */
$soft_bounce_count ++;
$this->contact->set_meta( 'soft_bounce_count', $soft_bounce_count );
/** save last status in contact meta */
$this->save_last_status();
$this->contact->set_status( self::$STATUS_SOFT_BOUNCED );
$this->contact->set_last_modified( current_time( 'mysql', 1 ) );
$this->save();
$this->contact->save_meta();
/** Check if contact is already bounced */
if ( ! $stop_hooks ) {
do_action( 'bwfcrm_after_contact_soft_bounced', $this->contact, $soft_bounce_count );
}
return true;
}
/**
* Mark contact complaint
*
* @param $stop_hooks
*
* @return bool
*/
public function mark_as_complaint( $stop_hooks = false ) {
if ( ! $this->is_contact_exists() ) {
return false;
}
/** Check if already bounced */
$is_already_complaint = null;
if ( false === $stop_hooks ) {
$is_already_complaint = self::$STATUS_COMPLAINT === absint( $this->contact->get_status() );
}
/** Remove data from unsubscribe table */
$this->remove_unsubscribe_data();
$this->contact->set_status( self::$STATUS_COMPLAINT );
$this->contact->set_last_modified( current_time( 'mysql', 1 ) );
$this->save();
$this->remove_soft_bounce_limit();
/** Run action if contact earlier has a different status */
if ( false === $is_already_complaint && ! $stop_hooks ) {
do_action( 'bwfcrm_after_contact_complaint', $this->contact );
}
return true;
}
/**
* Remove soft bounce limit meta
*
* @return void
*/
public function remove_soft_bounce_limit() {
$this->contact->delete_meta( 'soft_bounce_count' );
/** unset value */
$this->contact->unset_meta( 'soft_bounce_count' );
}
/**
* Remove contact entry from unsubscribe table
* Email and Phone no both.
*
* @return bool
*/
public function remove_unsubscribe_data() {
$is_unsubscribed = ! empty( $this->check_contact_unsubscribed() );
if ( empty( $is_unsubscribed ) ) {
return false;
}
$to_be_deleted = [];
if ( ! empty( $this->contact->get_email() ) ) {
$to_be_deleted[] = $this->contact->get_email();
}
if ( ! empty( $this->contact->get_contact_no() ) ) {
$to_be_deleted[] = $this->contact->get_contact_no();
}
return BWFAN_Model_Message_Unsubscribe::delete_unsubscribers( $to_be_deleted );
}
/**
* Get contact status to display in the front-end
*
* @return string
*/
public function get_marketing_status() {
$status = '';
switch ( $this->get_display_status() ) {
case BWFCRM_Contact::$DISPLAY_STATUS_UNSUBSCRIBED:
$status = __( 'Unsubscribed', 'wp-marketing-automations' );
break;
case BWFCRM_Contact::$DISPLAY_STATUS_SUBSCRIBED:
$status = __( 'Subscribed', 'wp-marketing-automations' );
break;
case BWFCRM_Contact::$DISPLAY_STATUS_UNVERIFIED:
$status = __( 'Unverified', 'wp-marketing-automations' );
break;
case BWFCRM_Contact::$DISPLAY_STATUS_BOUNCED:
$status = __( 'Bounced', 'wp-marketing-automations' );
break;
case BWFCRM_Contact::$DISPLAY_STATUS_SOFT_BOUNCED:
$status = __( 'Soft Bounced', 'wp-marketing-automations' );
break;
case BWFCRM_Contact::$DISPLAY_STATUS_COMPLAINT:
$status = __( 'Complaint', 'wp-marketing-automations' );
break;
}
return $status;
}
/**
* Update status
*
* @param $status
*
* @return bool
*/
public function update_status( $status ) {
$res = false;
switch ( $status ) {
case 0:
$res = $this->mark_as_unverified();
break;
case 1:
$res = $this->resubscribe();
break;
case 2:
$res = $this->mark_as_bounced();
break;
case 3:
$res = $this->unsubscribe();
break;
case 4:
$res = $this->mark_as_soft_bounced();
break;
case 5:
$res = $this->mark_as_complaint();
break;
}
return $res;
}
/**
* Save last status meta for a contact when status is changed to soft bounced or bounced
*
* @return void
*/
public function save_last_status() {
if ( self::$DISPLAY_STATUS_SOFT_BOUNCED === $this->get_display_status() ) {
return;
}
$this->contact->set_meta( 'last_status', [ 'status' => $this->get_display_status(), 'time' => current_time( 'mysql', 1 ) ] );
}
}
}