WC_Email_Customer_Abandoned_Cart_Recovery::handle_recovery_email_sendpublicWC 11.0.0

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{}

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() 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' ) );
}