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,137 @@
<?php
final class BWFAN_WC_Add_Custom_Field extends BWFAN_Action {
private static $ins = null;
private function __construct() {
$this->action_name = __( 'Add Custom Fields', 'wp-marketing-automations-pro' );
$this->action_desc = __( 'This action adds/ updates the custom fields', 'wp-marketing-automations-pro' );
$this->action_priority = 20;
$this->included_events = array(
'wc_new_order',
'wc_order_note_added',
'wc_order_status_change',
'wc_product_purchased',
'wc_product_refunded',
'wc_product_stock_reduced',
'wc_order_status_pending',
);
$this->support_v2 = true;
$this->support_v1 = false;
}
public static function get_instance() {
if ( null === self::$ins ) {
self::$ins = new self();
}
return self::$ins;
}
public function make_v2_data( $automation_data, $step_data ) {
$data_to_set = array();
$custom_fields = array();
$custom_fields_value = array();
$data_to_set['order_id'] = isset( $automation_data['global']['order_id'] ) ? $automation_data['global']['order_id'] : 0;
$custom_field_array = isset( $step_data['custom_fields'] ) ? $step_data['custom_fields'] : [];
if ( ! empty( $custom_field_array ) && is_array( $custom_field_array ) ) {
$custom_fields = array_column( $custom_field_array, 'field' );
$custom_fields_value = array_column( $custom_field_array, 'field_value' );
}
$meta_fields = array();
if ( is_array( $custom_fields ) && ! empty( $custom_fields ) ) {
foreach ( $custom_fields as $key => $field_alias ) {
if ( empty( $field_alias ) ) {
continue;
}
$meta_fields[ $field_alias ] = BWFAN_Common::decode_merge_tags( $custom_fields_value[ $key ] );
}
}
$data_to_set['order_metas'] = $meta_fields;
return $data_to_set;
}
public function process_v2() {
if ( 0 === intval( $this->data['order_id'] ) ) {
return $this->skipped_response( __( 'Order missing.', 'wp-marketing-automations-pro' ) );
}
$order = wc_get_order( intval( $this->data['order_id'] ) );
if ( ! $order instanceof WC_Order ) {
return $this->skipped_response( __( 'Not a WC order', 'wp-marketing-automations-pro' ) );
}
if ( empty( $this->data['order_metas'] ) ) {
return $this->skipped_response( __( 'Custom field(s) are required.', 'wp-marketing-automations-pro' ) );
}
foreach ( $this->data['order_metas'] as $meta_key => $meta_value ) {
$order->update_meta_data( $meta_key, $meta_value );
}
$order->save();
return $this->success_message( __( 'Custom Field added/updated.', 'wp-marketing-automations-pro' ) );
}
/**
* v2 Method: Get field Schema
*
* @return array[]
*/
public function get_fields_schema() {
return [
[
'id' => 'custom_fields',
'type' => 'repeater',
'label' => __( 'Enter Custom Field Key/ values', 'wp-marketing-automations-pro' ),
"fields" => [
[
'id' => 'field',
'type' => 'text',
'label' => "",
'tip' => "",
"description" => "",
"required" => false,
"placeholder" => __( 'Enter Field Key', 'wp-marketing-automations-pro' ),
],
[
"id" => 'field_value',
"label" => "",
"type" => 'text',
"class" => 'bwfan-input-wrapper',
"description" => "",
"required" => false,
"placeholder" => __( 'Enter Field value', 'wp-marketing-automations-pro' ),
]
],
'tip' => "",
"description" => ""
]
];
}
public function get_desc_text( $data ) {
$data = json_decode( wp_json_encode( $data ), true );
if ( ! isset( $data['custom_fields'] ) || empty( $data['custom_fields'] ) ) {
return '';
}
$count = count( $data['custom_fields'] );
return ( $count > 1 ) ? $count . ' fields' : $count . ' field';
}
}
/**
* Register this action. Registering the action will make it eligible to see it on single automation screen in select actions dropdown.
*/
return 'BWFAN_WC_Add_Custom_Field';

View File

@@ -0,0 +1,248 @@
<?php
final class BWFAN_WC_Add_Order_Note extends BWFAN_Action {
private static $ins = null;
protected function __construct() {
$this->action_name = __( 'Add Order Note', 'wp-marketing-automations-pro' );
$this->action_desc = __( 'This action adds an order note to the WC order', 'wp-marketing-automations-pro' );
$this->required_fields = array( 'order_id', 'body' );
$this->included_events = array(
'wc_new_order',
'wc_order_note_added',
'wc_order_status_change',
'wc_product_purchased',
'wc_product_refunded',
'wc_product_stock_reduced',
'wc_order_status_pending',
);
$this->action_priority = 25;
$this->support_v2 = true;
}
public static function get_instance() {
if ( null === self::$ins ) {
self::$ins = new self();
}
return self::$ins;
}
/**
* Show the html fields for the current action.
*/
public function get_view() {
?>
<script type="text/html" id="tmpl-action-<?php echo esc_html__( $this->get_slug() ); ?>">
<#
body = (_.has(data.actionSavedData, 'data') && _.has(data.actionSavedData.data, 'body')) ? data.actionSavedData.data.body : '';
note_type = (_.has(data.actionSavedData, 'data') && _.has(data.actionSavedData.data, 'note_type')) ? data.actionSavedData.data.note_type : '';
#>
<div class="bwfan-input-form clearfix">
<label for="" class="bwfan-label-title"><?php echo esc_html__( 'Order Note', 'wp-marketing-automations-pro' ); ?><?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">
<textarea required class="bwfan-input-wrapper" rows="4" placeholder="<?php echo esc_html__( 'Order Note', 'wp-marketing-automations-pro' ); ?>" name="bwfan[{{data.action_id}}][data][body]">{{body}}</textarea>
</div>
</div>
<div class="bwfan-input-form clearfix">
<label for="" class="bwfan-label-title"><?php echo esc_html__( 'Note Type', 'wp-marketing-automations-pro' ); ?></label>
<select required id="" class="bwfan-input-wrapper bwfan-single-select" name="bwfan[{{data.action_id}}][data][note_type]">
<option {{ note_type===
'private' ? 'selected' : '' }} value="private"><?php echo esc_html__( 'Private', 'wp-marketing-automations-pro' ); ?></option>
<option {{ note_type===
'public' ? 'selected' : '' }} value="public"><?php echo esc_html__( 'Note to Customer', 'wp-marketing-automations-pro' ); ?></option>
</select>
</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|void
*/
public function make_data( $integration_object, $task_meta ) {
$this->set_data_for_merge_tags( $task_meta );
$body = $task_meta['data']['body'];
$note_type = $task_meta['data']['note_type'];
$body = BWFAN_Common::decode_merge_tags( $body );
$data_to_set = array();
$data_to_set['body'] = $body;
$data_to_set['note_type'] = $note_type;
foreach ( $task_meta['global'] as $key1 => $value1 ) {
$data_to_set[ $key1 ] = $value1;
}
return $data_to_set;
}
public function make_v2_data( $automation_data, $step_data ) {
$data_to_set = array();
$data_to_set['body'] = BWFAN_Common::decode_merge_tags( $step_data['body'] );
$data_to_set['note_type'] = $step_data['note_type'];
$email = ( isset( $automation_data['global']['email'] ) && is_email( $automation_data['global']['email'] ) ) ? $automation_data['global']['email'] : '';
$data_to_set['order_id'] = isset( $automation_data['global']['order_id'] ) ? $automation_data['global']['order_id'] : 0;
$user = is_email( $email ) ? get_user_by( 'email', $email ) : '';
$data_to_set['user_id'] = $user instanceof WP_User ? $user->ID : 0;
$data_to_set['email'] = $email;
return $data_to_set;
}
/**
* 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 ( true === $result ) {
return array(
'status' => 3,
);
}
return $result;
}
/**
* 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 ) {
return $this->show_fields_error();
}
$order = BWFAN_Merge_Tag_Loader::get_data( 'wc_order' );
if ( ! $order instanceof WC_Order ) {
return array(
'status' => 4,
'message' => __( 'Not a WooCommerce Order Object', 'wp-marketing-automations-pro' ),
);
}
$note = $this->data['body'];
$is_customer_note = 'public' === $this->data['note_type'] ? true : false;
if ( false === $is_customer_note ) {
/** Prefix adding when private note */
add_filter( 'woocommerce_new_order_note_data', array( $this, 'add_autonami_prefix_in_notes' ), 9999, 2 );
}
$order->add_order_note( $note, $is_customer_note );
if ( false === $is_customer_note ) {
remove_filter( 'woocommerce_new_order_note_data', array( $this, 'add_autonami_prefix_in_notes' ), 9999, 2 );
}
return true;
}
public function process_v2() {
$order_id = absint( $this->data['order_id'] );
$order = wc_get_order( $order_id );
if ( ! $order instanceof WC_Order ) {
return $this->skipped_response( __( 'WooCommerce Order not found', 'wp-marketing-automations-pro' ) );
}
$note = $this->data['body'];
$is_customer_note = 'public' === $this->data['note_type'] ? true : false;
if ( false === $is_customer_note ) {
/** Prefix adding when private note */
add_filter( 'woocommerce_new_order_note_data', array( $this, 'add_autonami_prefix_in_notes' ), 9999, 2 );
}
$order->add_order_note( $note, $is_customer_note );
if ( false === $is_customer_note ) {
remove_filter( 'woocommerce_new_order_note_data', array( $this, 'add_autonami_prefix_in_notes' ), 9999, 2 );
}
return $this->success_message( __( 'Order note added.', 'wp-marketing-automations-pro' ) );
}
/**
* Append Autonami prefix in notes so that can be identified the note is added by Autonami
*
* @param $note
* @param $data
*
* @return mixed
*/
public function add_autonami_prefix_in_notes( $note, $data ) {
if ( isset( $this->data['order_id'] ) && intval( $this->data['order_id'] ) === intval( $data['order_id'] ) ) {
$note['comment_content'] = 'FKA: ' . $note['comment_content'];
}
return $note;
}
public function get_fields_schema() {
return [
[
'id' => 'body',
'type' => 'textarea',
'label' => __( 'Order Note', 'wp-marketing-automations-pro' ),
'placeholder' => __( 'Order Note', 'wp-marketing-automations-pro' ),
'tip' => "",
"description" => "",
"required" => true,
],
[
'id' => 'note_type',
'type' => 'wp_select',
'label' => __( 'Note Type', 'wp-marketing-automations-pro' ),
'options' => [
[
'label' => __( 'Private', 'wp-marketing-automations-pro' ),
'value' => 'private'
],
[
'label' => __( 'Note to Customer', 'wp-marketing-automations-pro' ),
'value' => 'public'
],
],
'placeholder' => __( 'Choose Note Type', 'wp-marketing-automations-pro' ),
'tip' => "",
"description" => "",
"required" => true,
]
];
}
/** set default values */
public function get_default_values() {
return [
'note_type' => 'public',
];
}
public function get_desc_text( $data ) {
$data = json_decode( wp_json_encode( $data ), true );
if ( ! isset( $data['body'] ) || empty( $data['body'] ) ) {
return '';
}
return $data['body'];
}
}
return 'BWFAN_WC_Add_Order_Note';

View File

@@ -0,0 +1,215 @@
<?php
final class BWFAN_WC_Change_order_status extends BWFAN_Action {
private static $ins = null;
protected function __construct() {
$this->action_name = __( 'Change Order Status', 'wp-marketing-automations-pro' );
$this->action_desc = __( 'This action changes the WooCommerce order status', 'wp-marketing-automations-pro' );
$this->required_fields = array( 'order_id', 'status' );
$this->included_events = array(
'wc_new_order',
'wc_order_note_added',
'wc_order_status_change',
'wc_product_purchased',
'wc_product_refunded',
'wc_product_stock_reduced',
'wc_order_status_pending',
);
$this->action_priority = 15;
$this->support_v2 = 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' ) ) {
$data = $this->get_view_data();
BWFAN_Core()->admin->set_actions_js_data( $this->get_class_slug(), 'status_options', $data );
}
}
public function get_view_data() {
return wc_get_order_statuses();
}
/**
* Show the html fields for the current action.
*/
public function get_view() {
?>
<script type="text/html" id="tmpl-action-<?php echo esc_html__( $this->get_slug() ); ?>">
<#
selected_status = (_.has(data.actionSavedData, 'data') && _.has(data.actionSavedData.data, 'status')) ? data.actionSavedData.data.status : '';
#>
<div data-element-type="bwfan-select" class="bwfan-<?php echo esc_html__( $this->get_slug() ); ?>">
<label for="" class="bwfan-label-title"><?php echo esc_html__( 'Change Order Status To', 'wp-marketing-automations-pro' ); ?></label>
<select data-element-type="bwfan-select" required id="" class="bwfan-input-wrapper" name="bwfan[{{data.action_id}}][data][status]">
<option value=""><?php echo esc_html__( 'Choose Order Status', 'wp-marketing-automations-pro' ); ?></option>
<#
if(_.has(data.actionFieldsOptions, 'status_options') && _.isObject(data.actionFieldsOptions.status_options) ) {
_.each( data.actionFieldsOptions.status_options, function( value, key ){
selected = (key == selected_status) ? 'selected' : '';
#>
<option value="{{key}}" {{selected}}>{{value}}</option>
<# })
}
#>
</select>
</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|void
*/
public function make_data( $integration_object, $task_meta ) {
return array(
'status' => $task_meta['data']['status'],
'order_id' => $task_meta['global']['order_id'],
);
}
public function make_v2_data( $automation_data, $step_data ) {
$data_to_set = array();
$data_to_set['status'] = $step_data['status'];
$email = ( isset( $automation_data['global']['email'] ) && is_email( $automation_data['global']['email'] ) ) ? $automation_data['global']['email'] : '';
$data_to_set['order_id'] = isset( $automation_data['global']['order_id'] ) ? $automation_data['global']['order_id'] : 0;
$user = is_email( $email ) ? get_user_by( 'email', $email ) : '';
$data_to_set['user_id'] = $user instanceof WP_User ? $user->ID : 0;
$data_to_set['email'] = $email;
return $data_to_set;
}
/**
* 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 ( $result ) {
return array(
'status' => 3,
);
}
return array(
'status' => 4,
'message' => __( 'Something went wrong', 'wp-marketing-automations-pro' ),
);
}
/**
* 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 ) {
return $this->show_fields_error();
}
return $this->change_status();
}
/**
* Change order status.
*
* order_id, status are required.
*
* @return array|bool
* @throws Exception
*/
public function change_status() {
$order = new WC_Order( $this->data['order_id'] );
add_filter( 'woocommerce_new_order_note_data', array( $this, 'add_autonami_prefix_in_notes' ), 9999, 2 );
$res = $order->update_status( $this->data['status'] );
remove_filter( 'woocommerce_new_order_note_data', array( $this, 'add_autonami_prefix_in_notes' ), 9999, 2 );
return $res;
}
public function process_v2() {
$order_id = absint( $this->data['order_id'] );
$order = wc_get_order( $order_id );
if ( ! $order instanceof WC_Order ) {
return $this->skipped_response( __( 'Not a WooCommerce Order Object', 'wp-marketing-automations-pro' ) );
}
$order->update_status( $this->data['status'] );
remove_filter( 'woocommerce_new_order_note_data', array( $this, 'add_autonami_prefix_in_notes' ), 9999, 2 );
return $this->success_message( __( 'Order status changed.', 'wp-marketing-automations-pro' ) );
}
public function add_autonami_prefix_in_notes( $note, $data ) {
if ( isset( $this->data['order_id'] ) && intval( $this->data['order_id'] ) === intval( $data['order_id'] ) ) {
$note['comment_content'] = 'FunnelKit Automations: ' . $note['comment_content'];
}
return $note;
}
public function get_fields_schema() {
$status = array_replace( [ '' => 'Select' ], $this->get_view_data() );
$options = BWFAN_PRO_Common::prepared_field_options( $status );
return [
[
'id' => 'status',
'label' => __( "Change Order Status To", 'wp-marketing-automations-pro' ),
'type' => 'wp_select',
'options' => $options,
'placeholder' => __( 'Choose Order Status', 'wp-marketing-automations-pro' ),
"class" => 'bwfan-input-wrapper',
'tip' => "",
"description" => "",
"required" => true,
],
];
}
public function get_desc_text( $data ) {
$data = json_decode( wp_json_encode( $data ), true );
if ( ! isset( $data['status'] ) || empty( $data['status'] ) ) {
return '';
}
$status = $this->get_view_data();
return $status[ $data['status'] ];
}
}
/**
* Register this action. Registering the action will make it eligible to see it on single automation screen in select actions dropdown.
*/
return 'BWFAN_WC_Change_order_status';

View File

@@ -0,0 +1,623 @@
<?php
final class BWFAN_Pro_WC_Create_Coupon extends BWFAN_Action {
private static $ins = null;
protected function __construct() {
$this->action_name = __( 'Create Coupon', 'wp-marketing-automations-pro' );
$this->action_desc = __( 'This action creates a new personalized coupon for the customer', 'wp-marketing-automations-pro' );
$this->required_fields = array( 'coupon', 'coupon_name' );
$this->action_priority = 5;
$this->support_v2 = true;
$this->support_v1 = false;
}
public static function get_instance() {
if ( null === self::$ins ) {
self::$ins = new self();
}
return self::$ins;
}
/**
* Make all the data which is required by the current action.
* This data will be used while executing the task of this action.
*
* @param $automation_data
* @param $step_data
*
* @return array|void
*/
public function make_v2_data( $automation_data, $step_data ) {
$data_to_set = array();
$data_to_set['email'] = $automation_data['global']['email'];
if ( ! isset( $step_data['coupon_data'] ) || empty( $step_data['coupon_data'] ) ) {
return;
}
$coupon_details = $step_data['coupon_data'];
$data_to_set['coupon'] = [];
$data_to_set['coupon_type'] = isset( $coupon_details['type'] ) ? $coupon_details['type'] : 'new';
$data_to_set['coupon']['prefix'] = isset( $coupon_details['general'] ) && isset( $coupon_details['general']['coupon_prefix'] ) ? BWFAN_Common::decode_merge_tags( $coupon_details['general']['coupon_prefix'] ) : '';
if ( $data_to_set['coupon_type'] === 'existing' ) {
$data_to_set['coupon_id'] = isset( $coupon_details['coupon_id'] ) && isset( $coupon_details['coupon_id']['key'] ) && ! empty( $coupon_details['coupon_id']['key'] ) ? $coupon_details['coupon_id']['key'] : '';
} else {
$data_to_set['coupon']['discount_type'] = isset( $coupon_details['general'] ) && isset( $coupon_details['general']['discount_type'] ) ? $coupon_details['general']['discount_type'] : 'percent';
$data_to_set['coupon']['coupon_amount'] = isset( $coupon_details['general'] ) && isset( $coupon_details['general']['amount'] ) ? $coupon_details['general']['amount'] : 0;
$data_to_set['coupon']['free_shipping'] = isset( $coupon_details['general'] ) && isset( $coupon_details['general']['allow_shipping'] ) ? $coupon_details['general']['allow_shipping'] : 0;
/** getting the restrictions info of the coupons */
if ( isset( $coupon_details['restrictions'] ) ) {
if ( isset( $coupon_details['restrictions']['min_spend'] ) ) {
$data_to_set['coupon']['minimum_amount'] = $coupon_details['restrictions']['min_spend'];
}
if ( isset( $coupon_details['restrictions']['max_spend'] ) ) {
$data_to_set['coupon']['maximum_amount'] = $coupon_details['restrictions']['max_spend'];
}
if ( isset( $coupon_details['restrictions']['exclude_sale_item'] ) ) {
$data_to_set['coupon']['exclude_sale_items'] = $coupon_details['restrictions']['exclude_sale_item'];
}
/** individual_use in coupon data */
if ( isset( $coupon_details['restrictions']['individual_use'] ) ) {
$data_to_set['coupon']['individual_use'] = $coupon_details['restrictions']['individual_use'];
}
/** restrict_customer_email in coupon data */
if ( isset( $coupon_details['restrictions']['restrict_customer_email'] ) ) {
$data_to_set['coupon']['restrict_customer_email'] = $coupon_details['restrictions']['restrict_customer_email'];
}
/** passing the product ids in coupon data */
if ( isset( $coupon_details['restrictions']['products'] ) && is_array( $coupon_details['restrictions']['products'] ) ) {
$data_to_set['coupon']['product_ids'] = array_map( function ( $product ) {
return isset( $product['id'] ) ? $product['id'] : "";
}, $coupon_details['restrictions']['products'] );
}
/** passing the excluded product ids in coupon data */
if ( isset( $coupon_details['restrictions']['exclude_products'] ) && is_array( $coupon_details['restrictions']['exclude_products'] ) ) {
$data_to_set['coupon']['exclude_product_ids'] = array_map( function ( $product ) {
return isset( $product['id'] ) ? $product['id'] : "";
}, $coupon_details['restrictions']['exclude_products'] );
}
/** passing the category ids in coupon data */
if ( isset( $coupon_details['restrictions']['categories'] ) && is_array( $coupon_details['restrictions']['categories'] ) ) {
$data_to_set['coupon']['product_categories'] = array_map( function ( $category ) {
return isset( $category['id'] ) ? $category['id'] : "";
}, $coupon_details['restrictions']['categories'] );
}
/** passing the excluded category ids in coupon data */
if ( isset( $coupon_details['restrictions']['exclude_categories'] ) && is_array( $coupon_details['restrictions']['exclude_categories'] ) ) {
$data_to_set['coupon']['exclude_product_categories'] = array_map( function ( $category ) {
return isset( $category['id'] ) ? $category['id'] : "";
}, $coupon_details['restrictions']['exclude_categories'] );
}
}
}
/** set the coupon expiry details */
if ( isset( $coupon_details['general'] ) && isset( $coupon_details['general']['expiry'] ) ) {
$data_to_set['coupon']['expiry'] = $coupon_details['general']['expiry'];
}
if ( isset( $coupon_details['general'] ) && isset( $coupon_details['general']['specific_expiry_type'] ) ) {
$data_to_set['coupon']['specific_expiry_type'] = $coupon_details['general']['specific_expiry_type'];
}
/** get details of the limit usage settings of coupon */
if ( isset( $coupon_details['limits'] ) ) {
if ( isset( $coupon_details['limits']['usage_limit_per_coupon'] ) ) {
$data_to_set['coupon']['usage_limit'] = $coupon_details['limits']['usage_limit_per_coupon'];
}
if ( isset( $coupon_details['limits']['usage_limit_per_user'] ) ) {
$data_to_set['coupon']['usage_limit_per_user'] = $coupon_details['limits']['usage_limit_per_user'];
}
if ( isset( $coupon_details['limits']['usage_limit_x_item'] ) ) {
$data_to_set['coupon']['limit_usage_to_x_items'] = $coupon_details['limits']['usage_limit_x_item'];
}
}
/** If opid (Optin form unique id) in automation data */
if ( isset( $automation_data['global']['opid'] ) ) {
$data_to_set['coupon']['opid'] = isset( $automation_data['global']['opid'] ) ? $automation_data['global']['opid'] : '';
}
if ( isset( $automation_data['global']['order_id'] ) ) {
$data_to_set['coupon']['order_id'] = isset( $automation_data['global']['order_id'] ) ? $automation_data['global']['order_id'] : '';
}
return $data_to_set;
}
public function process_v2() {
$data = $this->data;
$save = apply_filters( 'bwfan_save_coupon', false );
if ( $save ) {
/** Check if coupon is already saved in automation meta */
$coupon = $this->maybe_coupon_already_saved();
if ( ! empty( $coupon ) ) {
$data['coupon_name'] = $coupon;
$this->set_data( $data );
/** update new coupon value in automation contact row */
$automation_contact_id = $data['automation_contact_id'];
$this->update_automation_contact_row( $automation_contact_id, $coupon );
return $this->prepare_response( wc_get_coupon_id_by_code( $coupon ) );
}
}
/** Coupon name */
$coupon_prefix = $data['coupon']['prefix'];
$dynamic_string = BWFAN_Common::get_dynamic_string( 6 );
$coupon_name = $coupon_prefix . $dynamic_string;
/** set new coupon meta */
$new_coupon_meta['_is_bwfan_coupon'] = 1;
$new_coupon_meta['_bwfan_automation_id'] = $data['automation_id'];
$new_coupon_meta['_bwfan_step_id'] = $data['step_id'];
$new_coupon_meta['expiry_date'] = '';
$new_coupon_meta['date_expires'] = '';
$new_coupon_meta['customer_email'] = array();
$new_coupon_meta['usage_limit'] = isset( $data['coupon']['usage_limit'] ) ? $data['coupon']['usage_limit'] : '';
$specific_expiry_type = isset( $data['coupon']['specific_expiry_type'] ) ? intval( $data['coupon']['specific_expiry_type'] ) : 0;
/** set coupon expiry dates */
if ( $specific_expiry_type > 0 && $specific_expiry_type !== 3 && isset( $data['coupon']['expiry'] ) && ! empty( $data['coupon']['expiry'] ) && 0 < absint( $data['coupon']['expiry'] ) ) {
$expiry = $this->get_expiry_dates_v2( $data['coupon']['expiry'], $specific_expiry_type );
$new_coupon_meta['expiry_date'] = $expiry['expire_on'];
$new_coupon_meta['date_expires'] = $expiry['expiry_timestamped'];
}
if ( isset( $data['coupon_type'] ) && $data['coupon_type'] === 'existing' ) {
if ( ! isset( $data['coupon_id'] ) || empty( $data['coupon_id'] ) ) {
return $this->error_response( __( 'Coupon ID is required for existing coupon type', 'wp-marketing-automations-pro' ) );
}
$coupon_id = $data['coupon_id'];
$coupon = new WC_Coupon( $coupon_id );
if ( ! $coupon instanceof WC_Coupon ) {
return $this->error_response( __( 'Coupon does not exist', 'wp-marketing-automations-pro' ) );
}
/** creating new coupon */
$new_coupon_id = $this->create_coupon( $coupon_name, $new_coupon_meta );
if ( is_array( $new_coupon_id ) && count( $new_coupon_id ) > 0 ) {
/** Some error occurred while making coupon post */
return $this->prepare_response( $coupon_id );
}
$new_coupon = new WC_Coupon( $new_coupon_id );
// Get existing coupon meta
$existing_coupon_meta = get_post_meta( $coupon_id );
// Copy existing coupon meta to new coupon
foreach ( $existing_coupon_meta as $key => $values ) {
foreach ( $values as $value ) {
// Ensure to exclude core meta keys that should not be duplicated
if ( ! in_array( $key, array(
'_edit_lock',
'_edit_last',
'date_expires',
'usage_limit',
'usage_count',
'expiry_date',
'_is_bwfan_coupon',
'_bwfan_automation_id',
'_bwfan_step_id'
) ) ) {
add_post_meta( $new_coupon_id, $key, maybe_unserialize( $value ) );
}
}
}
if ( isset( $data['coupon']['limit_usage_to_x_items'] ) && ! empty( $data['coupon']['limit_usage_to_x_items'] ) ) {
$new_coupon->set_limit_usage_to_x_items( $data['coupon']['limit_usage_to_x_items'] );
}
if ( isset( $data['coupon']['usage_limit_per_user'] ) && ! empty( $data['coupon']['usage_limit_per_user'] ) ) {
$new_coupon->set_usage_limit_per_user( $data['coupon']['usage_limit_per_user'] );
}
// Save the new coupon
$new_coupon->save();
} else {
if ( ! isset( $data['coupon']['discount_type'] ) || ! array_key_exists( $data['coupon']['discount_type'], wc_get_coupon_types() ) ) {
return $this->error_response( __( 'Invalid discount type: ' . $data['coupon']['discount_type'], 'wp-marketing-automations-pro' ) );
}
/** creating new coupon */
$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 $this->prepare_response( $coupon_id );
}
/** restricted coupon with customer email */
if ( isset( $data['coupon']['restrict_customer_email'] ) && 1 === absint( $data['coupon']['restrict_customer_email'] ) ) {
$this->handle_coupon_restriction( $coupon_id, $data['email'] );
}
/** passing other coupon details */
$this->handle_other_coupon_restriction( $coupon_id, $data['coupon'] );
}
/** update new coupon value in automation contact row */
$automation_contact_id = $data['automation_contact_id'];
$this->update_automation_contact_row( $automation_contact_id, $coupon_name );
/** using special property to end the current automation process for a contact */
BWFAN_Common::$end_v2_current_contact_automation = true;
do_action( 'bwfan_coupon_created_v2', $coupon_id, $coupon_name, $data );
/** Set coupon name in data */
$data['coupon_name'] = $coupon_name;
$this->set_data( $data );
if ( $save ) {
/** Save coupon in optin form table or order meta */
$this->save_coupon_in_object( $coupon_name );
}
return $this->prepare_response( $coupon_id );
}
/**
* update new coupon value in automation contact row
*
* @param $automation_contact_id
* @param $coupon_name
*
* @return void
*/
public function update_automation_contact_row( $automation_contact_id, $coupon_name ) {
$row_data = $this->get_automation_contact_row( $automation_contact_id );
if ( empty( $row_data ) ) {
return;
}
$data = $this->data;
$coupons_data = isset( $row_data['coupons'] ) && is_array( $row_data['coupons'] ) ? $row_data['coupons'] : [];
$coupons_data[ $data['step_id'] ] = $coupon_name;
$row_data['coupons'] = $coupons_data;
BWFAN_Model_Automation_Contact::update( array(
'data' => json_encode( $row_data )
), array(
'ID' => $automation_contact_id,
) );
}
/**
* Save coupon in automation meta
*
* @param $coupon_name
*
* @return void
*/
public function save_coupon_in_object( $coupon_name ) {
$automation_sid = $this->data['step_id'];
$opid = isset( $this->data['coupon'] ) && isset( $this->data['coupon']['opid'] ) ? $this->data['coupon']['opid'] : '';
if ( ! empty( $opid ) ) {
$data = $this->get_optin_data( $opid );
$data['coupons'][ $automation_sid ] = $coupon_name;
global $wpdb;
$wpdb->update( "{$wpdb->prefix}bwf_optin_entries", [ 'data' => json_encode( $data ) ], [ 'opid' => $opid ] ); //phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
return;
}
$order = wc_get_order( $this->data['coupon']['order_id'] );
if ( ! $order instanceof WC_Order ) {
return;
}
$coupons = $order->get_meta( 'bwfan_coupons' );
$coupons = is_array( $coupons ) ? $coupons : [];
$coupons[ $automation_sid ] = $coupon_name;
$order->update_meta_data( 'bwfan_coupons', $coupons );
$order->save_meta_data();
}
/**
* @param $opid
*
* @return array
*/
public function get_optin_data( $opid ) {
global $wpdb;
$optin_data = $wpdb->get_var( $wpdb->prepare( "SELECT `data` FROM {$wpdb->prefix}bwf_optin_entries WHERE `opid`=%s", $opid ) ); //phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
$optin_data = json_decode( $optin_data, true );
return ! is_array( $optin_data ) ? [] : $optin_data;
}
/**
* Get automation contact row data only
*
* @param $automation_contact_id
*
* @return mixed|void|null
*/
public function get_automation_contact_row( $automation_contact_id ) {
if ( empty( $automation_contact_id ) ) {
return;
}
$automation_contact_data = BWFAN_Model_Automation_Contact::get_data( $automation_contact_id );
if ( empty( $automation_contact_data ) ) {
return;
}
return json_decode( $automation_contact_data['data'], true );
}
public function handle_other_coupon_restriction( $coupon_id, $coupon_data ) {
if ( empty( $coupon_data ) ) {
return;
}
$coupon = new WC_Coupon( $coupon_id );
if ( ! $coupon instanceof WC_Coupon ) {
return;
}
/** set coupon type */
$coupon->set_discount_type( $coupon_data['discount_type'] );
$coupon->set_amount( $coupon_data['coupon_amount'] );
$coupon->set_free_shipping( $coupon_data['free_shipping'] );
if ( isset( $coupon_data['minimum_amount'] ) ) {
$coupon->set_minimum_amount( $coupon_data['minimum_amount'] );
}
if ( isset( $coupon_data['maximum_amount'] ) ) {
$coupon->set_maximum_amount( $coupon_data['maximum_amount'] );
}
if ( isset( $coupon_data['exclude_sale_items'] ) ) {
$coupon->set_exclude_sale_items( $coupon_data['exclude_sale_items'] );
}
if ( isset( $coupon_data['individual_use'] ) ) {
$coupon->set_individual_use( $coupon_data['individual_use'] );
}
if ( isset( $coupon_data['product_ids'] ) ) {
$coupon->set_product_ids( $coupon_data['product_ids'] );
}
if ( isset( $coupon_data['exclude_product_ids'] ) ) {
$coupon->set_excluded_product_ids( $coupon_data['exclude_product_ids'] );
}
if ( isset( $coupon_data['product_categories'] ) ) {
$coupon->set_product_categories( $coupon_data['product_categories'] );
}
if ( isset( $coupon_data['exclude_product_categories'] ) ) {
$coupon->set_excluded_product_categories( $coupon_data['exclude_product_categories'] );
}
if ( isset( $coupon_data['usage_limit'] ) ) {
$coupon->set_usage_limit( $coupon_data['usage_limit'] );
}
if ( isset( $coupon_data['usage_limit_per_user'] ) ) {
$coupon->set_usage_limit_per_user( $coupon_data['usage_limit_per_user'] );
}
if ( isset( $coupon_data['limit_usage_to_x_items'] ) ) {
$coupon->set_limit_usage_to_x_items( $coupon_data['limit_usage_to_x_items'] );
}
$coupon->save();
return $coupon;
}
/** set expiry date for newly created coupon
*
* @param $expiry
* @param $specific_expiry_type
*
* @return array
*/
public function get_expiry_dates_v2( $expiry, $specific_expiry_type ) {
$dbj = new DateTime();
if ( $specific_expiry_type == 2 ) { // in case specific date mention
$exptime = strtotime( strval( $expiry ) );
$dbj->setTimestamp( $exptime );
} else {
$expiry += 1;
$exptime = strtotime( "+{$expiry} days" );
$dbj->setTimestamp( $exptime );
}
$exp_date = $dbj->format( 'Y-m-d' );
$exp_date_email = date( 'Y-m-d', $exptime );
$expiry_timestamp = $exptime;
return array(
'expiry' => $exp_date,
'expire_on' => $exp_date_email,
'expiry_timestamped' => $expiry_timestamp,
);
}
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 );
}
}
return $coupon_id;
}
return array(
'err_msg' => $coupon_id->get_error_message(),
);
}
public function prepare_response( $result ) {
if ( is_array( $result ) && count( $result ) > 0 ) { // Error in coupon creation
return $this->error_response( $result['err_msg'] );
}
if ( ! is_integer( $result ) ) {
return $this->error_response( __( 'Coupon does not exist', 'wp-marketing-automations-pro' ) );
}
$get_type = get_post_field( 'post_type', $result );
if ( 'shop_coupon' !== $get_type ) {
return $this->error_response( __( 'Coupon does not exist', 'wp-marketing-automations-pro' ) );
}
return $this->success_message( "Coupon {$this->data['coupon_name']} created." );
}
/**
* @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-pro' ),
);
}
$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-pro' ),
);
}
return array(
'status' => 3,
'message' => "Coupon {$this->data['coupon_name']} created."
);
}
public function get_fields_schema() {
return [
[
'id' => 'coupon_data',
'type' => 'create_coupon',
'required' => true,
'coupon_type_options' => BWFAN_Common::prepared_field_options( wc_get_coupon_types() ),
]
];
}
public function get_desc_text( $data ) {
$data = json_decode( wp_json_encode( $data ), true );
if ( ! isset( $data['coupon_data'] ) || empty( $data['coupon_data'] ) || ! isset( $data['coupon_data']['general'] ) ) {
return '';
}
return isset( $data['coupon_data']['general']['title'] ) ? $data['coupon_data']['general']['title'] : '';
}
/**
* Get saved coupon in automation meta
*
* @return false|mixed
*/
public function maybe_coupon_already_saved() {
$sid = $this->data['step_id'];
$opid = $this->data['coupon']['opid'] ?? '';
$order_id = $this->data['coupon']['order_id'] ?? '';
if ( empty( $opid ) && empty( $order_id ) ) {
return false;
}
if ( ! empty( $opid ) ) {
$optin_data = $this->get_optin_data( $opid );
return $optin_data['coupons'][ $sid ] ?? '';
}
$order = wc_get_order( $order_id );
if ( ! $order instanceof WC_Order ) {
return false;
}
$coupons = $order->get_meta( 'bwfan_coupons' );
return $coupons[ $sid ] ?? '';
}
}
/**
* Register this action. Registering the action will make it eligible to see it on single automation screen in select actions dropdown.
*/
return 'BWFAN_Pro_WC_Create_Coupon';

View File

@@ -0,0 +1,976 @@
<?php
if ( ! class_exists( 'BWFAN_WC_Create_Order' ) ) {
final class BWFAN_WC_Create_Order extends BWFAN_Action {
private static $ins = null;
protected function __construct() {
$this->action_name = __( 'Create Order', 'wp-marketing-automations-pro' );
$this->action_desc = __( 'This action creates a new WooCommerce order for a customer', 'wp-marketing-automations-pro' );
$this->action_priority = 7;
$this->support_v2 = true;
$this->support_v1 = false;
}
public static function get_instance() {
if ( null === self::$ins ) {
self::$ins = new self();
}
return self::$ins;
}
/**
* Generate the order data for processing
*
* @param array $automation_data
* @param array $step_data
*
* @return array
*/
public function make_v2_data( $automation_data, $step_data ) {
$data_to_set = [];
$data_to_set['status'] = $step_data['status'] ?? 'wc-on-hold';
$data_to_set['is_shipping_address'] = $step_data['is_shipping_address'] ?? 'same_as_billing';
/** Validate and set email */
$email = isset( $step_data['billing_email'] ) ? BWFAN_Common::decode_merge_tags( $step_data['billing_email'] ) : '';
$user = is_email( $email ) ? get_user_by( 'email', $email ) : '';
$data_to_set['customer_id'] = $user instanceof WP_User ? $user->ID : 0;
/** Set products */
$data_to_set['products'] = $step_data['products'] ?? [];
/** Set billing and shipping information */
$data_to_set['billing'] = self::get_billing_addresses( $step_data, $email );
$data_to_set['shipping'] = self::get_shipping_addresses( $step_data );
$data_to_set['order_note'] = BWFAN_Common::decode_merge_tags( $step_data['order_note'] ) ?? '';
/** Payment method */
$data_to_set['payment_method'] = BWFAN_Common::decode_merge_tags( $step_data['payment_method'] ) ?? '';
$data_to_set['shipping_methods'] = BWFAN_Common::decode_merge_tags( $step_data['shipping_methods'] ) ?? '';
$data_to_set['shipping_cost'] = isset( $step_data['shipping_cost'] ) ? BWFAN_Common::decode_merge_tags( $step_data['shipping_cost'] ) : '';
$data_to_set['contact_id'] = $automation_data['global']['contact_id'] ?? $automation_data['global']['cid'] ?? 0;
$data_to_set['bwfan_coupons'] = self::check_for_available_coupons( $step_data );
$data_to_set['skip_order_if_products'] = isset( $step_data['skip_order_if_products'] ) && (bool) $step_data['skip_order_if_products'];
$data_to_set['order_custom_fields'] = ! empty( $step_data['order_custom_fields'] ) ? $step_data['order_custom_fields'] : [];
return $data_to_set;
}
/**
* Process the order creation
*
* @return array
*/
public function process_v2() {
if ( ! function_exists( 'wc_create_order' ) ) {
return $this->error_response( __( '`wc_create_order` function is missing.', 'wp-marketing-automations-pro' ) );
}
$order_data = $this->data;
if ( ! isset( $order_data['products'] ) || empty( $order_data['products'] ) ) {
return $this->skipped_response( __( 'No products found. Add at least one product to proceed with the order.', 'wp-marketing-automations-pro' ) );
}
/** Validate email */
if ( empty( $order_data['billing']['email'] ) || ! is_email( $order_data['billing']['email'] ) ) {
return $this->error_response( __( 'Invalid or missing email address.', 'wp-marketing-automations-pro' ) );
}
$product_validation = self::validate_order_products( $order_data['products'] );
if ( empty( $product_validation ) ) {
return $this->error_response( __( 'Order not created. No valid products found.', 'wp-marketing-automations-pro' ) );
}
if ( isset( $order_data['skip_order_if_products'] ) && $order_data['skip_order_if_products'] && count( $product_validation ) !== count( $order_data['products'] ) ) {
return $this->skipped_response( __( 'Order not created. Some products are invalid or missing.', 'wp-marketing-automations-pro' ) );
}
$args = array(
'created_via' => __( 'Order created via FunnelKit Automations.', 'wp-marketing-automations-pro' ),
'customer_id' => $order_data['customer_id'],
);
$order = wc_create_order( $args );
if ( is_wp_error( $order ) ) {
return $this->error_response( __( 'Failed to create order: ', 'wp-marketing-automations-pro' ) . $order->get_error_message() );
}
/** Add validated products */
foreach ( $product_validation as $item ) {
$order->add_product( $item['product'], $item['quantity'], isset( $item['price'] ) ? [ 'totals' => [ 'subtotal' => $item['price'], 'total' => $item['price'] ] ] : [] );
}
/** Set addresses */
$order->set_address( $order_data['billing'] );
if ( 'same_as_billing' === $order_data['is_shipping_address'] ) {
$order->set_address( $order_data['billing'], 'shipping' );
} elseif ( 'different_shipping_address' === $order_data['is_shipping_address'] ) {
$order->set_address( $order_data['shipping'], 'shipping' );
}
/** Set shipping methods */
if ( ! empty( $order_data['shipping_methods'] ) ) {
$shipping_method_id = is_array( $order_data['shipping_methods'] ) ? reset( $order_data['shipping_methods'] ) : $order_data['shipping_methods'];
$shipping_method = $this->set_shipping_method( $shipping_method_id, $order_data['shipping_cost'] );
if ( ! empty( $shipping_method ) ) {
$order->add_item( $shipping_method );
}
}
// Calculate totals after adding products and shipping methods
$order->calculate_totals();
/** Add coupons */
if ( ! empty( $order_data['bwfan_coupons'] ) && is_array( $order_data['bwfan_coupons'] ) ) {
foreach ( $order_data['bwfan_coupons'] as $coupon_code ) {
try {
$result = $order->apply_coupon( $coupon_code );
if ( is_wp_error( $result ) ) {
$error_message = $result->get_error_message();
BWFAN_Common::log_test_data( sprintf( 'Coupon "%s" failed to apply on Order #%d: %s', $coupon_code, $order->get_id(), $error_message ), 'fka_order_created_log', true );
}
} catch ( Error $e ) {
return $this->skipped_response( sprintf( __( 'Order #%d was created but further processing was skipped due to coupon error: %s', 'wp-marketing-automations-pro' ), $order->get_id(), $e->getMessage() ) );
}
}
}
/** Add custom fields */
if ( ! empty( $order_data['order_custom_fields'] ) ) {
foreach ( $order_data['order_custom_fields'] as $field ) {
if ( ! empty( $field['field'] ) && ! empty( $field['field_value'] ) ) {
$order->update_meta_data( $field['field'], BWFAN_Common::decode_merge_tags( $field['field_value'] ) );
}
}
}
/** Set order note */
$order->add_order_note( $args['created_via'] );
/** Set payment method */
$order->set_payment_method( $order_data['payment_method'] );
/** Add order note */
if ( isset( $order_data['order_note'] ) && ! empty( trim( $order_data['order_note'] ) ) ) {
$order->add_order_note( $order_data['order_note'] );
}
/** Set contact ID */
$order->update_meta_data( '_woofunnel_cid', $order_data['contact_id'] ?? 0 );
/** set status */
$order->update_status( $order_data['status'] );
$order->save();
do_action( 'bwfan_order_created', $order, $order->get_id(), $order_data );
return $this->success_message( __( 'Order created successfully.', 'wp-marketing-automations-pro' ) );
}
/**
* Check for available coupons
*
* @param $data
*
* @return array
*/
public static function check_for_available_coupons( $data ) {
if ( ! isset( $data['couponType'] ) ) {
return [];
}
$coupons = [];
switch ( $data['couponType'] ) {
case 'static':
if ( ! empty( $data['bwfan_coupons'] ) || ! is_array( $data['bwfan_coupons'] ) ) {
foreach ( $data['bwfan_coupons'] as $coupon ) {
if ( ! empty( $coupon['name'] ) ) {
$coupons[] = wc_format_coupon_code( BWFAN_Common::decode_merge_tags( $coupon['name'] ) );
}
}
}
break;
case 'dynamic':
if ( ! empty( $data['dynamic_coupon'] ) ) {
$dynamic_coupon = explode( ',', $data['dynamic_coupon'] );
foreach ( $dynamic_coupon as $coupon ) {
$coupons[] = ! empty( $coupon ) ? wc_format_coupon_code( BWFAN_Common::decode_merge_tags( $coupon ) ) : '';
}
}
break;
default:
return [];
}
return array_filter( $coupons );
}
/**
* @param $method_id
* @param $shipping_cost
*
* @return WC_Order_Item_Shipping|null
*/
private function set_shipping_method( $method_id, $shipping_cost ) {
if ( ! class_exists( '\WC_Order_Item_Shipping' ) ) {
return null;
}
$shipping_methods = $this->get_available_shipping_methods();
if ( empty( $shipping_methods[ $method_id ] ) ) {
return null;
}
$item = new \WC_Order_Item_Shipping();
try {
$item->set_method_title( $shipping_methods[ $method_id ] );
$item->set_method_id( $method_id );
$item->set_total( floatval( $shipping_cost ) );
} catch ( \Exception $e ) {
$item = null;
}
return $item;
}
/**
* @param $products_data
*
* @return array
*/
public static function validate_order_products( $products_data ) {
$valid_products = [];
$invalid_products = [];
if ( empty( $products_data ) || ! is_array( $products_data ) ) {
BWFAN_Common::log_test_data( __( 'No products found. Add at least one product to proceed with the order.', 'wp-marketing-automations-pro' ), 'order_creation_errors', true );
return $valid_products;
}
foreach ( $products_data as $product_group ) {
if ( ! isset( $product_group['products'] ) || ! is_array( $product_group['products'] ) ) {
BWFAN_Common::log_test_data( __( 'Invalid product group: products array missing or invalid', 'wp-marketing-automations-pro' ), 'order_creation_errors', true );
continue;
}
foreach ( $product_group['products'] as $product ) {
$product_id = is_string( $product['id'] ) ? BWFAN_Common::decode_merge_tags( $product['id'] ) : $product['id'];
if ( ! is_numeric( $product_id ) ) {
$invalid_products[] = $product['id'];
BWFAN_Common::log_test_data( sprintf( __( 'Non-numeric product ID: "%s" (decoded: "%s")', 'wp-marketing-automations-pro' ), $product['id'], $product_id ), 'order_creation_errors', true );
continue;
}
$product_obj = wc_get_product( $product_id );
if ( ! $product_obj || ! $product_obj->exists() ) {
$invalid_products[] = $product['id'];
BWFAN_Common::log_test_data( sprintf( __( 'Product does not exist: %d', 'wp-marketing-automations-pro' ), $product_id ), 'order_creation_errors', true );
continue;
}
$product_data = [
'product' => $product_obj,
'quantity' => isset( $product_group['quantity'] ) && intval( $product_group['quantity'] ) > 0 ? floatval( $product_group['quantity'] ) : 1,
];
if ( isset( $product_group['price'] ) && '' !== $product_group['price'] ) {
$product_data['price'] = floatval( $product_group['price'] ) * $product_data['quantity'];
}
$valid_products[] = $product_data;
}
}
return $valid_products;
}
/**
* Returns decoded billing data
*
* @param $step_data
* @param $email
*
* @return array
*/
static function get_billing_addresses( $step_data, $email ) {
$country = BWFAN_Common::decode_merge_tags( $step_data['billing_country'][0]['id'] ?? '' );
$code = $step_data['billing_state'][0]['id'] ?? '';
$state_name = $step_data['billing_state'][0]['name'] ?? '';
$state = self::validate_state_for_country( $code, $country, $state_name );
return [
'first_name' => BWFAN_Common::decode_merge_tags( $step_data['billing_first_name'] ?? '' ),
'last_name' => BWFAN_Common::decode_merge_tags( $step_data['billing_last_name'] ?? '' ),
'company' => BWFAN_Common::decode_merge_tags( $step_data['billing_company'] ?? '' ),
'address_1' => BWFAN_Common::decode_merge_tags( $step_data['billing_address_line_1'] ?? '' ),
'address_2' => BWFAN_Common::decode_merge_tags( $step_data['billing_address_line_2'] ?? '' ),
'city' => BWFAN_Common::decode_merge_tags( $step_data['billing_city'] ?? '' ),
'postcode' => BWFAN_Common::decode_merge_tags( $step_data['billing_postcode'] ?? '' ),
'country' => $country,
'state' => $state,
'email' => $email,
'phone' => BWFAN_Common::decode_merge_tags( $step_data['billing_phone_no'] ?? '' ),
];
}
/**
* Returns decoded shipping addresses
*
* @param $step_data
*
* @return array
*/
static function get_shipping_addresses( $step_data ) {
$country = BWFAN_Common::decode_merge_tags( $step_data['shipping_country'][0]['id'] ?? '' );
$code = $step_data['shipping_state'][0]['id'] ?? '';
$state_name = $step_data['shipping_state'][0]['name'] ?? '';
$state = self::validate_state_for_country( $code, $country, $state_name );
return [
'first_name' => BWFAN_Common::decode_merge_tags( $step_data['shipping_first_name'] ?? '' ),
'last_name' => BWFAN_Common::decode_merge_tags( $step_data['shipping_last_name'] ?? '' ),
'company' => BWFAN_Common::decode_merge_tags( $step_data['shipping_company'] ?? '' ),
'address_1' => BWFAN_Common::decode_merge_tags( $step_data['shipping_address_line_1'] ?? '' ),
'address_2' => BWFAN_Common::decode_merge_tags( $step_data['shipping_address_line_2'] ?? '' ),
'city' => BWFAN_Common::decode_merge_tags( $step_data['shipping_city'] ?? '' ),
'postcode' => BWFAN_Common::decode_merge_tags( $step_data['shipping_postcode'] ?? '' ),
'country' => $country,
'state' => BWFAN_Common::decode_merge_tags( $state ),
'phone' => BWFAN_Common::decode_merge_tags( $step_data['shipping_phone_no'] ?? '' ),
];
}
/**
* Validate if state exists for the given country
*
* @param string $state_code
* @param string $country
* @param string $state_name
*
* @return string
*/
static function validate_state_for_country( $state_code, $country, $state_name ) {
if ( empty( $country ) ) {
return '';
}
$states = WC()->countries->get_states( $country );
if ( empty( $states ) ) {
return $state_name;
}
return isset( $states[ $state_code ] ) ? $state_code : '';
}
/**
* Added Field schema
*/
public function get_fields_schema() {
$status = BWFAN_PRO_Common::prepared_field_options( wc_get_order_statuses() );
$set_payment_gateways = array_replace( [ '' => 'N/A' ], self:: payment_gateways() );
$payment_gateways = BWFAN_PRO_Common::prepared_field_options( $set_payment_gateways );
$schema = [
[
'id' => 'products',
'label' => __( 'Products', 'wp-marketing-automations-pro' ),
'type' => 'repeater',
'add_btn_text' => __( 'Add Product', 'wp-marketing-automations-pro' ),
'class' => 'bwf-repeater-alter-w',
'required' => true,
"hint" => __( "Quantity and price are optional. If left blank, a quantity of 1 and the product's default unit price will be applied.", 'wp-marketing-automations-pro' ),
'tip' => __( 'Select products or use merge tag (e.g., {{product_id}}) to dynamically set the product during order creation.', 'wp-marketing-automations-pro' ),
'fields' => [
[
'id' => 'products',
'type' => 'custom_search',
'autocompleterOption' => [
'path' => 'wc_new_order_product',
'slug' => 'wc_new_order_product',
'labelText' => __( 'Product', 'wp-marketing-automations-pro' ),
'freeTextLabel' => __( 'Use merge tag {{query /}} to dynamically insert a product ID', 'wp-marketing-automations-pro' ),
],
'label' => __( 'Product', 'wp-marketing-automations-pro' ),
"allowFreeTextSearch" => true,
"multiple" => false,
],
[
'id' => 'quantity',
'type' => 'number',
'label' => __( 'Quantity', 'wp-marketing-automations-pro' ),
'placeholder' => __( 'Quantity', 'wp-marketing-automations-pro' ),
'min' => 1,
'default' => 1,
],
[
'id' => 'price',
'type' => 'number',
'label' => __( 'Price', 'wp-marketing-automations-pro' ),
'placeholder' => __( 'Price', 'wp-marketing-automations-pro' ),
],
],
],
[
'id' => 'skip_order_if_products',
'type' => 'checkbox',
'checkboxlabel' => __( 'Skip order creation if all product line items fail to add', 'wp-marketing-automations-pro' ),
'description' => '',
],
[
'id' => 'billing_email',
'label' => __( 'Email', 'wp-marketing-automations-pro' ),
'type' => 'text',
'placeholder' => __( 'Email', 'wp-marketing-automations-pro' ),
'class' => 'bwfan-input-wrapper bwfan-field-crm_create_contact bwf-2-col-item',
'description' => '',
'required' => true,
'automation_merge_tags' => true
],
[
'id' => 'billing_phone_no',
'label' => __( 'Billing Phone', 'wp-marketing-automations-pro' ),
'type' => 'text',
'placeholder' => __( 'Phone', 'wp-marketing-automations-pro' ),
"class" => 'bwfan-input-wrapper bwf-2-col-item',
'description' => '',
'required' => false,
],
[
'id' => 'billing_first_name',
'label' => __( 'Billing First Name', 'wp-marketing-automations-pro' ),
'type' => 'text',
'placeholder' => __( 'First Name', 'wp-marketing-automations-pro' ),
"class" => 'bwfan-input-wrapper bwf-3-col-item',
'description' => '',
'required' => false,
],
[
'id' => 'billing_last_name',
'label' => __( 'Billing Last Name', 'wp-marketing-automations-pro' ),
'type' => 'text',
'placeholder' => __( 'last Name', 'wp-marketing-automations-pro' ),
"class" => 'bwfan-input-wrapper bwf-3-col-item',
'description' => '',
'required' => false,
],
[
'id' => 'billing_company',
'label' => __( 'Billing Company', 'wp-marketing-automations-pro' ),
'type' => 'text',
'placeholder' => __( 'Company', 'wp-marketing-automations-pro' ),
"class" => 'bwfan-input-wrapper bwf-3-col-item',
'description' => '',
'required' => false,
],
[
'id' => 'billing_address_line_1',
'label' => __( 'Billing Address 1', 'wp-marketing-automations-pro' ),
'type' => 'text',
'placeholder' => __( 'Address 1', 'wp-marketing-automations-pro' ),
"class" => 'bwfan-input-wrapper bwf-2-col-item',
'description' => '',
'required' => false,
],
[
'id' => 'billing_address_line_2',
'label' => __( 'Billing Address 2', 'wp-marketing-automations-pro' ),
'type' => 'text',
'placeholder' => __( 'Address 2', 'wp-marketing-automations-pro' ),
"class" => 'bwfan-input-wrapper bwf-2-col-item',
'description' => '',
'required' => false,
],
[
'id' => 'billing_city',
'label' => __( 'Billing City', 'wp-marketing-automations-pro' ),
'type' => 'text',
'placeholder' => __( 'City', 'wp-marketing-automations-pro' ),
"class" => 'bwfan-input-wrapper bwf-2-col-item',
'description' => '',
'required' => false,
],
[
'id' => 'billing_postcode',
'label' => __( 'Billing Postcode / ZIP', 'wp-marketing-automations-pro' ),
'type' => 'text',
'placeholder' => __( 'Postcode / ZIP', 'wp-marketing-automations-pro' ),
"class" => 'bwfan-input-wrapper bwf-2-col-item',
'description' => '',
'required' => false,
],
[
'id' => 'billing_country',
'label' => __( 'Billing Country / Region', 'wp-marketing-automations-pro' ),
"type" => 'custom_search',
'autocompleterOption' => [
'path' => 'wc_countries',
'slug' => 'wc_countries',
'labelText' => __( 'Countries', 'wp-marketing-automations-pro' ),
],
"allowFreeTextSearch" => false,
"multiple" => false,
"class" => 'bwfan-input-wrapper bwf-2-col-item',
],
[
'id' => 'billing_state',
'label' => __( 'Billing State / Province', 'wp-marketing-automations-pro' ),
"type" => 'custom_search',
'autocompleterOption' => [
'path' => 'wc_states',
'slug' => 'wc_states',
'labelText' => __( 'States', 'wp-marketing-automations-pro' ),
'extraData' => [
'country' => 'billing_country'
]
],
"allowFreeTextSearch" => true,
"multiple" => false,
"class" => 'bwfan-input-wrapper bwf-2-col-item',
],
[
'id' => 'payment_method',
'label' => __( 'Payment method', 'wp-marketing-automations-pro' ),
'type' => 'wp_select',
'options' => $payment_gateways,
'placeholder' => __( 'Payment method', 'wp-marketing-automations-pro' ),
"class" => 'bwfan-input-wrapper bwf-2-col-item',
'description' => '',
'required' => false,
],
];
/** Shipping field if active */
$shipping_methods = $this->get_available_shipping_methods();
if ( ! empty( $shipping_methods ) ) {
$set_shipping_methods = array_replace( [ '' => 'N/A' ], $shipping_methods );
$shipping_methods = BWFAN_PRO_Common::prepared_field_options( $set_shipping_methods );
$schema[] = [
'id' => 'shipping_methods',
'label' => __( 'Shipping Methods', 'wp-marketing-automations-pro' ),
'type' => 'wp_select',
'options' => $shipping_methods,
"class" => 'bwfan-input-wrapper bwf-2-col-item',
'description' => '',
'required' => false,
];
$schema[] = [
'id' => 'shipping_cost',
'label' => __( 'Shipping Cost', 'wp-marketing-automations-pro' ),
'type' => 'number',
'min' => 0,
'placeholder' => __( 'Enter', 'wp-marketing-automations-pro' ),
"class" => 'bwfan-input-wrapper bwf-2-col-item',
"toggler" => [
'fields' => [
[
'id' => 'shipping_methods',
'value' => '',
]
],
],
];
}
/** Coupon fields if active */
$coupons_enabled = get_option( 'woocommerce_enable_coupons' ) === 'yes';
if ( $coupons_enabled ) {
$coupon_schema = [
[
'id' => 'couponType',
'label' => __( 'Coupon Type', 'wp-marketing-automations-pro' ),
'type' => 'radio',
'options' => [
[
'label' => __( 'Store Coupon', 'wp-marketing-automations-pro' ),
'value' => 'static'
],
[
'label' => __( 'Dynamic Coupon', 'wp-marketing-automations-pro' ),
'value' => 'dynamic'
],
],
],
[
'id' => 'bwfan_coupons',
'label' => __( "Coupon", 'wp-marketing-automations-pro' ),
'type' => 'search',
'autocompleter' => 'coupons',
"multiple" => true,
"required" => false,
"toggler" => [
'fields' => [
[
'id' => 'couponType',
'value' => 'static',
]
]
],
],
[
'id' => 'dynamic_coupon',
'label' => __( 'Dynamic Coupon', 'wp-marketing-automations-pro' ),
'type' => 'text',
"class" => 'bwfan-input-wrapper ',
'hint' => __( 'Use comma seperated values for multiple options.', 'wp-marketing-automations-pro' ),
"description" => "",
"placeholder" => __( 'Dynamic coupon merge tag', 'wp-marketing-automations-pro' ),
"required" => false,
'toggler' => [
'fields' => [
[
'id' => 'couponType',
'value' => 'dynamic',
]
]
],
]
];
$schema = array_merge( $schema, $coupon_schema );
}
$schema = array_merge( $schema, [
[
'id' => 'status',
'label' => __( "Order Status", 'wp-marketing-automations-pro' ),
'type' => 'wp_select',
'options' => $status,
'placeholder' => __( 'Status', 'wp-marketing-automations-pro' ),
"class" => 'bwfan-input-wrapper ',
'tip' => "",
"description" => "",
"required" => true,
],
[
'id' => 'order_note',
'label' => __( 'Order Note', 'wp-marketing-automations-pro' ),
'type' => 'text',
"class" => 'bwfan-input-wrapper ',
'tip' => "",
"description" => "",
"placeholder" => __( 'Note text', 'wp-marketing-automations-pro' ),
"required" => false,
]
] );
if ( $this->is_shipping_active() ) {
$schema = array_merge( $schema, [
[
'id' => 'is_shipping_address',
'label' => __( 'Shipping Address', 'wp-marketing-automations-pro' ),
'type' => 'radio',
'options' => [
[
'label' => __( 'Same as Billing', 'wp-marketing-automations-pro' ),
'value' => 'same_as_billing'
],
[
'label' => __( 'Different Shipping Address', 'wp-marketing-automations-pro' ),
'value' => 'different_shipping_address'
],
],
],
[
'id' => 'shipping_first_name',
'label' => __( 'Shipping First Name', 'wp-marketing-automations-pro' ),
'type' => 'text',
'placeholder' => __( 'First Name', 'wp-marketing-automations-pro' ),
"class" => 'bwfan-input-wrapper bwf-3-col-item',
'description' => '',
'required' => false,
'toggler' => [
'fields' => [
[
'id' => 'is_shipping_address',
'value' => 'different_shipping_address',
]
]
],
],
[
'id' => 'shipping_last_name',
'label' => __( 'Shipping Last Name', 'wp-marketing-automations-pro' ),
'type' => 'text',
'placeholder' => __( 'last Name', 'wp-marketing-automations-pro' ),
"class" => 'bwfan-input-wrapper bwf-3-col-item',
'description' => '',
'required' => false,
'toggler' => [
'fields' => [
[
'id' => 'is_shipping_address',
'value' => 'different_shipping_address',
]
]
],
],
[
'id' => 'shipping_company',
'label' => __( 'Shipping Company', 'wp-marketing-automations-pro' ),
'type' => 'text',
'placeholder' => __( 'Company', 'wp-marketing-automations-pro' ),
"class" => 'bwfan-input-wrapper bwf-3-col-item',
'description' => '',
'required' => false,
'toggler' => [
'fields' => [
[
'id' => 'is_shipping_address',
'value' => 'different_shipping_address',
]
]
],
],
[
'id' => 'shipping_address_line_1',
'label' => __( 'Shipping Address 1', 'wp-marketing-automations-pro' ),
'type' => 'text',
'placeholder' => __( 'Address 1', 'wp-marketing-automations-pro' ),
"class" => 'bwfan-input-wrapper bwf-2-col-item',
'description' => '',
'required' => false,
'toggler' => [
'fields' => [
[
'id' => 'is_shipping_address',
'value' => 'different_shipping_address',
]
]
],
],
[
'id' => 'shipping_address_line_2',
'label' => __( 'Shipping Address 2', 'wp-marketing-automations-pro' ),
'type' => 'text',
'placeholder' => __( 'Address 2', 'wp-marketing-automations-pro' ),
"class" => 'bwfan-input-wrapper bwf-2-col-item',
'description' => '',
'required' => false,
'toggler' => [
'fields' => [
[
'id' => 'is_shipping_address',
'value' => 'different_shipping_address',
]
]
],
],
[
'id' => 'shipping_city',
'label' => __( 'Shipping City', 'wp-marketing-automations-pro' ),
'type' => 'text',
'placeholder' => __( 'City', 'wp-marketing-automations-pro' ),
"class" => 'bwfan-input-wrapper bwf-2-col-item',
'description' => '',
'required' => false,
'toggler' => [
'fields' => [
[
'id' => 'is_shipping_address',
'value' => 'different_shipping_address',
]
]
],
],
[
'id' => 'shipping_postcode',
'label' => __( 'Shipping Postcode / ZIP', 'wp-marketing-automations-pro' ),
'type' => 'text',
'placeholder' => __( 'Postcode / ZIP', 'wp-marketing-automations-pro' ),
"class" => 'bwfan-input-wrapper bwf-2-col-item',
'description' => '',
'required' => false,
'toggler' => [
'fields' => [
[
'id' => 'is_shipping_address',
'value' => 'different_shipping_address',
]
]
],
],
[
'id' => 'shipping_country',
'label' => __( 'Shipping Country / Region', 'wp-marketing-automations-pro' ),
"type" => 'custom_search',
'autocompleterOption' => [
'path' => 'wc_countries',
'slug' => 'wc_countries',
'labelText' => __( 'Countries', 'wp-marketing-automations-pro' ),
],
"allowFreeTextSearch" => false,
"multiple" => false,
"class" => 'bwfan-input-wrapper bwf-2-col-item',
'toggler' => [
'fields' => [
[
'id' => 'is_shipping_address',
'value' => 'different_shipping_address',
]
]
],
],
[
'id' => 'shipping_state',
'label' => __( 'Shipping State / Province', 'wp-marketing-automations-pro' ),
"type" => 'custom_search',
'autocompleterOption' => [
'path' => 'wc_states',
'slug' => 'wc_states',
'labelText' => __( 'States', 'wp-marketing-automations-pro' ),
'extraData' => [
'country' => 'shipping_country'
]
],
"allowFreeTextSearch" => true,
"multiple" => false,
"class" => 'bwfan-input-wrapper bwf-2-col-item',
'toggler' => [
'fields' => [
[
'id' => 'is_shipping_address',
'value' => 'different_shipping_address',
]
]
],
],
[
'id' => 'shipping_phone_no',
'label' => __( 'Shipping Phone', 'wp-marketing-automations-pro' ),
'type' => 'text',
'placeholder' => __( 'Phone', 'wp-marketing-automations-pro' ),
"class" => 'bwfan-input-wrapper bwf-2-col-item',
'description' => '',
'required' => false,
'toggler' => [
'fields' => [
[
'id' => 'is_shipping_address',
'value' => 'different_shipping_address',
]
]
],
]
] );
}
return array_merge( $schema, [
[
'id' => 'order_custom_fields',
'type' => 'repeater',
'add_btn_text' => __( 'Add Field', 'wp-marketing-automations-pro' ),
'label' => __( 'Custom Meta Fields', 'wp-marketing-automations-pro' ),
"fields" => [
[
'id' => 'field',
'type' => 'text',
'label' => __( 'Field Key', 'wp-marketing-automations-pro' ),
'tip' => "",
"description" => "",
"required" => false,
"placeholder" => __( 'Field Key (e.g., custom_label)', 'wp-marketing-automations-pro' ),
],
[
"id" => 'field_value',
"label" => __( 'Field Value', 'wp-marketing-automations-pro' ),
"type" => 'text',
"class" => 'bwfan-input-wrapper',
"description" => "",
"required" => false,
"placeholder" => __( 'Field Value (e.g., 1234 or info@example.com)', 'wp-marketing-automations-pro' ),
]
],
'tip' => "",
"description" => "",
'wrap_after' => wc_tax_enabled() ? '<div class="bwf-single-automation-notice is-info bwf-mt-8">' . __( 'Tax will be automatically calculated and applied based on the order details at the time of creation.', 'wp-marketing-automations-pro' ) . '</div>' : '',
],
] );
}
/**
* @return array
* Added Default value
*/
public function get_default_values() {
return [
'billing_email' => '{{contact_email}}',
'billing_first_name' => '{{contact_first_name}}',
'billing_last_name' => '{{contact_last_name}}',
'billing_company' => '{{contact_company}}',
'billing_phone_no' => '{{contact_phone}}',
'shipping_first_name' => '{{contact_first_name}}',
'shipping_last_name' => '{{contact_last_name}}',
'shipping_company' => '{{contact_company}}',
'shipping_phone_no' => '{{contact_phone}}',
'is_shipping_address' => 'same_as_billing',
'couponType' => 'static',
'status' => 'wc-pending',
'order_custom_fields' => [],
];
}
/**
* Helper method to get available shipping methods
*/
private function get_available_shipping_methods() {
if ( ! $this->is_shipping_active() ) {
return [];
}
$methods = [];
$zones = WC_Shipping_Zones::get_zones();
foreach ( $zones as $zone ) {
foreach ( $zone['shipping_methods'] as $method ) {
if ( $method->is_enabled() ) {
$methods[ $method->id ] = $method->get_title();
}
}
}
// Check default zone (zone 0)
$default_zone = WC_Shipping_Zones::get_zone( 0 );
foreach ( $default_zone->get_shipping_methods() as $method ) {
if ( $method->is_enabled() ) {
$methods[ $method->id ] = $method->get_title();
}
}
return $methods;
}
private function is_shipping_active() {
$woocommerce_ship_to_countries = get_option( 'woocommerce_ship_to_countries' );
return 'disabled' !== $woocommerce_ship_to_countries;
}
/**
* @return array
*/
static function payment_gateways() {
$result = array();
foreach ( WC()->payment_gateways()->payment_gateways() as $gateway ) {
if ( 'yes' === $gateway->enabled ) {
$result[ $gateway->id ] = $gateway->get_title();
$result[ $gateway->id ] = $gateway->get_title();
}
}
return $result;
}
}
/**
* 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_Order';
}

View File

@@ -0,0 +1,283 @@
<?php
final class BWFAN_WC_Remove_Coupon extends BWFAN_Action {
private static $ins = null;
protected function __construct() {
$this->action_name = __( 'Delete Coupon', 'wp-marketing-automations-pro' );
$this->action_desc = __( 'This action deletes a WooCommerce coupon', 'wp-marketing-automations-pro' );
$this->required_fields = array( 'coupon_name' );
$this->support_v2 = true;
$this->action_priority = 10;
}
public static function get_instance() {
if ( null === self::$ins ) {
self::$ins = new self();
}
return self::$ins;
}
/**
* Show the html fields for the current action.
*/
public function get_view() {
?>
<script type="text/html" id="tmpl-action-<?php echo esc_html__( $this->get_slug() ); ?>">
<#
entered_coupon_name = (_.has(data.actionSavedData, 'data') && _.has(data.actionSavedData.data, 'coupon_name')) ? data.actionSavedData.data.coupon_name : '';
#>
<div class="bwfan-input-form clearfix">
<label for="" class="bwfan-label-title">
<?php echo esc_html__( 'Coupon Name', 'wp-marketing-automations-pro' ); ?>
<?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>
</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|void
*/
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_name'] = BWFAN_Common::decode_merge_tags( $task_meta['data']['coupon_name'] );
return $data_to_set;
}
public function make_v2_data( $automation_data, $step_data ) {
$data_to_set = array();
$type = isset( $step_data['coupon_type'] ) ? $step_data['coupon_type'] : 'static';
$coupon_name = '';
switch ( $type ) {
case 'static':
if ( isset( $step_data['coupon_name'] ) && ! empty( $step_data['coupon_name'] ) ) {
$coupon_name = $step_data['coupon_name'];
}
break;
case 'dynamic':
if ( isset( $step_data['dynamic_coupon_id'] ) && ! empty( $step_data['dynamic_coupon_id'] ) ) {
$coupon_name = '{{wc_dynamic_coupon id="' . $step_data['dynamic_coupon_id'] . '"}}';
}
}
$data_to_set['coupon_name'] = BWFAN_Common::decode_merge_tags( $coupon_name );
$data_to_set['order_id'] = isset( $automation_data['global']['order_id'] ) ? $automation_data['global']['order_id'] : 0;
$data_to_set['email'] = ( isset( $automation_data['global']['email'] ) && is_email( $automation_data['global']['email'] ) ) ? $automation_data['global']['email'] : '';
return $data_to_set;
}
/**
* 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 deletion, coupon does not exists.
$status = array(
'status' => 3,
'message' => $result['err_msg'],
);
return $status;
}
return array(
'status' => 3,
'message' => "Coupon {$this->data['coupon_name']} deleted.",
);
}
/**
* 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 = new WC_Coupon( $coupon_name );
$coupon_id = $coupon->get_id();
if ( 0 === $coupon_id ) { // Coupon does not exists
return [
'err_msg' => __( 'Coupon does not exists', 'wp-marketing-automations-pro' )
];
}
$coupons_email = $coupon->get_email_restrictions();
if ( is_array( $coupons_email ) && count( $coupons_email ) > 0 ) {
$index = array_search( $data['email'], $coupons_email, true );
if ( false !== $index ) {
unset( $coupons_email[ $index ] );
}
}
if ( is_array( $coupons_email ) && count( $coupons_email ) > 0 ) {
$coupon->set_email_restrictions( $coupons_email );
$coupon->save();
} else {
wp_delete_post( $coupon_id, true );
}
return $coupon_id;
}
public function process_v2() {
$data = $this->data;
$coupon_name = $data['coupon_name'];
$coupon = new WC_Coupon( $coupon_name );
$coupon_id = $coupon->get_id();
if ( 0 === $coupon_id ) { // Coupon does not exists
return $this->skipped_response( __( 'Coupon does not exist.', 'wp-marketing-automations-pro' ) );
}
$coupons_email = $coupon->get_email_restrictions();
if ( is_array( $coupons_email ) && count( $coupons_email ) > 0 ) {
$index = array_search( $data['email'], $coupons_email, true );
if ( false !== $index ) {
unset( $coupons_email[ $index ] );
}
}
if ( is_array( $coupons_email ) && count( $coupons_email ) > 0 ) {
$coupon->set_email_restrictions( $coupons_email );
$coupon->save();
} else {
wp_delete_post( $coupon_id, true );
}
return $this->success_message( __( 'Coupon deleted.', 'wp-marketing-automations-pro' ) );
}
public function get_fields_schema() {
return [
[
'id' => 'coupon_type',
'label' => __( 'Coupon Type', 'wp-marketing-automations-pro' ),
'type' => 'radio',
'options' => [
[
'label' => __( "Static Coupon", 'wp-marketing-automations-pro' ),
'value' => 'static',
],
[
'label' => __( "Dynamic Coupon", 'wp-marketing-automations-pro' ),
'value' => 'dynamic',
]
],
'class' => 'inline-radio-field',
'required' => false,
'wrap_before' => '',
],
[
"id" => 'coupon_name',
"label" => __( 'Coupon Name', 'wp-marketing-automations-pro' ),
"type" => 'text',
"class" => 'bwfan-input-wrapper',
"required" => true,
"hint" => __( 'Copy the value of coupon code. You can add dynamic coupon code merge tag or static coupon code. ( Only 1 allowed )', 'wp-marketing-automations-pro' ),
"toggler" => [
'fields' => [
[
'id' => 'coupon_type',
'value' => 'static'
]
],
'relation' => 'AND',
]
],
[
'id' => 'dynamic_coupon_id',
'type' => 'ajax',
'label' => __( 'Step ID', 'wp-marketing-automations-pro' ),
"class" => 'bwfan-input-wrapper',
"required" => true,
'placeholder' => __( 'Select', 'wp-marketing-automations-pro' ),
"description" => "",
"ajax_cb" => 'bwfan_get_automation_wc_dynamic_coupon',
"toggler" => [
'fields' => [
[
'id' => 'coupon_type',
'value' => 'dynamic'
]
],
'relation' => 'AND',
],
],
];
}
public function get_default_values() {
return [
'coupon_type' => 'static',
];
}
public function get_desc_text( $data ) {
$data = json_decode( wp_json_encode( $data ), true );
$type = isset( $data['coupon_type'] ) ? $data['coupon_type'] : 'static';
switch ( $type ) {
case 'static':
if ( ! isset( $data['coupon_name'] ) || empty( $data['coupon_name'] ) ) {
return '';
}
return $data['coupon_name'];
case 'dynamic':
if ( ! isset( $data['dynamic_coupon_id'] ) || empty( $data['dynamic_coupon_id'] ) ) {
return '';
}
return '{{wc_dynamic_coupon id="' . $data['dynamic_coupon_id'] . '"}}';
default:
return '';
}
}
}
/**
* Register this action. Registering the action will make it eligible to see it on single automation screen in select actions dropdown.
*/
return 'BWFAN_WC_Remove_Coupon';

View File

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