php - 在 Woocommerce 结帐中启用特定状态的交货时间选项

标签 php jquery wordpress woocommerce checkout

基于“Add a custom checkbox in WooCommerce checkout which value shows in admin edit order ”,我尝试仅当客户状态为纽约时显示自定义单选按钮字段,以便客户在结帐页面中选择交货时间通过选择交货时间选项。然后管理员可以在管理员订单编辑页面中看到所选的交货时间。

这张图片将解释一切:

enter image description here

这是我的代码尝试(带有一个用于测试的复选框):

$user_state = get_user_meta( get_current_user_id(), 'billing_state')
if($user_state=='NY'){
add_action( 'woocommerce_review_order_before_submit', 'my_custom_checkout_field' );
function my_custom_checkout_field() {
    echo '<div id="my_custom_checkout_field">';

    woocommerce_form_field( 'my_field_name', array(
        'type'      => 'checkbox',
        'class'     => array('input-checkbox'),
        'label'     => __('My custom checkbox'),
        'required'
    ),  WC()->checkout->get_value( 'my_field_name' ) );
    echo '</div>';
}

// Save the custom checkout field in the order meta, when checkbox has been checked
add_action( 'woocommerce_checkout_update_order_meta', 'custom_checkout_field_update_order_meta', 10, 1 );
function custom_checkout_field_update_order_meta( $order_id ) {
    if ( ! empty( $_POST['my_field_name'] ) )
            update_post_meta( $order_id, 'my_field_name', $_POST['my_field_name'] );
}

// Display the custom field result on the order edit page (backend) when checkbox has been checked
add_action( 'woocommerce_admin_order_data_after_billing_address', 'display_custom_field_on_order_edit_pages', 10, 1 );
function display_custom_field_on_order_edit_pages( $order ){
    $my_field_name = get_post_meta( $order->get_id(), 'my_field_name', true );
    if( $my_field_name == 1 )
        echo '<p><strong>My custom field: </strong> <span style="color:red;">Is enabled</span></p>';
}}

但不显示自定义字段值。如有任何帮助,我们将不胜感激。

最佳答案

首先,您需要在结账页面上显示自定义单选按钮的函数内包含您的州情(纽约):

if( WC()->customer->get_shipping_state() == 'NY' ) {
    // Do something for customers from "New York"
} 

为了实现这一点,需要 Ajax 和 WC_Session,因为结帐页面是 Ajax 刷新的,并且不会保留客户的选择。

所以我重新审视了您现有的所有代码:

// Custom setting function: Here define your delivery options for "New york"
function get_newyork_delivery_options(){
    return array(
        '9am-2pm'   => __('9 AM - 2 PM'),
        '2pm-6pm'   => __('2 PM - 6 PM'),
        '6pm-9pm'   => __('6 PM - 9 PM'),
    );
}

// Display delivery custom radio buttons field in checkout for "New york" state
add_action( 'woocommerce_review_order_after_shipping', 'display_delivery_choice_field', 20 );
function display_delivery_choice_field(){
    // Only for "New York" state
    if( WC()->customer->get_shipping_state() == 'NY' ) :

    $choice  = WC()->session->get('delivery_choice');

    // Display the radio buttons
    echo '<tr class="delivery-options">
    <th>' . __("Delivery time") . '<br><em>(' . __("for New York") . ')</em></th>
    <td><span class="woocommerce-input-wrapper">';

    foreach ( get_newyork_delivery_options() as $key => $label ) {
        $checked  = $choice == $key ? 'checked="checked"' : '';
        $field_id = 'delivery_time' . $key;

        echo '<label for="' . $field_id . '" class="radio " style="display:block">
        <input type="radio" class="input-radio " id="' . $field_id . '" name="delivery_time" value="' . $key . '" ' . $checked . '> ' . $label;
        echo '</label>';
    }
    echo '</span></td>
    <tr>';

    endif;
}

// jQuery - Ajax script
add_action( 'wp_footer', 'checkout_delivery_script' );
function checkout_delivery_script() {
    // Only on Checkout
    if( is_checkout() && ! is_wc_endpoint_url() ) :

    if( WC()->session->__isset('delivery_choice') )
        WC()->session->__unset('delivery_choice')
    ?>
    <script type="text/javascript">
    jQuery( function($){
        if (typeof wc_checkout_params === 'undefined')
            return false;

        $('form.checkout').on('change', 'input[name="delivery_time"]', function(){
            var delivery = $(this).val();

            $.ajax({
                type: 'POST',
                url: wc_checkout_params.ajax_url,
                data: {
                    'action': 'delivery_choice',
                    'delivery_choice': delivery,
                },
                success: function (result) {
                    $('body').trigger('update_checkout');
                },
            });
        });
    });
    </script>
    <?php
    endif;
}

// Get Ajax request and saving to WC session
add_action( 'wp_ajax_delivery_choice', 'get_delivery_choice' );
add_action( 'wp_ajax_nopriv_delivery_choice', 'get_delivery_choice' );
function get_delivery_choice() {
    if ( isset($_POST['delivery_choice']) ) {
        WC()->session->set('delivery_choice', esc_attr( $_POST['delivery_choice'] ) );
        echo WC()->session->get('delivery_choice');
    }
    die();
}

// Save the chosen delivery time as order meta data
add_action('woocommerce_checkout_create_order', 'custom_checkout_field_added_as_order_meta', 10, 2 );
function custom_checkout_field_added_as_order_meta( $order, $data ) {
    if ( isset( $_POST['delivery_option'] ) )
        $order->add_meta_data( '_delivery_time', esc_attr( $_POST['delivery_time'] ) );
}

// Display the chosen delivery time on order totals lines everywhere (except admin)
add_action('woocommerce_get_order_item_totals', 'display_bacs_option_on_order_totals', 10, 3 );
function display_bacs_option_on_order_totals( $total_rows, $order, $tax_display ) {
    if ( $delivery_time = $order->get_meta('_delivery_time') ) {
        $sorted_total_rows = [];

        foreach ( $total_rows as $key_row => $total_row ) {
            $sorted_total_rows[$key_row] = $total_row;
            if( $key_row === 'shipping' ) {
                $sorted_total_rows['delivery_time'] = [
                    'label' => __( "Delivery time", "woocommerce"),
                    'value' => esc_html( get_newyork_delivery_options()[$delivery_time] ),
                ];
            }
        }
        $total_rows = $sorted_total_rows;
    }
    return $total_rows;
}

// Display the chosen delivery option on admin order edit page for new york state
add_action( 'woocommerce_admin_order_data_after_shipping_address', 'display_custom_field_on_order_edit_pages', 10, 1 );
function display_custom_field_on_order_edit_pages( $order ){
    if( $key = $order->get_meta( '_delivery_time' ) ) {
        $label = get_newyork_delivery_options()[$key];
        echo '<p><strong>Delivery <em>(New York)</em>: </strong> <span style="color:green;">' . $label . '</span></p>';
    }
}

代码位于事件子主题(或事件主题)的 function.php 文件中。经过测试并有效。

enter image description here

enter image description here

关于php - 在 Woocommerce 结帐中启用特定状态的交货时间选项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57690187/

相关文章:

php - PHP Mail() 中的 Base 64 附件不起作用

php - 在 Woocommerce 3 中获取自定义订单项元数据

php - 解析两个词之间的文本

javascript - JS点击函数没有响应

php - 如何使用循环正则表达式和数组验证十六进制颜色?

html - 父 div 之外的扩展 div 内的内容未在移动设备中显示

php - CodeIgniter:$this->load->database() 出错;

jQuery 选择以特定开头的每个 id

javascript - 如何获取listview选定的id和href文本?

css - 如何将 CSS 添加到特定的 div 类 - WordPress