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>
This commit is contained in:
root
2025-11-03 21:04:30 -06:00
commit a22573bf0b
24068 changed files with 4993111 additions and 0 deletions

View File

@@ -0,0 +1,39 @@
<?php
final class BWFAN_CF7_Source extends BWFAN_Source {
private static $instance = null;
/**
* Constructor
*
* @access public
*/
protected function __construct() {
$this->event_dir = __DIR__;
$this->nice_name = __( 'Contact Form 7', 'wp-marketing-automations' );
$this->group_name = __( 'Forms', 'wp-marketing-automations' );
$this->group_slug = 'forms';
$this->priority = 110;
}
/**
* Ensures only one instance of the class is loaded or can be loaded.
*
* @return BWFAN_CF7_Source|null
*/
public static function get_instance() {
if ( null === self::$instance ) {
self::$instance = new self();
}
return self::$instance;
}
}
/**
* Register this as a source.
*/
if ( bwfan_is_cf7_active() ) {
BWFAN_Load_Sources::register( 'BWFAN_CF7_Source' );
}

View File

@@ -0,0 +1,678 @@
<?php
#[AllowDynamicProperties]
final class BWFAN_CF7_Form_Submit extends BWFAN_Event {
private static $instance = null;
public $form_id = 0;
public $form_title = '';
public $fields = [];
public $email = '';
public $first_name = '';
public $last_name = '';
public $contact_phone = '';
public $mark_subscribe = false;
private function __construct() {
$this->event_merge_tag_groups = array( 'cf7', 'bwf_contact' );
$this->event_name = esc_html__( 'Form Submits', 'wp-marketing-automations' );
$this->event_desc = esc_html__( 'This event runs after a form is submitted', 'wp-marketing-automations' );
$this->event_rule_groups = array(
'cf7',
'bwf_contact_segments',
'bwf_contact',
'bwf_contact_fields',
'bwf_contact_user',
'bwf_contact_wc',
'bwf_contact_geo',
'bwf_engagement',
'bwf_broadcast'
);
$this->optgroup_label = esc_html__( 'Contact Form 7', 'wp-marketing-automations' );
$this->priority = 10;
$this->customer_email_tag = '';
$this->v2 = true;
$this->force_async = true;
}
public static function get_instance() {
if ( null === self::$instance ) {
self::$instance = new self();
}
return self::$instance;
}
public function load_hooks() {
add_action( 'wp_ajax_bwfan_get_cf7_form_fields', array( $this, 'bwfan_get_cf7_form_fields' ) );
add_action( 'wpcf7_submit', array( $this, 'process' ), 10, 2 );
add_filter( 'bwfan_all_event_js_data', array( $this, 'add_form_data' ), 10, 2 );
}
/**
* Localize data for html fields for the current event.
*/
public function admin_enqueue_assets() {
if ( BWFAN_Common::is_load_admin_assets( 'automation' ) ) {
$data = $this->get_view_data();
BWFAN_Core()->admin->set_events_js_data( $this->get_slug(), 'form_options', $data );
}
}
public function get_view_data() {
$options = [];
$args = [
'post_type' => 'wpcf7_contact_form',
'posts_per_page' => 99,
'orderby' => 'title',
'order' => 'ASC',
'post_status' => 'publish',
];
$forms = ( new WP_Query( $args ) )->posts;
if ( ! empty( $forms ) ) {
foreach ( $forms as $form ) {
$options[ $form->ID ] = $form->post_title;
}
}
return $options;
}
/**
* Show the html fields for the current event.
*/
public function get_view( $db_eventmeta_saved_value ) {
?>
<script type="text/html" id="tmpl-event-<?php echo esc_html( $this->get_slug() ); ?>">
<#
selected_form_id = (_.has(data, 'eventSavedData') &&_.has(data.eventSavedData, 'form_id')) ? data.eventSavedData.form_id : '';
selected_field_map = (_.has(data, 'eventSavedData') &&_.has(data.eventSavedData, 'email_map')) ? data.eventSavedData.email_map : '';
#>
<div class="bwfan-col-sm-12 bwfan-p-0 bwfan-mt-15 bwfan-mb-15">
<label for="" class="bwfan-label-title"><?php esc_html_e( 'Select Form', 'wp-marketing-automations' ); ?></label>
<select id="bwfan-cf7_form_submit_form_id" class="bwfan-input-wrapper" name="event_meta[form_id]">
<option value=""><?php esc_html_e( 'Choose Form', 'wp-marketing-automations' ); ?></option>
<#
if(_.has(data.eventFieldsOptions, 'form_options') && _.isObject(data.eventFieldsOptions.form_options) ) {
_.each( data.eventFieldsOptions.form_options, function( value, key ){
selected =(key == selected_form_id)?'selected':'';
#>
<option value="{{key}}" {{selected}}>{{value}}</option>
<# })
} #>
</select>
</div>
<#
show_mapping = !_.isEmpty(selected_form_id)?'block':'none';
#>
<div class="bwfan-cf7-forms-map bwfan-col-sm-12 bwfan-p-0 bwfan-mt-5">
<div class="bwfan_spinner bwfan_hide"></div>
<div class="bwfan-col-sm-12 bwfan-p-0 bwfan-cf7-field-map" style="display:{{show_mapping}}">
<label for="" class="bwfan-label-title">
<?php esc_html_e( 'Select Email Field', 'wp-marketing-automations' ); ?>
<div class="bwfan_tooltip" data-size="2xl">
<span class="bwfan_tooltip_text" data-position="top"><?php esc_html_e( 'Map the email field to be used by appropriate Rules and Actions.', 'wp-marketing-automations' ); ?></span>
</div>
</label>
<select id="bwfan-cf7_email_field_map" class="bwfan-input-wrapper" name="event_meta[email_map]">
<option value=""><?php esc_html_e( 'none', 'wp-marketing-automations' ); ?></option>
<#
_.each( bwfan_events_js_data['cf7_form_submit']['selected_form_fields'], function( value, key ){
selected =(key == selected_field_map)?'selected':'';
#>
<option value="{{key}}" {{selected}}>{{value}}</option>
<# })
#>
</select>
</div>
</div>
</script>
<script>
jQuery(document).on('change', '#bwfan-cf7_form_submit_form_id', function () {
var selected_id = jQuery(this).val();
bwfan_events_js_data['cf7_form_submit']['selected_id'] = selected_id;
if (_.isEmpty(selected_id)) {
jQuery(".bwfan-cf7-field-map").hide();
return false;
}
jQuery(".bwfan-cf7-forms-map .bwfan_spinner").removeClass('bwfan_hide');
jQuery(".bwfan-cf7-field-map").hide();
jQuery.ajax({
method: 'post',
url: "<?php echo esc_url( admin_url( 'admin-ajax.php' ) ); ?>",
datatype: "JSON",
data: {
action: 'bwfan_get_cf7_form_fields',
id: selected_id,
},
success: function (response) {
jQuery(".bwfan-cf7-forms-map .bwfan_spinner").addClass('bwfan_hide');
jQuery(".bwfan-cf7-field-map").show();
update_cf7_email_field_map(response.fields);
bwfan_events_js_data['cf7_form_submit']['selected_form_fields'] = response.fields;
}
});
});
function update_cf7_email_field_map(fields) {
jQuery("#bwfan-cf7_email_field_map").html('');
var option = '<option value="">none</option>';
if (_.size(fields) > 0 && _.isObject(fields)) {
_.each(fields, function (v, e) {
option += '<option value="' + e + '">' + v + '</option>';
});
}
jQuery("#bwfan-cf7_email_field_map").html(option);
}
jQuery('body').on('bwfan-change-rule', function (e, v) {
if ('cf7_form_field' !== v.value) {
return;
}
var options = '';
_.each(bwfan_events_js_data['cf7_form_submit']['selected_form_fields'], function (value, key) {
options += '<option value="' + key + '">' + value + '</option>';
});
v.scope.find('.bwfan_cf7_form_fields').html(options);
});
jQuery('body').on('bwfan-selected-merge-tag', function (e, v) {
if ('cf7_form_field' !== v.tag) {
return;
}
var options = '';
var i = 1;
var selected = '';
_.each(bwfan_events_js_data['cf7_form_submit']['selected_form_fields'], function (value, key) {
selected = (i == 1) ? 'selected' : '';
options += '<option value="' + key + '" ' + selected + '>' + value + '</option>';
i++;
});
jQuery('.bwfan_cf7_form_fields').html(options);
jQuery('.bwfan_tag_select').trigger('change');
});
</script>
<?php
}
public function bwfan_get_cf7_form_fields() {
$form_id = absint( sanitize_text_field( $_POST['id'] ) ); // WordPress.CSRF.NonceVerification.NoNonceVerification
$fields = [];
if ( ! empty( $form_id ) ) {
$fields = $this->get_form_fields( $form_id );
}
/** handling form fields for the v2 automations */
if ( isset( $_POST['fromApp'] ) && $_POST['fromApp'] ) {
$finalarr = [];
foreach ( $fields as $key => $value ) {
$finalarr[] = [
'key' => $key,
'value' => $value
];
}
wp_send_json( array(
'results' => $finalarr
) );
exit;
}
wp_send_json( array(
'fields' => $fields,
) );
}
public function get_form_fields( $form_id ) {
if ( empty( $form_id ) ) {
return array();
}
$form = \WPCF7_ContactForm::get_instance( $form_id );
$form_fields = $form->scan_form_tags();
$fields = array();
if ( empty( $form_fields ) ) {
return $fields;
}
foreach ( $form_fields as $field ) {
if ( $field->type === 'submit' || false !== strpos( $field->type, 'file' ) ) {
continue;
}
$fields[ $field->name ] = $field->name;
}
return $fields;
}
public function process( $form, $result ) {
$invalid_status = [ 'validation_failed', 'spam' ];
if ( ( isset( $result['status'] ) && in_array( $result['status'], $invalid_status, true ) ) || ( isset( $result['demo_mode'] ) && false !== $result['demo_mode'] ) ) {
return;
}
$data = $this->get_default_data();
$data['fields'] = $this->get_submitted_form_values( $form );
$data['form_id'] = $result['contact_form_id'];
$data['form_title'] = get_the_title( $result['contact_form_id'] );
$this->send_async_call( $data );
}
/**
* @param WPCF7_ContactForm $form
*
* @return array
*/
public function get_submitted_form_values( $form ) {
$tags = $form->scan_form_tags();
$data = array();
foreach ( $tags as $tag ) {
if ( empty( $tag->name ) || false !== strpos( $tag->type, 'file' ) || $tag->type === 'submit' ) {
continue;
}
$pipes = $tag->pipes;
$value = ( ! empty( $_POST[ $tag->name ] ) ) ? $_POST[ $tag->name ] : '';
if ( ! WPCF7_USE_PIPE || ! $pipes instanceof \WPCF7_Pipes || $pipes->zero() ) {
$data[ $tag->name ] = $value;
}
//Select field pipes
if ( is_array( $value ) ) {
$new_value = [];
foreach ( $value as $v ) {
$new_value[] = $pipes->do_pipe( wp_unslash( $v ) );
}
$value = $new_value;
} else {
$value = $pipes->do_pipe( wp_unslash( $value ) );
}
$data[ $tag->name ] = $value;
}
return $data;
}
public function add_form_data( $event_js_data, $automation_meta ) {
if ( ! isset( $automation_meta['event_meta'] ) || ! isset( $event_js_data['cf7_form_submit'] ) || ! isset( $automation_meta['event_meta']['form_id'] ) ) {
return $event_js_data;
}
if ( isset( $automation_meta['event'] ) && ! empty( $automation_meta['event'] ) && 'cf7_form_submit' !== $automation_meta['event'] ) {
return $event_js_data;
}
$event_js_data['cf7_form_submit']['selected_id'] = $automation_meta['event_meta']['form_id'];
$fields = $this->get_form_fields( $automation_meta['event_meta']['form_id'] );
$event_js_data['cf7_form_submit']['selected_form_fields'] = $fields;
return $event_js_data;
}
/**
* Set up rules data
*
* @param $automation_data
*/
public function pre_executable_actions( $automation_data ) {
$email_map = isset( $automation_data['event_meta']['email_map'] ) ? $automation_data['event_meta']['email_map'] : '';
$this->email = ( ! empty( $email_map ) && isset( $this->fields[ $email_map ] ) && is_email( $this->fields[ $email_map ] ) ) ? $this->fields[ $email_map ] : '';
BWFAN_Core()->rules->setRulesData( $this->form_id, 'form_id' );
BWFAN_Core()->rules->setRulesData( $this->form_title, 'form_title' );
BWFAN_Core()->rules->setRulesData( $this->fields, 'fields' );
BWFAN_Core()->rules->setRulesData( $this->email, 'email' );
BWFAN_Core()->rules->setRulesData( BWFAN_Common::get_bwf_customer( $this->email, $this->get_user_id_event() ), 'bwf_customer' );
}
/**
* Registers the tasks for current event.
*
* @param $automation_id
* @param $integration_data
* @param $event_data
*/
public function register_tasks( $automation_id, $integration_data, $event_data ) {
if ( ! is_array( $integration_data ) ) {
return;
}
$data_to_send = $this->get_event_data();
$this->create_tasks( $automation_id, $integration_data, $event_data, $data_to_send );
}
public function get_event_data() {
$data_to_send = [];
$data_to_send['global']['form_id'] = $this->form_id;
$data_to_send['global']['form_title'] = $this->form_title;
$data_to_send['global']['fields'] = $this->fields;
$data_to_send['global']['email'] = $this->email;
return $data_to_send;
}
/**
* Make the view data for the current event which will be shown in task listing screen.
*
* @param $global_data
*
* @return false|string
*/
public function get_task_view( $global_data ) {
ob_start();
?>
<li>
<strong><?php echo esc_html__( 'Form ID:', 'wp-marketing-automations' ); ?> </strong>
<span><?php echo esc_html( $global_data['form_id'] ); ?></span>
</li>
<li>
<strong><?php echo esc_html__( 'Form Title:', 'wp-marketing-automations' ); ?> </strong>
<?php echo esc_html( $global_data['form_title'] ); ?>
</li>
<?php
if ( isset( $global_data['fields'] ) && is_array( $global_data['fields'] ) && count( $global_data['fields'] ) > 0 ) {
$h = 0;
foreach ( $global_data['fields'] as $key => $value ) {
if ( ! empty( $value ) ) {
?>
<li>
<strong><?php echo esc_html__( 'Field ', 'wp-marketing-automations' ) . '(' . esc_html( $key ); ?>): </strong>
<?php echo is_array( $value ) ? implode( ', ', $value ) : $value; //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
</li>
<?php
$h ++;
}
if ( 2 <= $h ) {
break;
}
}
}
return ob_get_clean();
}
/**
* Set global data for all the merge tags which are supported by this event.
*
* @param $task_meta
*/
public function set_merge_tags_data( $task_meta ) {
$get_data = BWFAN_Merge_Tag_Loader::get_data( 'form_id' );
if ( ( empty( $get_data ) || intval( $get_data ) !== intval( $task_meta['global']['form_id'] ) ) ) {
$set_data = array(
'form_id' => intval( $task_meta['global']['form_id'] ),
'form_title' => $task_meta['global']['form_title'],
'fields' => $task_meta['global']['fields'],
'email' => $task_meta['global']['email'],
);
BWFAN_Merge_Tag_Loader::set_data( $set_data );
}
}
/**
* Capture the async data for the current event.
* @return array|bool
*/
public function capture_async_data() {
$this->form_id = BWFAN_Common::$events_async_data['form_id'];
$this->form_title = BWFAN_Common::$events_async_data['form_title'];
$this->fields = BWFAN_Common::$events_async_data['fields'];
return $this->run_automations();
}
public function get_email_event() {
return is_email( $this->email ) ? $this->email : false;
}
public function get_user_id_event() {
if ( is_email( $this->email ) ) {
$user = get_user_by( 'email', $this->email );
return ( $user instanceof WP_User ) ? $user->ID : false;
}
return false;
}
/**
* Validating form id after submission with the selected form id in the event
*
* @param $automations_arr
*
* @return mixed
*/
public function validate_event_data_before_creating_task( $automations_arr ) {
$automations_arr_temp = $automations_arr;
foreach ( $automations_arr as $automation_id => $automation_data ) {
if ( isset( $automation_data['event_meta']['form_id'] ) && absint( $this->form_id ) !== absint( $automation_data['event_meta']['form_id'] ) ) {
unset( $automations_arr_temp[ $automation_id ] );
}
}
return $automations_arr_temp;
}
/**
* Capture the async data for the current event.
* @return array|bool
*/
public function capture_v2_data( $automation_data ) {
$email_map = isset( $automation_data['event_meta']['bwfan-cf7_email_field_map'] ) ? $automation_data['event_meta']['bwfan-cf7_email_field_map'] : '';
$this->form_id = BWFAN_Common::$events_async_data['form_id'];
$this->form_title = BWFAN_Common::$events_async_data['form_title'];
$this->fields = BWFAN_Common::$events_async_data['fields'];
$this->email = ( ! empty( $email_map ) && isset( $this->fields[ $email_map ] ) && is_email( $this->fields[ $email_map ] ) ) ? $this->fields[ $email_map ] : '';
$automation_data['form_id'] = $this->form_id;
$automation_data['form_title'] = $this->form_title;
$automation_data['fields'] = $this->fields;
$automation_data['email'] = $this->email;
/** check for autonami pro active and also for method exists */
$first_name_map = isset( $automation_data['event_meta']['bwfan-cf7_fname_field_map'] ) ? $automation_data['event_meta']['bwfan-cf7_fname_field_map'] : '';
$last_name_map = isset( $automation_data['event_meta']['bwfan-cf7_lname_field_map'] ) ? $automation_data['event_meta']['bwfan-cf7_lname_field_map'] : '';
$phone_map = isset( $automation_data['event_meta']['bwfan-cf7_phone_field_map'] ) ? $automation_data['event_meta']['bwfan-cf7_phone_field_map'] : '';
$this->mark_subscribe = isset( $automation_data['event_meta']['bwfan-mark-contact-subscribed'] ) ? $automation_data['event_meta']['bwfan-mark-contact-subscribed'] : 0;
$this->first_name = ( ! empty( $first_name_map ) && isset( $this->fields[ $first_name_map ] ) ) ? $this->fields[ $first_name_map ] : '';
$this->last_name = ( ! empty( $last_name_map ) && isset( $this->fields[ $last_name_map ] ) ) ? $this->fields[ $last_name_map ] : '';
$this->contact_phone = ( ! empty( $phone_map ) && isset( $this->fields[ $phone_map ] ) ) ? $this->fields[ $phone_map ] : '';
$automation_data['first_name'] = $this->first_name;
$automation_data['last_name'] = $this->last_name;
$automation_data['contact_phone'] = $this->contact_phone;
$automation_data['mark_contact_subscribed'] = $this->mark_subscribe;
BWFAN_Common::maybe_create_update_contact( $automation_data );
return $automation_data;
}
/**
* v2 Method: Validate event settings
*
* @param $automation_data
*
* @return bool
*/
public function validate_v2_event_settings( $automation_data ) {
if ( absint( $automation_data['form_id'] ) !== absint( $automation_data['event_meta']['bwfan-cf7_form_submit_form_id'] ) ) {
return false;
}
return true;
}
/**
* v2 Method: Get fields schema
* @return array[][]
*/
public function get_fields_schema() {
$forms = BWFAN_Common::prepared_field_options( $this->get_view_data() );
$contact_setting = [];
/** checking for autonami pro and method exists maybe_create_update_contact */
if ( bwfan_is_autonami_pro_active() && method_exists( 'BWFAN_PRO_Common', 'maybe_create_update_contact' ) ) {
$contact_setting = [
[
'id' => 'bwfan-cf7_fname_field_map',
'type' => 'ajax',
'label' => __( 'Select First Name', 'wp-marketing-automations' ),
"class" => 'bwfan-input-wrapper bwf-3-col-item',
"required" => false,
'placeholder' => __( 'Select', 'wp-marketing-automations' ),
"description" => "",
"ajax_cb" => 'bwfan_get_cf7_form_fields',
"ajax_field" => [
'id' => 'bwfan-cf7_form_submit_form_id'
],
"fieldChange" => 'bwfan-cf7_form_submit_form_id',
"toggler" => [
'fields' => array(
array(
'id' => 'bwfan-cf7_form_submit_form_id',
'value' => '',
),
),
'relation' => 'AND',
]
],
[
'id' => 'bwfan-cf7_lname_field_map',
'type' => 'ajax',
'label' => __( 'Select Last Name', 'wp-marketing-automations' ),
"class" => 'bwfan-input-wrapper bwf-3-col-item',
"required" => false,
'placeholder' => 'Select',
"description" => "",
"ajax_cb" => 'bwfan_get_cf7_form_fields',
"ajax_field" => [
'id' => 'bwfan-cf7_form_submit_form_id'
],
"fieldChange" => 'bwfan-cf7_form_submit_form_id',
"toggler" => [
'fields' => array(
array(
'id' => 'bwfan-cf7_form_submit_form_id',
'value' => '',
),
),
'relation' => 'AND',
]
],
[
'id' => 'bwfan-cf7_phone_field_map',
'type' => 'ajax',
'label' => __( 'Select Phone', 'wp-marketing-automations' ),
"class" => 'bwfan-input-wrapper bwf-3-col-item',
"required" => false,
'placeholder' => 'Select',
"description" => "",
"ajax_cb" => 'bwfan_get_cf7_form_fields',
"ajax_field" => [
'id' => 'bwfan-cf7_form_submit_form_id'
],
"fieldChange" => 'bwfan-cf7_form_submit_form_id',
"toggler" => [
'fields' => array(
array(
'id' => 'bwfan-cf7_form_submit_form_id',
'value' => '',
),
),
'relation' => 'AND',
]
],
[
'id' => 'bwfan-mark-contact-subscribed',
'type' => 'checkbox',
'checkboxlabel' => __( 'Mark Contact as Subscribed', 'wp-marketing-automations' ),
'description' => '',
"toggler" => [
'fields' => array(
array(
'id' => 'bwfan-cf7_form_submit_form_id',
'value' => '',
),
),
'relation' => 'AND',
]
]
];
}
$settings = [
[
'id' => 'bwfan-cf7_form_submit_form_id',
'type' => 'select',
'options' => $forms,
'label' => __( 'Select Form', 'wp-marketing-automations' ),
"class" => 'bwfan-input-wrapper',
"placeholder" => __( 'Select', 'wp-marketing-automations' ),
"required" => true,
"errorMsg" => __( 'Form is required.', 'wp-marketing-automations' ),
"description" => ""
],
[
'id' => 'bwfan-cf7_email_field_map',
'type' => 'ajax',
'label' => __( 'Select Email Field', 'wp-marketing-automations' ),
"class" => 'bwfan-input-wrapper',
"tip" => "Map the field to be used by appropriate Rules and Actions.",
"required" => true,
"errorMsg" => __( 'Email field is required.', 'wp-marketing-automations' ),
'placeholder' => __( 'Select', 'wp-marketing-automations' ),
"description" => "",
"ajax_cb" => 'bwfan_get_cf7_form_fields',
"ajax_field" => [
'id' => 'bwfan-cf7_form_submit_form_id'
],
"toggler" => [
'fields' => array(
array(
'id' => 'bwfan-cf7_form_submit_form_id',
'value' => '',
),
),
'relation' => 'AND',
]
],
];
$settings = array_merge( $settings, $contact_setting );
return $settings;
}
}
/**
* Register this event to a source.
* This will show the current event in dropdown in single automation screen.
*/
if ( bwfan_is_cf7_active() ) {
return 'BWFAN_CF7_Form_Submit';
}

View File

@@ -0,0 +1,2 @@
<?php
// Silence is golden.

View File

@@ -0,0 +1,2 @@
<?php
// Silence is golden.

View File

@@ -0,0 +1,37 @@
<?php
if ( ! bwfan_is_autonami_pro_active() && ! class_exists( 'BWFAN_OptinForm_Source' ) ) {
class BWFAN_OptinForm_Source extends BWFAN_Source {
private static $instance = null;
public function __construct() {
$this->event_dir = __DIR__;
$this->nice_name = __( 'Funnel Builder', 'wp-marketing-automations' );
$this->group_name = __( 'Funnel Builder', 'wp-marketing-automations' );
$this->group_slug = 'woofunnels';
$this->priority = 8;
}
/**
* Ensures only one instance of the class is loaded or can be loaded.
*
* @return BWFAN_OptinForm_Source|null
*/
public static function get_instance() {
if ( null === self::$instance ) {
self::$instance = new self();
}
return self::$instance;
}
}
/**
* Register this as a source.
*/
if ( function_exists( 'bwfan_is_funnel_optin_forms_active' ) && bwfan_is_funnel_optin_forms_active() ) {
BWFAN_Load_Sources::register( 'BWFAN_OptinForm_Source' );
}
}

View File

@@ -0,0 +1,348 @@
<?php
if ( ! bwfan_is_autonami_pro_active() && ! class_exists( 'BWFAN_Funnel_Optin_Form_Submit' ) ) {
#[AllowDynamicProperties]
final class BWFAN_Funnel_Optin_Form_Submit extends BWFAN_Event {
private static $instance = null;
public $form_id = 0;
public $form_title = '';
public $fields = [];
public $email = '';
public $first_name = '';
public $last_name = '';
public $contact_phone = '';
public $mark_subscribe = false;
/**
* @var int
*/
public $cid = 0;
private function __construct() {
$this->event_merge_tag_groups = array( 'optinforms', 'bwf_contact' );
$this->event_name = esc_html__( 'Form Submits', 'wp-marketing-automations' );
$this->event_desc = esc_html__( 'This event runs after a form is submitted', 'wp-marketing-automations' );
$this->event_rule_groups = array(
'optinforms',
'bwf_contact_segments',
'bwf_contact',
'bwf_contact_fields',
'bwf_contact_user',
'bwf_contact_wc',
'bwf_contact_geo',
'bwf_engagement',
'bwf_broadcast'
);
$this->optgroup_label = esc_html__( 'Optin Form', 'wp-marketing-automations' );
$this->priority = 10;
$this->customer_email_tag = '';
$this->v2 = true;
$this->support_v1 = false;
$this->optgroup_priority = 20;
}
public static function get_instance() {
if ( null === self::$instance ) {
self::$instance = new self();
}
return self::$instance;
}
public function load_hooks() {
add_action( 'wp_ajax_bwfan_get_optin_form_fields', array( $this, 'bwfan_get_optin_form_fields' ) );
add_action( 'wffn_optin_form_submit', array( $this, 'process' ), 999, 2 );
}
public function get_view_data() {
$options = [];
$args = array(
'post_type' => 'wffn_optin',
'post_status' => 'publish',
'posts_per_page' => - 1,
);
$optin_forms = new WP_Query( $args );
if ( ! empty( $optin_forms->posts ) ) {
foreach ( $optin_forms->posts as $form ) {
$funnel_id = get_post_meta( $form->ID, '_bwf_in_funnel', true );
$options[ $form->ID ] = $form->post_title;
if ( absint( $funnel_id ) > 0 ) {
$funnel = new WFFN_Funnel( $funnel_id );
if ( ! ( $funnel instanceof WFFN_Funnel ) && $funnel_id !== $funnel->get_id() && empty( $funnel->get_title() ) ) {
continue;
}
$options[ $form->ID ] .= ! empty( $funnel->get_title() ) ? ' (' . $funnel->get_title() . ')' : '( no title )';
$options[ $form->ID ] = str_replace( '((', '(', $options[ $form->ID ] );
$options[ $form->ID ] = str_replace( '))', ')', $options[ $form->ID ] );
}
}
}
return $options;
}
public function bwfan_get_optin_form_fields() {
$form_id = filter_input( INPUT_POST, 'id' );
$fields = [];
if ( ! empty( $form_id ) ) {
$fields = $this->get_form_fields( $form_id );
}
/** fields for v2 */
$fromApp = filter_input( INPUT_POST, 'fromApp' );
if ( ! empty( $fromApp ) ) {
$final_arr = [];
foreach ( $fields as $key => $value ) {
$final_arr[] = [
'key' => $key,
'value' => $value
];
}
wp_send_json( array(
'results' => $final_arr
) );
}
wp_send_json( array(
'fields' => $fields,
) );
}
public function get_form_fields( $form_id ) {
if ( empty( $form_id ) ) {
return array();
}
if ( ! function_exists( 'WFOPP_Core' ) ) {
return array();
}
$form_fields = WFOPP_Core()->optin_pages->form_builder->get_optin_layout( $form_id );
if ( empty( $form_fields ) ) {
return array();
}
$fields = array();
foreach ( $form_fields as $step_field ) {
/** Empty step fields than continue */
if ( empty( $step_field ) ) {
continue;
}
foreach ( $step_field as $field ) {
$fields[ $field['InputName'] ] = $field['label'];
}
}
return $fields;
}
public function process( $optin_page_id, $posted_data ) {
$data = $this->get_default_data();
$data['form_id'] = $optin_page_id;
$data['fields'] = $this->get_submitted_form_values( $optin_page_id, $posted_data );
$data['form_title'] = get_the_title( $optin_page_id );
if ( isset( $posted_data['cid'] ) && ! empty( $posted_data['cid'] ) ) {
$data['cid'] = absint( $posted_data['cid'] );
}
$this->send_async_call( $data );
}
/**
* @param $form_id
*
* @return array
*/
public function get_submitted_form_values( $form_id, $posted_data ) {
$fields = $this->get_form_fields( $form_id );
$fields = array_keys( $fields );
$data = [];
foreach ( $fields as $field ) {
if ( false !== strpos( $field, 'wfop_' ) ) {
$fieldname = str_replace( 'wfop_', '', $field );
$data[ $field ] = isset( $posted_data[ $fieldname ] ) ? $posted_data[ $fieldname ] : '';
} else {
$data[ $field ] = isset( $_REQUEST[ $field ] ) ? $_REQUEST[ $field ] : '';
}
}
return $data;
}
public function get_user_id_event() {
if ( is_email( $this->email ) ) {
$user = get_user_by( 'email', $this->email );
return ( $user instanceof WP_User ) ? $user->ID : false;
}
return false;
}
public function get_event_data() {
$data_to_send = [];
$data_to_send['global']['form_id'] = $this->form_id;
$data_to_send['global']['form_title'] = $this->form_title;
$data_to_send['global']['fields'] = $this->fields;
$data_to_send['global']['email'] = $this->email;
return $data_to_send;
}
public function get_email_event() {
return is_email( $this->email ) ? $this->email : false;
}
/**
* v2 Method: Validate event settings
*
* @param $automation_data
*
* @return bool
*/
public function validate_v2_event_settings( $automation_data ) {
if ( absint( $automation_data['form_id'] ) !== absint( $automation_data['event_meta']['bwfan-optin_form_submit_form_id'] ) ) {
return false;
}
return true;
}
/**
* Capture the async data for the current event.
* @return array|bool
*/
public function capture_v2_data( $automation_data ) {
$map_fields = isset( $automation_data['event_meta']['bwfan-form-field-map'] ) ? $automation_data['event_meta']['bwfan-form-field-map'] : [];
$email_map = isset( $map_fields['bwfan_email_field_map'] ) ? $map_fields['bwfan_email_field_map'] : '';
$first_name_map = isset( $map_fields['bwfan_first_name_field_map'] ) ? $map_fields['bwfan_first_name_field_map'] : '';
$last_name_map = isset( $map_fields['bwfan_last_name_field_map'] ) ? $map_fields['bwfan_last_name_field_map'] : '';
$phone_map = isset( $map_fields['bwfan_phone_field_map'] ) ? $map_fields['bwfan_phone_field_map'] : '';
$this->form_id = BWFAN_Common::$events_async_data['form_id'];
$this->form_title = BWFAN_Common::$events_async_data['form_title'];
$this->fields = BWFAN_Common::$events_async_data['fields'];
$this->email = ( ! empty( $email_map ) && isset( $this->fields[ $email_map ] ) && is_email( $this->fields[ $email_map ] ) ) ? $this->fields[ $email_map ] : '';
$this->first_name = ( ! empty( $first_name_map ) && isset( $this->fields[ $first_name_map ] ) ) ? $this->fields[ $first_name_map ] : '';
$this->last_name = ( ! empty( $last_name_map ) && isset( $this->fields[ $last_name_map ] ) ) ? $this->fields[ $last_name_map ] : '';
$this->contact_phone = ( ! empty( $phone_map ) && isset( $this->fields[ $phone_map ] ) ) ? $this->fields[ $phone_map ] : '';
$this->mark_subscribe = isset( $automation_data['event_meta']['bwfan-mark-contact-subscribed'] ) ? $automation_data['event_meta']['bwfan-mark-contact-subscribed'] : 0;
$automation_data['form_id'] = $this->form_id;
$automation_data['form_title'] = $this->form_title;
$automation_data['fields'] = $this->fields;
$automation_data['email'] = $this->email;
$automation_data['first_name'] = $this->first_name;
$automation_data['contact_phone'] = $this->contact_phone;
$automation_data['last_name'] = $this->last_name;
$automation_data['mark_contact_subscribed'] = $this->mark_subscribe;
$this->maybe_create_update_contact( $automation_data );
return $automation_data;
}
/**
* v2 Method: Get fields schema
* @return array[][]
*/
public function get_fields_schema() {
$forms = $this->get_view_data();
$forms = array_map( function ( $label, $value ) {
return array(
'label' => $label,
'value' => $value,
);
}, $forms, array_keys( $forms ) );
return [
[
'id' => 'bwfan-optin_form_submit_form_id',
'type' => 'select',
'options' => $forms,
'label' => __( 'Select Form', 'wp-marketing-automations' ),
"class" => 'bwfan-input-wrapper',
"placeholder" => __( 'Select', 'wp-marketing-automations' ),
"required" => true,
"errorMsg" => __( "Form is required.", 'wp-marketing-automations' ),
"description" => ""
],
[
'id' => 'bwfan-form-field-map',
'type' => 'bwf_form_submit',
"class" => 'bwfan-input-wrapper',
"required" => true,
'placeholder' => __( 'Select', 'wp-marketing-automations' ),
"description" => "",
"ajax_cb" => 'bwfan_get_optin_form_fields',
"ajax_field" => [
'id' => 'bwfan-optin_form_submit_form_id'
],
"fieldChange" => 'bwfan-optin_form_submit_form_id',
"toggler" => [
'fields' => array(
array(
'id' => 'bwfan-optin_form_submit_form_id',
'value' => '',
)
),
'relation' => 'AND',
]
],
[
'id' => 'bwfan-mark-contact-subscribed',
'type' => 'checkbox',
'checkboxlabel' => __( 'Mark Contact as Subscribed', 'wp-marketing-automations' ),
'description' => '',
"toggler" => [
'fields' => array(
array(
'id' => 'bwfan-optin_form_submit_form_id',
'value' => '',
),
),
'relation' => 'AND',
]
]
];
}
public static function maybe_create_update_contact( $automation_data ) {
$email = $automation_data['email'];
if ( ! is_email( trim( $email ) ) ) {
return;
}
$contact = new WooFunnels_Contact( '', $email );
if ( ! $contact instanceof WooFunnels_Contact ) {
return;
}
if ( isset( $automation_data['first_name'] ) && ! empty( $automation_data['first_name'] ) ) {
$contact->set_f_name( $automation_data['first_name'] );
}
if ( isset( $automation_data['last_name'] ) && ! empty( $automation_data['last_name'] ) ) {
$contact->set_l_name( $automation_data['last_name'] );
}
if ( isset( $automation_data['contact_phone'] ) && ! empty( $automation_data['contact_phone'] ) ) {
$contact->set_contact_no( $automation_data['contact_phone'] );
}
if ( isset( $automation_data['mark_contact_subscribed'] ) && 1 === intval( $automation_data['mark_contact_subscribed'] ) ) {
$contact->set_status( 1 );
}
$contact->save();
}
}
/**
* Register this event to a source.
* This will show the current event in dropdown in single automation screen.
*/
if ( function_exists( 'bwfan_is_funnel_optin_forms_active' ) && bwfan_is_funnel_optin_forms_active() ) {
return 'BWFAN_Funnel_Optin_Form_Submit';
}
}

View File

@@ -0,0 +1,443 @@
<?php
final class BWFAN_WC_Create_Coupon extends BWFAN_Action {
private static $ins = null;
protected function __construct() {
$this->action_name = __( 'Create Coupon', 'wp-marketing-automations' );
$this->action_desc = __( 'This action creates a personalized coupon for the customer', 'wp-marketing-automations' );
$this->required_fields = array( 'coupon', 'coupon_name' );
$this->action_priority = 5;
$this->support_v2 = false;
$this->support_v1 = true;
}
public static function get_instance() {
if ( null === self::$ins ) {
self::$ins = new self();
}
return self::$ins;
}
/**
* Localize data for html fields for the current action.
*/
public function admin_enqueue_assets() {
if ( BWFAN_Common::is_load_admin_assets( 'automation' ) ) {
$coupons = [];
$searched_coupons = array();
$action_slug = $this->get_slug();
$automation_actions = BWFAN_Core()->automations->get_automation_details();
if ( is_array( $automation_actions ) && count( $automation_actions ) > 0 ) {
foreach ( $automation_actions as $single_row_actions ) {
if ( is_array( $single_row_actions ) && count( $single_row_actions ) > 0 ) {
foreach ( $single_row_actions as $action_details ) {
if ( isset( $action_details['action_slug'] ) && $action_details['action_slug'] === $action_slug ) {
$coupons[] = $action_details['data']['coupon'];
}
if ( ! is_array( $action_details ) ) {
continue;
}
foreach ( $action_details as $single_action ) {
if ( isset( $single_action['action_slug'] ) && $single_action['action_slug'] === $action_slug && isset( $single_action['data']['searched_coupon'] ) ) {
$searched_coupon = $single_action['data']['searched_coupon'];
$searched_coupon = json_decode( $searched_coupon, ARRAY_A );
if ( isset( $searched_coupon['id'] ) ) {
$searched_coupons[ $searched_coupon['id'] ] = get_the_title( absint( $searched_coupon['id'] ) );
}
}
}
}
}
}
}
$coupons = array_unique( $coupons );
if ( is_array( $coupons ) && count( $coupons ) > 0 ) {
$args = array(
'post__in' => $coupons,
'orderby' => 'title',
'order' => 'asc',
'post_type' => 'shop_coupon',
'post_status' => 'publish',
);
$coupons_found = get_posts( $args );
$result = [];
if ( is_array( $coupons_found ) && count( $coupons_found ) > 0 ) {
foreach ( $coupons_found as $coupon ) {
$result[ $coupon->ID ] = $coupon->post_title;
}
}
$coupons = $result;
}
$restrict_data = array(
'yes' => __( 'Restrict coupon with user email', 'wp-marketing-automations' ),
);
BWFAN_Core()->admin->set_select2ajax_js_data( 'coupon', $coupons );
BWFAN_Core()->admin->set_actions_js_data( $this->get_class_slug(), 'restrict_options', $restrict_data );
if ( ! empty( $searched_coupons ) ) {
BWFAN_Core()->admin->set_actions_js_data( $this->get_class_slug(), 'automation_searched_coupons', $searched_coupons );
}
}
}
/**
* Show the html fields for the current action.
*/
public function get_view() {
?>
<script>
jQuery(document).ready(function ($) {
$('body').on('change', '.bwfan-coupon-search', function () {
var temp_coupon = {id: $(this).val(), name: $(this).find(':selected').text()};
$(this).parent().find('.bwfan_searched_coupon_name').val(JSON.stringify(temp_coupon));
});
});
</script>
<script type="text/html" id="tmpl-action-<?php echo esc_attr( $this->get_slug() ); ?>">
<#
automation_searched_coupons = _.has(data.actionFieldsOptions, 'automation_searched_coupons') && _.isObject(data.actionFieldsOptions.automation_searched_coupons) ? data.actionFieldsOptions.automation_searched_coupons : '';
searched_coupon = (_.has(data.actionSavedData, 'data') && _.has(data.actionSavedData.data, 'searched_coupon')) ? data.actionSavedData.data.searched_coupon : '';
if(!_.isEmpty(searched_coupon) && !_.isEmpty(automation_searched_coupons) ) {
try {
searched_coupon = JSON.parse(searched_coupon);
searched_coupon.name = automation_searched_coupons[searched_coupon.id];
}
catch(e) {
//Do Nothing
}
}
selected_coupon = (_.has(data.actionSavedData, 'data') && _.has(data.actionSavedData.data, 'coupon')) ? data.actionSavedData.data.coupon : '';
entered_coupon_name = (_.has(data.actionSavedData, 'data') && _.has(data.actionSavedData.data, 'coupon_name')) ? data.actionSavedData.data.coupon_name : '';
entered_expiry = (_.has(data.actionSavedData, 'data') && _.has(data.actionSavedData.data, 'expiry')) ? data.actionSavedData.data.expiry : '';
entered_restrict = (_.has(data.actionSavedData, 'data') && _.has(data.actionSavedData.data, 'restrict')) ? data.actionSavedData.data.restrict : '';
selected_event = BWFAN_Auto.uiDataDetail.trigger.event;
if(selected_event=='ab_cart_abandoned' && '' == entered_coupon_name){
entered_coupon_name = '{{cart_billing_first_name}}SHOP{{cart_abandoned_id}}';
}
#>
<div class="bwfan-input-form clearfix">
<label for="" class="bwfan-label-title">
<?php esc_html_e( 'Select Coupon', 'wp-marketing-automations' ); ?>
<?php
$message = __( "The selected Coupon data will be used to generate a new coupon", 'wp-marketing-automations' );
echo $this->add_description( $message, '2xl', 'right' ); //phpcs:ignore WordPress.Security.EscapeOutput
?>
</label>
<select required id="" data-search="coupon"
data-search-text="<?php esc_attr_e( 'Select Coupon', 'wp-marketing-automations' ); ?>"
class="bwfan-select2ajax-single bwfan-coupon-search bwfan-input-wrapper"
name="bwfan[{{data.action_id}}][data][coupon]">
<option value=""><?php esc_html_e( 'Choose Coupon', 'wp-marketing-automations' ); ?></option>
<#
if(_.size(searched_coupon) >0) {
temp_selected_coupon = _.isObject(searched_coupon) ? searched_coupon : JSON.parse(searched_coupon);
if(temp_selected_coupon.id == selected_coupon){
#>
<option value="{{temp_selected_coupon.id}}" selected>{{temp_selected_coupon.name}}</option>
<#
}
}
stringify_searched_coupon = _.isObject(searched_coupon) ? JSON.stringify(searched_coupon) :
searched_coupon;
#>
</select>
<input type="hidden" class="bwfan_searched_coupon_name"
name="bwfan[{{data.action_id}}][data][searched_coupon]" value="{{stringify_searched_coupon}}"/>
</div>
<div class="bwfan-input-form clearfix">
<label for="" class="bwfan-label-title">
<?php esc_html_e( 'New Coupon Code', 'wp-marketing-automations' ); ?>
<?php echo $this->inline_merge_tag_invoke(); //phpcs:ignore WordPress.Security.EscapeOutput
?>
</label>
<input required type="text" class="bwfan-input-wrapper"
name="bwfan[{{data.action_id}}][data][coupon_name]" value="{{entered_coupon_name}}"/>
<div class="clearfix bwfan_field_desc">
<?php esc_html_e( 'Use merge tags to generate personalized coupon', 'wp-marketing-automations' ); ?>
</div>
</div>
<div class="bwfan-input-form clearfix">
<label for=""
class="bwfan-label-title"><?php esc_html_e( 'Coupon Expiry (days)', 'wp-marketing-automations' ); ?></label>
<div class="bwfan-col-sm-4 bwfan-pl-0">
<input min="0" type="number" placeholder="xx" class="bwfan-input-wrapper"
name="bwfan[{{data.action_id}}][data][expiry]" value="{{entered_expiry}}"/>
</div>
<div class="clearfix bwfan_field_desc">
<?php esc_html_e( 'Leave blank for no coupon expiry', 'wp-marketing-automations' ); ?>
</div>
</div>
<div class="bwfan-input-form clearfix">
<label for=""
class="bwfan-label-title"><?php esc_html_e( 'Email Restriction', 'wp-marketing-automations' ); ?></label>
<#
if(_.has(data.actionFieldsOptions, 'restrict_options') &&
_.isObject(data.actionFieldsOptions.restrict_options) ) {
_.each( data.actionFieldsOptions.restrict_options, function( value, key ){
checked = '';
if(entered_restrict!='' && _.contains(entered_restrict, key)){
checked = 'checked';
}
#>
<input type="checkbox" name="bwfan[{{data.action_id}}][data][restrict][]" id="bwfan-{{key}}"
value="{{key}}" class="<?php echo esc_attr( $this->get_slug() ); ?>-restrict" {{checked}}/>
<label for="bwfan-{{key}}" class="bwfan-checkbox-label">{{value}}</label>
<# })
}
#>
</div>
</script>
<?php
}
/**
* Make all the data which is required by the current action.
* This data will be used while executing the task of this action.
*
* @param $integration_object
* @param $task_meta
*
* @return array
*/
public function make_data( $integration_object, $task_meta ) {
$this->set_data_for_merge_tags( $task_meta );
$data_to_set = array();
$data_to_set['email'] = $task_meta['global']['email'];
$data_to_set['coupon'] = $task_meta['data']['coupon'];
$data_to_set['coupon_name'] = BWFAN_Common::decode_merge_tags( $task_meta['data']['coupon_name'] );
$data_to_set['expiry'] = ( isset( $task_meta['data']['expiry'] ) && 0 < intval( $task_meta['data']['expiry'] ) ) ? $task_meta['data']['expiry'] : '';
$data_to_set['restrict'] = '';
if ( isset( $task_meta['data']['restrict'] ) ) {
if ( is_array( $task_meta['data']['restrict'] ) && count( $task_meta['data']['restrict'] ) > 0 ) {
$data_to_set['restrict'] = 1;
}
}
return $data_to_set;
}
public function get_coupon_data( $coupon_id ) {
$coupon_meta = array();
$meta = get_post_meta( $coupon_id );
if ( is_array( $meta ) && count( $meta ) > 0 ) {
foreach ( $meta as $key => $val ) {
if ( '_edit_lock' !== $key && '_edit_last' !== $key ) {
$coupon_meta[ $key ] = maybe_serialize( $val[0] ) ? maybe_unserialize( $val[0] ) : $val[0];
}
}
}
return $coupon_meta;
}
public function get_expiry_dates( $no_of_days ) {
$dbj = new DateTime();
$no_of_days += 1;
$exptime = strtotime( "+{$no_of_days} days" );
$dbj->setTimestamp( $exptime );
$exp_date = $dbj->format( 'Y-m-d' );
$exp_date_email = date( 'Y-m-d', $exptime );
$expiry_timestamp = $exptime;
$date = array(
'expiry' => $exp_date,
'expire_on' => $exp_date_email,
'expiry_timestamped' => $expiry_timestamp,
);
return $date;
}
public function create_coupon( $coupon_name, $meta_data ) {
$args = array(
'post_type' => 'shop_coupon',
'post_status' => 'publish',
'post_title' => $coupon_name,
);
$coupon_id = wp_insert_post( $args );
if ( ! is_wp_error( $coupon_id ) ) {
$meta_data['usage_count'] = 0;
if ( is_array( $meta_data ) && count( $meta_data ) > 0 ) {
foreach ( $meta_data as $key => $val ) {
update_post_meta( $coupon_id, $key, $val );
}
}
$result = $coupon_id;
return $result;
}
$errormsg = $coupon_id->get_error_message();
$result = array(
'err_msg' => $errormsg,
);
return $result;
}
/**
* @param $coupon_id
* @param $email
*
* @return void|WC_Coupon
*/
public function handle_coupon_restriction( $coupon_id, $email ) {
if ( ! is_email( $email ) ) {
return;
}
$coupon = new WC_Coupon( $coupon_id );
if ( 0 === $coupon->get_id() ) {
return;
}
$coupon->set_email_restrictions( [ $email ] );
$coupon->save();
return $coupon;
}
/**
* Execute the current action.
* Return 3 for successful execution , 4 for permanent failure.
*
* @param $action_data
*
* @return array
*/
public function execute_action( $action_data ) {
$this->set_data( $action_data['processed_data'] );
$result = $this->process();
if ( $this->fields_missing ) {
return array(
'status' => 4,
'message' => $result['body'][0],
);
}
if ( is_array( $result ) && count( $result ) > 0 ) { // Error in coupon creation
return array(
'status' => 4,
'message' => $result['err_msg'],
);
}
if ( ! is_integer( $result ) ) {
return array(
'status' => 4,
'message' => __( 'Coupon does not exist', 'wp-marketing-automations' ),
);
}
$get_type = get_post_field( 'post_type', $result );
if ( 'shop_coupon' !== $get_type ) {
return array(
'status' => 4,
'message' => __( 'Coupon does not exist', 'wp-marketing-automations' ),
);
}
return array(
'status' => 3,
/* translators: 1: Dynamic Data */ 'message' => sprintf( __( 'Coupon %1$s created', 'wp-marketing-automations' ), $this->data['coupon_name'] ),
);
}
/**
* Process and do the actual processing for the current action.
* This function is present in every action class.
*/
public function process() {
$is_required_fields_present = $this->check_fields( $this->data, $this->required_fields );
if ( false === $is_required_fields_present ) {
$this->fields_missing = true;
return $this->show_fields_error();
}
$data = $this->data;
$coupon_name = $data['coupon_name'];
$coupon_meta = $this->get_coupon_data( $data['coupon'] );
$get_wc_coupon = new WC_Coupon( $coupon_name );
$new_coupon_meta = $coupon_meta;
if ( $get_wc_coupon->get_id() === 0 ) {
/** Create a new coupon */
$new_coupon_meta['_is_bwfan_coupon'] = 1;
$new_coupon_meta['_bwfan_automation_id'] = $data['automation_id'];
$new_coupon_meta['expiry_date'] = '';
$new_coupon_meta['date_expires'] = '';
$new_coupon_meta['usage_count'] = '0';
$new_coupon_meta['customer_email'] = [];
if ( ! empty( $data['expiry'] ) && 0 < absint( $data['expiry'] ) ) {
$expiry = $this->get_expiry_dates( $data['expiry'] );
$new_coupon_meta['expiry_date'] = $expiry['expire_on'];
$new_coupon_meta['date_expires'] = $expiry['expiry_timestamped'];
}
$coupon_id = $this->create_coupon( $coupon_name, $new_coupon_meta );
if ( is_array( $coupon_id ) && count( $coupon_id ) > 0 ) {
/** Some error occurred while making coupon post */
return $coupon_id;
}
if ( 1 === absint( $data['restrict'] ) ) {
$this->handle_coupon_restriction( $coupon_id, $data['email'] );
}
do_action( 'bwfan_coupon_created', $coupon_id );
return $coupon_id;
} else {
/** Update an existing coupon */
$coupon_id = $get_wc_coupon->get_id();
$coupon_meta = [];
if ( ! empty( $data['expiry'] ) && 0 < absint( $data['expiry'] ) ) {
$expiry = $this->get_expiry_dates( $data['expiry'] );
$coupon_meta['expiry_date'] = $expiry['expire_on'];
$coupon_meta['date_expires'] = $expiry['expiry_timestamped'];
foreach ( $coupon_meta as $key => $val ) {
update_post_meta( $coupon_id, $key, $val );
}
}
if ( 1 === absint( $data['restrict'] ) ) {
$this->handle_coupon_restriction( $coupon_id, $data['email'] );
} else {
$get_wc_coupon->set_email_restrictions( [] );
$get_wc_coupon->save();
}
do_action( 'bwfan_coupon_created', $coupon_id );
return $coupon_id;
}
}
}
/**
* Register this action. Registering the action will make it eligible to see it on single automation screen in select actions dropdown.
*/
return 'BWFAN_WC_Create_Coupon';

View File

@@ -0,0 +1,2 @@
<?php
// Silence is golden.

View File

@@ -0,0 +1,40 @@
<?php
final class BWFAN_WC_Source extends BWFAN_Source {
// source type contains slug of current source. this helps events to become a child of a source
private static $instance = null;
/**
* Constructor
*
* @access public
*/
protected function __construct() {
$this->event_dir = __DIR__;
$this->nice_name = __( 'WooCommerce', 'wp-marketing-automations' );
$this->group_slug = 'wc';
$this->group_name = __( 'WooCommerce', 'wp-marketing-automations' );
$this->priority = 10;
}
/**
* Ensures only one instance of the class is loaded or can be loaded.
*
* @return BWFAN_WC_Source|null
*/
public static function get_instance() {
if ( null === self::$instance ) {
self::$instance = new self();
}
return self::$instance;
}
}
/**
* Register this as a source.
*/
if ( bwfan_is_woocommerce_active() ) {
BWFAN_Load_Sources::register( 'BWFAN_WC_Source' );
}

View File

@@ -0,0 +1,42 @@
<?php
final class BWFAN_WC_Integration extends BWFAN_Integration {
private static $instance = null;
/**
* Constructor
*
* @access public
*/
private function __construct() {
$this->action_dir = __DIR__;
$this->native_integration = true;
$this->nice_name = __( 'WooCommerce', 'wp-marketing-automations' );
$this->group_name = __( 'WooCommerce', 'wp-marketing-automations' );
$this->group_slug = 'wc';
$this->priority = 35;
}
/**
* Ensures only one instance of the class is loaded or can be loaded.
*
* @return BWFAN_Wc_Integration|null
*/
public static function get_instance() {
if ( null === self::$instance ) {
self::$instance = new self();
}
return self::$instance;
}
}
/**
* Register this class as an integration.
*/
if ( bwfan_is_woocommerce_active() ) {
BWFAN_Load_Integrations::register( 'BWFAN_WC_Integration' );
}

View File

@@ -0,0 +1,314 @@
<?php
final class BWFAN_WC_Comment_Post extends BWFAN_Event {
private static $instance = null;
public $comment_id = null;
public $comment_details = null;
private function __construct() {
$this->optgroup_label = esc_html__( 'Reviews', 'wp-marketing-automations' );
$this->event_name = esc_html__( 'Review Received', 'wp-marketing-automations' );
$this->event_desc = esc_html__( 'This event runs after a new review is submitted on a product.', 'wp-marketing-automations' );
$this->event_merge_tag_groups = array( 'bwf_contact', 'wc_product', 'wc_review' );
$this->event_rule_groups = array(
'wc_comment',
'bwf_contact_segments',
'bwf_contact',
'bwf_contact_fields',
'bwf_contact_user',
'bwf_contact_wc',
'bwf_contact_geo',
'bwf_engagement',
'bwf_broadcast'
);
$this->priority = 35;
$this->v2 = true;
$this->optgroup_priority = 30;
}
public function load_hooks() {
add_action( 'comment_post', array( $this, 'product_review' ), 10, 2 );
add_action( 'transition_comment_status', array( $this, 'my_approve_comment_callback' ), 20, 3 );
}
public static function get_instance() {
if ( null === self::$instance ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* This function is the callback function for comment hook
*
* @param $comment_id
* @param $status
*/
public function product_review( $comment_id, $status ) {
if ( 1 !== absint( $status ) ) {
return;
}
$this->process( $comment_id );
}
/**
* Make the required data for the current event and send it asynchronously.
*
* @param $comment_id
*/
public function process( $comment_id ) {
$data = $this->get_default_data();
$data['comment_id'] = $comment_id;
$this->send_async_call( $data );
}
/**
* Registers the tasks for current event.
*
* @param $automation_id
* @param $integration_data
* @param $event_data
*/
public function register_tasks( $automation_id, $integration_data, $event_data ) {
if ( ! is_array( $integration_data ) ) {
return;
}
$data_to_send = $this->get_event_data();
$this->create_tasks( $automation_id, $integration_data, $event_data, $data_to_send );
}
public function get_event_data() {
$data_to_send = [];
$data_to_send['global']['comment_id'] = $this->comment_details['comment_id'];
$data_to_send['global']['email'] = $this->comment_details['email'];
$data_to_send['global']['product_id'] = isset( $this->comment_details['product_id'] ) ? $this->comment_details['product_id'] : 0;
$data_to_send['global']['comment_message'] = isset( $this->comment_details['comment_message'] ) ? $this->comment_details['comment_message'] : '';
$data_to_send['global']['rating_number'] = isset( $this->comment_details['rating_number'] ) ? $this->comment_details['rating_number'] : '';
return $data_to_send;
}
/**
* This function gets fired when state of a comment is changed to approved
*
* @param $comment
*/
public function my_approve_comment_callback( $new_status, $old_status, $comment ) {
if ( 'approved' !== $new_status ) {
return;
}
$comment_id = $comment->comment_ID;
$this->process( $comment_id );
}
/**
* Make the view data for the current event which will be shown in task listing screen.
*
* @param $global_data
*
* @return false|string
*/
public function get_task_view( $global_data ) {
ob_start();
if ( ! is_array( $global_data ) ) {
return '';
}
if ( isset( $global_data['comment_id'] ) ) {
?>
<li>
<strong><?php esc_html_e( 'Comment ID:', 'wp-marketing-automations' ); ?> </strong>
<?php echo "<a href='" . get_edit_comment_link( $global_data['comment_id'] ) . "' target='blank'>" . esc_html( $global_data['comment_id'] ) . '</a>'; //phpcs:ignore WordPress.Security.EscapeOutput ?>
</li>
<?php
}
if ( isset( $global_data['email'] ) ) {
?>
<li>
<strong><?php esc_html_e( 'Email:', 'wp-marketing-automations' ); ?> </strong>
<?php echo $global_data['email']; //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
</li>
<?php
}
return ob_get_clean();
}
/**
* Set global data for all the merge tags which are supported by this event.
*
* @param $task_meta
*/
public function set_merge_tags_data( $task_meta ) {
$wc_comment_id = BWFAN_Merge_Tag_Loader::get_data( 'wc_comment_id' );
if ( empty( $wc_comment_id ) || $wc_comment_id !== $task_meta['global']['comment_id'] ) {
$set_data = array(
'wc_comment_id' => $task_meta['global']['comment_id'],
'email' => $task_meta['global']['email'],
'wc_comment_details' => $this->get_comment_feed( $task_meta['global']['comment_id'] ),
);
$set_data['user_id'] = $set_data['wc_comment_details']['user_id'];
$set_data['product_id'] = $set_data['wc_comment_details']['product_id'];
BWFAN_Merge_Tag_Loader::set_data( $set_data );
}
}
/**
*
* This function is a wrapper function and it returns a single feed for comment
*
* @param $comment_id
*
* @return array
*/
public function get_comment_feed( $comment_id ) {
$final_data = array();
$args = array(
'comment__in' => array( $comment_id ),
'post_type' => 'product',
);
$comment_details = get_comments( $args );
if ( ! is_array( $comment_details ) || 0 === count( $comment_details ) ) {
return $final_data;
}
$comment_details = $comment_details[0];
$single_feed_data = $this->get_single_comment_data( $comment_details );
if ( ! is_array( $single_feed_data ) || 0 === count( $single_feed_data ) ) {
return $final_data;
}
$final_data = $single_feed_data;
return $final_data;
}
/**
*
* This function makes a single feed data for a comment
*
* @param $comment_details
*
* @return array
*/
public function get_single_comment_data( $comment_details ) {
$comment_details = (array) $comment_details;
$single_feed_details = array();
$post_id = $comment_details['comment_post_ID'];
$product_details = get_post( $post_id );
$rating = get_comment_meta( $comment_details['comment_ID'], 'rating', true );
$single_feed_details['product_id'] = $product_details->ID;
$single_feed_details['product_name'] = $product_details->post_title;
$single_feed_details['full_name'] = $this->capitalize_word( $comment_details['comment_author'] );
$single_feed_details['comment_message'] = $comment_details['comment_content'];
$single_feed_details['email'] = $comment_details['comment_author_email'];
$single_feed_details['ip'] = $comment_details['comment_author_IP'];
$single_feed_details['rating_star'] = $rating;
$single_feed_details['rating_number'] = $rating;
$single_feed_details['is_verified'] = get_comment_meta( $comment_details['comment_ID'], 'verified', true );
$single_feed_details['user_id'] = $comment_details['user_id'];
$single_feed_details['comment_id'] = $comment_details['comment_ID'];
$single_feed_details['comment_date'] = $comment_details['comment_date_gmt'];
return $single_feed_details;
}
public function capitalize_word( $text ) {
return ucwords( strtolower( $text ) );
}
/**
* Recalculate action's execution time with respect to order date.
* eg.
* today is 22 jan.
* order was placed on 17 jan.
* user set an email to send after 10 days of order placing.
* user setup the sync process.
* email should be sent on 27 Jan as the order date was 17 jan.
*
* @param $actions
*
* @return mixed
* @throws Exception
*/
public function recalculate_actions_time( $actions ) {
$comment_date = $this->comment_details['comment_date'];
$comment_date = DateTime::createFromFormat( 'Y-m-d H:i:s', $comment_date );
$actions = $this->calculate_actions_time( $actions, $comment_date );
return $actions;
}
/**
* Capture the async data for the current event.
* @return array|bool
*/
public function capture_async_data() {
$comment_id = BWFAN_Common::$events_async_data['comment_id'];
$this->comment_id = $comment_id;
$this->comment_details = $this->get_comment_feed( $this->comment_id );
if ( ! isset( $this->comment_details['product_id'] ) ) {
return false;
}
return $this->run_automations();
}
/**
* Capture the async data for the current event.
* @return array|bool
*/
public function capture_v2_data( $automation_data ) {
$this->comment_id = BWFAN_Common::$events_async_data['comment_id'];
$this->comment_details = $this->get_comment_feed( $this->comment_id );
$this->comment_id = BWFAN_Common::$events_async_data['comment_id'];
$this->comment_details = $this->get_comment_feed( $this->comment_id );
$automation_data['comment_id'] = $this->comment_id;
$automation_data['rating_number'] = isset( $this->comment_details['rating_number'] ) ? $this->comment_details['rating_number'] : '';
return $automation_data;
}
/**
* Set up rules data
*
* @param $value
*/
public function pre_executable_actions( $value ) {
BWFAN_Core()->rules->setRulesData( $this->event_automation_id, 'automation_id' );
BWFAN_Core()->rules->setRulesData( $this->comment_details, 'wc_comment' );
BWFAN_Core()->rules->setRulesData( BWFAN_Common::get_bwf_customer( $this->get_email_event(), $this->get_user_id_event() ), 'bwf_customer' );
}
public function get_email_event() {
if ( ! isset( $this->comment_details['email'] ) ) {
return false;
}
return $this->comment_details['email'];
}
public function get_user_id_event() {
if ( ! isset( $this->comment_details['user_id'] ) ) {
return false;
}
return $this->comment_details['user_id'];
}
}
/**
* Register this event to a source.
* This will show the current event in dropdown in single automation screen.
*/
if ( bwfan_is_woocommerce_active() ) {
return 'BWFAN_WC_Comment_Post';
}

View File

@@ -0,0 +1,860 @@
<?php
final class BWFAN_WC_New_Order extends BWFAN_Event {
private static $instance = null;
// Environment variables for current event
public $order_id = null;
/** @var WC_Order $order */
public $order = null;
public $to_status = null;
public $has_run = 0;
private function __construct() {
$this->optgroup_label = esc_html__( 'Orders', 'wp-marketing-automations' );
$this->event_name = esc_html__( 'Order Created', 'wp-marketing-automations' );
$this->event_desc = esc_html__( 'This event runs after a new WooCommerce order is created. Can only run once on selected WC order statuses.', 'wp-marketing-automations' );
$this->event_merge_tag_groups = array( 'bwf_contact', 'wc_order' );
$this->event_rule_groups = array(
'wc_order',
'aerocheckout',
'bwf_contact_segments',
'bwf_contact',
'bwf_contact_fields',
'bwf_contact_user',
'bwf_contact_wc',
'bwf_contact_geo',
'bwf_engagement',
'bwf_broadcast'
);
$this->priority = 15;
$this->support_lang = true;
$this->v2 = true;
$this->is_goal = true;
$this->goal_name = esc_html__( 'Product Purchased', 'wp-marketing-automations' );
$this->supported_blocks = [ 'order' ];
$this->automation_add = true;
}
public static function get_instance() {
if ( null === self::$instance ) {
self::$instance = new self();
}
return self::$instance;
}
public function load_hooks() {
// event trigger hooks
add_action( 'woocommerce_new_order', [ $this, 'new_order' ], 11 );
add_action( 'bwfan_wc_order_status_changed', array( $this, 'bwfan_order_status_changed' ), 11, 3 );
add_filter( 'bwfan_wc_event_order_status_' . $this->get_slug(), array( $this, 'modify_order_statuses' ), 10, 1 );
// this filter tells if the logs should be made during sync process for the current event
add_filter( 'bwfan_before_making_logs', array( $this, 'check_if_bulk_process_executing' ), 10, 1 );
add_action( 'bwfan_sync_call_delete_tasks', array( $this, 'terminate_automations_tasks' ), 10, 2 );
}
/**
* Localize data for html fields for the current event.
*/
public function admin_enqueue_assets() {
if ( false === BWFAN_Common::is_load_admin_assets( 'automation' ) ) {
return;
}
$integration_data = $this->get_view_data();
BWFAN_Core()->admin->set_events_js_data( $this->get_slug(), 'order_status_options', $integration_data );
}
public function get_view_data() {
$all_status = wc_get_order_statuses();
if ( isset( $all_status['wc-cancelled'] ) ) {
unset( $all_status['wc-cancelled'] );
}
if ( isset( $all_status['wc-failed'] ) ) {
unset( $all_status['wc-failed'] );
}
if ( isset( $all_status['wc-refunded'] ) ) {
unset( $all_status['wc-refunded'] );
}
if ( isset( $all_status['wc-wfocu-pri-order'] ) ) {
unset( $all_status['wc-wfocu-pri-order'] );
}
asort( $all_status, SORT_REGULAR );
$all_status = apply_filters( 'bwfan_wc_event_order_status_' . $this->get_slug(), $all_status );
return apply_filters( 'bwfan_wc_event_order_status', $all_status );
}
/**
* Show the html fields for the current event.
*/
public function get_view( $db_eventmeta_saved_value ) {
?>
<script type="text/html" id="tmpl-event-<?php echo esc_attr( $this->get_slug() ); ?>">
<div class="bwfan-col-sm-12 bwfan-p-0 bwfan-mt-15">
<#
selected_statuses = (_.has(data, 'eventSavedData') &&_.has(data.eventSavedData, 'order_status')) ? data.eventSavedData.order_status : '';
is_validated = (_.has(data, 'eventSavedData') &&_.has(data.eventSavedData, 'validate_event')) ? 'checked' : '';
terminate_on_order = (_.has(data, 'eventSavedData') &&_.has(data.eventSavedData, 'terminate_on_order')) ? 'checked' : '';
#>
<label for="" class="bwfan-label-title"><?php echo esc_html__( 'Select Order Statuses', 'wp-marketing-automations' ); ?></label>
<#
if(_.has(data.eventFieldsOptions, 'order_status_options') && _.isObject(data.eventFieldsOptions.order_status_options) ) {
_.each( data.eventFieldsOptions.order_status_options, function( value, key ){
checked = '';
if(selected_statuses!='' && _.contains(selected_statuses, key)){
checked = 'checked';
}
#>
<div class="bwfan-checkboxes">
<input type="checkbox" name="event_meta[order_status][]" id="bwfan-{{key}}" value="{{key}}" class="bwfan-checkbox" data-warning="<?php echo esc_html__( 'Please select atleast 1 order status', 'wp-marketing-automations' ); ?>" {{checked}}/>
<label for="bwfan-{{key}}" class="bwfan-checkbox-label">{{value}}</label>
</div>
<# })
}
#>
<div class="clearfix bwfan_field_desc bwfan-pt-0">
This automation would run on new orders with selected statuses.
</div>
</div>
<#
if(1 == bwfanParams.pro_active){
#>
<div class="bwfan-col-sm-12 bwfan-p-0 bwfan-mt-15">
<label class="bwfan-label-title">End Automation</label>
<div>
<input type="checkbox" name="event_meta[terminate_on_order]" id="bwfan_end_automation" value="1" {{terminate_on_order}}/>
<label for="bwfan_end_automation" class="bwfan-checkbox-label"><?php esc_html_e( 'End automation if customer places the order during the automation', 'wp-marketing-automations' ) ?></label>
</div>
</div>
<#
}
#>
<?php
$this->get_validation_html( $this->get_slug(), 'Validate Order status before executing task', 'Validate' );
?>
</script>
<?php
}
/**
* Set up rules data
*
* @param $automation_data
*/
public function pre_executable_actions( $automation_data ) {
BWFAN_Core()->rules->setRulesData( $this->event_automation_id, 'automation_id' );
BWFAN_Core()->rules->setRulesData( $this->order, 'wc_order' );
BWFAN_Core()->rules->setRulesData( BWFAN_Common::get_bwf_customer( $this->order->get_billing_email(), $this->order->get_user_id() ), 'bwf_customer' );
}
/**
* Save active automation ids in order meta when a new order is created so that can be processed later on.
*
* @param $order_id
*/
public function new_order( $order_id ) {
$order = wc_get_order( $order_id );
if ( ! $order instanceof WC_Order ) {
return;
}
if ( BWFAN_Common::bwf_check_to_skip_child_order( $order_id ) ) {
BWFAN_Core()->logger->log( 'Skip child order for ID - ' . $order_id . ', Event - ' . $this->get_slug() . ' and function name ' . __FUNCTION__, $this->log_type );
return;
}
/** Check if v1 automations exists */
BWFAN_Core()->public->load_active_automations( $this->get_slug() );
$automation_not_found = false;
if ( ( ! is_array( $this->automations_arr ) || count( $this->automations_arr ) === 0 ) ) {
$automation_not_found = true;
}
if ( $automation_not_found ) {
BWFAN_Core()->logger->log( 'No active automations for order ID - ' . $order_id . ', Event - ' . $this->get_slug() . ' and function name ' . __FUNCTION__, $this->log_type );
return;
}
/** For v1 */
if ( count( $this->automations_arr ) > 0 ) {
$order->update_meta_data( '_bwfan_' . $this->get_slug(), count( $this->automations_arr ) );
$order->save_meta_data();
}
}
/**
* Returns the current event settings set in the automation at the time of task creation.
*
* @param $value
*
* @return array
*/
public function get_automation_event_data( $value ) {
return [
'event_source' => $value['source'],
'event_slug' => $value['event'],
'validate_event' => ( isset( $value['event_meta']['validate_event'] ) ) ? 1 : 0,
'order_status' => $value['event_meta']['order_status']
];
}
/**
* Registers the tasks for current event.
*
* @param $automation_id
* @param $integration_data
* @param $event_data
*/
public function register_tasks( $automation_id, $integration_data, $event_data ) {
if ( ! is_array( $integration_data ) ) {
return;
}
$data_to_send = $this->get_event_data();
$this->create_tasks( $automation_id, $integration_data, $event_data, $data_to_send );
}
public function get_event_data() {
$data_to_send = [];
$data_to_send['global']['order_id'] = $this->order_id;
$this->order = wc_get_order( $this->order_id );
$user_id = BWFAN_Common::get_wp_user_id_from_order( $this->order_id, $this->order );
$email = ! empty( $user_id ) ? BWFAN_Common::get_contact_email( $user_id ) : '';
/** Set billing email if email is empty */
$data_to_send['global']['email'] = ! empty( $email ) ? $email : BWFAN_Common::get_email_from_order( $this->order_id, $this->order );
$data_to_send['global']['phone'] = BWFAN_Common::get_phone_from_order( $this->order_id, $this->order );
if ( intval( $user_id ) > 0 ) {
$data_to_send['global']['user_id'] = $user_id;
}
$order_lang = BWFAN_Common::get_order_language( $this->order );
if ( ! empty( $order_lang ) ) {
$data_to_send['global']['language'] = $order_lang;
}
return $data_to_send;
}
public function terminate_automations_tasks( $email, $phone ) {
if ( empty( $email ) && empty( $phone ) ) {
return;
}
$event_slug = $this->get_slug();
$automations = BWFAN_Core()->automations->get_active_automations( 1, $event_slug );
$selected_automations = array();
foreach ( $automations as $automation_id => $automation ) {
if ( isset( $automation['meta']['event_meta']['terminate_on_order'] ) && $automation['meta']['event_meta']['terminate_on_order'] ) {
$selected_automations[] = $automation_id;
}
}
$schedule_tasks = [];
if ( ! empty( $email ) ) {
$schedule_tasks_email = BWFAN_Common::get_schedule_task_by_email( $selected_automations, $email );
$schedule_tasks = array_merge( $schedule_tasks, $schedule_tasks_email );
}
if ( ! empty( $phone ) ) {
$schedule_tasks_phone = BWFAN_Common::get_schedule_task_by_phone( $selected_automations, $phone );
$schedule_tasks = array_merge( $schedule_tasks, $schedule_tasks_phone );
}
$schedule_tasks = array_filter( $schedule_tasks );
if ( 0 === count( $schedule_tasks ) ) {
return;
}
$schedule_tasks = array_unique( $schedule_tasks );
foreach ( $schedule_tasks as $tasks ) {
if ( empty( $tasks ) ) {
continue;
}
$delete_tasks = array();
foreach ( $tasks as $task ) {
$delete_tasks[] = $task['ID'];
}
BWFAN_Core()->tasks->delete_tasks( $delete_tasks );
}
}
public function bwfan_order_status_changed( $order, $from_status, $to_status ) {
if ( ! $order instanceof WC_Order ) {
return;
}
$this->order_id = $order->get_id();
$this->order = $order;
if ( BWFAN_Common::bwf_check_to_skip_child_order( $this->order_id ) ) {
BWFAN_Core()->logger->log( 'Skip child order for ID - ' . $this->order_id . ', Event - ' . $this->get_slug() . ' and function name ' . __FUNCTION__, $this->log_type );
return;
}
/** Check if automations v1 or v2 exists */
BWFAN_Core()->public->load_active_automations( $this->get_slug() );
BWFAN_Core()->public->load_active_v2_automations( $this->get_slug() );
$automation_not_found = false;
/** No v1 or v2 automations */
if ( ( ! is_array( $this->automations_arr ) || count( $this->automations_arr ) === 0 ) && ( ! is_array( $this->automations_v2_arr ) || count( $this->automations_v2_arr ) === 0 ) ) {
$automation_not_found = true;
}
/** Check for goals */
if ( true === $automation_not_found ) {
$automation_not_found = empty( $this->get_current_goal_automations() );
}
if ( true === $automation_not_found ) {
BWFAN_Core()->logger->log( 'No active automations for order ID - ' . $this->order_id . ', Event - ' . $this->get_slug() . ' and function name ' . __FUNCTION__, $this->log_type );
return;
}
$to_status = 'wc-' . $to_status;
$this->to_status = $to_status;
$this->process( $this->order_id );
$this->to_status = null;
}
/**
* Make the required data for the current event.
*
* @param $order_id
*/
public function process( $order_id ) {
$data = $this->get_default_data();
$data['order_id'] = $order_id;
$data['email'] = $this->order->get_billing_email();
$data['phone'] = $this->order->get_billing_phone();
if ( ! is_null( $this->to_status ) ) {
$data['to_status'] = $this->to_status;
}
/** Run v2 automation */
BWFAN_Common::maybe_run_v2_automations( $this->get_slug(), $data );
/** Run v1 automation */
if ( count( $this->automations_arr ) > 0 ) {
$this->order->delete_meta_data( '_bwfan_' . $this->get_slug() );
$this->order->save_meta_data();
$this->run_automations();
}
}
/**
* Make the view data for the current event which will be shown in task listing screen.
*
* @param $global_data
*
* @return false|string
*/
public function get_task_view( $global_data ) {
ob_start();
$order = wc_get_order( $global_data['order_id'] );
if ( $order instanceof WC_Order ) {
?>
<li>
<strong><?php echo esc_html__( 'Order:', 'wp-marketing-automations' ); ?> </strong>
<a target="_blank" href="<?php echo get_edit_post_link( $global_data['order_id'] ); //phpcs:ignore WordPress.Security.EscapeOutput
?>"><?php echo '#' . esc_attr( $global_data['order_id'] . ' ' . $order->get_billing_first_name() . ' ' . $order->get_billing_last_name() ); ?></a>
</li>
<?php } ?>
<li>
<strong><?php echo esc_html__( 'Email:', 'wp-marketing-automations' ); ?> </strong>
<?php echo $global_data['email']; //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
</li>
<?php
return ob_get_clean();
}
/**
* This function decides if the task has to be executed or not.
* The event has validate checkbox in its meta fields.
*
* @param $task_details
*
* @return array|mixed
*/
public function validate_event( $task_details ) {
$result = [];
$task_event = $task_details['event_data']['event_slug'];
$automation_id = $task_details['processed_data']['automation_id'];
$automation_details = BWFAN_Model_Automations::get( $automation_id );
$current_automation_event = $automation_details['event'];
$current_automation_event_meta = BWFAN_Model_Automationmeta::get_meta( $automation_id, 'event_meta' );
$current_automation_event_validation_status = ( isset( $current_automation_event_meta['validate_event'] ) ) ? $current_automation_event_meta['validate_event'] : 0;
$current_automation_order_statuses = $current_automation_event_meta['order_status'];
// Current automation has no checking
if ( 0 === $current_automation_event_validation_status ) {
return $this->get_automation_event_validation();
}
// Current automation event does not match with the event of task when the task was made
if ( $task_event !== $current_automation_event ) {
return $this->get_automation_event_status();
}
$order_id = $task_details['processed_data']['order_id'];
$order = wc_get_order( $order_id );
$task_order_status = BWFAN_Woocommerce_Compatibility::get_order_status( $order );
if ( in_array( $task_order_status, $current_automation_order_statuses, true ) ) {
return $this->get_automation_event_success();
}
$result['status'] = 4;
$result['message'] = esc_html__( 'Order status in automation has been changed', 'wp-marketing-automations' );
return $result;
}
public function validate_event_data_before_executing_task( $data ) {
return $this->validate_order( $data );
}
/**
* validate v2 event settings
* @return bool
*/
public function validate_v2_event_settings( $automation_data ) {
/** validate settings */
$current_automation_order_statuses = ( isset( $automation_data['event_meta'] ) && isset( $automation_data['event_meta']['order_status'] ) ) ? $automation_data['event_meta']['order_status'] : array();
$task_order_status = $automation_data['to_status'];
/** check order status with automation setting */
if ( ! in_array( $task_order_status, $current_automation_order_statuses, true ) ) {
return false;
}
/** validate order */
if ( false === $this->validate_order( $automation_data ) ) {
return false;
}
/** Validate automation if contact is already exists with same order */
if ( false === $this->validate_automation( $automation_data ) ) {
return false;
}
return BWFAN_Common::validate_create_order_event_setting( $automation_data );
}
/**
* @param $automation_data
*
* @return bool
*/
public function validate_automation( $automation_data ) {
$this->order_id = $automation_data['order_id'];
$global_data = BWFAN_Common::get_global_data( $this->get_event_data() );
$cid = isset( $global_data['global']['contact_id'] ) ? $global_data['global']['contact_id'] : 0;
$cid = empty( $cid ) && isset( $global_data['global']['cid'] ) ? $global_data['global']['cid'] : $cid;
if ( empty( $cid ) ) {
return false;
}
/** Check if contact is already exists in automation with same order */
if ( BWFAN_Common::is_contact_in_automation( $automation_data['id'], $cid, $this->order_id, '', $this->get_slug() ) ) {
return false;
}
return true;
}
/**
* Before starting automation on a contact, validating if cart row exists
*
* @param $row
*
* @return bool
*/
public function validate_v2_before_start( $row ) {
if ( empty( $row['data'] ) ) {
return false;
}
$data = isset( $row['data'] ) ? json_decode( $row['data'], true ) : [];
$data = isset( $data['global'] ) ? $data['global'] : [];
return $this->validate_order( $data );
}
public function validate_goal_settings( $automation_settings, $automation_data ) {
if ( ! is_array( $automation_settings ) || ! is_array( $automation_data ) || ! isset( $automation_settings['order_status'] ) || ! isset( $automation_data['order_id'] ) ) {
return false;
}
$order_id = absint( $automation_data['order_id'] );
$order = wc_get_order( $order_id );
if ( ! $order instanceof WC_Order ) {
return false;
}
$status_selected = $automation_settings['order_status'];
if ( ! is_array( $status_selected ) || empty( $status_selected ) ) {
return false;
}
$order_status = $automation_data['to_status'];
$order_status = empty( $order_status ) ? $order->get_status() : $order_status;
/** Order status not matched */
if ( ! in_array( $order_status, $status_selected ) ) {
return false;
}
/** Any product case */
if ( 'any' === $automation_settings['order-contains'] ) {
return true;
}
/** Specific product case */
$get_selected_product = $automation_settings['products'];
$order_items = $order->get_items();
$ordered_products = array();
foreach ( $order_items as $item ) {
$product_id = $item->get_product_id();
$ordered_products[] = $product_id;
/** In case variation */
if ( $item->get_variation_id() ) {
$ordered_products[] = $item->get_variation_id();
}
}
$product_selected = empty( $get_selected_product ) ? [] : array_column( $get_selected_product, 'id' );
$ordered_products = array_unique( $ordered_products );
sort( $ordered_products );
return count( array_intersect( $product_selected, $ordered_products ) ) > 0;
}
/**
* Capture the async data for the current event.
*
* @return array|bool|void
*/
public function capture_async_data() {
$order_id = BWFAN_Common::$events_async_data['order_id'];
if ( isset( BWFAN_Common::$events_async_data['to_status'] ) ) {
$this->to_status = BWFAN_Common::$events_async_data['to_status'];
}
$this->order_id = $order_id;
$order = wc_get_order( $order_id );
if ( ! $order instanceof WC_Order ) {
return;
}
$order->delete_meta_data( '_bwfan_' . $this->get_slug() );
$order->save();
$this->order = $order;
return $this->run_automations();
}
/**
* Get Contact ID for goal
*/
public function get_contact_id_for_goal( $capture_args ) {
if ( ! is_array( $capture_args ) || ! isset( $capture_args['order_id'] ) || empty( $capture_args['order_id'] ) || ! bwfan_is_woocommerce_active() ) {
return 0;
}
$order = wc_get_order( absint( $capture_args['order_id'] ) );
if ( ! $order instanceof WC_Order ) {
return 0;
}
$email = $order->get_billing_email();
$user_id = $order->get_user_id();
$contact = new WooFunnels_Contact( $user_id, $email );
if ( ! $contact instanceof WooFunnels_Contact || 0 === absint( $contact->get_id() ) ) {
return 0;
}
return absint( $contact->get_id() );
}
public function handle_single_automation_run( $automation_data, $automation_id ) {
/** If current status or order is same as the order status selected by user in automation */
if ( isset( $automation_data['event_meta']['order_status'] ) && is_array( $automation_data['event_meta']['order_status'] ) && ( in_array( $this->to_status, $automation_data['event_meta']['order_status'], true ) ) ) {
return parent::handle_single_automation_run( $automation_data, $automation_id );
}
/** History sync handling */
if ( ! empty( $this->user_selected_actions ) ) {
return parent::handle_single_automation_run( $automation_data, $automation_id );
}
$meta_automations = $this->order->get_meta( '_bwfan_' . $this->get_slug() );
$meta_automations = ( ! is_array( $meta_automations ) ) ? [] : $meta_automations;
$meta_automations[] = $automation_id;
$meta_automations = array_filter( array_unique( $meta_automations ) );
$this->order->update_meta_data( '_bwfan_' . $this->get_slug(), maybe_serialize( $meta_automations ) ); // Update order meta so that we can check if task for this order should be made or not on order status change hook
$this->order->save();
return false;
}
public function modify_order_statuses( $statuses ) {
unset( $statuses['wc-pending'] );
return $statuses;
}
/**
* @param $actions
*
* Recalculate action's execution time with respect to order date.
*
* @return mixed
* @throws Exception
*/
public function recalculate_actions_time( $actions ) {
$order_date = BWFAN_Woocommerce_Compatibility::get_order_date( $this->order );
return $this->calculate_actions_time( $actions, $order_date );
}
/** v2 Methods: START */
public function get_fields_schema() {
$arr = [
[
'id' => 'order_status',
'label' => __( 'Order Statuses', 'wp-marketing-automations' ),
'type' => 'checkbox_grid',
'class' => '',
'placeholder' => '',
'required' => true,
"errorMsg" => __( 'Select at least one status.', 'wp-marketing-automations' ),
'options' => $this->get_view_data(),
'hint' => __( 'This automation would run on new orders with selected statuses.', 'wp-marketing-automations' ),
],
[
'id' => 'order-contains',
'label' => __( 'Order Contains', 'wp-marketing-automations' ),
'type' => 'radio',
'options' => [
[
'label' => __( 'Any Product', 'wp-marketing-automations' ),
'value' => 'any'
],
[
'label' => __( 'Specific Products', 'wp-marketing-automations' ),
'value' => 'selected_product'
],
],
"class" => 'bwfan-input-wrapper',
"tip" => "",
"required" => false,
"description" => ""
],
];
if ( bwfan_is_autonami_pro_active() ) {
$arr[] = [
'id' => 'products',
'label' => __( 'Select Products', 'wp-marketing-automations' ),
'type' => 'search',
'autocompleter' => 'products',
'class' => '',
'placeholder' => '',
'required' => true,
'toggler' => [
'fields' => [
[
'id' => 'order-contains',
'value' => 'selected_product',
]
]
],
];
} else {
$arr[] = [
'id' => 'products',
'type' => 'notice',
'class' => '',
'status' => 'warning',
'message' => __( 'This is a Pro feature.', 'wp-marketing-automations' ),
'dismiss' => false,
'required' => false,
'toggler' => [
'fields' => [
[
'id' => 'order-contains',
'value' => 'selected_product',
]
]
],
];
}
return $arr;
}
/**
* Goal schema
*
* @return array[]
*/
public function get_goal_fields_schema() {
return [
[
'id' => 'order_status',
'label' => __( 'Order Statuses', 'wp-marketing-automations' ),
'type' => 'checkbox_grid',
'class' => '',
'placeholder' => '',
'required' => true,
"errorMsg" => __( 'Select at least one status.', 'wp-marketing-automations' ),
'options' => $this->get_view_data(),
'hint' => __( 'The goal will be met if the new order has the selected order status.', 'wp-marketing-automations' ),
],
[
'id' => 'order-contains',
'label' => __( 'Order Contains', 'wp-marketing-automations' ),
'type' => 'radio',
'options' => [
[
'label' => __( 'Any Product', 'wp-marketing-automations' ),
'value' => 'any'
],
[
'label' => __( 'Specific Products', 'wp-marketing-automations' ),
'value' => 'selected_product'
],
],
"class" => 'bwfan-input-wrapper',
"tip" => "",
"required" => true,
"description" => ""
],
[
'id' => 'products',
'label' => __( 'Select Products', 'wp-marketing-automations' ),
'type' => 'search',
'autocompleter' => 'products',
'class' => '',
'placeholder' => '',
'required' => false,
'hint' => __( 'The goal will be met if at least one of the selected product is purchased.', 'wp-marketing-automations' ),
'toggler' => [
'fields' => [
[
'id' => 'order-contains',
'value' => 'selected_product',
]
]
],
],
];
}
/**
* Default values for goal values
*
* @return array
*/
public function get_default_goal_values() {
return [
'order-contains' => 'any'
];
}
public function get_desc_text( $data ) {
$data = json_decode( wp_json_encode( $data ), true );
if ( ! isset( $data['order_status'] ) || empty( $data['order_status'] ) ) {
return '';
}
$statues = [];
$options = $this->get_view_data();
foreach ( $data['order_status'] as $status ) {
if ( ! isset( $options[ $status ] ) || empty( $options[ $status ] ) ) {
continue;
}
$statues[] = $options[ $status ];
}
return $statues;
}
/** v2 Methods: END */
/** set default values */
public function get_default_values() {
return [
'order-contains' => 'any'
];
}
/**
* get contact automation data
*
* @param $automation_data
* @param $cid
*
* @return array|null[]
*/
public function get_manually_added_contact_automation_data( $automation_data, $cid ) {
$contact = new WooFunnels_Contact( '', '', '', $cid );
/** Check if contact exists */
if ( ! $contact instanceof WooFunnels_Contact || empty( $contact->get_id() ) ) {
return [ 'status' => 0, 'type' => 'contact_not_found' ];
}
$order = BWFAN_Common::fetch_last_order_by_contact( $contact );
if ( empty( $order ) || ! $order[0] instanceof WC_Order ) {
return [ 'status' => 0, 'type' => '', 'message' => __( "Contact doesn't have any order.", 'wp-marketing-automations' ) ];
}
$this->order_id = $order[0]->get_id();
$this->to_status = 'wc-' . $order[0]->get_status();
$automation_data = array_merge( $automation_data, [ 'order_id' => $this->order_id, 'to_status' => $this->to_status ] );
if ( BWFAN_Common::validate_create_order_event_setting( $automation_data ) === false ) {
return [ 'status' => 0, 'type' => '', 'message' => __( "No Ordered Products are matching with event products.", 'wp-marketing-automations' ) ];
}
return $automation_data;
}
}
/**
* Register this event to a source.
* This will show the current event in dropdown in single automation screen.
*/
if ( bwfan_is_woocommerce_active() ) {
return 'BWFAN_WC_New_Order';
}

View File

@@ -0,0 +1,433 @@
<?php
/**
*
* This class work only for admin created note `not for checkout order not field`
* Class BWFAN_WC_Order_Note_Added\
*/
final class BWFAN_WC_Order_Note_Added extends BWFAN_Event {
private static $instance = null;
public $order_id = null;
public $order = null;
private $is_customer_note = false;
private $comment_content = '';
private $order_note_types = [];
private function __construct() {
$this->optgroup_label = esc_html__( 'Orders', 'wp-marketing-automations' );
$this->event_name = esc_html__( 'Order Note Added', 'wp-marketing-automations' );
$this->event_desc = esc_html__( 'This event runs after a new order note is added.', 'wp-marketing-automations' );
$this->event_merge_tag_groups = array( 'bwf_contact', 'wc_order' );
$this->event_rule_groups = array(
'wc_order',
'aerocheckout',
'bwf_contact_segments',
'bwf_contact',
'bwf_contact_fields',
'bwf_contact_user',
'bwf_contact_wc',
'bwf_contact_geo',
'bwf_engagement',
'bwf_broadcast'
);
$this->priority = 15.5;
$this->support_lang = true;
$this->order_note_types = [
'both' => __( 'Both', 'wp-marketing-automations' ),
'private' => __( 'Private', 'wp-marketing-automations' ),
'public' => __( 'Customer', 'wp-marketing-automations' ),
];
$this->v2 = true;
$this->supported_blocks = [ 'order' ];
}
public static function get_instance() {
if ( null === self::$instance ) {
self::$instance = new self();
}
return self::$instance;
}
public function load_hooks() {
add_filter( 'woocommerce_new_order_note_data', [ $this, 'process_note' ], 10, 2 );
}
/**
* Localize data for html fields for the current event.
*/
public function admin_enqueue_assets() {
BWFAN_Core()->admin->set_events_js_data( $this->get_slug(), 'order_note_type', $this->order_note_types );
}
/**
* Returns the current event settings set in the automation at the time of task creation.
*
* @param $value
*
* @return array
*/
public function get_automation_event_data( $value ) {
return [
'event_source' => $value['source'],
'event_slug' => $value['event'],
'validate_event' => ( isset( $value['event_meta']['validate_event'] ) ) ? 1 : 0,
];
}
public function validate_event_data_before_executing_task( $data ) {
return $this->validate_order( $data );
}
/**
* Make the view data for the current event which will be shown in task listing screen.
*
* @param $global_data
*
* @return false|string
*/
public function get_task_view( $global_data ) {
ob_start();
$order = wc_get_order( $global_data['order_id'] );
if ( $order instanceof WC_Order ) {
?>
<li>
<strong><?php esc_html_e( 'Order:', 'wp-marketing-automations' ); ?> </strong>
<a target="_blank" href="<?php echo get_edit_post_link( $global_data['order_id'] ); //phpcs:ignore WordPress.Security.EscapeOutput
?>"><?php echo '#' . wp_strip_all_tags( $global_data['order_id'] . ' ' . $order->get_billing_first_name() . ' ' . $order->get_billing_last_name() ); //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></a>
</li>
<?php } ?>
<li>
<strong><?php esc_html_e( 'Email:', 'wp-marketing-automations' ); ?> </strong>
<?php echo $global_data['email']; //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
</li>
<?php if ( isset( $global_data['current_order_note'] ) ) { ?>
<li>
<strong><?php esc_html_e( 'Content:', 'wp-marketing-automations' ); ?> </strong>
<?php echo $global_data['current_order_note']; //phpcs:ignore WordPress.Security.EscapeOutput ?>
</li>
<?php } ?>
<li>
<strong><?php esc_html_e( 'Type:', 'wp-marketing-automations' ); ?> </strong>
<?php
if ( wc_string_to_bool( $global_data['order_customer_note_type'] ) ) {
esc_html_e( 'Note to customer', 'woocommerce' ); // phpcs:ignore WordPress.WP.I18n.TextDomainMismatch
} else {
esc_html_e( 'Private note', 'woocommerce' ); // phpcs:ignore WordPress.WP.I18n.TextDomainMismatch
}
?>
</li>
<?php
return ob_get_clean();
}
/**
* Show the html fields for the current event.
*/
public function get_view( $db_eventmeta_saved_value ) {
?>
<script type="text/html" id="tmpl-event-<?php echo esc_attr( $this->get_slug() ); ?>">
<div class="bwfan_mt15"></div>
<label for="bwfan-select-box-order-note" class="bwfan-label-title"><?php esc_html_e( 'Select Order Note Mode', 'wp-marketing-automations' ); ?></label>
<div class="bwfan-select-box">
<#
selected_statuses = (_.has(data, 'eventSavedData') &&_.has(data.eventSavedData, 'bwfan_order_note_type')) ? data.eventSavedData.bwfan_order_note_type : 'both';
#>
<select name="event_meta[bwfan_order_note_type]" id="bwfan-select-box-order-note" class="bwfan-input-wrapper">
<#
if(_.has(bwfan_events_js_data, 'wc_order_note_added') && _.isObject(bwfan_events_js_data.wc_order_note_added.order_note_type) ) {
_.each( bwfan_events_js_data.wc_order_note_added.order_note_type, function( title, key ){
selected = (key == selected_statuses) ? 'selected' : '';
#>
<option value="{{key}}" {{selected}}>{{title}}</option>
<# })
}
#>
</select>
</div>
</script>
<?php
}
/**
* Admin add customer note
*
* @param $comment_data
* @param $data
*
* @return mixed
*/
public function process_note( $comment_data, $data ) {
$order = wc_get_order( $comment_data['comment_post_ID'] );
if ( ! $order instanceof WC_Order || 'shop_order' !== $order->get_type() || $comment_data['comment_type'] !== 'order_note' ) {
return $comment_data;
}
$data['comment_content'] = $comment_data['comment_content'];
$this->process( $data );
return $comment_data;
}
/**
* Make the required data for the current event and send it asynchronously.
*
* @param $comment_data
*/
public function process( $comment_data ) {
$data = $this->get_default_data();
$data['order_id'] = $comment_data['order_id'];
$data['comment_content'] = $comment_data['comment_content'];
$data['is_customer_note'] = $comment_data['is_customer_note'];
$this->send_async_call( $data );
}
/**
* Capture the async data for the current event.
* @return array|bool
*/
public function capture_async_data() {
$order_id = BWFAN_Common::$events_async_data['order_id'];
$this->comment_content = BWFAN_Common::$events_async_data['comment_content'];
$this->is_customer_note = BWFAN_Common::$events_async_data['is_customer_note'];
$this->order_id = $order_id;
$this->order = wc_get_order( $order_id );
return $this->run_automations();
}
public function run_automations() {
BWFAN_Core()->public->load_active_automations( $this->get_slug() );
if ( ! is_array( $this->automations_arr ) || count( $this->automations_arr ) === 0 ) {
BWFAN_Core()->logger->log( 'Async callback: No active automations found. Event - ' . $this->get_slug(), $this->log_type );
return false;
}
$automation_actions = [];
foreach ( $this->automations_arr as $automation_id => $value1 ) {
if ( $this->get_slug() !== $value1['event'] ) {
continue;
}
if ( ! isset( $value1['actions'] ) || empty( $value1['actions'] ) ) {
continue;
}
$ran_actions = $this->handle_single_automation_run( $value1, $automation_id );
$automation_actions[ $automation_id ] = $ran_actions;
}
return $automation_actions;
}
/**
* Set up rules data
*
* @param $value
*/
public function pre_executable_actions( $value ) {
BWFAN_Core()->rules->setRulesData( $this->event_automation_id, 'automation_id' );
BWFAN_Core()->rules->setRulesData( $this->order, 'wc_order' );
BWFAN_Core()->rules->setRulesData( $this->comment_content, 'wc_order_note' );
BWFAN_Core()->rules->setRulesData( BWFAN_Common::get_bwf_customer( $this->order->get_billing_email(), $this->order->get_user_id() ), 'bwf_customer' );
}
/**
* Registers the tasks for current event.
*
* @param $automation_id
* @param $integration_data
* @param $event_data
*/
public function register_tasks( $automation_id, $integration_data, $event_data ) {
if ( ! is_array( $integration_data ) ) {
return;
}
$meta = BWFAN_Model_Automationmeta::get_meta( $automation_id, 'event_meta' );
if ( '' === $meta || ! is_array( $meta ) || ! isset( $meta['bwfan_order_note_type'] ) ) {
return;
}
/** @var bool $note_type - if true then public */
$note_type = wc_string_to_bool( $this->is_customer_note );
$save_type = $meta['bwfan_order_note_type'];
$register_task = false;
if ( 'both' === $save_type ) {
$register_task = true;
} elseif ( 'public' === $save_type && true === $note_type ) {
$register_task = true;
} elseif ( 'private' === $save_type && true !== $note_type ) {
$register_task = true;
}
if ( false === $register_task ) {
return;
}
$data_to_send = $this->get_event_data( $save_type );
$this->create_tasks( $automation_id, $integration_data, $event_data, $data_to_send );
}
public function get_event_data( $save_type = '' ) {
$data_to_send = [];
$data_to_send['global']['order_id'] = $this->order_id;
$data_to_send['global']['current_order_note'] = $this->comment_content;
$data_to_send['global']['order_customer_note_type'] = $this->is_customer_note;
if ( ! is_array( $save_type ) ) {
$data_to_send['global']['order_save_note_type'] = $save_type;
}
$this->order = wc_get_order( $this->order_id );
$user_id = BWFAN_Common::get_wp_user_id_from_order( $this->order_id, $this->order );
if ( intval( $user_id ) > 0 ) {
$data_to_send['global']['user_id'] = $user_id;
}
$email = ! empty( $user_id ) ? BWFAN_Common::get_contact_email( $user_id ) : '';
/** Set billing email if email is empty */
$data_to_send['global']['email'] = ! empty( $email ) ? $email : BWFAN_Common::get_email_from_order( $this->order_id, $this->order );
$data_to_send['global']['phone'] = BWFAN_Common::get_phone_from_order( $this->order_id, $this->order );
$order_lang = BWFAN_Common::get_order_language( $this->order );
if ( ! empty( $order_lang ) ) {
$data_to_send['global']['language'] = $order_lang;
}
return $data_to_send;
}
public function set_merge_tags_data( $task_meta ) {
parent::set_merge_tags_data( $task_meta );
$merge_data = BWFAN_Merge_Tag_Loader::get_data();
$merge_data['current_order_note'] = $task_meta['global']['current_order_note'];
BWFAN_Merge_Tag_Loader::set_data( $merge_data );
}
/**
* Validate v2 event settings
*
* @param $automation_data
*
* @return bool
*/
public function validate_v2_event_settings( $automation_data ) {
if ( ! isset( $automation_data['version'] ) || 2 !== intval( $automation_data['version'] ) ) {
return false;
}
/** Checking if valid order */
if ( ! $this->validate_order( $automation_data ) ) {
return false;
}
if ( 'both' === $automation_data['event_meta'] ['bwfan_order_note_type'] ) {
return $this->note_text_matches( $automation_data );
}
if ( 'public' === $automation_data['event_meta'] ['bwfan_order_note_type'] && $automation_data['is_customer_note'] ) {
return $this->note_text_matches( $automation_data );
}
if ( 'private' === $automation_data['event_meta'] ['bwfan_order_note_type'] && ! $automation_data['is_customer_note'] ) {
return $this->note_text_matches( $automation_data );
}
return false;
}
/**
* Validate the note text
*
* @param $automation_data
*
* @return bool
*/
protected function note_text_matches( $automation_data ) {
if ( ! isset( $automation_data['event_meta'] ) || ! isset( $automation_data['event_meta']['bwfan_note_text_matches'] ) || empty( trim( $automation_data['event_meta']['bwfan_note_text_matches'] ) ) ) {
return true;
}
$text_to_match = $automation_data['event_meta']['bwfan_note_text_matches'];
$text_to_match = trim( $text_to_match );
if ( false !== strpos( $automation_data['comment_content'], $text_to_match ) ) {
return true;
}
return false;
}
/**
* Capture the async data for the current event.
* @return array|bool
*/
public function capture_v2_data( $automation_data ) {
$this->order_id = BWFAN_Common::$events_async_data['order_id'];
$this->comment_content = BWFAN_Common::$events_async_data['comment_content'];
$this->is_customer_note = BWFAN_Common::$events_async_data['is_customer_note'];
$automation_data['order_id'] = $this->order_id;
$automation_data['comment_content'] = $this->comment_content;
$automation_data['is_customer_note'] = $this->is_customer_note;
return $automation_data;
}
/**
* v2 Method: Get fields schema
* @return array[][]
*/
public function get_fields_schema() {
$note_types = BWFAN_Common::prepared_field_options( $this->order_note_types );
return [
[
'id' => 'bwfan_order_note_type',
'type' => 'wp_select',
'options' => $note_types,
'label' => __( 'Select Order Note Mode', 'wp-marketing-automations' ),
"class" => 'bwfan-input-wrapper',
"placeholder" => __( 'Select', 'wp-marketing-automations' ),
"required" => true,
"errorMsg" => __( 'Select note type.', 'wp-marketing-automations' ),
"description" => ""
],
[
'id' => 'bwfan_note_text_matches',
'type' => 'text',
'label' => __( 'Note Text Matches', 'wp-marketing-automations' ),
"class" => 'bwfan-input-wrapper',
"placeholder" => '',
"required" => false,
"description" => ""
],
];
}
/** set default values */
public function get_default_values() {
return [
'bwfan_order_note_type' => 'both',
];
}
}
/**
* Register this event to a source.
* This will show the current event in dropdown in single automation screen.
*/
if ( bwfan_is_woocommerce_active() ) {
return 'BWFAN_WC_Order_Note_Added';
}

View File

@@ -0,0 +1,558 @@
<?php
final class BWFAN_WC_Order_Status_Change extends BWFAN_Event {
private static $instance = null;
public $order_id = null;
public $from_status = null;
public $to_status = null;
public $order = null;
private function __construct() {
$this->optgroup_label = esc_html__( 'Orders', 'wp-marketing-automations' );
$this->event_name = esc_html__( 'Order Status Changed', 'wp-marketing-automations' );
$this->event_desc = esc_html__( 'This event runs after an order status is changed.', 'wp-marketing-automations' );
$this->event_merge_tag_groups = array( 'bwf_contact', 'wc_order' );
$this->event_rule_groups = array(
'wc_order',
'aerocheckout',
'wc_order_state',
'bwf_contact_segments',
'bwf_contact',
'bwf_contact_fields',
'bwf_contact_user',
'bwf_contact_wc',
'bwf_contact_geo',
'bwf_engagement',
'bwf_broadcast'
);
$this->priority = 15.2;
$this->support_lang = true;
$this->v2 = true;
$this->supported_blocks = [ 'order' ];
}
public function load_hooks() {
add_action( 'bwfan_wc_order_status_changed', array( $this, 'order_status_changed' ), 11, 3 );
}
public static function get_instance() {
if ( null === self::$instance ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Localize data for html fields for the current event.
*/
public function admin_enqueue_assets() {
if ( false === BWFAN_Common::is_load_admin_assets( 'automation' ) ) {
return;
}
$wc_order_statuses = $this->get_view_data();
$to_wc_order_statuses = $this->get_view_data();
if ( isset( $to_wc_order_statuses['wc-pending'] ) ) {
unset( $to_wc_order_statuses['wc-pending'] );
}
BWFAN_Core()->admin->set_events_js_data( $this->get_slug(), 'from_options', $wc_order_statuses );
BWFAN_Core()->admin->set_events_js_data( $this->get_slug(), 'to_options', $to_wc_order_statuses );
}
public function get_view_data() {
return wc_get_order_statuses();
}
/**
* Show the html fields for the current event.
*/
public function get_view( $db_eventmeta_saved_value ) {
?>
<script type="text/html" id="tmpl-event-<?php echo esc_attr( $this->get_slug() ); ?>">
<#
is_validated = (_.has(data, 'eventSavedData') &&_.has(data.eventSavedData, 'validate_event')) ? 'checked' : '';
selected_from_status = (_.has(data, 'eventSavedData') &&_.has(data.eventSavedData, 'from')) ? data.eventSavedData.from : '';
selected_to_status = (_.has(data, 'eventSavedData') &&_.has(data.eventSavedData, 'to')) ? data.eventSavedData.to : '';
#>
<div class="bwfan_mt15"></div>
<div class="bwfan-col-sm-6 bwfan-pl-0">
<label for="" class="bwfan-label-title"><?php esc_html_e( 'From Status', 'wp-marketing-automations' ); ?></label>
<select required id="" class="bwfan-input-wrapper" name="event_meta[from]">
<option value="wc-any"><?php esc_html_e( 'Any', 'wp-marketing-automations' ); ?></option>
<#
if(_.has(data.eventFieldsOptions, 'from_options') && _.isObject(data.eventFieldsOptions.from_options) ) {
_.each( data.eventFieldsOptions.from_options, function( value, key ){
selected = (key == selected_from_status) ? 'selected' : '';
#>
<option value="{{key}}" {{selected}}>{{value}}</option>
<# })
}
#>
</select>
</div>
<div class="bwfan-col-sm-6 bwfan-pr-0">
<label for="" class="bwfan-label-title"><?php esc_html_e( 'To Status', 'wp-marketing-automations' ); ?></label>
<select required id="" class="bwfan-input-wrapper" name="event_meta[to]">
<option value="wc-any"><?php esc_html_e( 'Any', 'wp-marketing-automations' ); ?></option>
<#
if(_.has(data.eventFieldsOptions, 'to_options') && _.isObject(data.eventFieldsOptions.to_options) ) {
_.each( data.eventFieldsOptions.to_options, function( value, key ){
selected = (key == selected_to_status) ? 'selected' : '';
#>
<option value="{{key}}" {{selected}}>{{value}}</option>
<# })
}
#>
</select>
</div>
<?php
$this->get_validation_html( $this->get_slug(), 'Validate order status before executing task', 'Validate' );
?>
</script>
<?php
}
/**
* Set up rules data
*
* @param $value
*/
public function pre_executable_actions( $value ) {
$order = wc_get_order( $this->order_id );
$this->order = $order;
BWFAN_Core()->rules->setRulesData( $this->order, 'wc_order' );
BWFAN_Core()->rules->setRulesData( $this->event_automation_id, 'automation_id' );
BWFAN_Core()->rules->setRulesData( BWFAN_Common::get_bwf_customer( $this->order->get_billing_email(), $this->order->get_user_id() ), 'bwf_customer' );
}
public function handle_single_automation_run( $value1, $automation_id ) {
$is_register_task = false;
$to_status = $this->to_status;
$from_status = $this->from_status;
$event_meta = $value1['event_meta'];
$from = str_replace( 'wc-', '', $event_meta['from'] );
$to = str_replace( 'wc-', '', $event_meta['to'] );
if ( 'any' === $from && 'any' === $to ) {
$is_register_task = true;
} elseif ( 'any' === $from && $to_status === $to ) {
$is_register_task = true;
} elseif ( $from_status === $from && 'any' === $to ) {
$is_register_task = true;
} elseif ( $from_status === $from && $to_status === $to ) {
$is_register_task = true;
}
if ( $is_register_task ) {
$all_statuses = wc_get_order_statuses();
$value1['from'] = $all_statuses[ 'wc-' . $from_status ];
$value1['from_slug'] = 'wc-' . $from_status;
$value1['to'] = $all_statuses[ 'wc-' . $to_status ];
$value1['to_slug'] = 'wc-' . $to_status;
return parent::handle_single_automation_run( $value1, $automation_id );
}
return '';
}
public function order_status_changed( $order, $from_status, $to_status ) {
if ( ! $order instanceof WC_Order ) {
return;
}
$this->order_id = $order->get_id();
$this->order = $order;
$this->from_status = $from_status;
$this->to_status = $to_status;
if ( BWFAN_Common::bwf_check_to_skip_child_order( $this->order_id ) ) {
return;
}
BWFAN_Core()->public->load_active_automations( $this->get_slug() );
$this->process( $this->order_id, $from_status, $to_status );
}
/**
* Make the required data for the current event and send it asynchronously.
*
* @param $order_id
* @param $from_status
* @param $to_status
*/
public function process( $order_id, $from_status, $to_status ) {
$data = $this->get_default_data();
$data['order_id'] = $order_id;
$data['from_status'] = $from_status;
$data['to_status'] = $to_status;
$data['email'] = $this->order->get_billing_email();
$data['phone'] = $this->order->get_billing_phone();
$all_statuses = wc_get_order_statuses();
$data['from'] = $all_statuses[ 'wc-' . $this->from_status ];
$data['from_slug'] = 'wc-' . $this->from_status;
$data['to'] = $all_statuses[ 'wc-' . $this->to_status ];
$data['to_slug'] = 'wc-' . $this->to_status;
/** Run v2 automation */
BWFAN_Common::maybe_run_v2_automations( $this->get_slug(), $data );
/** Run v1 automation */
if ( count( $this->automations_arr ) > 0 ) {
$this->run_automations();
}
}
/**
* Returns the current event settings set in the automation at the time of task creation.
*
* @param $value
*
* @return array
*/
public function get_automation_event_data( $value ) {
$event_meta = $value['event_meta'];
return [
'event_source' => $value['source'],
'event_slug' => $value['event'],
'validate_event' => ( isset( $value['event_meta']['validate_event'] ) ) ? 1 : 0,
'from_status' => $event_meta['from'],
'to_status' => $event_meta['to'],
'from' => $value['from'],
'from_slug' => $value['from_slug'],
'to' => $value['to'],
'to_slug' => $value['to_slug'],
];
}
/**
* Registers the tasks for current event.
*
* @param $automation_id
* @param $actions : after processing events data
* @param $event_data
*/
public function register_tasks( $automation_id, $actions, $event_data ) {
if ( ! is_array( $actions ) ) {
return;
}
$data_to_send = $this->get_event_data( $event_data );
$this->create_tasks( $automation_id, $actions, $event_data, $data_to_send );
}
public function get_event_data( $event_data = array() ) {
$data_to_send = [];
$data_to_send['global']['order_id'] = $this->order_id;
$data_to_send['global']['from'] = isset( $event_data['from'] ) ? $event_data['from'] : '';
$data_to_send['global']['to'] = isset( $event_data['to'] ) ? $event_data['to'] : '';
$this->order = wc_get_order( $this->order_id );
$user_id = BWFAN_Common::get_wp_user_id_from_order( $this->order_id, $this->order );
if ( intval( $user_id ) > 0 ) {
$data_to_send['global']['user_id'] = $user_id;
}
$email = ! empty( $user_id ) ? BWFAN_Common::get_contact_email( $user_id ) : '';
/** Set billing email if email is empty */
$data_to_send['global']['email'] = ! empty( $email ) ? $email : BWFAN_Common::get_email_from_order( $this->order_id, $this->order );
$data_to_send['global']['phone'] = BWFAN_Common::get_phone_from_order( $this->order_id, $this->order );
$order_lang = BWFAN_Common::get_order_language( $this->order );
if ( ! empty( $order_lang ) ) {
$data_to_send['global']['language'] = $order_lang;
}
return $data_to_send;
}
/**
* Make the view data for the current event which will be shown in task listing screen.
*
* @param $global_data
*
* @return false|string
*/
public function get_task_view( $global_data ) {
ob_start();
$order = wc_get_order( $global_data['order_id'] );
if ( $order instanceof WC_Order ) {
?>
<li>
<strong><?php esc_html_e( 'Order:', 'wp-marketing-automations' ); ?> </strong>
<a target="_blank" href="<?php echo get_edit_post_link( $global_data['order_id'] ); //phpcs:ignore WordPress.Security.EscapeOutput
?>"><?php echo '#' . wp_strip_all_tags( $global_data['order_id'] . ' ' . $order->get_billing_first_name() . ' ' . $order->get_billing_last_name() ); //phpcs:ignore WordPress.Security.EscapeOutput ?></a>
</li>
<?php } ?>
<li>
<strong><?php esc_html_e( 'Email:', 'wp-marketing-automations' ); ?> </strong>
<?php echo $global_data['email']; //phpcs:ignore WordPress.Security.EscapeOutput ?>
</li>
<li>
<strong><?php esc_html_e( 'From Status:', 'wp-marketing-automations' ); ?> </strong>
<?php echo $global_data['from']; //phpcs:ignore WordPress.Security.EscapeOutput ?>
</li>
<li>
<strong><?php esc_html_e( 'To Status:', 'wp-marketing-automations' ); ?> </strong>
<?php echo $global_data['to']; //phpcs:ignore WordPress.Security.EscapeOutput ?>
</li>
<?php
return ob_get_clean();
}
/**
* This function decides if the task has to be executed or not.
* The event has validate checkbox in its meta fields.
*
* @param $task_details
*
* @return array|mixed
*/
public function validate_event( $task_details ) {
$result = [];
$task_event = $task_details['event_data']['event_slug'];
$automation_id = $task_details['processed_data']['automation_id'];
$automation_details = BWFAN_Model_Automations::get_automation_with_data( $automation_id );
$current_automation_event = $automation_details['event'];
$current_automation_event_meta = $automation_details['meta']['event_meta'];
$current_automation_event_validation_status = ( isset( $current_automation_event_meta['validate_event'] ) ) ? $current_automation_event_meta['validate_event'] : 0;
$current_automation_status_to = $current_automation_event_meta['to'];
if ( 'wc-any' === $current_automation_event_meta['from'] && 'wc-any' === $current_automation_event_meta['to'] ) {
return $this->get_automation_event_success();
}
/** Using current automation 'order to' state rather than saved one in the task */
/** Current automation has no checking */
if ( 0 === $current_automation_event_validation_status ) {
return $this->get_automation_event_validation();
}
/** Current automation event does not match with the event of task when the task was made */
if ( $task_event !== $current_automation_event ) {
return $this->get_automation_event_status();
}
$order_id = $task_details['processed_data']['order_id'];
$order = wc_get_order( $order_id );
$task_order_status = BWFAN_Woocommerce_Compatibility::get_order_status( $order );
if ( $task_order_status === $current_automation_status_to ) {
return $this->get_automation_event_success();
}
$result['status'] = 4;
$result['message'] = __( 'Order status in automation has been changed', 'wp-marketing-automations' );
return $result;
}
public function validate_event_data_before_executing_task( $data ) {
return $this->validate_order( $data );
}
/**
* Set global data for all the merge tags which are supported by this event.
*
* @param $task_meta
*/
public function set_merge_tags_data( $task_meta ) {
$wc_order_id = BWFAN_Merge_Tag_Loader::get_data( 'wc_order_id' );
if ( empty( $wc_order_id ) || $wc_order_id !== $task_meta['global']['order_id'] ) {
$set_data = array(
'wc_order_id' => $task_meta['global']['order_id'],
'email' => $task_meta['global']['email'],
'wc_order' => wc_get_order( $task_meta['global']['order_id'] ),
);
BWFAN_Merge_Tag_Loader::set_data( $set_data );
}
}
/**
* validate v2 event settings
* @return bool
*/
public function validate_v2_event_settings( $automation_data ) {
if ( ! isset( $automation_data['event_meta'] ) || empty( $automation_data['event_meta'] ) || ! is_array( $automation_data['event_meta'] ) ) {
return false;
}
$current_automation_event_meta = $automation_data['event_meta'];
$current_automation_status_to = isset( $current_automation_event_meta['to'] ) ? $current_automation_event_meta['to'] : '';
$current_automation_status_from = isset( $current_automation_event_meta['from'] ) ? $current_automation_event_meta['from'] : '';
$current_order_contains = isset( $current_automation_event_meta['order-contains'] ) ? $current_automation_event_meta['order-contains'] : '';
if ( ! $this->validate_order( $automation_data ) ) {
return false;
}
/** from any to any status checking */
if ( ( 'wc-any' === $current_automation_status_from && 'wc-any' === $current_automation_status_to ) && ( empty( $current_order_contains ) || 'any' === $current_order_contains ) ) {
return true;
}
/** Specific product case */
if ( 'selected_product' === $current_order_contains ) {
$order_id = absint( $automation_data['order_id'] );
$order = wc_get_order( $order_id );
$order_items = $order->get_items();
$ordered_products = array();
foreach ( $order_items as $item ) {
$product_id = $item->get_product_id();
$ordered_products[] = $product_id;
/** In case variation */
if ( $item->get_variation_id() ) {
$ordered_products[] = $item->get_variation_id();
}
}
$ordered_products = array_unique( $ordered_products );
$get_selected_product = $automation_data['event_meta']['products'];
$product_selected = array_column( $get_selected_product, 'id' );
$check_products = count( array_intersect( $product_selected, $ordered_products ) );
/** No selected products found */
if ( $check_products <= 0 ) {
return false;
}
}
$order_status_from = 'wc-' . $automation_data['from_status'];
$order_status_to = 'wc-' . $automation_data['to_status'];
/** checking from any to any status */
if ( 'wc-any' === $current_automation_status_from && 'wc-any' === $current_automation_status_to ) {
return true;
}
/** checking any status to selected status */
if ( 'wc-any' === $current_automation_status_from ) {
return ( $order_status_to === $current_automation_status_to );
}
/** checking selected status to any status */
if ( 'wc-any' === $current_automation_status_to ) {
return ( $order_status_from === $current_automation_status_from );
}
/** checking selected status to selected status */
return ( ( $order_status_from === $current_automation_status_from ) && ( $order_status_to === $current_automation_status_to ) );
}
/**
* v2 Method: Get fields schema
* @return array[][]
*/
public function get_fields_schema() {
$default = [
'wc-any' => 'Any'
];
$status = array_replace( $default, $this->get_view_data() );
$status = BWFAN_Common::prepared_field_options( $status );
$arr = [
[
'id' => 'from',
'type' => 'wp_select',
'options' => $status,
'placeholder' => __( 'Select Status', 'wp-marketing-automations' ),
'label' => __( 'From Status', 'wp-marketing-automations' ),
"class" => 'bwfan-input-wrapper bwf-3-col-item',
"required" => true,
"description" => ""
],
[
'id' => 'to',
'type' => 'wp_select',
'options' => $status,
'label' => __( 'To Status', 'wp-marketing-automations' ),
'placeholder' => __( 'Select Status', 'wp-marketing-automations' ),
"class" => 'bwfan-input-wrapper bwf-3-col-item',
"required" => true,
"description" => ""
],
[
'id' => 'order-contains',
'label' => __( 'Order Contains', 'wp-marketing-automations' ),
'type' => 'radio',
'options' => [
[
'label' => __( 'Any Product', 'wp-marketing-automations' ),
'value' => 'any'
],
[
'label' => __( 'Specific Products', 'wp-marketing-automations' ),
'value' => 'selected_product'
],
],
"class" => 'bwfan-input-wrapper',
"tip" => "",
"required" => true,
"description" => ""
],
];
if ( bwfan_is_autonami_pro_active() ) {
$arr[] = [
'id' => 'products',
'label' => __( 'Select Products', 'wp-marketing-automations' ),
'type' => 'search',
'autocompleter' => 'products',
'class' => '',
'placeholder' => '',
'required' => true,
'toggler' => [
'fields' => [
[
'id' => 'order-contains',
'value' => 'selected_product',
]
]
],
];
} else {
$arr[] = [
'id' => 'products',
'type' => 'notice',
'class' => '',
'status' => 'warning',
'message' => __( 'This is a Pro feature.', 'wp-marketing-automations' ),
'dismiss' => false,
'required' => false,
'toggler' => [
'fields' => [
[
'id' => 'order-contains',
'value' => 'selected_product',
]
]
],
];
}
return $arr;
}
/** set default values */
public function get_default_values() {
return [
'from' => 'wc-any',
'to' => 'wc-any',
'order-contains' => 'any',
];
}
}
/**
* Register this event to a source.
* This will show the current event in dropdown in single automation screen.
*/
if ( bwfan_is_woocommerce_active() ) {
return 'BWFAN_WC_Order_Status_Change';
}

View File

@@ -0,0 +1,756 @@
<?php
final class BWFAN_WC_Product_Purchased extends BWFAN_Event {
private static $instance = null;
public $order_id = null;
/** @var WC_Order $order */
public $order = null;
public $to_status = null;
public $single_item = null;
public $single_item_id = null;
public $has_run = 0;
private function __construct() {
$this->optgroup_label = esc_html__( 'Orders', 'wp-marketing-automations' );
$this->event_name = esc_html__( 'Order Created - Per Product', 'wp-marketing-automations' );
$this->event_desc = esc_html__( 'This event runs after a new WooCommerce order is created and runs per line item. Can only run once on selected WC order statuses.', 'wp-marketing-automations' );
$this->event_merge_tag_groups = array( 'bwf_contact', 'wc_order', 'wc_items' );
$this->event_rule_groups = array(
'wc_order',
'wc_items',
'wc_order_items_data',
'aerocheckout',
'bwf_contact_segments',
'bwf_contact',
'bwf_contact_fields',
'bwf_contact_user',
'bwf_contact_wc',
'bwf_contact_geo',
'bwf_engagement',
'bwf_broadcast'
);
$this->support_lang = true;
$this->priority = 15.1;
$this->v2 = true;
$this->automation_add = true;
$this->supported_blocks = [ 'order' ];
}
public function load_hooks() {
// event trigger hooks
add_action( 'woocommerce_new_order', [ $this, 'new_order' ], 11 );
add_action( 'bwfan_wc_order_status_changed', array( $this, 'order_status_changed' ), 11, 3 );
add_filter( 'bwfan_wc_event_order_status_' . $this->get_slug(), array( $this, 'modify_order_statuses' ), 10, 1 );
add_filter( 'bwfan_before_making_logs', array( $this, 'check_if_bulk_process_executing' ), 10, 1 );
}
public static function get_instance() {
if ( null === self::$instance ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Localize data for html fields for the current event.
*/
public function admin_enqueue_assets() {
if ( BWFAN_Common::is_load_admin_assets( 'automation' ) ) {
$integration_data = $this->get_view_data();
BWFAN_Core()->admin->set_events_js_data( $this->get_slug(), 'order_status_options', $integration_data );
}
}
public function get_view_data() {
$all_status = wc_get_order_statuses();
if ( isset( $all_status['wc-cancelled'] ) ) {
unset( $all_status['wc-cancelled'] );
}
if ( isset( $all_status['wc-failed'] ) ) {
unset( $all_status['wc-failed'] );
}
if ( isset( $all_status['wc-refunded'] ) ) {
unset( $all_status['wc-refunded'] );
}
if ( isset( $all_status['wc-wfocu-pri-order'] ) ) {
unset( $all_status['wc-wfocu-pri-order'] );
}
asort( $all_status, SORT_REGULAR );
$all_status = apply_filters( 'bwfan_wc_event_order_status_' . $this->get_slug(), $all_status );
return apply_filters( 'bwfan_wc_event_order_status', $all_status );
}
/**
* Show the html fields for the current event.
*/
public function get_view( $db_eventmeta_saved_value ) {
?>
<script type="text/html" id="tmpl-event-<?php echo esc_html( $this->get_slug() ); ?>">
<div class="bwfan-col-sm-12 bwfan-p-0 bwfan-mt-15">
<#
selected_statuses = (_.has(data, 'eventSavedData') &&_.has(data.eventSavedData, 'order_status')) ? data.eventSavedData.order_status : '';
is_validated = (_.has(data, 'eventSavedData') &&_.has(data.eventSavedData, 'validate_event')) ? 'checked' : '';
#>
<label for="" class="bwfan-label-title"><?php esc_html_e( 'Select Order Statuses', 'wp-marketing-automations' ); ?></label>
<#
if(_.has(data.eventFieldsOptions, 'order_status_options') && _.isObject(data.eventFieldsOptions.order_status_options) ) {
_.each( data.eventFieldsOptions.order_status_options, function( value, key ){
checked = '';
if(selected_statuses!='' && _.contains(selected_statuses, key)){
checked = 'checked';
}
#>
<div class="bwfan-checkboxes">
<input type="checkbox" name="event_meta[order_status][]" id="bwfan-{{key}}" value="{{key}}" class="bwfan-checkbox" data-warning="<?php esc_html_e( 'Please select atleast 1 order status', 'wp-marketing-automations' ); ?>" {{checked}}/>
<label for="bwfan-{{key}}" class="bwfan-checkbox-label">{{value}}</label>
</div>
<# })
}
#>
<div class="clearfix bwfan_field_desc bwfan-pt-0">
This automation would run on new order items with selected order statuses.
</div>
</div>
<?php
$this->get_validation_html( $this->get_slug(), 'Validate Order status before executing task', 'Validate' );
?>
</script>
<?php
}
/**
* Set up rules data
*
* @param $value
*/
public function pre_executable_actions( $value ) {
BWFAN_Core()->rules->setRulesData( $this->event_automation_id, 'automation_id' );
BWFAN_Core()->rules->setRulesData( $this->order, 'wc_order' );
BWFAN_Core()->rules->setRulesData( $this->single_item, 'wc_items' );
BWFAN_Core()->rules->setRulesData( BWFAN_Common::get_bwf_customer( $this->order->get_billing_email(), $this->order->get_user_id() ), 'bwf_customer' );
}
/**
* Save active automation ids in order meta when a new order is created so that can be processed later on.
*
* @param $order_id
*/
public function new_order( $order_id ) {
$order = wc_get_order( $order_id );
if ( ! $order instanceof WC_Order ) {
return;
}
/** Check if v1 automations exists */
BWFAN_Core()->public->load_active_automations( $this->get_slug() );
if ( ! is_array( $this->automations_arr ) || count( $this->automations_arr ) === 0 ) {
BWFAN_Core()->logger->log( 'No active automations for order ID - ' . $order_id . ', Event - ' . $this->get_slug() . ' and function name ' . __FUNCTION__, $this->log_type );
return;
}
$order->update_meta_data( '_bwfan_' . $this->get_slug(), count( $this->automations_arr ) );
$order->save_meta_data();
}
/**
* Returns the current event settings set in the automation at the time of task creation.
*
* @param $value
*
* @return array
*/
public function get_automation_event_data( $value ) {
return [
'event_source' => $value['source'],
'event_slug' => $value['event'],
'validate_event' => ( isset( $value['event_meta']['validate_event'] ) ) ? 1 : 0,
'order_status' => $value['event_meta']['order_status'],
];
}
/**
* Registers the tasks for current event.
*
* @param $automation_id
* @param $integration_data
* @param $event_data
*/
public function register_tasks( $automation_id, $integration_data, $event_data ) {
if ( ! is_array( $integration_data ) ) {
return;
}
$data_to_send = $this->get_event_data();
$this->create_tasks( $automation_id, $integration_data, $event_data, $data_to_send );
}
public function get_event_data() {
$data_to_send = [];
$data_to_send['global']['order_id'] = $this->order_id;
$data_to_send['global']['wc_single_item_id'] = $this->single_item_id;
$this->order = wc_get_order( $this->order_id );
$user_id = BWFAN_Common::get_wp_user_id_from_order( $this->order_id, $this->order );
if ( intval( $user_id ) > 0 ) {
$data_to_send['global']['user_id'] = $user_id;
}
$email = ! empty( $user_id ) ? BWFAN_Common::get_contact_email( $user_id ) : '';
/** Set billing email if email is empty */
$data_to_send['global']['email'] = ! empty( $email ) ? $email : BWFAN_Common::get_email_from_order( $this->order_id, $this->order );
$data_to_send['global']['phone'] = BWFAN_Common::get_phone_from_order( $this->order_id, $this->order );
$order_lang = BWFAN_Common::get_order_language( $this->order );
if ( ! empty( $order_lang ) ) {
$data_to_send['global']['language'] = $order_lang;
}
return $data_to_send;
}
public function order_status_changed( $order, $from_status, $to_status ) {
if ( ! $order instanceof WC_Order ) {
return;
}
$this->order_id = $order->get_id();
$this->order = $order;
if ( BWFAN_Common::bwf_check_to_skip_child_order( $this->order_id ) ) {
BWFAN_Core()->logger->log( 'Skip child order for ID - ' . $this->order_id . ', Event - ' . $this->get_slug() . ' and function name ' . __FUNCTION__, $this->log_type );
return;
}
/** Check if automations v1 or v2 exists */
BWFAN_Core()->public->load_active_automations( $this->get_slug() );
BWFAN_Core()->public->load_active_v2_automations( $this->get_slug() );
$automation_not_found = false;
if ( ( ! is_array( $this->automations_arr ) || count( $this->automations_arr ) === 0 ) && ( ! is_array( $this->automations_v2_arr ) || count( $this->automations_v2_arr ) === 0 ) ) {
$automation_not_found = true;
}
if ( true === $automation_not_found ) {
BWFAN_Core()->logger->log( 'No active automations for order ID - ' . $this->order_id . ', Event - ' . $this->get_slug() . ' and function name ' . __FUNCTION__, $this->log_type );
return;
}
$this->to_status = 'wc-' . $to_status;
$this->process( $this->order_id );
$this->to_status = null;
}
/**
* Make the required data for the current event and send it asynchronously.
*
* @param $order_id
*/
public function process( $order_id ) {
$data = $this->get_default_data();
$data['order_id'] = $order_id;
$data['email'] = $this->order->get_billing_email();
$data['phone'] = $this->order->get_billing_phone();
if ( ! is_null( $this->to_status ) ) {
$data['to_status'] = $this->to_status;
}
/** Run v2 automation */
BWFAN_Common::maybe_run_v2_automations( $this->get_slug(), $data );
/** For v1 automation */
$count = BWFAN_Woocommerce_Compatibility::get_order_data( $this->order, '_bwfan_' . $this->get_slug() );
if ( empty( $count ) ) {
return;
}
$this->order->delete_meta_data( '_bwfan_' . $this->get_slug() );
$this->order->save();
$items = $this->order->get_items();
foreach ( $items as $item_id => $item ) {
if ( ! $item instanceof WC_Order_Item ) {
continue;
}
$this->single_item = $item;
$this->single_item_id = $item_id;
$this->run_automations();
}
}
/**
* Make the view data for the current event which will be shown in task listing screen.
*
* @param $global_data
*
* @return false|string
*/
public function get_task_view( $global_data ) {
ob_start();
$order = wc_get_order( $global_data['order_id'] );
if ( $order instanceof WC_Order ) {
?>
<li>
<strong><?php esc_html_e( 'Order', 'wp-marketing-automations' ); ?> </strong>
<a target="_blank" href="<?php echo get_edit_post_link( $global_data['order_id'] ); //phpcs:ignore WordPress.Security.EscapeOutput
?>"><?php echo '#' . wp_strip_all_tags( $global_data['order_id'] . ' ' . $order->get_billing_first_name() . ' ' . $order->get_billing_last_name() ); //phpcs:ignore WordPress.Security.EscapeOutput ?></a>
</li>
<?php } ?>
<li>
<strong><?php esc_html_e( 'Email:', 'wp-marketing-automations' ); ?> </strong>
<?php echo $global_data['email']; //phpcs:ignore WordPress.Security.EscapeOutput ?>
</li>
<?php
return ob_get_clean();
}
/**
* This function decides if the task has to be executed or not.
* The event has validate checkbox in its meta fields.
*
* @param $task_details
*
* @return array|mixed
*/
public function validate_event( $task_details ) {
$result = [];
$task_event = $task_details['event_data']['event_slug'];
$automation_id = $task_details['processed_data']['automation_id'];
$automation_details = BWFAN_Model_Automations::get( $automation_id );
$current_automation_event = $automation_details['event'];
$current_automation_event_meta = BWFAN_Model_Automationmeta::get_meta( $automation_id, 'event_meta' );
$current_automation_event_validation_status = ( isset( $current_automation_event_meta['validate_event'] ) ) ? $current_automation_event_meta['validate_event'] : 0;
$current_automation_order_statuses = $current_automation_event_meta['order_status'];
// Current automation has no checking
if ( 0 === $current_automation_event_validation_status ) {
return $this->get_automation_event_validation();
}
// Current automation event does not match with the event of task when the task was made
if ( $task_event !== $current_automation_event ) {
return $this->get_automation_event_status();
}
$order_id = $task_details['processed_data']['order_id'];
$order = wc_get_order( $order_id );
$task_order_status = BWFAN_Woocommerce_Compatibility::get_order_status( $order );
if ( in_array( $task_order_status, $current_automation_order_statuses, true ) ) {
return $this->get_automation_event_success();
}
$result['status'] = 4;
$result['message'] = __( 'Order status in automation has been changed', 'wp-marketing-automations' );
return $result;
}
public function validate_event_data_before_executing_task( $data ) {
return $this->validate_order( $data );
}
/**
* Set global data for all the merge tags which are supported by this event.
*
* @param $task_meta
*/
public function set_merge_tags_data( $task_meta ) {
$get_data = BWFAN_Merge_Tag_Loader::get_data();
$set_data = array(
'wc_single_item_id' => $task_meta['global']['wc_single_item_id'],
);
if ( ! isset( $get_data['wc_order_id'] ) || $get_data['wc_order_id'] !== $task_meta['global']['order_id'] ) {
$set_data['wc_order_id'] = $task_meta['global']['order_id'];
$set_data['email'] = $task_meta['global']['email'];
$set_data['wc_order'] = wc_get_order( $task_meta['global']['order_id'] );
}
if ( isset( $set_data['wc_order'] ) ) {
$items = $set_data['wc_order']->get_items();
} else {
$items = $get_data['wc_order']->get_items();
}
foreach ( $items as $item_id => $item ) {
if ( $set_data['wc_single_item_id'] !== $item_id ) {
continue;
}
$set_data['wc_single_item'] = $item;
}
BWFAN_Merge_Tag_Loader::set_data( $set_data );
}
public function handle_single_automation_run( $value1, $automation_id ) {
/** If current status or order is same as the order status selected by user in automation */
if ( isset( $value1['event_meta']['order_status'] ) && is_array( $value1['event_meta']['order_status'] ) && ( in_array( $this->to_status, $value1['event_meta']['order_status'], true ) ) ) {
return parent::handle_single_automation_run( $value1, $automation_id );
}
if ( ! empty( $this->user_selected_actions ) ) {
return parent::handle_single_automation_run( $value1, $automation_id );
}
$meta_automations = $this->order->get_meta( '_bwfan_' . $this->get_slug() );
$meta_automations = ( ! is_array( $meta_automations ) ) ? [] : $meta_automations;
$meta_automations[] = $automation_id;
$meta_automations = array_filter( array_unique( $meta_automations ) );
$this->order->update_meta_data( '_bwfan_' . $this->get_slug(), maybe_serialize( $meta_automations ) ); // Update order meta so that we can check if task for this order should be made or not on order status change hook
$this->order->save();
return false;
}
public function modify_order_statuses( $statuses ) {
if ( isset( $statuses['wc-pending'] ) ) {
unset( $statuses['wc-pending'] );
}
return $statuses;
}
/**
* @param $actions
*
* Recalculate action's execution time with respect to order date.
*
* @return mixed
* @throws Exception
*/
public function recalculate_actions_time( $actions ) {
$order_date = BWFAN_Woocommerce_Compatibility::get_order_date( $this->order );
return $this->calculate_actions_time( $actions, $order_date );
}
/**
* validate v2 event settings
* @return bool
*/
public function validate_v2_event_settings( $automation_data ) {
/** validate settings*/
$current_automation_order_statuses = ( isset( $automation_data['event_meta'] ) && isset( $automation_data['event_meta']['order_status'] ) ) ? $automation_data['event_meta']['order_status'] : array();
$task_order_status = $automation_data['to_status'];
/** check order status with automation setting */
if ( ! in_array( $task_order_status, $current_automation_order_statuses, true ) ) {
return false;
}
/** validate order */
return $this->validate_order( $automation_data );
}
/**
* validate the order items for specific or any
*
* @param $automation_data
* @param $product_selected
* @param $item
*
* @return bool
*/
public function validate_event_order_items( $automation_data, $product_selected, $item ) {
if ( ! $item instanceof WC_Order_Item ) {
return false;
}
/** Any product case */
if ( ! isset( $automation_data['event_meta'] ) || ! isset( $automation_data['event_meta']['order-contains'] ) || 'any' === $automation_data['event_meta']['order-contains'] ) {
return true;
}
$ordered_products = [ $item->get_product_id() ];
/** In case variation */
$ordered_products = ( $item->get_variation_id() ) ? array_merge( $ordered_products, [ $item->get_variation_id() ] ) : $ordered_products;
return count( array_intersect( $product_selected, $ordered_products ) ) > 0;
}
/**
* Before starting automation on a contact, validating if cart row exists
*
* @param $row
*
* @return bool
*/
public function validate_v2_before_start( $row ) {
if ( empty( $row['data'] ) ) {
return false;
}
$data = isset( $row['data'] ) ? json_decode( $row['data'], true ) : [];
$data = isset( $data['global'] ) ? $data['global'] : [];
return $this->validate_order( $data );
}
public function handle_automation_run_v2( $automation_id, $automation_data ) {
/** If no start node found */
if ( ! isset( $automation_data['start'] ) || 0 === intval( $automation_data['start'] ) ) {
return false;
}
/** Global data */
$global_data = $this->global_data;
if ( empty( $global_data ) ) {
return false;
}
$global_data = BWFAN_Common::get_global_data( $global_data );
/** If no contact ID found, log and return */
if ( ! isset( $global_data['global'] ) || ! isset( $global_data['global']['cid'] ) || 0 === intval( $global_data['global']['cid'] ) ) {
BWFAN_Common::log_test_data( 'No cid found for Automation ID - ' . $automation_id . '. Event - ' . $this->get_slug(), 'no-contact-id', true );
BWFAN_Common::log_test_data( $global_data, 'no-contact-id', true );
return false;
}
$exclude_check = false;
if ( isset( $automation_data['event_meta'] ) && isset( $automation_data['event_meta']['enter_automation_on_active_contact'] ) && 1 === absint( $automation_data['event_meta']['enter_automation_on_active_contact'] ) ) {
$exclude_check = true;
}
/** set automation id in event global data */
$global_data['global']['automation_id'] = $automation_id;
$order_id = isset( $automation_data['order_id'] ) ? $automation_data['order_id'] : 0;
$order = wc_get_order( $order_id );
if ( ! $order instanceof WC_Order ) {
return false;
}
/** Event data */
$event_data = $this->event_data;
$global_data['event_data'] = ! is_array( $event_data ) ? [] : $event_data;
/** Specific product case */
$get_selected_product = isset( $automation_data['event_meta']['products'] ) ? $automation_data['event_meta']['products'] : [];
$product_selected = empty( $get_selected_product ) ? [] : array_column( $get_selected_product, 'id' );
$insert_id = 0;
$items = $order->get_items();
foreach ( $items as $item_id => $item ) {
if ( ! $item instanceof WC_Order_Item ) {
continue;
}
/** If contact is active in automation */
if ( false === $exclude_check && BWFAN_Model_Automation_Contact::maybe_contact_in_automation( $global_data['global']['cid'], $automation_id ) ) {
BWFAN_Common::log_test_data( 'Contact ' . $global_data['global']['cid'] . ' is active in the automation - ' . $automation_id . '. Event - ' . $this->get_slug(), 'contact-exist-automation', true );
return false;
}
/** Validate automation if contact is already exists with same order */
if ( false === $this->validate_automation( $automation_data, $item_id ) ) {
return false;
}
/** Validate automation common settings like run count */
if ( false === BWFAN_Model_Automations_V2::validation_automation_run_count( $automation_id, $global_data['global']['cid'], $automation_data, $exclude_check ) ) {
BWFAN_Common::log_test_data( 'Automation ID ' . $automation_id . ' already run on a contact ' . $global_data['global']['cid'] . '. Event - ' . $this->get_slug(), 'contact-exist-automation', true );
return false;
}
/** Validate automation event settings per item */
if ( false === $this->validate_event_order_items( $automation_data, $product_selected, $item ) ) {
continue;
}
$global_data['global']['wc_single_item_id'] = $item_id;
$data = [
'cid' => intval( $global_data['global']['cid'] ),
'aid' => $automation_id,
'event' => $this->get_slug(),
'c_date' => current_time( 'mysql', 1 ),
'e_time' => current_time( 'timestamp', 1 ),
'last_time' => current_time( 'timestamp', 1 ),
'data' => json_encode( $global_data )
];
/** In case of duplicate run, when hook runs twice. */
$already_exists = BWFAN_Model_Automation_Contact::check_duplicate_automation_contact( $data );
if ( $already_exists ) {
BWFAN_Common::log_test_data( 'Automation ID ' . $data['aid'] . ' already exists with same data for contact ' . $data['cid'] . '. Event - ' . $data['event'], 'contact-duplicate-automation', true );
BWFAN_Common::log_test_data( $global_data, 'contact-duplicate-automation', true );
continue;
}
BWFAN_Model_Automation_Contact::insert( $data );
$insert_id = BWFAN_Model_Automation_Contact::insert_id();
}
/** Update automation active and entered contact fields */
$this->update_automation_contact_field( intval( $global_data['global']['cid'] ), $automation_id );
$this->has_run = true;
return $insert_id;
}
/**
* @param $automation_data
*
* @return bool
*/
public function validate_automation( $automation_data, $item_id ) {
$this->order_id = $automation_data['order_id'];
$global_data = BWFAN_Common::get_global_data( $this->get_event_data() );
$cid = isset( $global_data['global']['contact_id'] ) ? $global_data['global']['contact_id'] : 0;
$cid = empty( $cid ) && isset( $global_data['global']['cid'] ) ? $global_data['global']['cid'] : $cid;
if ( empty( $cid ) ) {
return false;
}
/** Check if contact is already exists in automation with same order */
if ( BWFAN_Common::is_contact_in_automation( $automation_data['id'], $cid, $this->order_id, $item_id, $this->get_slug() ) ) {
return false;
}
return true;
}
/** v2 Methods: START */
public function get_fields_schema() {
$arr = [
[
'id' => 'order_status',
'label' => __( 'Order Statuses', 'wp-marketing-automations' ),
'type' => 'checkbox_grid',
'class' => '',
'placeholder' => '',
'required' => true,
"errorMsg" => __( 'Select at least one status.', 'wp-marketing-automations' ),
'options' => $this->get_view_data(),
'hint' => __( 'This automation would run on new orders product with selected statuses.', 'wp-marketing-automations' ),
],
[
'id' => 'order-contains',
'label' => __( 'Order Contains', 'wp-marketing-automations' ),
'type' => 'radio',
'options' => [
[
'label' => __( 'Any Product', 'wp-marketing-automations' ),
'value' => 'any'
],
[
'label' => __( 'Specific Products', 'wp-marketing-automations' ),
'value' => 'selected_product'
],
],
"class" => 'bwfan-input-wrapper',
"tip" => "",
"required" => false,
"description" => ""
],
];
if ( bwfan_is_autonami_pro_active() ) {
$arr[] = [
'id' => 'products',
'label' => __( 'Select Products', 'wp-marketing-automations' ),
'type' => 'search',
'autocompleter' => 'products',
'class' => '',
'placeholder' => '',
'required' => true,
'toggler' => [
'fields' => [
[
'id' => 'order-contains',
'value' => 'selected_product',
]
]
],
];
} else {
$arr[] = [
'id' => 'products',
'type' => 'notice',
'class' => '',
'status' => 'warning',
'message' => __( 'This is a Pro feature.', 'wp-marketing-automations' ),
'dismiss' => false,
'required' => false,
'toggler' => [
'fields' => [
[
'id' => 'order-contains',
'value' => 'selected_product',
]
]
],
];
}
return $arr;
}
public function get_default_values() {
return [
'order-contains' => 'any'
];
}
/**
* get contact automation data
*
* @param $automation_data
* @param $cid
*
* @return array|null[]
*/
public function get_manually_added_contact_automation_data( $automation_data, $cid ) {
$contact = new WooFunnels_Contact( '', '', '', $cid );
/** Check if contact exists */
if ( ! $contact instanceof WooFunnels_Contact || empty( $contact->get_id() ) ) {
return [ 'status' => 0, 'type' => 'contact_not_found' ];
}
$order = BWFAN_Common::fetch_last_order_by_contact( $contact );
if ( empty( $order ) || ! $order[0] instanceof WC_Order ) {
return [ 'status' => 0, 'type' => '', 'message' => __( "Contact doesn't have any order.", 'wp-marketing-automations' ) ];
}
$this->order_id = $order[0]->get_id();
$this->to_status = 'wc-' . $order[0]->get_status();
$automation_data = array_merge( $automation_data, [ 'order_id' => $this->order_id, 'to_status' => $this->to_status ] );
if ( BWFAN_Common::validate_create_order_event_setting( $automation_data ) === false ) {
return [ 'status' => 0, 'type' => '', 'message' => __( "No Ordered Products are matching with event products.", 'wp-marketing-automations' ) ];
}
return $automation_data;
}
}
/**
* Register this event to a source.
* This will show the current event in dropdown in single automation screen.
*/
if ( bwfan_is_woocommerce_active() ) {
return 'BWFAN_WC_Product_Purchased';
}

View File

@@ -0,0 +1,224 @@
<?php
final class BWFAN_WC_Product_Refunded extends BWFAN_Event {
private static $instance = null;
public $order_id = null;
/** @var WC_Order $order */
public $order = null;
public $refund_id = null;
private function __construct() {
$this->optgroup_label = esc_html__( 'Orders', 'wp-marketing-automations' );
$this->event_name = esc_html__( 'Order Refunded', 'wp-marketing-automations' );
$this->event_desc = esc_html__( 'This event runs when an order is refunded.', 'wp-marketing-automations' );
$this->event_merge_tag_groups = array( 'bwf_contact', 'wc_order', 'wc_order_refund' );
$this->event_rule_groups = array(
'wc_order',
'bwf_contact_segments',
'bwf_contact',
'bwf_contact_fields',
'bwf_contact_user',
'bwf_contact_wc',
'bwf_contact_geo',
'bwf_engagement',
'bwf_broadcast'
);
$this->support_lang = true;
$this->priority = 15.3;
$this->v2 = true;
$this->supported_blocks = [ 'order' ];
$this->automation_add = true;
}
public function load_hooks() {
add_action( 'woocommerce_order_refunded', array( $this, 'process' ), 10, 2 );
}
public static function get_instance() {
if ( null === self::$instance ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Set up rules data
*
* @param $value
*/
public function pre_executable_actions( $value ) {
BWFAN_Core()->rules->setRulesData( $this->event_automation_id, 'automation_id' );
BWFAN_Core()->rules->setRulesData( $this->order, 'wc_order' );
BWFAN_Core()->rules->setRulesData( BWFAN_Common::get_bwf_customer( $this->order->get_billing_email(), $this->order->get_user_id() ), 'bwf_customer' );
}
/**
* Registers the tasks for current event.
*
* @param $automation_id
* @param $integration_data
* @param $event_data
*/
public function register_tasks( $automation_id, $integration_data, $event_data ) {
if ( ! is_array( $integration_data ) ) {
return;
}
$data_to_send = $this->get_event_data();
$this->create_tasks( $automation_id, $integration_data, $event_data, $data_to_send );
}
public function get_event_data() {
$data_to_send = [];
$data_to_send['global']['order_id'] = $this->order_id;
$data_to_send['global']['refund_id'] = $this->refund_id;
$this->order = wc_get_order( $this->order_id );
$user_id = BWFAN_Common::get_wp_user_id_from_order( $this->order_id, $this->order );
if ( intval( $user_id ) > 0 ) {
$data_to_send['global']['user_id'] = $user_id;
}
$email = ! empty( $user_id ) ? BWFAN_Common::get_contact_email( $user_id ) : '';
/** Set billing email if email is empty */
$data_to_send['global']['email'] = ! empty( $email ) ? $email : BWFAN_Common::get_email_from_order( $this->order_id, $this->order );
$data_to_send['global']['phone'] = BWFAN_Common::get_phone_from_order( $this->order_id, $this->order );
$order_lang = BWFAN_Common::get_order_language( $this->order );
if ( ! empty( $order_lang ) ) {
$data_to_send['global']['language'] = $order_lang;
}
return $data_to_send;
}
/**
* Make the required data for the current event and send it asynchronously.
*
* @param $order_id
*/
public function process( $order_id, $refund_id ) {
$data = $this->get_default_data();
$data['order_id'] = $order_id;
$data['refund_id'] = $refund_id;
$this->send_async_call( $data );
}
/**
* Make the view data for the current event which will be shown in task listing screen.
*
* @param $global_data
*
* @return false|string
*/
public function get_task_view( $global_data ) {
ob_start();
$order = wc_get_order( $global_data['order_id'] );
if ( $order instanceof WC_Order ) {
?>
<li>
<strong><?php esc_html_e( 'Order:', 'wp-marketing-automations' ); ?> </strong>
<a target="_blank" href="<?php echo get_edit_post_link( $global_data['order_id'] ); //phpcs:ignore WordPress.Security.EscapeOutput
?>"><?php echo '#' . wp_strip_all_tags( $global_data['order_id'] . ' ' . $order->get_billing_first_name() . ' ' . $order->get_billing_last_name() );//phpcs:ignore WordPress.Security.EscapeOutput ?></a>
</li>
<?php } ?>
<li>
<strong><?php esc_html_e( 'Email:', 'wp-marketing-automations' ); ?> </strong>
<?php echo $global_data['email']; //phpcs:ignore WordPress.Security.EscapeOutput ?>
</li>
<?php
return ob_get_clean();
}
public function validate_event_data_before_executing_task( $data ) {
return $this->validate_order( $data );
}
/**
* Set global data for all the merge tags which are supported by this event.
*
* @param $task_meta
*/
public function set_merge_tags_data( $task_meta ) {
$get_data = BWFAN_Merge_Tag_Loader::get_data();
$set_data = [];
if ( ! isset( $get_data['wc_order_id'] ) || $get_data['wc_order_id'] !== $task_meta['global']['order_id'] ) {
$set_data['wc_order_id'] = $task_meta['global']['order_id'];
$set_data['email'] = $task_meta['global']['email'];
$set_data['wc_order'] = wc_get_order( $task_meta['global']['order_id'] );
}
BWFAN_Merge_Tag_Loader::set_data( $set_data );
}
/**
* Capture the async data for the current event.
*/
public function capture_async_data() {
$order_id = BWFAN_Common::$events_async_data['order_id'];
$refund_id = BWFAN_Common::$events_async_data['refund_id'];
$order = wc_get_order( $order_id );
$this->order_id = $order_id;
$this->order = $order;
$this->refund_id = $refund_id;
$this->run_automations();
}
/**
* Capture the async data for the current event.
* @return array|bool
*/
public function capture_v2_data( $automation_data ) {
$this->order_id = BWFAN_Common::$events_async_data['order_id'];
$this->refund_id = BWFAN_Common::$events_async_data['refund_id'];
$this->order = wc_get_order( $this->order_id );
$automation_data['order_id'] = $this->order_id;
$automation_data['refund_id'] = $this->refund_id;
return $automation_data;
}
/**
* get contact automation data
*
* @param $automation_data
* @param $cid
*
* @return array|null[]
*/
public function get_manually_added_contact_automation_data( $automation_data, $cid ) {
$contact = new WooFunnels_Contact( '', '', '', $cid );
/** Check if contact exists */
if ( ! $contact instanceof WooFunnels_Contact || empty( $contact->get_id() ) ) {
return [ 'status' => 0, 'type' => 'contact_not_found' ];
}
$refund = BWFAN_Common::fetch_last_refund_of_contact( $contact );
if ( empty( $refund ) || ! isset( $refund['refund_id'] ) ) {
return [ 'status' => 0, 'type' => '', 'message' => __( "Contact doesn't have any refunded order.", 'wp-marketing-automations' ) ];
}
$this->order_id = $refund['order_id'];
$this->refund_id = $refund['refund_id'];
return array_merge( $automation_data, [ 'order_id' => $this->order_id, 'refund_id' => $this->refund_id ] );
}
}
/**
* Register this event to a source.
* This will show the current event in dropdown in single automation screen.
*/
if ( bwfan_is_woocommerce_active() ) {
return 'BWFAN_WC_Product_Refunded';
}

View File

@@ -0,0 +1,237 @@
<?php
final class BWFAN_WC_Product_Stock_Reduced extends BWFAN_Event {
private static $instance = null;
public $reduced_products = [];
public $order_id = null;
public $single_item_id = null;
public $qty = null;
public $single_item = null;
/** @var WC_Order $order */
public $order = null;
private function __construct() {
$this->optgroup_label = esc_html__( 'Orders', 'wp-marketing-automations' );
$this->event_name = esc_html__( 'Order Item Stock Reduced', 'wp-marketing-automations' );
$this->event_desc = esc_html__( 'This event runs after an order payment is complete and its relative product items stocks reduced (runs per product item).', 'wp-marketing-automations' );
$this->event_merge_tag_groups = array( 'bwf_contact', 'wc_items' );
$this->event_rule_groups = array(
'wc_items',
'bwf_contact_segments',
'bwf_contact',
'bwf_contact_fields',
'bwf_contact_user',
'bwf_contact_wc',
'bwf_contact_geo',
'bwf_engagement',
'bwf_broadcast'
);
$this->priority = 15.4;
$this->v2 = true;
$this->supported_blocks = [ 'order' ];
}
public function load_hooks() {
add_filter( 'woocommerce_payment_complete_reduce_order_stock', [ $this, 'trigger_reduce_stock_event' ], 999999, 2 );
}
/**
* @return BWFAN_WC_Product_Stock_Reduced|null
*/
public static function get_instance() {
if ( null === self::$instance ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Set up rules data
*
* @param $value
*/
public function pre_executable_actions( $value ) {
BWFAN_Core()->rules->setRulesData( $this->order, 'wc_order' );
BWFAN_Core()->rules->setRulesData( $this->single_item, 'wc_items' );
BWFAN_Core()->rules->setRulesData( $this->qty, 'qty' );
}
public function trigger_reduce_stock_event( $trigger_reduce, $order_id ) {
// Only continue if we're reducing stock.
if ( ! $trigger_reduce ) {
return $trigger_reduce;
}
$this->order_id = $order_id;
add_filter( 'woocommerce_order_item_quantity', [ $this, 'get_item_data' ], 999999, 3 );
add_action( 'woocommerce_reduce_order_stock', [ $this, 'process' ] );
return $trigger_reduce;
}
public function get_item_data( $item_qty, $order, $item ) {
$this->reduced_products[] = [
'item' => $item,
'order' => $order,
'qty' => $item_qty,
];
return $item_qty;
}
public function get_task_view( $global_data ) {
ob_start();
if ( ! is_array( $global_data ) ) {
return '';
}
if ( ! isset( $global_data['single_item_id'] ) || 0 === absint( $global_data['single_item_id'] ) ) {
return;
}
/** @var WC_Order_Item $item_ins */
$item_ins = new WC_Order_Item_Product( absint( $global_data['single_item_id'] ) );
if ( ! $item_ins instanceof WC_Order_Item_Product || ! is_array( $item_ins->get_data() ) ) {
return;
}
$data = $item_ins->get_data();
?>
<li>
<strong><?php esc_html_e( 'Product :', 'wp-marketing-automations' ); ?> </strong>
<a target="_blank" href="<?php echo get_edit_post_link( $data['product_id'] ); //phpcs:ignore WordPress.Security.EscapeOutput ?>"><?php echo esc_attr( $data['name'] ); ?></a>
</li>
<li>
<strong><?php esc_html_e( 'Reduced Quantity :', 'wp-marketing-automations' ); ?> </strong>
<?php echo esc_attr( $global_data['qty'] ); ?>
</li>
<?php
return ob_get_clean();
}
/**
* Make the required data for the current event and send it asynchronously.
*
* @param $order WC_Product
*/
public function process( $order ) {
if ( ! is_array( $this->reduced_products ) || 0 === count( $this->reduced_products ) ) {
return;
}
foreach ( $this->reduced_products as $single ) {
$data = $this->get_default_data();
$data['details'] = array(
'order_id' => $single['order']->get_id(),
'single_item_id' => $single['item']->get_id(),
'qty' => $single['qty'],
);
$this->send_async_call( $data );
}
}
/**
* Registers the tasks for current event.
*
* @param $automation_id
* @param $integration_data
* @param $event_data
*/
public function register_tasks( $automation_id, $integration_data, $event_data ) {
if ( ! is_array( $integration_data ) ) {
return;
}
$data_to_send = $this->get_event_data();
$this->create_tasks( $automation_id, $integration_data, $event_data, $data_to_send );
}
public function get_event_data() {
$data_to_send = [];
$data_to_send['global']['order_id'] = $this->order_id;
$data_to_send['global']['wc_single_item_id'] = $this->single_item_id;
$data_to_send['global']['qty'] = $this->qty;
$data_to_send['global']['single_item'] = $this->single_item;
$this->order = $this->order instanceof WC_Order ? $this->order : wc_get_order( $this->order_id );
$user_id = BWFAN_Common::get_wp_user_id_from_order( $this->order_id, $this->order );
if ( intval( $user_id ) > 0 ) {
$data_to_send['global']['user_id'] = $user_id;
}
$email = ! empty( $user_id ) ? BWFAN_Common::get_contact_email( $user_id ) : '';
/** Set billing email if email is empty */
$data_to_send['global']['email'] = ! empty( $email ) ? $email : BWFAN_Common::get_email_from_order( $this->order_id, $this->order );
$data_to_send['global']['phone'] = BWFAN_Common::get_phone_from_order( $this->order_id, $this->order );
$order_lang = BWFAN_Common::get_order_language( $this->order );
if ( ! empty( $order_lang ) ) {
$data_to_send['global']['language'] = $order_lang;
}
return $data_to_send;
}
/**
* Set global data for all the merge tags which are supported by this event.
*
* @param $task_meta
*/
public function set_merge_tags_data( $task_meta ) {
$get_data = BWFAN_Merge_Tag_Loader::get_data();
$set_data = array(
'wc_single_item_id' => $task_meta['global']['wc_single_item_id'],
);
if ( ! isset( $get_data['wc_order_id'] ) || $get_data['wc_order_id'] !== $task_meta['global']['order_id'] ) {
$set_data['wc_order_id'] = $task_meta['global']['order_id'];
$set_data['wc_order'] = wc_get_order( $task_meta['global']['order_id'] );
}
$set_data['wc_single_item'] = $task_meta['global']['single_item'];
BWFAN_Merge_Tag_Loader::set_data( $set_data );
}
/**
* Capture the async data for the current event.
* @return array|bool
*/
public function capture_async_data() {
$details = BWFAN_Common::$events_async_data['details'];
$this->single_item_id = $details['single_item_id'];
$this->single_item = new WC_Order_Item_Product( $this->single_item_id );
$this->qty = $details['qty'];
$this->run_automations();
}
/**
* Capture the async data for the current event.
* @return array|bool
*/
public function capture_v2_data( $automation_data ) {
$details = BWFAN_Common::$events_async_data['details'];
$this->single_item_id = $details['single_item_id'];
$this->order_id = $details['order_id'];
$this->single_item = new WC_Order_Item_Product( $this->single_item_id );
$this->qty = $details['qty'];
$this->order_id = $details['order_id'];
$automation_data['wc_single_item_id'] = $this->single_item_id;
$automation_data['order_id'] = $this->order_id;
$automation_data['qty'] = $this->qty;
return $automation_data;
}
}
/**
* Register this event to a source.
* This will show the current event in dropdown in single automation screen.
*/
if ( bwfan_is_woocommerce_active() ) {
return 'BWFAN_WC_Product_Stock_Reduced';
}

View File

@@ -0,0 +1,2 @@
<?php
// Silence is golden.

View File

@@ -0,0 +1,2 @@
<?php
// Silence is golden.

View File

@@ -0,0 +1,2 @@
<?php
// Silence is golden.

View File

@@ -0,0 +1,44 @@
<?php
final class BWFAN_WP_Integration extends BWFAN_Integration {
private static $ins = null;
private function __construct() {
$this->action_dir = __DIR__;
$this->native_integration = true;
$this->nice_name = __( 'Email', 'wp-marketing-automations' );
$this->group_name = __( 'Messaging', 'wp-marketing-automations' );
$this->group_slug = 'messaging';
$this->priority = 25;
add_filter( 'bwfan_email_services', array( $this, 'add_as_email_service' ), 10, 1 );
}
public static function get_instance() {
if ( null === self::$ins ) {
self::$ins = new self();
}
return self::$ins;
}
/**
* Add this integration to email services list.
*
* @param $email_services
*
* @return array
*/
public function add_as_email_service( $email_services ) {
$integration = $this->get_slug();
$email_services[ $integration ] = $this->nice_name;
return $email_services;
}
}
/**
* Register this class as an integration.
*/
BWFAN_Load_Integrations::register( 'BWFAN_WP_Integration' );

View File

@@ -0,0 +1,37 @@
<?php
final class BWFAN_WP_Source extends BWFAN_Source {
private static $instance = null;
/**
* Constructor
*
* @access public
*/
protected function __construct() {
$this->event_dir = __DIR__;
$this->nice_name = __( 'WordPress', 'wp-marketing-automations' );
$this->group_name = __( 'WordPress', 'wp-marketing-automations' );
$this->group_slug = 'wp';
$this->priority = 20;
}
/**
* Ensures only one instance of the class is loaded or can be loaded.
*
* @return BWFAN_WP_Source|null
*/
public static function get_instance() {
if ( null === self::$instance ) {
self::$instance = new self();
}
return self::$instance;
}
}
/**
* Register this as a source.
*/
BWFAN_Load_Sources::register( 'BWFAN_WP_Source' );

View File

@@ -0,0 +1,240 @@
<?php
#[AllowDynamicProperties]
final class BWFAN_WP_User_Creation extends BWFAN_Event {
private static $instance = null;
/** @var WP_User $user */
public $user = null;
public $user_id = null;
private function __construct() {
$this->optgroup_label = esc_html__( 'User', 'wp-marketing-automations' );
$this->event_name = esc_html__( 'User Created', 'wp-marketing-automations' );
$this->event_desc = esc_html__( 'This event runs after a new user is created.', 'wp-marketing-automations' );
$this->event_merge_tag_groups = array( 'bwf_contact' );
$this->event_rule_groups = array(
'wp_user',
'bwf_contact_segments',
'bwf_contact',
'bwf_contact_fields',
'bwf_contact_user',
'bwf_contact_wc',
'bwf_contact_geo',
'bwf_engagement',
'bwf_broadcast'
);
$this->priority = 105;
$this->v2 = true;
$this->automation_add = true;
}
/**
* @return BWFAN_WP_User_Creation|null
*/
public static function get_instance() {
if ( null === self::$instance ) {
self::$instance = new self();
}
return self::$instance;
}
public function load_hooks() {
add_action( 'user_register', [ $this, 'user_created' ], 10, 1 );
}
/**
* Set up rules data
*
* @param $value
*/
public function pre_executable_actions( $value ) {
BWFAN_Core()->rules->setRulesData( $this->user, 'wp_user' );
BWFAN_Core()->rules->setRulesData( $this->user_id, 'user_id' );
BWFAN_Core()->rules->setRulesData( BWFAN_Common::get_bwf_customer( $this->user->user_email, $this->user_id ), 'bwf_customer' );
}
public function user_created( $user_id ) {
$this->process( [
'user_id' => $user_id,
] );
}
/**
* Make the required data for the current event and send it asynchronously.
*
* @param $details
*/
public function process( $details ) {
$data = $this->get_default_data();
$data['details'] = $details;
$this->send_async_call( $data );
}
/**
* Registers the tasks for current event.
*
* @param $automation_id
* @param $integration_data
* @param $event_data
*/
public function register_tasks( $automation_id, $integration_data, $event_data ) {
if ( ! is_array( $integration_data ) ) {
return;
}
$data_to_send = $this->get_event_data();
$this->create_tasks( $automation_id, $integration_data, $event_data, $data_to_send );
}
public function get_event_data() {
$data_to_send = [];
$data_to_send['global']['user_id'] = $this->user_id;
$data_to_send['global']['email'] = is_object( $this->user ) ? $this->user->user_email : '';
$data_to_send['global']['new_role'] = is_object( $this->user ) ? $this->user->roles : '';
return $data_to_send;
}
/**
* Make the view data for the current event which will be shown in task listing screen.
*
* @param $global_data
*
* @return false|string
*/
public function get_task_view( $global_data ) {
ob_start();
$user_data = get_userdata( $global_data['user_id'] );
?>
<li>
<strong><?php esc_html_e( 'User:', 'wp-marketing-automations' ); ?> </strong>
<a target="_blank" href="<?php echo admin_url( 'user-edit.php?user_id=' . $global_data['user_id'] ); //phpcs:ignore WordPress.Security.EscapeOutput ?>"><?php echo esc_html( $user_data->user_nicename ); ?></a>
</li>
<li>
<strong><?php esc_html_e( 'Email:', 'wp-marketing-automations' ); ?> </strong>
<span><?php echo $global_data['email']; //phpcs:ignore WordPress.Security.EscapeOutput ?></span>
</li>
<?php
return ob_get_clean();
}
public function get_email_event() {
if ( $this->user instanceof WP_User ) {
return $this->user->user_email;
}
if ( ! empty( absint( $this->user_id ) ) ) {
$user = get_user_by( 'id', absint( $this->user_id ) );
return false !== $user ? $user->user_email : false;
}
return false;
}
public function get_user_id_event() {
if ( ! empty( absint( $this->user_id ) ) ) {
return absint( $this->user_id );
}
if ( $this->user instanceof WP_User ) {
return $this->user->ID;
}
return false;
}
/**
* Set global data for all the merge tags which are supported by this event.
*
* @param $task_meta
*/
public function set_merge_tags_data( $task_meta ) {
$get_data = BWFAN_Merge_Tag_Loader::get_data( 'user_id' );
if ( empty( $get_data ) || intval( $get_data ) !== intval( $task_meta['global']['user_id'] ) ) {
$set_data = array(
'user_id' => intval( $task_meta['global']['user_id'] ),
'email' => $task_meta['global']['email'],
'wp_user' => get_user_by( 'ID', $task_meta['global']['user_id'] ),
'new_role' => $task_meta['global']['new_role'],
);
BWFAN_Merge_Tag_Loader::set_data( $set_data );
}
}
/**
* Capture the async data for the current event.
* @return array|bool
*/
public function capture_async_data() {
$details = BWFAN_Common::$events_async_data['details'];
$this->user_id = intval( $details['user_id'] );
$this->user = get_user_by( 'ID', $this->user_id );
return $this->run_automations();
}
/**
* Capture the async data for the current event.
* @return array|bool
*/
public function capture_v2_data( $automation_data ) {
$details = BWFAN_Common::$events_async_data['details'];
$this->user_id = intval( $details['user_id'] );
$this->user = get_user_by( 'ID', $this->user_id );
$automation_data['user_id'] = $this->user_id;
$automation_data['email'] = $this->user instanceof WP_User ? $this->user->user_email : '';
return $automation_data;
}
/**
* Get contact automation data for manual triggers
*
* @param $automation_data
* @param $cid
*
* @return array
*/
public function get_manually_added_contact_automation_data( $automation_data, $cid ) {
$contact = new WooFunnels_Contact( '', '', '', $cid );
/** Check if contact exists */
if ( ! $contact instanceof WooFunnels_Contact || empty( $contact->get_id() ) ) {
return [ 'status' => 0, 'type' => 'contact_not_found' ];
}
$user_id = $contact->get_wpid();
/** Validate user ID */
if ( empty( $user_id ) || $user_id <= 0 ) {
return [ 'status' => 0, 'type' => 'user_not_found' ];
}
/** Verify user exists */
$user = get_user_by( 'id', $user_id );
if ( ! $user instanceof WP_User ) {
return [ 'status' => 0, 'type' => '', 'message' => __( "Associated user no longer exists.", 'wp-marketing-automations' ) ];
}
/** Set user data for the event */
$this->user_id = $user_id;
$this->user = $user;
/** Merge automation data with user info */
$data = [
'user_id' => $user_id,
];
return array_merge( $automation_data, $data );
}
}
/**
* Register this event to a source.
* This will show the current event in dropdown in single automation screen.
*/
return 'BWFAN_WP_User_Creation';

View File

@@ -0,0 +1,247 @@
<?php
#[AllowDynamicProperties]
final class BWFAN_WP_User_Login extends BWFAN_Event {
private static $instance = null;
public $user = null;
public $user_id = null;
private function __construct() {
$this->optgroup_label = esc_html__( 'User', 'wp-marketing-automations' );
$this->event_name = esc_html__( 'User Login', 'wp-marketing-automations' );
$this->event_desc = esc_html__( 'This event runs after a user logged in.', 'wp-marketing-automations' );
$this->event_merge_tag_groups = array( 'bwf_contact' );
$this->event_rule_groups = array(
'wp_user',
'bwf_contact_segments',
'bwf_contact',
'bwf_contact_fields',
'bwf_contact_user',
'bwf_contact_wc',
'bwf_contact_geo',
'bwf_engagement',
'bwf_broadcast'
);
$this->priority = 105.1;
$this->v2 = true;
$this->automation_add = true;
}
public static function get_instance() {
if ( null === self::$instance ) {
self::$instance = new self();
}
return self::$instance;
}
public function load_hooks() {
add_action( 'wp_login', array( $this, 'user_logged_in' ), 10, 2 );
}
/**
* Set up rules data
*
* @param $value
*/
public function pre_executable_actions( $value ) {
BWFAN_Core()->rules->setRulesData( $this->user, 'wp_user' );
BWFAN_Core()->rules->setRulesData( $this->user_id, 'user_id' );
BWFAN_Core()->rules->setRulesData( BWFAN_Common::get_bwf_customer( $this->user->user_email, $this->user_id ), 'bwf_customer' );
}
/**
* @param $user_login
* @param $user WP_User
*
* @return void
*/
public function user_logged_in( $user_login = false, $user = false ) {
$user = BWFAN_Common::get_user( $user_login, $user );
if ( empty( $user ) || ! $user instanceof WP_User ) {
return;
}
$this->process( array(
'user_id' => $user->ID,
) );
}
/**
* Make the required data for the current event and send it asynchronously.
*
* @param $details
*/
public function process( $details ) {
$data = $this->get_default_data();
$data['details'] = $details;
$this->send_async_call( $data );
}
/**
* Registers the tasks for current event.
*
* @param $automation_id
* @param $integration_data
* @param $event_data
*/
public function register_tasks( $automation_id, $integration_data, $event_data ) {
if ( ! is_array( $integration_data ) ) {
return;
}
$data_to_send = $this->get_event_data();
$this->create_tasks( $automation_id, $integration_data, $event_data, $data_to_send );
}
public function get_event_data() {
$data_to_send = array();
$data_to_send['global']['user_id'] = $this->user_id;
$data_to_send['global']['email'] = is_object( $this->user ) ? $this->user->user_email : '';
return $data_to_send;
}
/**
* Make the view data for the current event which will be shown in task listing screen.
*
* @param $global_data
*
* @return false|string
*/
public function get_task_view( $global_data ) {
ob_start();
$user_data = get_userdata( $global_data['user_id'] );
?>
<li>
<strong><?php esc_html_e( 'User:', 'wp-marketing-automations' ); ?> </strong>
<a target="_blank" href="<?php echo admin_url( 'user-edit.php?user_id=' . $global_data['user_id'] ); //phpcs:ignore WordPress.Security.EscapeOutput ?>"><?php echo esc_html( $user_data->user_nicename ); ?></a>
</li>
<li>
<strong><?php esc_html_e( 'Email:', 'wp-marketing-automations' ); ?> </strong>
<span><?php echo $global_data['email']; //phpcs:ignore WordPress.Security.EscapeOutput ?></span>
</li>
<?php
return ob_get_clean();
}
public function get_email_event() {
if ( $this->user instanceof WP_User ) {
return $this->user->user_email;
}
if ( ! empty( absint( $this->user_id ) ) ) {
$user = get_user_by( 'id', absint( $this->user_id ) );
return false !== $user ? $user->user_email : false;
}
return false;
}
public function get_user_id_event() {
if ( ! empty( absint( $this->user_id ) ) ) {
return absint( $this->user_id );
}
if ( $this->user instanceof WP_User ) {
return $this->user->ID;
}
return false;
}
/**
* Set global data for all the merge tags which are supported by this event.
*
* @param $task_meta
*/
public function set_merge_tags_data( $task_meta ) {
$get_data = BWFAN_Merge_Tag_Loader::get_data( 'user_id' );
if ( empty( $get_data ) || intval( $get_data ) !== intval( $task_meta['global']['user_id'] ) ) {
$set_data = array(
'user_id' => intval( $task_meta['global']['user_id'] ),
'email' => $task_meta['global']['email'],
'wp_user' => get_user_by( 'ID', $task_meta['global']['user_id'] ),
);
BWFAN_Merge_Tag_Loader::set_data( $set_data );
}
}
/**
* Capture the async data for the current event.
*
* @return array|bool
*/
public function capture_async_data() {
$details = BWFAN_Common::$events_async_data['details'];
$this->user_id = intval( $details['user_id'] );
$this->user = get_user_by( 'ID', $this->user_id );
return $this->run_automations();
}
/**
* Capture the async data for the current event.
*
* @return array|bool
*/
public function capture_v2_data( $automation_data ) {
$details = BWFAN_Common::$events_async_data['details'];
$this->user_id = absint( $details['user_id'] );
$this->user = get_user_by( 'ID', $this->user_id );
$automation_data['user_id'] = $this->user_id;
$automation_data['email'] = $this->user instanceof WP_User ? $this->user->user_email : '';
return $automation_data;
}
/**
* Get contact automation data for manual triggers
*
* @param $automation_data
* @param $cid
*
* @return array
*/
public function get_manually_added_contact_automation_data( $automation_data, $cid ) {
$contact = new WooFunnels_Contact( '', '', '', $cid );
/** Check if contact exists */
if ( ! $contact instanceof WooFunnels_Contact || empty( $contact->get_id() ) ) {
return [ 'status' => 0, 'type' => 'contact_not_found' ];
}
$user_id = $contact->get_wpid();
/** Validate user ID */
if ( empty( $user_id ) || $user_id <= 0 ) {
return [ 'status' => 0, 'type' => 'user_not_found' ];
}
/** Verify user exists */
$user = get_user_by( 'id', $user_id );
if ( ! $user instanceof WP_User ) {
return [ 'status' => 0, 'type' => '', 'message' => __( "Associated user no longer exists.", 'wp-marketing-automations' ) ];
}
/** Set user data for the event */
$this->user_id = $user_id;
$this->user = $user;
/** Merge automation data with user info */
$data = [
'user_id' => $user_id,
];
return array_merge( $automation_data, $data );
}
}
/**
* Register this event to a source.
* This will show the current event in dropdown in single automation screen.
*/
return 'BWFAN_WP_User_Login';

View File

@@ -0,0 +1,2 @@
<?php
// Silence is golden.

View File

@@ -0,0 +1,2 @@
<?php
// Silence is golden.

View File

@@ -0,0 +1,222 @@
<?php
$unique_slug = $this->get_slug();
$wc_enabled = apply_filters( 'bwfan_enable_wc_email_template', false );
?>
<script type="text/html" id="tmpl-action-<?php echo esc_html( $unique_slug ); ?>">
<#
selected_event_src = BWFAN_Auto.uiDataDetail.trigger.source;
selected_event = BWFAN_Auto.uiDataDetail.trigger.event;
email_merge_tag = '';
email_sub = '';
email_body = '';
ae = bwfan_automation_data.all_triggers_events;
if(_.has(ae, selected_event_src) &&
_.has(ae[selected_event_src], selected_event) &&
_.has(ae[selected_event_src][selected_event], 'customer_email_tag')) {
email_merge_tag = ae[selected_event_src][selected_event].customer_email_tag;
}
if(selected_event=='ab_cart_abandoned'){
email_sub = 'We\'re still holding the cart for you';
email_body = '<p>Hi {{cart_billing_first_name}},</p>' +
"<p>I noticed that you were trying to purchase but could not complete the process.</p>" +
'<p>{{cart_items template = "cart-table"}}</p>'+
'<p>We have reserved the cart for you, <a href="{{cart_recovery_link}}">Click here</a> to complete your purchase.</p>' +
'<p>If you have any questions, feel free to get in touch with us.</p>' +
'<p>Hit reply and I\'ll be happy to answer your questions.</p>' +
'<p>Thanks!</p>';
}
selected_template = (_.has(data.actionSavedData, 'data') && _.has(data.actionSavedData.data, 'template')) ? data.actionSavedData.data.template : 'raw_template';
is_enable_wysiwyg = ('raw_template' === selected_template || 'wc_template' === selected_template) ? '' : 'bwfan-display-none';
is_enable_textarea = ('raw' === selected_template) ? '' : 'bwfan-display-none';
email_heading = (_.has(data.actionSavedData, 'data') && _.has(data.actionSavedData.data, 'email_heading')) ? data.actionSavedData.data.email_heading : '';
to = (_.has(data.actionSavedData, 'data') && _.has(data.actionSavedData.data, 'to')) ? data.actionSavedData.data.to : email_merge_tag;
subject = (_.has(data.actionSavedData, 'data') && _.has(data.actionSavedData.data, 'subject')) ? data.actionSavedData.data.subject : email_sub;
body = (_.has(data.actionSavedData, 'data') && _.has(data.actionSavedData.data, 'body')) ? data.actionSavedData.data.body : email_body;
body_raw = (_.has(data.actionSavedData, 'data') && _.has(data.actionSavedData.data, 'body_raw')) ? data.actionSavedData.data.body_raw : email_body;
show_email_heading = (selected_template=='wc_template' || selected_template=='') ? '' : 'bwfan-display-none';
is_promotional = (_.has(data.actionSavedData, 'data') && _.has(data.actionSavedData.data, 'promotional_email')) ? 'checked' : '';
is_append_utm = (_.has(data.actionSavedData, 'data') && _.has(data.actionSavedData.data, 'append_utm')) ? 'checked' : '';
show_utm_parameters = (_.has(data.actionSavedData, 'data') && _.has(data.actionSavedData.data, 'append_utm')) ? '' : 'bwfan-display-none';
entered_utm_source = (_.has(data.actionSavedData, 'data') && _.has(data.actionSavedData.data, 'utm_source')) ? data.actionSavedData.data.utm_source : '';
email_preheading = (_.has(data.actionSavedData, 'data') && _.has(data.actionSavedData.data, 'preheading')) ? data.actionSavedData.data.preheading : '';
entered_utm_medium = (_.has(data.actionSavedData, 'data') && _.has(data.actionSavedData.data, 'utm_medium')) ? data.actionSavedData.data.utm_medium : '';
entered_utm_campaign = (_.has(data.actionSavedData, 'data') && _.has(data.actionSavedData.data, 'utm_campaign')) ? data.actionSavedData.data.utm_campaign : '';
entered_utm_term = (_.has(data.actionSavedData, 'data') && _.has(data.actionSavedData.data, 'utm_term')) ? data.actionSavedData.data.utm_term : '';
if(_.has(data.actionFieldsOptions, 'default_promotional_status') && 1 == data.actionFieldsOptions.default_promotional_status && !_.has(data.actionSavedData,'data')) {
is_promotional = 'checked';
}
#>
<div data-element-type="bwfan-editor" data-temp="{{selected_template}}" class="bwfan-<?php echo esc_html( $unique_slug ); ?>">
<label for="" class="bwfan-label-title">
<?php esc_html_e( 'Template', 'wp-marketing-automations' ); ?>
<?php
$message = "<strong>Rich Text Template:</strong> " . __( "Use this template for more control over the email body. Rich text style is auto-applied.", 'wp-marketing-automations' );
if ( $wc_enabled ) {
$message .= "<br/><br/><strong>WooCommerce Template:</strong> " . __( "Use native WooCommerce header/footer template. Write content inside the email body using a combination of text and code.", 'wp-marketing-automations' );
}
$message .= "<br/><br/><strong>Raw HTML Template:</strong> " . __( "Use this template for complete control by pasting any Custom HTML/CSS (usually designed using an external email editor).", 'wp-marketing-automations' );
echo $this->add_description( $message, '3xl', 'right', false ); //phpcs:ignore WordPress.Security.EscapeOutput
?>
</label>
<div class="bwfan-col-sm-12 bwfan-pl-0 bwfan-pr-0 bwfan-mb-15">
<#
if(_.has(data.actionFieldsOptions, 'template_options') && _.isObject(data.actionFieldsOptions.template_options) ) {
_.each( data.actionFieldsOptions.template_options, function( value, key ){
<?php
if ( ! $wc_enabled ) { ?>
if(selected_template != 'wc_template' && key == 'wc_template') {
return;
}
<?php } ?>
selected = (key == selected_template) ? 'checked="checked"' : '';
#>
<label class="bwf-radio-button">
<input type="radio" name="bwfan[{{data.action_id}}][data][template]" value="{{key}}" {{selected}} class="bwfan_email_template bwf-radio-hide">
<span class="button bwfan_button">{{value}}</span>
</label>
<# })
}
#>
</div>
<label for="" class="bwfan-label-title">
<?php esc_html_e( 'To', 'wp-marketing-automations' ); ?>
<?php
$message = __( 'Receiver email address', 'wp-marketing-automations' );
echo $this->add_description( $message, 'xl', 'right' ); //phpcs:ignore WordPress.Security.EscapeOutput
?>
<?php echo $this->inline_merge_tag_invoke(); //phpcs:ignore WordPress.Security.EscapeOutput ?>
</label>
<div class="bwfan-col-sm-12 bwfan-pl-0 bwfan-pr-0 bwfan-mb-15">
<input required type="text" class="bwfan-input-wrapper bwfan-field-<?php echo esc_html( $unique_slug ); ?>" name="bwfan[{{data.action_id}}][data][to]" placeholder="E.g. customer_email@gmail.com" value="{{to}}"/>
</div>
<label for="" class="bwfan-label-title">
<?php esc_html_e( 'Subject', 'wp-marketing-automations' ); ?>
<?php
$message = __( 'Email subject', 'wp-marketing-automations' );
echo $this->add_description( $message, 'm', 'right' ); //phpcs:ignore WordPress.Security.EscapeOutput
?>
<?php echo $this->inline_merge_tag_invoke(); //phpcs:ignore WordPress.Security.EscapeOutput ?>
</label>
<div class="bwfan-col-sm-12 bwfan-pl-0 bwfan-pr-0 bwfan-mb-15">
<input required type="text" id='bwfan_email_subject' class="bwfan-input-wrapper bwfan-field-<?php echo esc_html( $unique_slug ); ?>" name="bwfan[{{data.action_id}}][data][subject]" placeholder="Enter Subject" value="{{subject}}"/>
</div>
<label for="" class="bwfan-label-title">
<?php esc_html_e( 'Pre Header', 'wp-marketing-automations' ); ?>
<?php
$message = __( 'Email pre header', 'wp-marketing-automations' );
echo $this->add_description( $message, 'm', 'right' ); //phpcs:ignore WordPress.Security.EscapeOutput
?>
<?php echo $this->inline_merge_tag_invoke(); //phpcs:ignore WordPress.Security.EscapeOutput ?>
</label>
<div class="bwfan-col-sm-12 bwfan-pl-0 bwfan-pr-0 bwfan-mb-15">
<input required type="text" id='bwfan_email_preheader' class="bwfan-input-wrapper bwfan-field-<?php echo esc_html( $unique_slug ); ?>" name="bwfan[{{data.action_id}}][data][preheading]" placeholder="Enter Pre Heading" value="{{email_preheading}}"/>
</div>
<div class="bwfan_email_template {{show_email_heading}} bwfan_wc_email_heading">
<label for="" class="bwfan-label-title">
<?php esc_html_e( 'Email Heading', 'wp-marketing-automations' ); ?>
<?php echo $this->inline_merge_tag_invoke(); //phpcs:ignore WordPress.Security.EscapeOutput ?>
</label>
<div class="bwfan-col-sm-12 bwfan-pl-0 bwfan-pr-0 bwfan-mb-15">
<input type="text" id='bwfan_email_heading' class="bwfan-input-wrapper bwfan-field-<?php echo esc_html( $unique_slug ); ?>" name="bwfan[{{data.action_id}}][data][email_heading]" placeholder="Your Store Name" value="{{email_heading}}"/>
</div>
</div>
<div style="display: flex;
flex-direction: row;
width: 100%;
justify-content: space-between;
margin: 10px 0;"
>
<label for="" class="bwfan-label-title"><?php esc_html_e( 'Body', 'wp-marketing-automations' ); ?></label>
<?php echo $this->inline_template_mergetags_selector_invoke(); //phpcs:ignore WordPress.Security.EscapeOutput ?>
</div>
<div class="bwfan-email-content bwfan-col-sm-12 bwfan-pl-0 bwfan-pr-0 bwfan-mb-15 bwfan-email-wysiwyg {{is_enable_wysiwyg}}">
<textarea class="bwfan-input-wrapper" id="bwfan-editor" rows="6" placeholder="<?php esc_html_e( 'Email Message', 'wp-marketing-automations' ); ?>" name="bwfan[{{data.action_id}}][data][body]">{{body}}</textarea>
</div>
<div class="bwfan-email-content bwfan-col-sm-12 bwfan-pl-0 bwfan-pr-0 bwfan-mb-15 bwfan-email-textarea {{is_enable_textarea}}">
<textarea class="bwfan-input-wrapper" id="bwfan-raw_textarea" rows="15" placeholder="<?php esc_html_e( 'Email Message with HTML/CSS', 'wp-marketing-automations' ); ?>" name="bwfan[{{data.action_id}}][data][body_raw]">{{body_raw}}</textarea>
</div>
<?php do_action( 'bwfan_action_send_email_editors' ); ?>
<div class="bwfan_preview_email_container bwfan-mb-15">
<?php echo $this->save_email_option_template(); //phpcs:ignore WordPress.Security.EscapeOutput ?>
<a href="javascript:void(0);" class="bwfan_preview_email"><?php esc_html_e( 'Generate Preview', 'wp-marketing-automations' ); ?></a>
</div>
<label for="" class="bwfan-label-title"><?php esc_html_e( 'Send Test Mail', 'wp-marketing-automations' ); ?></label>
<div class="bwfan_send_test_email bwfan-mb-15">
<input type="email" name="test_email" id="bwfan_test_email">
<input type="button" id="bwfan_test_email_btn" class="button bwfan-btn-inner" value="<?php esc_html_e( 'Send', 'wp-marketing-automations' ); ?>">
</div>
<div class="bwfan-input-form bwfan-row-sep"></div>
<label for="" class="bwfan-label-title">Other</label>
<div class="bwfan_email_tracking bwfan-mb-15">
<label for="bwfan_promotional_email">
<input type="checkbox" name="bwfan[{{data.action_id}}][data][promotional_email]" id="bwfan_promotional_email" value="1" {{is_promotional}}/>
<?php
esc_html_e( 'Mark as Promotional', 'wp-marketing-automations' );
$message = __( "Email marked as promotional will not be send to the unsubscribers.", 'wp-marketing-automations' );
echo $this->add_description( $message, 'xl' ); //phpcs:ignore WordPress.Security.EscapeOutput
?>
</label>
</div>
<?php
do_action( 'bwfan_' . $this->get_slug() . '_setting_html', $this )
?>
</div>
</script>
<script>
jQuery(document).ready(function ($) {
/** Email heading functionality for woocommerce */
$('body').on('change', '.bwfan_email_template', function (event) {
var $this = jQuery(this);
var selected_template = $this.val();
$this.parents('.bwfan-wp_sendemail').attr('data-temp', selected_template);
if ('raw' === selected_template) {
jQuery('.bwfan_email_template').hide();
jQuery('.bwfan-email-content').hide();
jQuery('.bwfan-email-textarea').show();
jQuery('.bwfan-email-editor').addClass('bwfan-display-none');
} else if ('raw_template' === selected_template) {
jQuery('.bwfan_email_template').hide();
jQuery('.bwfan-email-content').hide();
jQuery('.bwfan-email-wysiwyg').show();
jQuery('.bwfan-email-editor').addClass('bwfan-display-none');
} else if ('editor' === selected_template) {
jQuery('.bwfan_email_template').hide();
jQuery('.bwfan-email-content').hide();
jQuery('.bwfan-email-editor').removeClass('bwfan-display-none');
} else if ('wc_template' === selected_template) {
jQuery('.bwfan_email_template').hide();
jQuery('.bwfan-email-content').hide();
jQuery('.bwfan-email-wysiwyg').show();
jQuery('.bwfan_wc_email_heading').removeClass('bwfan-display-none');
jQuery('.bwfan_wc_email_heading').show();
}
});
/** UTM parameters functionality */
$('body').on('change', '#bwfan_append_utm', function (event) {
var $this = jQuery(this);
if ($this.is(":checked")) {
jQuery('.bwfan_utm_sources').show();
} else {
jQuery('.bwfan_utm_sources').hide();
}
});
});
</script>
<?php do_action( 'bwfan_action_send_email_template' ) ?>