- 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>
2935 lines
92 KiB
PHP
Executable File
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 ) ] );
|
|
}
|
|
}
|
|
}
|