WC_Email_Customer_Abandoned_Cart_Recovery::handle_recovery_email_send
Handle a merchant-initiated send from the order edit page.
Fired by woocommerce_order_action_send_abandoned_cart_recovery_email after the order metabox save flow has validated the request. We re-check the capability and order status as defense in depth in case the hook is invoked from a non-metabox path.
Method of the class: WC_Email_Customer_Abandoned_Cart_Recovery{}
Hooks from the method
Returns
null. Nothing (null).
Usage
$WC_Email_Customer_Abandoned_Cart_Recovery = new WC_Email_Customer_Abandoned_Cart_Recovery(); $WC_Email_Customer_Abandoned_Cart_Recovery->handle_recovery_email_send( $order ): void;
- $order(WC_Order) (required)
- The order whose customer should receive the email.
Changelog
| Since 11.0.0 | Introduced. |
WC_Email_Customer_Abandoned_Cart_Recovery::handle_recovery_email_send() WC Email Customer Abandoned Cart Recovery::handle recovery email send code WC 11.0.0
public function handle_recovery_email_send( $order ): void {
if ( ! $order instanceof WC_Order ) {
return;
}
if ( ! current_user_can( 'edit_shop_orders' ) ) {
return;
}
// Don't record an order note for a send that the underlying trigger
// would silently bail on.
if ( ! $this->is_enabled() || self::is_suppressed() ) {
return;
}
if ( ! $this->is_order_eligible_for_recovery( $order ) ) {
return;
}
// Customer-side preference wins over merchant action — don't bypass
// an unsubscribe by manual send.
if ( self::is_recipient_unsubscribed( $order->get_billing_email() ) ) {
return;
}
// Mirror trigger()'s dedup gate before firing the before/after
// resend hooks so extensions don't see a resend event for a send
// that trigger() would short-circuit.
if ( '' !== (string) $order->get_meta( self::META_KEY_SENT_AT ) ) {
return;
}
/**
* Fires before the abandoned cart recovery email is manually resent.
*
* @since 11.0.0
*
* @param WC_Order $order Order being recovered.
* @param string $email_type Email identifier ('customer_abandoned_cart_recovery').
*/
do_action( 'woocommerce_before_resend_order_emails', $order, $this->id );
// Gate the note + admin notice on trigger()'s return so the audit
// trail only records sends that actually went out.
if ( ! $this->trigger( $order->get_id() ) ) {
return;
}
$order->add_order_note(
__( 'Abandoned cart recovery email sent from the order actions menu.', 'woocommerce' ),
0,
true,
array( 'note_group' => OrderNoteGroup::EMAIL_NOTIFICATION )
);
/**
* Fires after the abandoned cart recovery email has been manually resent.
*
* @since 11.0.0
*
* @param WC_Order $order Order being recovered.
* @param string $email_type Email identifier ('customer_abandoned_cart_recovery').
*/
do_action( 'woocommerce_after_resend_order_email', $order, $this->id );
// Reuse the existing "Order updated. Email sent." admin notice (message id 11) on the
// classic order edit page. HPOS uses a different redirect pipeline that sets the
// message directly in Edit.php, so this filter is a no-op there — matching the
// behavior of the built-in `send_order_details` action.
add_filter( 'redirect_post_location', array( 'WC_Meta_Box_Order_Actions', 'set_email_sent_message' ) );
}