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,119 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
#[AllowDynamicProperties]
class BWFCRM_Transactional_Mail_Cancelled_Order extends BWFCRM_Transactional_Mail_Base {
/**
* Track which order IDs have been scheduled for email processing
* @var array
*/
private $scheduled_ids = [];
public function __construct( $load_hooks = false, $data = [] ) {
$this->slug = 'cancelled_order';
$this->name = __( 'Cancelled Order', 'wp-marketing-automations-pro' );
$this->description = __( 'Cancelled order emails are sent to chosen recipient(s) when orders have been marked cancelled (if they were previously processing or on-hold).', 'wp-marketing-automations-pro' );
$this->priority = 24;
$this->recipient = 'admin';
$this->subject = '{{store_name}}: ' . __( 'Order', 'wp-marketing-automations-pro' ) . ' #{{order_id}}' . __( ' has been cancelled', 'wp-marketing-automations-pro' );
$this->merge_tag_group = [
'wc_order',
];
$this->supported_block = [ 'order' ];
$this->template_data = $data;
$this->wc_mail_id = 'cancelled_order';
$this->set_data_by_template_data();
if ( $load_hooks && self::is_valid() ) {
/** Add restriction hook to stop default mail */
add_filter( 'woocommerce_email_enabled_cancelled_order', '__return_false' );
/** Add action to send mail and set_data function hit */
add_action( 'woocommerce_order_status_processing_to_cancelled', array( $this, 'run_cancelled_order_mail' ), 30, 2 );
add_action( 'woocommerce_order_status_on-hold_to_cancelled', array( $this, 'run_cancelled_order_mail' ), 30, 2 );
add_action( 'bwfcrm_before_resend_order_email_cancelled_order', array( $this, 'resend_order_emails' ) );
}
}
/**
* Resend order emails for cancelled orders
*
* @param $order
*
* @return void
*/
public function resend_order_emails( $order ) {
if ( ! $order instanceof WC_Order ) {
return;
}
$this->run_cancelled_order_mail( $order->get_id() );
}
/**
* Run canceled order mail in the shutdown hook
*
* @param int $order_id
* @param WC_Order $order Order object.
*/
public function run_cancelled_order_mail( $order_id, $order = null ) {
$order_id = (int) $order_id;
if ( isset( $this->scheduled_ids[ $order_id ] ) ) {
return; // Prevent multiple scheduling
}
add_action( 'shutdown', function () use ( $order_id ) {
$this->bwf_cancelled_order_mail( $order_id );
} );
$this->scheduled_ids[ $order_id ] = true; // Mark as scheduled
}
/**
* Check if mail is valid with dependency
*
* @return bool
*/
public function is_valid() {
return bwfan_is_woocommerce_active();
}
/**
* Set data for mail
*
* @param int $order_id
*/
public function bwf_cancelled_order_mail( $order_id ) {
/** Return if template id or order id is empty */
if ( empty( $this->template_data['template_id'] ) || empty( $order_id ) ) {
return;
}
/** Get order Object */
$order = wc_get_order( $order_id );
if ( ! $order instanceof WC_Order ) {
return;
}
/** Get template id */
$template_id = intval( $this->template_data['template_id'] );
$order_language = BWFAN_Common::get_order_language( $order );
if ( ! empty( $order_language ) && isset( $this->template_data['lang'][ $order_language ] ) ) {
$template_id = $this->template_data['lang'][ $order_language ];
}
/** Set data for merge tag */
$set_data = array(
'oid' => $order_id,
'order_id' => $order_id,
'email' => BWFAN_Common::$admin_email,
'wc_order' => $order,
'contact_id' => 0,
);
/** Call to base function to create engagement tracking */
$this->create_engagement_tracking( $template_id, $this->get_api_data(), $set_data );
}
}

View File

@@ -0,0 +1,119 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
#[AllowDynamicProperties]
class BWFCRM_Transactional_Mail_Completed_Order extends BWFCRM_Transactional_Mail_Base {
/**
* Track which order IDs have been scheduled for email processing
*
* @var array
*/
private $scheduled_ids = [];
public function __construct( $load_hooks = false, $data = [] ) {
$this->slug = 'completed_order';
$this->name = __( 'Completed Order', 'wp-marketing-automations-pro' );
$this->description = __( 'Order complete emails are sent to customers when their orders are marked completed and usually indicate that their orders have been shipped.', 'wp-marketing-automations-pro' );
$this->priority = 8;
$this->recipient = 'customer';
$this->subject = __( 'Your', 'wp-marketing-automations-pro' ) . ' {{store_name}} ' . __( 'order is now complete', 'wp-marketing-automations-pro' );
$this->merge_tag_group = [
'wc_order',
];
$this->supported_block = [ 'order' ];
$this->template_data = $data;
$this->wc_mail_id = 'customer_completed_order';
$this->set_data_by_template_data();
if ( $load_hooks && self::is_valid() ) {
/** Add restriction hook to stop default mail */
add_filter( 'woocommerce_email_enabled_customer_completed_order', '__return_false' );
/** Add action to send mail and set_data function hit */
add_action( 'woocommerce_order_status_completed', array( $this, 'run_completed_order_mail' ), 30, 2 );
add_action( 'bwfcrm_before_resend_order_email_customer_completed_order', array( $this, 'resend_order_emails' ) );
}
}
/**
* Resend order emails for completed orders
*
* @param $order
*
* @return void
*/
public function resend_order_emails( $order ) {
if ( ! $order instanceof WC_Order ) {
return;
}
$this->run_completed_order_mail( $order->get_id() );
}
/**
* Run completed order mail in the shutdown hook
*
* @param int $order_id
* @param WC_Order $order Order object.
*/
public function run_completed_order_mail( $order_id, $order = null ) {
$order_id = (int) $order_id;
if ( isset( $this->scheduled_ids[ $order_id ] ) ) {
return; // Prevent multiple scheduling
}
add_action( 'shutdown', function () use ( $order_id ) {
$this->bwf_order_status_to_completed( $order_id );
} );
$this->scheduled_ids[ $order_id ] = true; // Mark as scheduled
}
/**
* Check if mail is valid with dependency
*
* @return bool
*/
public function is_valid() {
return bwfan_is_woocommerce_active();
}
/**
* Set data for mail
*
* @param int $order_id
*/
public function bwf_order_status_to_completed( $order_id ) {
/** Return if template id or order id is empty */
if ( empty( $this->template_data['template_id'] ) || empty( $order_id ) ) {
return;
}
/** Get order object */
$order = wc_get_order( $order_id );
if ( ! $order instanceof WC_Order ) {
return;
}
/** Get template id */
$template_id = intval( $this->template_data['template_id'] );
$order_language = BWFAN_Common::get_order_language( $order );
if ( ! empty( $order_language ) && isset( $this->template_data['lang'][ $order_language ] ) ) {
$template_id = $this->template_data['lang'][ $order_language ];
}
/** Set data for merge tag */
$set_data = array(
'order_id' => $order_id,
'oid' => $order_id,
'email' => BWFAN_Woocommerce_Compatibility::get_order_data( $order, '_billing_email' ),
'wc_order' => $order,
'contact_id' => BWFAN_Woocommerce_Compatibility::get_order_data( $order, '_woofunnel_cid' ),
);
/** Create engagement tracking */
$this->create_engagement_tracking( $template_id, $this->get_api_data(), $set_data );
}
}

View File

@@ -0,0 +1,119 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
#[AllowDynamicProperties]
class BWFCRM_Transactional_Mail_Customer_Failed_Order extends BWFCRM_Transactional_Mail_Base {
/**
* Track which order IDs have been scheduled for email processing
*
* @var array
*/
private $scheduled_ids = [];
public function __construct( $load_hooks = false, $data = [] ) {
$this->slug = 'customer_failed_order';
$this->name = __( 'Failed Order', 'wp-marketing-automations-pro' );
$this->description = __( 'Order failed emails are sent to customers when their orders are marked as failed.', 'wp-marketing-automations-pro' );
$this->priority = 15;
$this->subject = __( 'Your order at', 'wp-marketing-automations-pro' ) . ' {{store_name}} ' . __( 'was unsuccessful', 'wp-marketing-automations-pro' );
$this->recipient = 'customer';
$this->merge_tag_group = [
'wc_order',
];
$this->supported_block = [ 'order' ];
$this->template_data = $data;
$this->wc_mail_id = 'customer_failed_order';
$this->set_data_by_template_data();
if ( $load_hooks && self::is_valid() ) {
/** Add restriction hook to stop default mail */
add_filter( 'woocommerce_email_enabled_customer_failed_order', '__return_false' );
/** Add action to send mail and set_data function hit */
add_action( 'woocommerce_order_status_failed', array( $this, 'run_failed_order_mail' ), 30, 2 );
add_action( 'bwfcrm_before_resend_order_email_failed_order', array( $this, 'resend_order_emails' ) );
}
}
/**
* Resend order emails for failed orders
*
* @param $order
*
* @return void
*/
public function resend_order_emails( $order ) {
if ( ! $order instanceof WC_Order ) {
return;
}
$this->run_failed_order_mail( $order->get_id() );
}
/**
* Run failed order mail in the shutdown hook
*
* @param int $order_id
* @param WC_Order $order Order object.
*/
public function run_failed_order_mail( $order_id, $order = null ) {
$order_id = (int) $order_id;
if ( isset( $this->scheduled_ids[ $order_id ] ) ) {
return; // Prevent multiple scheduling
}
add_action( 'shutdown', function () use ( $order_id ) {
$this->bwf_failed_order_mail( $order_id );
} );
$this->scheduled_ids[ $order_id ] = true; // Mark as scheduled
}
/**
* Check if mail is valid with dependency
*
* @return bool
*/
public function is_valid() {
return bwfan_is_woocommerce_active() && version_compare( WC_VERSION, '9.5.0', '>=' );
}
/**
* Set data for mail
*
* @param int $order_id
*/
public function bwf_failed_order_mail( $order_id ) {
/** Return if template id or order id is empty */
if ( empty( $this->template_data['template_id'] ) || empty( $order_id ) ) {
return;
}
/** Get order object */
$order = wc_get_order( $order_id );
if ( ! $order instanceof WC_Order ) {
return;
}
/** Get template id */
$template_id = intval( $this->template_data['template_id'] );
$order_language = BWFAN_Common::get_order_language( $order );
if ( ! empty( $order_language ) && isset( $this->template_data['lang'][ $order_language ] ) ) {
$template_id = $this->template_data['lang'][ $order_language ];
}
/** Set data for merge tag */
$set_data = array(
'order_id' => $order_id,
'oid' => $order_id,
'email' => BWFAN_Woocommerce_Compatibility::get_order_data( $order, '_billing_email' ),
'wc_order' => $order,
'contact_id' => BWFAN_Woocommerce_Compatibility::get_order_data( $order, '_woofunnel_cid' ),
);
/** Create engagement tracking */
$this->create_engagement_tracking( $template_id, $this->get_api_data(), $set_data );
}
}

View File

@@ -0,0 +1,85 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
#[AllowDynamicProperties]
class BWFCRM_Transactional_Mail_Customer_Note extends BWFCRM_Transactional_Mail_Base {
public function __construct( $load_hooks = false, $data = [] ) {
$this->slug = 'customer_note';
$this->name = __( 'Customer Note Added', 'wp-marketing-automations-pro' );
$this->description = __( 'Customer note emails are sent when you add a note to an order.', 'wp-marketing-automations-pro' );
$this->priority = 14;
$this->subject = __( 'Note added to your', 'wp-marketing-automations-pro' ) . ' {{store_name}} ' . __( 'order from ', 'wp-marketing-automations-pro' ) . "{{order_date format='j M Y'}}";
$this->recipient = 'customer';
$this->merge_tag_group = [
'wc_order',
];
$this->supported_block = [ 'order' ];
$this->template_data = $data;
$this->wc_mail_id = 'customer_note';
$this->set_data_by_template_data();
if ( $load_hooks && self::is_valid() ) {
/** Add restriction hook to stop default mail */
add_filter( 'woocommerce_email_enabled_customer_note', '__return_false' );
/** Add action to send mail and set_data for mail */
add_action( 'woocommerce_new_customer_note', [ $this, 'bwf_new_customer_note_added' ] );
}
}
/**
* Check if mail is valid with dependency
*
* @return bool
*/
public function is_valid() {
return bwfan_is_woocommerce_active();
}
/**
* Set data for mail
*
* @param array $args - Arguments order_id, customer_note
*/
public function bwf_new_customer_note_added( $args = [] ) {
/** Return if template id or order id is empty */
if ( empty( $this->template_data['template_id'] ) || empty( $args['order_id'] ) ) {
return;
}
/** Get order id */
$order_id = intval( $args['order_id'] );
if ( empty( $order_id ) ) {
return;
}
/** Get order */
$order = wc_get_order( $order_id );
if ( ! $order instanceof WC_Order ) {
return;
}
/** Get template id */
$template_id = intval( $this->template_data['template_id'] );
$order_language = BWFAN_Common::get_order_language( $order );
if ( ! empty( $order_language ) && isset( $this->template_data['lang'][ $order_language ] ) ) {
$template_id = $this->template_data['lang'][ $order_language ];
}
/** Set data for merge tag */
$set_data = array(
'order_id' => $order_id,
'oid' => $order_id,
'email' => BWFAN_Woocommerce_Compatibility::get_order_data( $order, '_billing_email' ),
'wc_order' => $order,
'contact_id' => BWFAN_Woocommerce_Compatibility::get_order_data( $order, '_woofunnel_cid' ),
'current_order_note' => isset( $args['customer_note'] ) ? $args['customer_note'] : '',
);
/** Create engagement tracking */
$this->create_engagement_tracking( $template_id, $this->get_api_data(), $set_data );
}
}

View File

@@ -0,0 +1,105 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
#[AllowDynamicProperties]
class BWFCRM_Transactional_Mail_Failed_Order extends BWFCRM_Transactional_Mail_Base {
/**
* Track which order IDs have been scheduled for email processing
*
* @var array
*/
private $scheduled_ids = [];
public function __construct( $load_hooks = false, $data = [] ) {
$this->slug = 'failed_order';
$this->name = __( 'Failed Order', 'wp-marketing-automations-pro' );
$this->description = __( 'Failed order emails are sent to chosen recipient(s) when orders have been marked failed (if they were previously pending or on-hold).', 'wp-marketing-automations-pro' );
$this->priority = 22;
$this->subject = '{{store_name}}: ' . __( 'Order', 'wp-marketing-automations-pro' ) . ' #{{order_id}}' . __( ' has failed', 'wp-marketing-automations-pro' );
$this->recipient = 'admin';
$this->merge_tag_group = [
'wc_order',
];
$this->supported_block = [ 'order' ];
$this->template_data = $data;
$this->wc_mail_id = 'failed_order';
$this->set_data_by_template_data();
if ( $load_hooks && self::is_valid() ) {
/** Add restriction hook to stop default mail */
add_filter( 'woocommerce_email_enabled_failed_order', '__return_false' );
/** Add action to send mail and set_data function hit */
add_action( 'woocommerce_order_status_pending_to_failed', array( $this, 'run_failed_order_mail' ), 30, 2 );
add_action( 'woocommerce_order_status_on-hold_to_failed', array( $this, 'run_failed_order_mail' ), 30, 2 );
}
}
/**
* Run failed order mail in the shutdown hook
*
* @param int $order_id
* @param WC_Order $order Order object.
*/
public function run_failed_order_mail( $order_id, $order ) {
$order_id = (int) $order_id;
if ( isset( $this->scheduled_ids[ $order_id ] ) ) {
return; // Prevent multiple scheduling
}
add_action( 'shutdown', function () use ( $order_id ) {
$this->bwf_failed_order_mail( $order_id );
} );
$this->scheduled_ids[ $order_id ] = true; // Mark as scheduled
}
/**
* Check if mail is valid with dependency
*
* @return bool
*/
public function is_valid() {
return bwfan_is_woocommerce_active();
}
/**
* Set data for mail
*
* @param int $order_id
* @param WC_Order|false $order Order object.
*/
public function bwf_failed_order_mail( $order_id ) {
/** Return if template id or order id is empty */
if ( empty( $this->template_data['template_id'] ) || empty( $order_id ) ) {
return;
}
/** Get order object */
$order = wc_get_order( $order_id );
if ( ! $order instanceof WC_Order ) {
return;
}
/** Get template id */
$template_id = intval( $this->template_data['template_id'] );
$order_language = BWFAN_Common::get_order_language( $order );
if ( ! empty( $order_language ) && isset( $this->template_data['lang'][ $order_language ] ) ) {
$template_id = $this->template_data['lang'][ $order_language ];
}
/** Set data for merge tag */
$set_data = array(
'order_id' => $order_id,
'oid' => $order_id,
'email' => BWFAN_Common::$admin_email,
'wc_order' => $order,
'contact_id' => 0,
);
/** Create engagement tracking */
$this->create_engagement_tracking( $template_id, $this->get_api_data(), $set_data );
}
}

View File

@@ -0,0 +1,123 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
#[AllowDynamicProperties]
class BWFCRM_Transactional_Mail_New_Account extends BWFCRM_Transactional_Mail_Base {
public $customer_created = [];
public function __construct( $load_hooks = false, $data = [] ) {
$this->slug = 'new_account';
$this->name = __( 'New Account', 'wp-marketing-automations-pro' );
$this->description = __( 'Customer "new account" emails are sent to the customer when a customer signs up via checkout or account pages.', 'wp-marketing-automations-pro' );
$this->priority = 16;
$this->subject = __( 'Your', 'wp-marketing-automations-pro' ) . ' {{store_name}}: ' . __( 'account has been created!', 'wp-marketing-automations-pro' );
$this->recipient = 'customer';
$this->merge_tag_group = [
'bwf_contact',
'bwf_user',
];
$this->template_data = $data;
$this->wc_mail_id = 'customer_new_account';
$this->set_data_by_template_data();
if ( $load_hooks && self::is_valid() ) {
/** Add restriction hook to stop default mail */
add_filter( 'woocommerce_email_enabled_customer_new_account', '__return_false' );
/** Add action to send mail and set_data function hit */
add_action( 'woocommerce_created_customer', array( $this, 'bwf_new_account_mail' ), 30, 3 );
/** Hook in below to access the order data */
add_action( 'shutdown', array( $this, 'wc_order_processed' ) );
}
}
/**
* Check if mail is valid with dependency
*
* @return bool
*/
public function is_valid() {
return bwfan_is_woocommerce_active();
}
/**
* Customer new account welcome email.
*
* @param int $customer_id Customer ID.
* @param array $new_customer_data New customer data.
* @param bool $password_generated If password is generated.
*/
public function bwf_new_account_mail( $customer_id, $new_customer_data = array(), $password_generated = false ) {
/** Return if template id or user id is empty */
if ( empty( $this->template_data['template_id'] ) || ! $customer_id ) {
return;
}
$email = isset( $new_customer_data['user_email'] ) ? $new_customer_data['user_email'] : '';
if ( empty( $email ) ) {
$user = get_user_by( 'id', $customer_id );
$email = $user instanceof WP_User ? $user->user_email : $email;
}
$set_data = array(
'email' => $email,
'user_id' => $customer_id,
'oid' => $customer_id
);
$this->customer_created = $set_data;
}
public function wc_order_processed() {
if ( empty( $this->customer_created ) ) {
return;
}
/** Get template id */
$template_id = intval( $this->template_data['template_id'] );
/** Check for users last order */
$order = $this->get_user_last_order( $this->customer_created['user_id'] );
if ( $order instanceof WC_Order ) {
$order_language = BWFAN_Common::get_order_language( $order );
if ( ! empty( $order_language ) && isset( $this->template_data['lang'][ $order_language ] ) ) {
$template_id = $this->template_data['lang'][ $order_language ];
}
$this->customer_created['order_id'] = $order->get_id();
$this->customer_created['wc_order'] = $order;
$this->customer_created['wc_order'] = BWFAN_Woocommerce_Compatibility::get_order_data( $order, '_woofunnel_cid' );
}
/** Create engagement tracking */
$this->create_engagement_tracking( $template_id, $this->get_api_data(), $this->customer_created );
}
/**
* Get user last order
*
* @param $user_id
*
* @return mixed|WC_Order|null
*/
protected function get_user_last_order( $user_id ) {
$args = array(
'customer_id' => $user_id,
'status' => array( 'completed', 'processing', 'on-hold' ), // You might adjust statuses
'limit' => 1,
'orderby' => 'date',
'order' => 'DESC',
);
$orders = wc_get_orders( $args );
if ( empty( $orders ) ) {
return false; // No orders found for the user
}
return $orders[0]; // Return the most recent order
}
}

View File

@@ -0,0 +1,157 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
#[AllowDynamicProperties]
class BWFCRM_Transactional_Mail_New_Order extends BWFCRM_Transactional_Mail_Base {
/**
* Track which order IDs have been scheduled for email processing
*
* @var array
*/
private $scheduled_ids = [];
public function __construct( $load_hooks = false, $data = [] ) {
$this->slug = 'new_order';
$this->name = __( 'New Order', 'wp-marketing-automations-pro' );
$this->description = __( 'New order emails are sent to chosen recipient(s) when a new order is received.', 'wp-marketing-automations-pro' );
$this->priority = 20;
$this->recipient = 'admin';
$this->subject = '{{store_name}}: ' . __( 'New order', 'wp-marketing-automations-pro' ) . ' #{{order_id}}';
$this->merge_tag_group = [
'wc_order',
];
$this->supported_block = [ 'order' ];
$this->template_data = $data;
$this->wc_mail_id = 'new_order';
$this->set_data_by_template_data();
if ( $load_hooks && self::is_valid() ) {
/** Add restriction hook to stop default mail */
add_filter( 'woocommerce_email_enabled_new_order', '__return_false' );
/** Add action to send mail and set_data function hit */
add_action( 'woocommerce_order_status_pending_to_processing', array( $this, 'bwf_new_order_mail_admin' ), 1, 2 );
add_action( 'woocommerce_order_status_pending_to_completed', array( $this, 'bwf_new_order_mail_admin' ), 1, 2 );
add_action( 'woocommerce_order_status_pending_to_on-hold', array( $this, 'bwf_new_order_mail_admin' ), 1, 2 );
add_action( 'woocommerce_order_status_failed_to_processing', array( $this, 'bwf_new_order_mail_admin' ), 1, 2 );
add_action( 'woocommerce_order_status_failed_to_completed', array( $this, 'bwf_new_order_mail_admin' ), 1, 2 );
add_action( 'woocommerce_order_status_failed_to_on-hold', array( $this, 'bwf_new_order_mail_admin' ), 1, 2 );
add_action( 'woocommerce_order_status_cancelled_to_processing', array( $this, 'bwf_new_order_mail_admin' ), 1, 2 );
add_action( 'woocommerce_order_status_cancelled_to_completed', array( $this, 'bwf_new_order_mail_admin' ), 1, 2 );
add_action( 'woocommerce_order_status_cancelled_to_on-hold', array( $this, 'bwf_new_order_mail_admin' ), 1, 2 );
add_action( 'bwfcrm_before_resend_order_email_new_order', array( $this, 'resend_order_emails' ) );
}
}
/**
* Resend order emails for new orders
*
* @param $order
*
* @return void
*/
public function resend_order_emails( $order ) {
if ( ! $order instanceof WC_Order ) {
return;
}
$this->bwf_new_order_mail_admin( $order->get_id() );
}
/**
* Run new order mail in the shutdown hook
*
* @param int $order_id
* @param WC_Order $order Order object.
*/
public function bwf_new_order_mail_admin( $order_id, $order = null ) {
$order_id = (int) $order_id;
if ( isset( $this->scheduled_ids[ $order_id ] ) ) {
return; // Prevent multiple scheduling
}
// if the order is not passed, get it from order ID
if ( ! $order instanceof WC_Order && ! empty( $order_id ) ) {
$order = wc_get_order( $order_id );
}
// If the order is still not valid, return
if ( ! $order instanceof WC_Order ) {
return;
}
$email_already_sent = $order->get_new_order_email_sent();
if ( $email_already_sent && ! apply_filters( 'woocommerce_new_order_email_allows_resend', true ) ) {
return;
}
add_action( 'shutdown', function () use ( $order_id, $order ) {
$this->bwf_new_order_mail( $order_id, $order );
} );
$this->scheduled_ids[ $order_id ] = true; // Mark as scheduled
}
/**
* Check if mail is valid with dependency
*
* @return bool
*/
public function is_valid() {
return bwfan_is_woocommerce_active();
}
/**
* Set data for mail
*
* @param int $order_id
* @param WC_Order|false $order Order object.
*
* @return void
*/
public function bwf_new_order_mail( $order_id, $order ) {
/** Return if template id or order id is empty */
if ( empty( $this->template_data['template_id'] ) || empty( $order_id ) ) {
return;
}
/** Get order object if not passed */
if ( ! $order ) {
$order = wc_get_order( $order_id );
}
if ( ! $order instanceof WC_Order ) {
return;
}
/** Get template id */
$template_id = intval( $this->template_data['template_id'] );
$email_already_sent = $order->get_new_order_email_sent();
if ( $email_already_sent && ! apply_filters( 'woocommerce_new_order_email_allows_resend', true ) ) {
return;
}
$order_language = BWFAN_Common::get_order_language( $order );
if ( ! empty( $order_language ) && isset( $this->template_data['lang'][ $order_language ] ) ) {
$template_id = $this->template_data['lang'][ $order_language ];
}
/** Set data for merge tag */
$set_data = array(
'order_id' => $order_id,
'oid' => $order_id,
'email' => BWFAN_Common::$admin_email,
'wc_order' => $order,
'contact_id' => 0,
);
/** Create engagement tracking */
$status = $this->create_engagement_tracking( $template_id, $this->get_api_data(), $set_data );
if ( $status ) {
$order->update_meta_data( '_new_order_email_sent', 'true' );
$order->save();
}
}
}

View File

@@ -0,0 +1,122 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
#[AllowDynamicProperties]
class BWFCRM_Transactional_Mail_Onhold_Order extends BWFCRM_Transactional_Mail_Base {
/**
* Track which order IDs have been scheduled for email processing
*
* @var array
*/
private $scheduled_ids = [];
public function __construct( $load_hooks = false, $data = [] ) {
$this->slug = 'onhold_order';
$this->name = __( 'Order On-hold', 'wp-marketing-automations-pro' );
$this->description = __( 'This is an order notification sent to customers containing order details after an order is placed on-hold from Pending, Cancelled or Failed order status.', 'wp-marketing-automations-pro' );
$this->priority = 9;
$this->subject = __( 'Your', 'wp-marketing-automations-pro' ) . ' {{store_name}} ' . __( 'order has been received!', 'wp-marketing-automations-pro' );
$this->recipient = 'customer';
$this->merge_tag_group = [
'wc_order',
];
$this->supported_block = [ 'order' ];
$this->template_data = $data;
$this->wc_mail_id = 'customer_on_hold_order';
$this->set_data_by_template_data();
if ( $load_hooks && self::is_valid() ) {
/** Add restriction hook to stop default mail */
add_filter( 'woocommerce_email_enabled_customer_on_hold_order', '__return_false' );
/** Add action to send mail and set_data function hit */
add_action( 'woocommerce_order_status_pending_to_on-hold', array( $this, 'run_onhold_order_mail' ), 30, 2 );
add_action( 'woocommerce_order_status_failed_to_on-hold', array( $this, 'run_onhold_order_mail' ), 30, 2 );
add_action( 'woocommerce_order_status_cancelled_to_on-hold', array( $this, 'run_onhold_order_mail' ), 30, 2 );
add_action( 'bwfcrm_before_resend_order_email_onhold_order', array( $this, 'resend_order_emails' ) );
}
}
/**
* Resend order emails for on-hold orders
*
* @param $order
*
* @return void
*/
public function resend_order_emails( $order ) {
if ( ! $order instanceof WC_Order ) {
return;
}
$this->run_onhold_order_mail( $order->get_id() );
}
/**
* Run on-hold order mail in the shutdown hook
*
* @param int $order_id
* @param WC_Order $order Order object.
*/
public function run_onhold_order_mail( $order_id, $order = null ) {
$order_id = (int) $order_id;
if ( isset( $this->scheduled_ids[ $order_id ] ) ) {
return; // Prevent multiple scheduling
}
add_action( 'shutdown', function () use ( $order_id ) {
$this->bwf_order_status_to_onhold( $order_id );
} );
$this->scheduled_ids[ $order_id ] = true; // Mark as scheduled
}
/**
* Check if mail is valid with dependency
*
* @return bool
*/
public function is_valid() {
return bwfan_is_woocommerce_active();
}
/**
* Set data for mail
*
* @param int $order_id
*/
public function bwf_order_status_to_onhold( $order_id ) {
/** Return if template id or order id is empty */
if ( empty( $this->template_data['template_id'] ) || empty( $order_id ) ) {
return;
}
/** Get order object */
$order = wc_get_order( $order_id );
if ( ! $order instanceof WC_Order ) {
return;
}
/** Get template id */
$template_id = intval( $this->template_data['template_id'] );
$order_language = BWFAN_Common::get_order_language( $order );
if ( ! empty( $order_language ) && isset( $this->template_data['lang'][ $order_language ] ) ) {
$template_id = $this->template_data['lang'][ $order_language ];
}
/** Set data for merge tag */
$set_data = array(
'order_id' => $order_id,
'oid' => $order_id,
'email' => BWFAN_Woocommerce_Compatibility::get_order_data( $order, '_billing_email' ),
'wc_order' => $order,
'contact_id' => BWFAN_Woocommerce_Compatibility::get_order_data( $order, '_woofunnel_cid' ),
);
/** Create engagement tracking */
$this->create_engagement_tracking( $template_id, $this->get_api_data(), $set_data );
}
}

View File

@@ -0,0 +1,86 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
#[AllowDynamicProperties]
class BWFCRM_Transactional_Mail_Order_Details extends BWFCRM_Transactional_Mail_Base {
public function __construct( $load_hooks = false, $data = [] ) {
$this->slug = 'order_details';
$this->name = __( 'Order Details', 'wp-marketing-automations-pro' );
$this->description = __( 'Order detail emails can be sent to customers containing their order information and payment links.', 'wp-marketing-automations-pro' );
$this->priority = 12;
$this->recipient = 'customer';
$this->subject = __( 'Detail for order', 'wp-marketing-automations-pro' ) . ' #{{order_id}} ' . __( 'on', 'wp-marketing-automations-pro' ) . ' {{store_name}}';
$this->merge_tag_group = [
'wc_order',
];
$this->supported_block = [ 'order' ];
$this->template_data = $data;
$this->wc_mail_id = 'customer_invoice';
$this->set_data_by_template_data();
if ( $load_hooks && self::is_valid() ) {
/** Add restriction hook to stop default mail */
add_filter( 'woocommerce_email_recipient_customer_invoice', array( $this, 'remove_recipients_form_order_invoice' ) );
add_action( 'bwfcrm_before_resend_order_email_customer_invoice', array( $this, 'resend_order_emails' ) );
}
}
/**
* Check if mail is valid with dependency
*
* @return bool
*/
public function is_valid() {
return bwfan_is_woocommerce_active();
}
/**
* Remove recipients form order invoice
*
* @param string $recipient
*
* @return string
*/
public function remove_recipients_form_order_invoice( $recipient ) {
return '';
}
/**
* Set data for mail
*
* @param int $order
*/
public function resend_order_emails( $order ) {
/** Return if template id or order id is empty */
if ( empty( $this->template_data['template_id'] ) ) {
return;
}
if ( ! $order instanceof WC_Order ) {
return;
}
/** Get template id */
$template_id = intval( $this->template_data['template_id'] );
$order_language = BWFAN_Common::get_order_language( $order );
if ( ! empty( $order_language ) && isset( $this->template_data['lang'][ $order_language ] ) ) {
$template_id = $this->template_data['lang'][ $order_language ];
}
/** Set data for merge tag */
$set_data = array(
'order_id' => $order->get_id(),
'oid' => $order->get_id(),
'email' => BWFAN_Woocommerce_Compatibility::get_order_data( $order, '_billing_email' ),
'wc_order' => $order,
'contact_id' => BWFAN_Woocommerce_Compatibility::get_order_data( $order, '_woofunnel_cid' ),
);
/** Create engagement tracking */
$this->create_engagement_tracking( $template_id, $this->get_api_data(), $set_data );
}
}

View File

@@ -0,0 +1,123 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
#[AllowDynamicProperties]
class BWFCRM_Transactional_Mail_Processing_Order extends BWFCRM_Transactional_Mail_Base {
/**
* Track which order IDs have been scheduled for email processing
*
* @var array
*/
private $scheduled_ids = [];
public function __construct( $load_hooks = false, $data = [] ) {
$this->slug = 'processing_order';
$this->name = __( 'Processing Order', 'wp-marketing-automations-pro' );
$this->description = __( 'This is an order notification sent to customers containing order details after payment.', 'wp-marketing-automations-pro' );
$this->priority = 5;
$this->recipient = 'customer';
$this->subject = __( 'Your', 'wp-marketing-automations-pro' ) . ' {{store_name}} ' . __( 'order has been received!', 'wp-marketing-automations-pro' );
$this->merge_tag_group = [
'wc_order',
];
$this->supported_block = [ 'order' ];
$this->template_data = $data;
$this->wc_mail_id = 'customer_processing_order';
$this->set_data_by_template_data();
if ( $load_hooks && self::is_valid() ) {
/** Add restriction hook to stop default mail */
add_filter( 'woocommerce_email_enabled_customer_processing_order', '__return_false' );
/** Add action to send mail and set_data function hit */
add_action( 'woocommerce_order_status_cancelled_to_processing', array( $this, 'run_processing_order_mail' ), 30, 2 );
add_action( 'woocommerce_order_status_failed_to_processing', array( $this, 'run_processing_order_mail' ), 30, 2 );
add_action( 'woocommerce_order_status_on-hold_to_processing', array( $this, 'run_processing_order_mail' ), 30, 2 );
add_action( 'woocommerce_order_status_pending_to_processing', array( $this, 'run_processing_order_mail' ), 30, 2 );
add_action( 'bwfcrm_before_resend_order_email_customer_processing_order', array( $this, 'resend_order_emails' ) );
}
}
/**
* Resend order emails for processing orders
*
* @param $order
*
* @return void
*/
public function resend_order_emails( $order ) {
if ( ! $order instanceof WC_Order ) {
return;
}
$this->run_processing_order_mail( $order->get_id(), $order );
}
/**
* Run processing order mail in the shutdown hook
*
* @param int $order_id
* @param WC_Order $order Order object.
*/
public function run_processing_order_mail( $order_id, $order = null ) {
$order_id = (int) $order_id;
if ( isset( $this->scheduled_ids[ $order_id ] ) ) {
return; // Prevent multiple scheduling
}
add_action( 'shutdown', function () use ( $order_id ) {
$this->bwf_order_status_to_processing( $order_id );
} );
$this->scheduled_ids[ $order_id ] = true; // Mark as scheduled
}
/**
* Check if mail is valid with dependency
*
* @return bool
*/
public function is_valid() {
return bwfan_is_woocommerce_active();
}
/**
* Set data for mail
*
* @param int $order_id
*/
public function bwf_order_status_to_processing( $order_id ) {
/** Return if template id or order id is empty */
if ( empty( $this->template_data['template_id'] ) || empty( $order_id ) ) {
return;
}
/** Get order object */
$order = wc_get_order( $order_id );
if ( ! $order instanceof WC_Order ) {
return;
}
/** Get template id */
$template_id = intval( $this->template_data['template_id'] );
$order_language = BWFAN_Common::get_order_language( $order );
if ( ! empty( $order_language ) && isset( $this->template_data['lang'][ $order_language ] ) ) {
$template_id = $this->template_data['lang'][ $order_language ];
}
/** Set data for merge tag */
$set_data = array(
'order_id' => $order_id,
'oid' => $order_id,
'email' => BWFAN_Woocommerce_Compatibility::get_order_data( $order, '_billing_email' ),
'wc_order' => $order,
'contact_id' => BWFAN_Woocommerce_Compatibility::get_order_data( $order, '_woofunnel_cid' ),
);
/** Create engagement tracking */
$this->create_engagement_tracking( $template_id, $this->get_api_data(), $set_data );
}
}

View File

@@ -0,0 +1,117 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
#[AllowDynamicProperties]
class BWFCRM_Transactional_Mail_Refunded_Order extends BWFCRM_Transactional_Mail_Base {
public function __construct( $load_hooks = false, $data = [] ) {
$this->slug = 'refunded_order';
$this->name = __( 'Refunded Order', 'wp-marketing-automations-pro' );
$this->description = __( 'Order refunded emails are sent to customers when their orders are refunded.', 'wp-marketing-automations-pro' );
$this->priority = 10;
$this->recipient = 'customer';
$this->subject = __( 'Your', 'wp-marketing-automations-pro' ) . ' {{store_name}}: ' . __( 'order', 'wp-marketing-automations-pro' ) . ' #{{order_id}} ' . __( 'has been refunded', 'wp-marketing-automations-pro' );
$this->merge_tag_group = [
'wc_order',
];
$this->supported_block = [ 'order' ];
$this->template_data = $data;
$this->wc_mail_id = 'customer_refunded_order';
$this->set_data_by_template_data();
if ( $load_hooks && self::is_valid() ) {
/** Add restriction hook to stop default mail */
add_filter( 'woocommerce_email_enabled_customer_refunded_order', '__return_false' );
/** Add action to send mail and set_data function hit */
add_action( 'woocommerce_order_fully_refunded', array( $this, 'bwf_order_status_trigger_full' ), 10, 2 );
add_action( 'woocommerce_order_partially_refunded', array( $this, 'bwf_order_status_trigger_partial' ), 10, 2 );
add_action( 'bwfcrm_before_resend_order_email_refunded_order', array( $this, 'resend_order_emails' ) );
}
}
/**
* Resend order emails for refunded orders
*
* @param $order
*
* @return void
*/
public function resend_order_emails( $order ) {
if ( ! $order instanceof WC_Order ) {
return;
}
$this->bwf_order_status_to_refunded( $order->get_id() );
}
/**
* Check if mail is valid with dependency
*
* @return bool
*/
public function is_valid() {
return bwfan_is_woocommerce_active();
}
/**
* Full refund notification.
*
* @param int $order_id Order ID.
* @param int $refund_id Refund ID.
*/
public function bwf_order_status_trigger_full( $order_id, $refund_id = null ) {
$this->bwf_order_status_to_refunded( $order_id, $refund_id, false );
}
/**
* Partial refund notification.
*
* @param int $order_id Order ID.
* @param int $refund_id Refund ID.
*/
public function bwf_order_status_trigger_partial( $order_id, $refund_id = null ) {
$this->bwf_order_status_to_refunded( $order_id, $refund_id, true );
}
/**
* Set data for mail
*
* @param int $order_id
* @param int|null $refund_id
* @param bool $partial
*/
public function bwf_order_status_to_refunded( $order_id, $refund_id = null, $partial = false ) {
/** Return if template id or order id is empty */
if ( empty( $this->template_data['template_id'] ) || empty( $order_id ) ) {
return;
}
/** Get order object if not passed */
$order = wc_get_order( $order_id );
if ( ! $order instanceof WC_Order ) {
return;
}
/** Get template id */
$template_id = intval( $this->template_data['template_id'] );
$order_language = BWFAN_Common::get_order_language( $order );
if ( ! empty( $order_language ) && isset( $this->template_data['lang'][ $order_language ] ) ) {
$template_id = $this->template_data['lang'][ $order_language ];
}
/** Set data for merge tag */
$set_data = array(
'order_id' => $order_id,
'oid' => $order_id,
'email' => BWFAN_Woocommerce_Compatibility::get_order_data( $order, '_billing_email' ),
'wc_order' => $order,
'contact_id' => BWFAN_Woocommerce_Compatibility::get_order_data( $order, '_woofunnel_cid' ),
);
/** Create engagement tracking */
$this->create_engagement_tracking( $template_id, $this->get_api_data(), $set_data );
}
}

View File

@@ -0,0 +1,109 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
#[AllowDynamicProperties]
class BWFCRM_Transactional_Mail_Reset_Password extends BWFCRM_Transactional_Mail_Base {
public function __construct( $load_hooks = false, $data = [] ) {
$this->slug = 'reset_password';
$this->name = __( 'Reset Password', 'wp-marketing-automations-pro' );
$this->description = __( 'Customer "reset password" emails are sent when customers reset their passwords.', 'wp-marketing-automations-pro' );
$this->priority = 18;
$this->recipient = 'customer';
$this->subject = __( 'Password Reset Request for ', 'wp-marketing-automations-pro' ) . ' {{store_name}}';
$this->merge_tag_group = [
'bwf_contact',
'bwf_user',
];
$this->template_data = $data;
$this->wc_mail_id = 'customer_reset_password';
$this->set_data_by_template_data();
if ( $load_hooks && self::is_valid() ) {
/** Add restriction hook to stop default mail */
add_filter( 'woocommerce_email_enabled_customer_reset_password', '__return_false' );
/** Add action to send mail and set_data function hit */
add_action( 'woocommerce_reset_password_notification', array( $this, 'bwf_reset_password_mail' ), 10, 2 );
}
}
/**
* Check if mail is valid with dependency
*
* @return bool
*/
public function is_valid() {
return bwfan_is_woocommerce_active();
}
/**
* Customer reset account email.
*
* @param string $user_login User login.
* @param string $reset_key Password reset key.
*/
public function bwf_reset_password_mail( $user_login = '', $reset_key = '' ) {
/** Return if template id or order id is empty */
if ( empty( $this->template_data['template_id'] ) || ! $user_login ) {
return;
}
$user = get_user_by( 'login', $user_login );
if ( ! $user instanceof WP_User ) {
return;
}
$email = $user->user_email;
$set_data = array(
'email' => $email,
'user_id' => $user->ID,
'oid' => $user->ID,
'user_reset_key' => $reset_key,
);
/** Get template id */
$template_id = intval( $this->template_data['template_id'] );
/** Check for users last order */
$order = $this->get_user_last_order( $user->ID );
if ( $order instanceof WC_Order ) {
$order_language = BWFAN_Common::get_order_language( $order );
if ( ! empty( $order_language ) && isset( $this->template_data['lang'][ $order_language ] ) ) {
$template_id = $this->template_data['lang'][ $order_language ];
}
$set_data['order_id'] = $order->get_id();
$set_data['wc_order'] = $order;
}
/** Create engagement tracking */
$this->create_engagement_tracking( $template_id, $this->get_api_data(), $set_data );
}
/**
* Get user last order
*
* @param $user_id
*
* @return mixed|WC_Order|null
*/
protected function get_user_last_order( $user_id ) {
$args = array(
'customer_id' => $user_id,
'status' => array( 'completed', 'processing', 'on-hold' ), // You might adjust statuses
'limit' => 1,
'orderby' => 'date',
'order' => 'DESC',
);
$orders = wc_get_orders( $args );
if ( empty( $orders ) ) {
return false; // No orders found for the user
}
return $orders[0]; // Return the most recent order
}
}