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

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

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

682 lines
18 KiB
PHP
Executable File

<?php
/**
* BWFCRM_Actions_Handler
*/
#[AllowDynamicProperties]
class BWFCRM_Link_Trigger_Handler {
/**
* Class instance
*/
private static $ins = null;
protected $contact_obj;
protected $link_id = 0;
/**
* Class constructor
*/
public function __construct() {
$this->contact_obj = new stdClass();
/** Action to handle link trigger click */
add_action( 'wp_loaded', array( $this, 'handle_link_trigger_click' ), 101 );
/** Check for link trigger URL */
add_filter( 'bwfan_is_link_trigger_url', array( $this, 'is_link_trigger_url' ), 10, 2 );
/** Handle schedule action */
add_action( 'bwfcrm_run_link_trigger_async', array( $this, 'link_trigger_async_cb' ), 10, 2 );
/** Returns contacts link trigger data */
add_action( 'bwfan_get_contact_field_by_slug', array( $this, 'link_trigger_contact_data' ), 10, 3 );
}
/**
* Returns class instance
*
* @return BWFCRM_Link_Trigger_Handler|null
*/
public static function get_instance() {
if ( null === self::$ins ) {
self::$ins = new self();
}
return self::$ins;
}
/**
* Handling link trigger click
*/
public function handle_link_trigger_click() {
/** If link trigger is not set, return */
if ( ! isset( $_GET['bwfan-link-trigger'] ) || empty( $_GET['bwfan-link-trigger'] ) ) {
return;
}
/** Link data */
$link_hash = filter_input( INPUT_GET, 'bwfan-link-trigger' );
$link_data = BWFAN_Model_Link_Triggers::bwfan_get_link_trigger( 0, $link_hash );
$target_url = isset( $link_data['data']['redirect_url'] ) ? $link_data['data']['redirect_url'] : '';
/** Record engagement tracking */
$this->trigger_engagement_click( $target_url );
/** Link Trigger is inactive or no target URL defined */
if ( ! isset( $link_data['status'] ) || $link_data['status'] != 2 || empty( $target_url ) ) {
return;
}
/** @var WooFunnels_Contact $db_contact */
$db_contact = $this->get_contact_obj();
/** Set object cache */
if ( $db_contact instanceof WooFunnels_Contact ) {
$this->contact_obj = $db_contact;
}
/** Primary key */
$link_id = isset( $link_data['ID'] ) ? $link_data['ID'] : 0;
$run_async = apply_filters( 'bwfan_link_trigger_async', true, $link_id, $link_data );
/** Check for sync option */
if ( true === $run_async ) {
/** Schedule link trigger action */
$this->schedule_link_trigger_async( $link_id );
} else {
/** Direct process link trigger */
$this->link_trigger_processing( $link_id, $link_data, $db_contact );
}
/** Update click count */
$this->update_link_clicks( $link_id, $link_data );
/** If URL contains merge tag */
if ( true === $this->url_contains_merge_tag( $target_url ) ) {
/** Get the Contact object from object cache */
$db_contact = $this->contact_obj;
if ( ! $db_contact instanceof WooFunnels_Contact ) {
$db_contact = $this->get_contact_obj();
/** Set object cache */
if ( $db_contact instanceof WooFunnels_Contact ) {
$this->contact_obj = $db_contact;
}
}
if ( $db_contact instanceof WooFunnels_Contact && $db_contact->get_id() > 0 ) {
/** Set contact Id for merge tag */
BWFAN_Merge_Tag_Loader::set_data( array(
'contact_id' => $db_contact->get_id(),
'contact_mode' => 1
) );
/** Decode target URL merge tags */
$target_url = BWFAN_Common::decode_merge_tags( $target_url );
}
}
/** Link trigger might have auto login enabled */
$this->maybe_login( $link_data );
do_action( 'bwfan_before_redirect_link_trigger', $link_data );
/** Redirect to target url */
BWFAN_PRO_Common::wp_redirect( $this->may_append_query_arg( $target_url ) );
exit;
}
/**
* Record engagement conversation click
*
* @param $target_url
*/
protected function trigger_engagement_click( $target_url ) {
$track_id = filter_input( INPUT_GET, 'bwfan-track-id' );
if ( empty( $track_id ) ) {
return;
}
$engagement_ins = BWFAN_Email_Conversations::get_instance();
$engagement_ins->track_click_skip( $target_url );
}
/**
* Schedule link trigger action
*
* @param $link_id
*/
protected function schedule_link_trigger_async( $link_id ) {
$contact_data = $this->get_contact_id();
if ( empty( $contact_data ) ) {
return;
}
$args = array(
'contact' => $contact_data,
'link_id' => $link_id,
);
/** Schedule if not scheduled */
if ( ! bwf_has_action_scheduled( 'bwfcrm_run_link_trigger_async', $args, 'autonami-link-trigger' ) ) {
bwf_schedule_single_action( time(), 'bwfcrm_run_link_trigger_async', $args, 'autonami-link-trigger' );
}
}
/**
* Callback of async event
*/
public function link_trigger_async_cb( $contact_data, $link_id ) {
/** CRM contact object */
$contact = $this->get_contact_obj( $contact_data );
/** Get link data */
$link_data = BWFAN_Model_Link_Triggers::bwfan_get_link_trigger( $link_id );
/** Process link trigger */
$this->link_trigger_processing( $link_id, $link_data, $contact );
}
/**
* Perform link trigger actions
*
* @param $link_id
* @param $link_data
* @param $db_contact
*/
protected function link_trigger_processing( $link_id, $link_data, $db_contact ) {
/** Actions to run */
$actions = ( isset( $link_data['data']['actions'] ) && count( $link_data['data']['actions'] ) > 0 ) ? $link_data['data']['actions'] : array();
/** No contact found, just redirect. */
if ( ! $db_contact instanceof WooFunnels_Contact || 0 === $db_contact->get_id() ) {
return;
}
/** CRM contact object */
$contact = new BWFCRM_Contact( $db_contact );
/** Set cookie */
$uid = $db_contact->get_uid();
if ( ! empty( $uid ) ) {
BWFAN_Common::set_cookie( '_fk_contact_uid', $uid, time() + 10 * 365 * 24 * 60 * 60 );
}
/** Trigger hook - link trigger clicked */
do_action( 'bwfan_link_triggered', $link_id, $contact );
/** Get contact link triggered array */
$contact_link_clicked = $contact->get_field_by_slug( 'link-trigger-click' );
$contact_clicked_ids = json_decode( $contact_link_clicked, true );
$contact_clicked_ids = ( ! empty( $contact_clicked_ids ) && is_array( $contact_clicked_ids ) ) ? $contact_clicked_ids : array();
if ( empty( $actions ) ) {
/** Update Contact link click */
$this->update_contact_link_click( $contact, $link_id, $contact_clicked_ids );
return;
}
/** Check Action runs times */
$actions_run_time = isset( $link_data['data']['action_run'] ) ? $link_data['data']['action_run'] : 'once';
/** Filter to run link trigger action multiple times ( by default false ) */
if ( apply_filters( 'bwfan_link_trigger_multi_execution', false ) ) {
$actions_run_time = 'multiple';
}
/** Clicked multiple times, just redirect */
if ( $actions_run_time == 'once' && in_array( $link_id, $contact_clicked_ids ) ) {
return;
}
$this->link_id = $link_id;
/** Run actions */
$logs = $this->process_actions( $actions, $contact );
/** Maybe create logs contact note */
$this->create_contact_logs_note( $logs, $contact, $link_data );
/** Update Contact link click */
$this->update_contact_link_click( $contact, $link_id, $contact_clicked_ids );
}
/**
* Updated link trigger field for contact
*
* @param array $logs
* @param \BWFCRM_Contact $contact
* @param array $link_data
*/
protected function create_contact_logs_note( $logs, $contact, $link_data ) {
if ( ! isset( $link_data['data']['add_contact_note'] ) || 1 !== absint( $link_data['data']['add_contact_note'] ) || empty( $logs ) ) {
return;
}
$title = 'Link Trigger "' . $link_data['title'] . '" logs';
$body = is_array( $logs ) ? implode( ' | ', $logs ) : $logs;
new BWFCRM_Note( 0, true, array(
'cid' => $contact->get_id(),
'title' => $title,
'body' => $body,
'type' => 'log',
) );
}
/**
* Updated link trigger field for contact
*
* @param $contact
* @param $link_id
* @param array $contact_clicked_ids
*/
protected function update_contact_link_click( $contact, $link_id, $contact_clicked_ids = array() ) {
/** Check if link trigger id already exists */
if ( ! in_array( $link_id, $contact_clicked_ids ) ) {
$contact_clicked_ids[] = $link_id;
$contact_clicked_ids = wp_json_encode( array_unique( $contact_clicked_ids ) );
/** Set updated link-trigger-click value */
$contact->set_field_by_slug( 'link-trigger-click', $contact_clicked_ids );
$contact->save_fields();
}
}
/**
* Get contact Id
*
* @return array|false
*/
protected function get_contact_id() {
/** check if URL contains contacts uid */
$uid = filter_input( INPUT_GET, 'bwfan-uid' );
if ( ! empty( $uid ) ) {
return array( 'uid' => $uid );
}
/** Check for logged-in user */
$user = wp_get_current_user();
if ( $user instanceof WP_User ) {
return array( 'wpid' => $user->ID );
}
return false;
}
/**
* Get contact obj
*
* @return stdClass|WooFunnels_Contact
*/
protected function get_contact_obj( $data = false ) {
/** Ready contact data */
if ( empty( $data ) ) {
$data = $this->get_contact_id();
}
/** Returns if data is empty */
if ( false === $data ) {
return new stdClass();
}
/** Initialize CRM Object */
$bwf_contacts = BWF_Contacts::get_instance();
/** Get CRM contact object by CRM uid */
if ( isset( $data['uid'] ) ) {
return $bwf_contacts->get_contact_by( 'uid', $data['uid'] );
}
/** Get CRM contact object by WordPress user id */
if ( isset( $data['wpid'] ) ) {
return $bwf_contacts->get_contact_by( 'wpid', $data['wpid'] );
}
return new stdClass();
}
/**
* Process actions
*
* @param $actions
* @param $contact_crm
*
* @return array|void
*/
protected function process_actions( $actions, $contact_crm ) {
$logs = array();
/** Check for empty action */
if ( empty( $actions ) ) {
return;
}
/** Iterate over action */
foreach ( $actions as $action => $data ) {
$data = empty( $data ) ? [] : $data;
/** Initialize Action Object */
$action_obj = BWFCRM_Core()->actions->get_action_by_slug( $action );
if ( ! $action_obj instanceof \BWFCRM\Actions\Base ) {
continue;
}
if ( 'end_automation' === $action ) {
$data['from'] = 'Link Trigger';
$data['link_id'] = $this->link_id;
}
if ( count( $data ) > 0 ) {
/** Keys has extra spacings, removing that */
$data = array_combine( array_map( 'trim', array_keys( $data ) ), $data );
/** In case of status field, set the status id */
if ( isset( $data['status'] ) ) {
$status_key = $this->get_status_key( trim( $data['status'] ) );
$data['status'] = $status_key;
}
}
/** Call to action handler function */
$result = $action_obj->handle_action( $contact_crm, $data );
/** Collect Logs from actions */
if ( is_array( $result ) && ! empty( $result['message'] ) ) {
$message = is_array( $result['message'] ) ? $result['message'] : ( empty( $result['message'] ) ? array() : array( $result['message'] ) );
$logs = array_values( array_merge( $logs, $message ) );
}
}
return $logs;
}
/**
* Get status id by label
*
* @param $label
*
* @return int|string
*/
protected function get_status_key( $label ) {
$arr = array(
'0' => 'Unverified',
'1' => 'Subscribed',
'3' => 'Unsubscribed',
'2' => 'Bounced',
'4' => 'Soft Bounced',
'5' => 'Complaint',
);
if ( method_exists( 'BWFAN_Common', 'get_contact_status_array_list' ) ) {
$status = BWFAN_Common::get_contact_status_array_list();
$arr = [];
foreach ( $status as $value ) {
$arr[ $value['id'] ] = $value['name'];
}
}
$data = array_search( $label, $arr );
return ( false === $data ) ? '0' : $data;
}
/**
* Update link clicks count
*
* @param $link_id
* @param $link_data
*/
protected function update_link_clicks( $link_id, $link_data ) {
/** Update click count */
$clicked = isset( $link_data['total_clicked'] ) ? absint( $link_data['total_clicked'] ) : 0;
$clicked ++;
/** Link trigger data */
$values = array(
'total_clicked' => $clicked,
'updated_at' => current_time( 'mysql', 1 ),
);
/** Set condition */
$where = array(
'ID' => $link_id,
);
/** Update Link Trigger DB data */
BWFAN_Model_Link_Triggers::update( $values, $where );
}
protected function maybe_login( $link_data ) {
$key = 'enable_auto_login';
/** If auto login disabled */
if ( ! isset( $link_data['data'][ $key ] ) || 1 !== absint( $link_data['data'][ $key ] ) ) {
return;
}
/** Get contact object */
$db_contact = $this->contact_obj;
if ( ! $db_contact instanceof WooFunnels_Contact ) {
$db_contact = $this->get_contact_obj();
}
/** No contact found */
if ( ! $db_contact instanceof WooFunnels_Contact || 0 === $db_contact->get_id() ) {
return;
}
/** Is contact associated with WP User */
$wp_id = $db_contact->get_wpid();
if ( 0 === absint( $wp_id ) ) {
return;
}
$user = get_user_by( 'ID', $wp_id );
/** WP User not present */
if ( ! $user instanceof WP_User ) {
return;
}
/** If user role is admin or editor then return */
$roles = apply_filters( 'bwfan_disabled_autologin_roles', array( 'administrator', 'editor' ) );
if ( array_intersect( $roles, (array) $user->roles ) ) {
return;
}
/** Check if expiry time reached */
$crm_contact = new BWFCRM_Contact( $db_contact );
$auth_hash = filter_input( INPUT_GET, 'bwfan-auth' );
if ( ! $this->verify_auth_hash( $crm_contact, $link_data, $auth_hash ) ) {
return;
}
/** Auto login user */
wp_set_current_user( $user->ID, $user->user_login );
/** if WooCommerce is active */
if ( function_exists( 'bwfan_is_woocommerce_active' ) && bwfan_is_woocommerce_active() ) {
wc_set_customer_auth_cookie( $user->ID );
} else {
wp_set_auth_cookie( $user->ID );
}
/** Add Hook */
do_action( 'wp_login', $user->user_login, $user );
}
/**
* Check if URL contains link trigger string
*
* @param $status
* @param $url
*
* @return bool|mixed
*/
public function is_link_trigger_url( $status, $url ) {
if ( empty( $url ) ) {
return $status;
}
return ( false !== strpos( $url, 'bwfan-link-trigger' ) );
}
/**
* Check if URL contains merge tag
*
* @param $url
*
* @return bool
*/
public function url_contains_merge_tag( $url ) {
return ( false !== strpos( $url, '{{' ) );
}
/**
* Appends the additional parameters to redirect link
*
* @param $url
*
* @return mixed|string
*/
public function may_append_query_arg( $url ) {
$url = apply_filters( 'bwfan_modify_link_trigger_target_url', $url, $this->contact_obj );
$args = filter_input_array( INPUT_GET );
$filter_arr = [];
foreach ( $args as $key => $arg ) {
if ( 'l_hash' === $key ) {
continue;
}
if ( strpos( $key, 'bwfan-' ) === false ) {
$val = str_replace( '%20', '+', $arg );
$val = str_replace( ' ', '+', $val );
$filter_arr[ $key ] = $val;
}
}
if ( empty( $filter_arr ) ) {
return $url;
}
return add_query_arg( $filter_arr, $url );
}
/**
* @param BWFCRM_Contact $contact
* @param string $url
*
* @return false|string
*/
public function get_auth_hash( $contact, $url ) {
$parsed_url = parse_url( $url );
parse_str( $parsed_url['query'], $query );
$link_hash = $query['bwfan-link-trigger'];
if ( ! $contact instanceof BWFCRM_Contact || ! $contact->is_contact_exists() || empty( $link_hash ) ) {
return false;
}
/** Get Link and Auto Login Data */
$link = BWFAN_Model_Link_Triggers::bwfan_get_link_trigger( 0, $link_hash );
if ( ! isset( $link['data']['enable_auto_login'] ) || empty( $link['data']['enable_auto_login'] ) || ! isset( $link['data']['auto_login'] ) ) {
return false;
}
$auto_login = $link['data']['auto_login'];
if ( empty( $auto_login ) || empty( $auto_login['text'] ) || empty( $auto_login['unit'] ) ) {
return false;
}
/** Get New Expiry time based on the link data */
$current_time = new DateTime( 'now' );
$expiry_time = ( $current_time )->modify( '+' . $auto_login['text'] . ' ' . $auto_login['unit'] );
$expiry_time = $expiry_time->getTimestamp();
/** Populate Auth Field, if empty */
$auth = $contact->get_field_by_slug( 'auth' );
if ( ! empty( $auth ) ) {
$auth = json_decode( $auth, true );
}
/** Populate auth hash if empty */
$current_time = $current_time->getTimestamp();
$auth_hash = '';
if ( ! is_array( $auth ) || 0 === count( $auth ) ) {
$contact_id = $contact->get_id();
$auth_hash = md5( $contact_id . $current_time );
$auth = array( $auth_hash => '' );
} else {
$auth_hash = array_keys( $auth )[0];
}
/** Populate Expiry if empty or Old Expiry is less than New Expiry */
$old_expiry_time = array_values( $auth )[0];
if ( empty( $old_expiry_time ) || absint( $old_expiry_time ) < $expiry_time ) {
$auth[ $auth_hash ] = $expiry_time;
$contact->set_field_by_slug( 'auth', wp_json_encode( $auth ) );
$contact->save_fields();
}
return $auth_hash;
}
public function verify_auth_hash( $contact, $link_data, $auth_hash ) {
if ( ! $contact instanceof BWFCRM_Contact || ! $contact->is_contact_exists() || empty( $link_data ) || empty( $auth_hash ) ) {
return false;
}
/** Check if auto login enabled */
if ( 0 === absint( $link_data['data']['enable_auto_login'] ) ) {
return false;
}
/** Get Auth from Contact Field, Check if it is valid */
$auth = $contact->get_field_by_slug( 'auth' );
$auth = ! empty( $auth ) ? json_decode( $auth, true ) : $auth;
if ( ! is_array( $auth ) || 0 === count( $auth ) ) {
return false;
}
/** Verify contact auth against auth hash */
return ( isset( $auth[ $auth_hash ] ) && ( absint( $auth[ $auth_hash ] ) > time() ) );
}
/**
* Return contact link trigger field data
*
* @param $val
* @param $field
* @param $contact
*
* @return mixed
*/
public function link_trigger_contact_data( $val, $field, $contact ) {
if ( $field === 'links' ) {
$val = $contact->get_field_by_slug( 'link-trigger-click' );
if ( ! empty( $val ) ) {
$link_triggers = BWFAN_Model_Link_Triggers::get_link_triggers( '', '', 0, 0, false, json_decode( $val, true ) );
$links = [];
if ( isset( $link_triggers['links'] ) && ! empty( $link_triggers['links'] ) ) {
foreach ( $link_triggers['links'] as $link ) {
if ( isset( $link['title'] ) ) {
$links[] = $link['title'];
}
}
$val = implode( ', ', $links );
}
}
}
return $val;
}
}
/**
* Register action handler to BWFCRM_Core
*/
if ( class_exists( 'BWFCRM_Link_Trigger_Handler' ) ) {
BWFCRM_Core::register( 'link_trigger_handler', 'BWFCRM_Link_Trigger_Handler' );
}