php Woocommerce -自动更改订单状态并向选定的地址发送电子邮件

lokaqttq  于 5个月前  发布在  PHP
关注(0)|答案(2)|浏览(75)

我正在自定义woocommerce来创建一个食品预订系统。我已经成功地删除了所有不必要的结账字段,我已经禁用了支付网关,因为我只需要注册订单。我现在正在使用elementor和我正在编写的自定义插件向结账页面添加一些自定义字段。我现在有这个代码,我需要自定义结账,当客户端进行预订(订单),我将需要发送电子邮件到一些自定义的电子邮件地址,可以从用户使用自定义结帐字段,我已经添加了选择。是否可以自动更改订单状态完成,并发送电子邮件,什么是挂钩使用?

class CustomCheckout {        
    
    #
    public function __construct()
    {
        # 
        add_action( 'woocommerce_checkout_fields', array( $this, 'remove_default_checkout_fields') );
        # 
        add_action( 'woocommerce_after_checkout_billing_form', array( $this, 'add_custom_checkout_fields') );
        # 
        add_action( 'phpmailer_init', array( $this, 'mailtrap') );
        # 
        add_filter( 'woocommerce_cart_needs_payment', '__return_false' );
    }

    # debug email woocommerce
    public function mailtrap( $phpmailer ) 
    {
        $phpmailer->isSMTP();
        $phpmailer->Host = 'sandbox.smtp.mailtrap.io';
        $phpmailer->SMTPAuth = true;
        $phpmailer->Port = 2525;
        $phpmailer->Username = '****';
        $phpmailer->Password = '***';
    }
        
    #
    public function remove_default_checkout_fields( $fields )
    {
        //unset( $fields['billing']['first_name'] );
        //unset( $fields['billing']['last_name'] );
        unset( $fields['billing']['billing_company'] );
        unset( $fields['billing']['billing_country'] );
        unset( $fields['billing']['billing_address_1'] );
        unset( $fields['billing']['billing_address_2'] );
        unset( $fields['billing']['billing_city'] );
        unset( $fields['billing']['billing_state'] );
        unset( $fields['billing']['billing_postcode'] );
        # Rimuovo campi spedizione
        unset( $fields['shipping']['shipping_first_name'] );
        unset( $fields['shipping']['shipping_last_name'] );
        unset( $fields['shipping']['shipping_company'] );
        unset( $fields['shipping']['shipping_country'] );
        unset( $fields['shipping']['shipping_address_1'] );
        unset( $fields['shipping']['shipping_addredd_2'] );
        unset( $fields['shipping']['shipping_city'] );
        unset( $fields['shipping']['shipping_state'] );
        unset( $fields['shipping']['shipping_postcode'] );

        #
        return $fields;
    }
    
    #
    public function add_custom_checkout_fields( $checkout )
    {
        # 
        woocommerce_form_field( 
            'pdvselector', 
            array(
                'type' => 'select',
                'required' => true,
                'class' => array('form-row-first'),
                'label' => 'Punto di ritiro',
                //'label_class'
                'options' => array(
                    '' => 'Select a store',
                    '[email protected]' => 'Value 1',
                    '[email protected]' => 'Value 2',
                    '[email protected]' => 'Value 3'
                )
            ),
            $checkout->get_value( 'pdvselector' )
        );

        #
        woocommerce_form_field( 
            'dateselector', 
            array(
                'type' => 'date',
                'required' => true,
                'class' => array('form-row-last'),
                'label' => 'Reservation day'
            ), 
            $checkout->get_value( 'dateselector' ) 
        );
    
        #
        woocommerce_form_field(
            'hourselector',
            array(
                'type' => 'time',
                'required' => true,
                'class' => array('form-row-last'),
                'label' => 'Reservation hour'
            ),
            $checkout->get_value( 'hourselector' )
        );
    }
  
    #
    public function send_order_status_change_email( $order_id )
    {
        #
        $order = wc_get_order( $order_id );
        //$order->update_status( '' );
        #
    }
}

$checkout = new CustomCheckout();

字符串

nkkqxpd9

nkkqxpd91#

**1.**Hook到woocommerce_thankyou动作:

此操作在成功下订单时触发,非常适合处理状态更改和电子邮件通知等订单后任务。

**2.**修改您的send_order_status_change_email方法:

public function send_order_status_change_email( $order_id ) {
    $order = wc_get_order( $order_id );

    // Get the selected email address from the custom field
    $selected_email = $order->get_meta( 'pdvselector' );

    // Change the order status to completed
    $order->update_status( 'completed' );

    // Send the email notification to the selected address
    WC()->mailer()->send( 'customer_completed_order', $order_id, $selected_email );
}

字符串

**3.**在CustomCheckout构造函数中添加action hook:

public function __construct() {

    //add this line
    add_action( 'woocommerce_thankyou', array( $this, 'send_order_status_change_email' ), 10, 1 );
}


当客户下订单时,会触发send_order_status_change_email方法,从pdvselector自定义字段中检索所选邮箱地址,订单状态更新为“completed",并将“customer_completed_order”邮件模板发送到所选邮箱地址,通知其预订。

编辑1

您可以通过使用不同的钩子并对代码进行一些调整来避免发送两封电子邮件。

**1.**勾入woocommerce_order_status_changed

不使用woocommerce_thankyou,而是利用woocommerce_order_status_changed操作。每当订单状态更改时,此操作就会触发,从而允许您捕获完成时刻,而无需依赖于结帐页面完成。

**2.**优化send_order_status_change_email方法:

修改您现有的方法,以便在发送电子邮件之前检查新订单的状态。

public function send_order_status_change_email( $order_id, $old_status, $new_status ) {
    if ( $new_status !== 'completed' ) {
        return; // Do not send email if not completed
    }

    $order = wc_get_order( $order_id );

    // ... Get selected email and send email logic ...

}

**3.**注册action hook:

更新构造函数的代码,用更新后的方法注册钩子:

public function __construct() {
    //add this line
    add_action( 'woocommerce_order_status_changed', array( $this, 'send_order_status_change_email' ), 10, 3 );
}


这样,只有当订单状态变为“完成”时,电子邮件才会发送,有效防止重复电子邮件,并确认订单成功完成到所选电子邮件地址。

dxpyg8gm

dxpyg8gm2#

要使用的正确挂钩不是woocommerce_thankyou,而是woocommerce_new_order,以避免多个电子邮件通知。
对于电子邮件调试,您可以使用WP邮件捕手插件.
在下面的代码中,我添加了一些函数来验证和保存自定义结帐字段值.

class CustomCheckout {        
    
    #
    public function __construct()
    {
        # 
        add_action( 'woocommerce_checkout_fields', array( $this, 'remove_default_checkout_fields') );
        # 
        add_action( 'woocommerce_after_checkout_billing_form', array( $this, 'add_custom_checkout_fields') );
        # 
        add_filter( 'woocommerce_cart_needs_payment', '__return_false' );
        # 
        add_action( 'woocommerce_after_checkout_validation', array( $this, 'custom_checkout_fields_validation'), 10, 2 );
        # 
        add_action( 'woocommerce_checkout_create_order', array( $this, 'save_order_meta_checkout_fields_values'), 10, 2 );
        # 
        add_action( 'woocommerce_checkout_update_customer', array( $this, 'save_customer_meta_checkout_field_value'), 10, 2 );

        add_action( 'woocommerce_new_order', array( $this, 'auto_complete_new_order'), 10, 2 );

        add_filter( 'woocommerce_email_headers', array( $this, 'additional_cc_recipient'), 10, 3 );
    }
        
    #
    public function remove_default_checkout_fields( $fields )
    {
        //unset( $fields['billing']['first_name'] );
        //unset( $fields['billing']['last_name'] );
        unset( $fields['billing']['billing_company'] );
        unset( $fields['billing']['billing_country'] );
        unset( $fields['billing']['billing_address_1'] );
        unset( $fields['billing']['billing_address_2'] );
        unset( $fields['billing']['billing_city'] );
        unset( $fields['billing']['billing_state'] );
        unset( $fields['billing']['billing_postcode'] );
        # Rimuovo campi spedizione
        unset( $fields['shipping']['shipping_first_name'] );
        unset( $fields['shipping']['shipping_last_name'] );
        unset( $fields['shipping']['shipping_company'] );
        unset( $fields['shipping']['shipping_country'] );
        unset( $fields['shipping']['shipping_address_1'] );
        unset( $fields['shipping']['shipping_addredd_2'] );
        unset( $fields['shipping']['shipping_city'] );
        unset( $fields['shipping']['shipping_state'] );
        unset( $fields['shipping']['shipping_postcode'] );
        #
        return $fields;
    }
    
    #
    public function add_custom_checkout_fields( $checkout )
    {
        # 
        woocommerce_form_field( 'withdrawal_point', array(
            'type' => 'select',
            'required' => true,
            'class' => array('form-row-first'),
            'label' => __('Withdrawal point', 'woocommerce'),
            'options' => array(
                ''                 => __('Select a store', 'woocommerce'),
                '[email protected]' => __('Store one', 'woocommerce'),
                '[email protected]' => __('Store two', 'woocommerce'),
                '[email protected]' => __('Store three', 'woocommerce'),
            ) 
        ), $checkout->get_value( 'withdrawal_point' ) );

        #
        woocommerce_form_field( 'booking_day', array(
            'type' => 'date',
            'required' => true,
            'class' => array('form-row-last'),
            'label' => 'Booking day'
        ), $checkout->get_value('booking_day') );
    
        #
        woocommerce_form_field( 'booking_hour', array(
            'type' => 'time',
            'required' => true,
            'class' => array('form-row-last'),
            'label' => 'Booking hour'
        ), $checkout->get_value('booking_hour') );
    }

    # Save custom checkout fields values as customer metadata
    public function custom_checkout_fields_validation( $data, $errors ) {
        if ( isset($_POST['withdrawal_point']) && empty($_POST['withdrawal_point']) ) {
            $errors->add( 'pos_error', __( '<strong>Withdrawal point</strong> is a required field.', 'woocommerce' ), 'error' );
        }
        if ( isset($_POST['booking_day']) && empty($_POST['booking_day']) ) {
            $errors->add( 'pos_error', __( '<strong>Booking day</strong> is a required field.', 'woocommerce' ), 'error' );
        }
        if ( isset($_POST['booking_hour']) && empty($_POST['booking_hour']) ) {
            $errors->add( 'pos_error', __( '<strong>Booking hour</strong> is a required field.', 'woocommerce' ), 'error' );
        }
    }

    # Save custom checkout fields values as order metadata
    public function save_order_meta_checkout_fields_values( $order, $data ) {
        if ( isset($_POST['withdrawal_point']) && ! empty($_POST['withdrawal_point']) ) {
            $order->update_meta_data('withdrawal_point', sanitize_email($_POST['withdrawal_point']));
        }
        if ( isset($_POST['booking_day']) && ! empty($_POST['booking_day']) ) {
            $order->update_meta_data('booking_day', esc_attr($_POST['booking_day']));
        }
        if ( isset($_POST['booking_hour']) && ! empty($_POST['booking_hour']) ) {
            $order->update_meta_data('booking_hour', esc_attr($_POST['booking_hour']));
        }
    }

    # Save custom checkout fields values as customer metadata
    public function save_customer_meta_checkout_field_value( $customer, $data ) {
        if ( isset($_POST['withdrawal_point']) && ! empty($_POST['withdrawal_point']) ) {
            $customer->update_meta_data('withdrawal_point', sanitize_email($_POST['withdrawal_point']));
        }
    }

    # Change order status, send new order email to admin and selected store
    # Send email customer completed order email to customer
    public function auto_complete_new_order( $order_id, $order ) {
        $order->update_status('wc-completed');
    }

    # Add selected store as CC recipient to "new order email"
    public function additional_cc_recipient( $headers, $email_id, $order ) {
        if ( $email_id === 'new_order' && ( $pos_email = $order->get_meta('withdrawal_point') ) ) {
            $headers .= "Cc: " . $pos_email . "\r\n";
        }
        return $headers;
    }
}

$checkout = new CustomCheckout();

字符串
代码放在你的子主题的functions.php文件中(或插件中)。测试和工作。

相关问题