dongyuan9892 2017-11-13 21:35
浏览 90
已采纳

使用WooCommerce中的默认Wordpress字段同步其他结算注册字段

I Have added the below codes into Woocommerce user registration form to get the Billing Details on the registration page.

Now what is happening when a new user register, the first and last name will get registered in the database of billing details & as well as in the default wordpress user account. If the user update his first name & last name on his account (wordpress user account), the same should update on the billing details.

Woocommerce settings:

Guest checkout is disabled. Checkout page user registration is enabled. Login Page Registration is enabled. Only Registered user can make purchases.

  1. This is the user registration form where I'm pulling these additional billing details from checkout process.

User Registration Form

  1. On "Account Details" I updated the "First Name", it worked here but i didn't get the same update on "Billing Details". I want the same "First Name" & "Last Name" update on the "Billing Details" if a user update these 2 fields and his email address on his "Account Details".

Updates "First Name" & "Last Name" on "Account Details

  1. Now after updating the "First Name" & "Last Name" on "Account Details", I came back to "Billing Details" but it is still displaying the old "First Name" & "Last Name" which were used during registeration process. Also, I want to hide these 3 fields from Billing details, "First Name", "Last Name" & "Email Address"- to not to confuse the registered users. I need these updates on "Billing Details" in database only because these information will be printed on the invoices & Emails

Scrrenshot of "Billing Details" After Updates on "Account Details"

The data will only sync/update if an administrator or store manager go to the user profile (from back-end) and manually press the "update" button then only it will take the effects. I want the data to sync/update automatically when a registered user made any changes from his account (front-end).

Any help will be highly appreciated.

Please check the below code:

// Custom function to display the Billing Address form to registration page
add_action('woocommerce_register_form_start','zk_add_billing_form_to_registration');
function zk_add_billing_form_to_registration(){
    $checkout = WC()->checkout;
    foreach ( $checkout->get_checkout_fields( 'billing' ) as $key => $field ) :
        if($key!='billing_email')
            woocommerce_form_field( $key, $field, $checkout->get_value( $key ) );
    endforeach;
}

// Custom function to save Usermeta or Billing Address of registered user
add_action('woocommerce_created_customer','zk_save_billing_address');
function zk_save_billing_address($user_id){
    $address = $_POST;
    foreach ($address as $key => $field){
        // Only billing fields values
        if( strpos( $key, 'billing_' ) !== false ){
            // Condition to add firstname and last name to user meta table
            if($key == 'billing_first_name' || $key == 'billing_last_name'){
                $new_key = str_replace( 'billing_', '', $key );
                update_user_meta( $user_id, $new_key, $_POST[$key] );
            }
            update_user_meta( $user_id, $key, $_POST[$key] );
        }
    }
}

// Checking & validation of the additional fields in registration form.
add_action('woocommerce_register_post','zk_validation_billing_address', 10, 3 );
function zk_validation_billing_address( $username, $email, $validation_errors ){
    foreach ($_POST as $key => $field) :
        // Validation: Required fields
        if( strpos( $key, 'billing_' ) !== false ){
            if($key == 'billing_country' && empty($field) ){
                $validation_errors->add( $key.'_error',  __( 'Please select a country.', 'woocommerce' ));
            }
            if($key == 'billing_first_name' && empty($field) ){
                $validation_errors->add( $key.'_error', __( 'Please enter first name.', 'woocommerce' ) );
            }
            if($key == 'billing_last_name' && empty($field) ){
                $validation_errors->add( $key.'_error', __( 'Please enter last name.', 'woocommerce' ) );
            }
            if($key == 'billing_address_1' && empty($field) ){
                $validation_errors->add( $key.'_error', __( 'Please enter address.', 'woocommerce' ) );
            }
            if($key == 'billing_city' && empty($field) ){
                $validation_errors->add( $key.'_error', __( 'Please enter city.', 'woocommerce' ) );
            }
            if($key == 'billing_state' && empty($field) ){
                if(count( WC()->countries->get_states($_POST['billing_country']) ) > 0)
                    $validation_errors->add( $key.'_error', __( 'Please enter state.', 'woocommerce' ) );
            }
            if($key == 'billing_postcode' && empty($field) ){
                $validation_errors->add( $key.'_error', __( 'Please enter a postcode.', 'woocommerce' ) );
            }
            /*
            if($key == 'billing_email' && empty($field) ){
                $validation_errors->add( $key.'_error', __( 'Please enter billing email address.', 'woocommerce' ) );
            }
            */
            if($key == 'billing_phone' && empty($field) ){
                $validation_errors->add( $key.'_error', __( 'Please enter phone number.', 'woocommerce' ) );
            }

        }
    endforeach;
}

add_filter( 'woocommerce_billing_fields', 'sv_required_billing_fields' );
function sv_required_billing_fields( $fields ) {
    $fields['billing_phone']['required'] = true;
    $fields['billing_city']['required'] = true;
    $fields['billing_country']['required'] = true;
    $fields['billing_address_1']['required'] = true;
    return $fields;
}

// Hidding some billing fields (Wordpress edit user pages)
add_action( 'edit_user_profile', 'user_profile_hide_some_fields_css', 1, 1 );
function user_profile_hide_some_fields_css( $user ){
    ?>
    <style>
    .user-edit-php table#fieldset-billing tr:first-child,
    .user-edit-php table#fieldset-billing tr:nth-child(2),
    .user-edit-php table#fieldset-billing tr:last-child {
        display:none;
    }
    </style>
    <?php
}

// Sync hidden billing fields (Wordpress edit user pages)
add_action( 'personal_options_update', 'sync_user_data_wp_and_billing_wc', 100, 1 );
add_action( 'edit_user_profile_update', 'sync_user_data_wp_and_billing_wc', 100, 1 );
function sync_user_data_wp_and_billing_wc( $user_id )
{
    if( ! empty($_POST['first_name']) ) {
        update_user_meta( $user_id, 'billing_first_name', sanitize_text_field( $_POST['first_name'] ) );
    }

    if( ! empty($_POST['last_name']) ) {
        update_user_meta( $user_id, 'billing_last_name', sanitize_text_field( $_POST['last_name'] ) );
    }

    if( ! empty($_POST['email']) ) {
        update_user_meta( $user_id, 'billing_email', sanitize_text_field( $_POST['email'] ), sanitize_text_field( $_POST['billing_email'] ) );
    }
}
  • 写回答

1条回答 默认 最新

  • duanlun1955 2017-11-13 23:42
    关注

    I have revisited your code a bit, as for example the 4 last functions can be merged in one, and other things…

    Data update and sync

    Now when a customer updates his data on his my account pages, all data is synched by woocommerce everywhere, except on his existing past Orders

    If a customer change checkout fields and process checkout, the data is also updated everywhere…

    So you don't need to worry about customer synched data.

    Note: The function hooked in woocommerce_billing_fields will be enabled either in your additional registration fields and in checkout fields, as you are using checkout object to generate additional registration fields… You can use the conditional ! is_checkout() to only target my account registration fields.

    Here is your revisited code:

    // Custom function to display the Billing Address form to registration page
    add_action('woocommerce_register_form_start','zk_add_billing_form_to_registration');
    function zk_add_billing_form_to_registration(){
        $checkout = WC()->checkout;
        foreach ( $checkout->get_checkout_fields( 'billing' ) as $key => $field ) :
            if($key!='billing_email')
                woocommerce_form_field( $key, $field, $checkout->get_value( $key ) );
        endforeach;
    }
    
    // Custom function to save Usermeta or Billing Address of registered user
    add_action('woocommerce_created_customer','zk_save_billing_address');
    function zk_save_billing_address($user_id){
        $address = $_POST;
        foreach ($address as $key => $field){
            // Only billing fields values
            if( strpos( $key, 'billing_' ) !== false ){
                // Condition to add firstname and last name to user meta table
                if($key == 'billing_first_name' || $key == 'billing_last_name'){
                    $new_key = str_replace( 'billing_', '', $key );
                    update_user_meta( $user_id, $new_key, $_POST[$key] );
                }
                update_user_meta( $user_id, $key, $_POST[$key] );
            }
        }
    }
    
    // Checking & validation of the additional fields in registration form.
    add_action('woocommerce_register_post','zk_validation_billing_address', 10, 3 );
    function zk_validation_billing_address( $username, $email, $validation_errors ){
        foreach ($_POST as $key => $field) :
            // Validation: Required fields
            if( strpos( $key, 'billing_' ) !== false ){
                if($key == 'billing_country' && empty($field) ){
                    $validation_errors->add( $key.'_error',  __( 'Please select a country.', 'woocommerce' ));
                }
                if($key == 'billing_first_name' && empty($field) ){
                    $validation_errors->add( $key.'_error', __( 'Please enter first name.', 'woocommerce' ) );
                }
                if($key == 'billing_last_name' && empty($field) ){
                    $validation_errors->add( $key.'_error', __( 'Please enter last name.', 'woocommerce' ) );
                }
                if($key == 'billing_address_1' && empty($field) ){
                    $validation_errors->add( $key.'_error', __( 'Please enter address.', 'woocommerce' ) );
                }
                if($key == 'billing_city' && empty($field) ){
                    $validation_errors->add( $key.'_error', __( 'Please enter city.', 'woocommerce' ) );
                }
                if($key == 'billing_state' && empty($field) ){
                    if(count( WC()->countries->get_states($_POST['billing_country']) ) > 0)
                        $validation_errors->add( $key.'_error', __( 'Please enter state.', 'woocommerce' ) );
                }
                if($key == 'billing_postcode' && empty($field) ){
                    $validation_errors->add( $key.'_error', __( 'Please enter a postcode.', 'woocommerce' ) );
                }
                /*
                if($key == 'billing_email' && empty($field) ){
                    $validation_errors->add( $key.'_error', __( 'Please enter billing email address.', 'woocommerce' ) );
                }
                */
                if($key == 'billing_phone' && empty($field) ){
                    $validation_errors->add( $key.'_error', __( 'Please enter phone number.', 'woocommerce' ) );
                }
    
            }
        endforeach;
    }
    
    add_filter( 'woocommerce_billing_fields', 'sv_required_billing_fields' );
    function sv_required_billing_fields( $fields ) {
        $fields['billing_phone']['required'] = true;
        $fields['billing_city']['required'] = true;
        $fields['billing_country']['required'] = true;
        $fields['billing_address_1']['required'] = true;
        return $fields;
    }
    

    The customer can't access (never) to WordPress backend User edit pages. Only shop Manager and administrators can do it…
    To sync Wordpress user data in backend you need to choose which fields will have the priority:

    • the Wordpress default fields (or)
    • the billing fields (from WooCommerce).

    Is better to give the priority to WordPress default fields and hide necessary billing fields…

    This code will hide the 3 billing fields (first name, last name and email) and will sync them with default fields updated values:

    // Hidding some billing fields (Wordpress edit user pages)
    add_action( 'edit_user_profile', 'user_profile_hide_some_fields_css', 1, 1 );
    function user_profile_hide_some_fields_css( $user ){
        ?>
        <style>
        .user-edit-php table#fieldset-billing tr:first-child,
        .user-edit-php table#fieldset-billing tr:nth-child(2),
        .user-edit-php table#fieldset-billing tr:last-child {
            display:none;
        }
        </style>
        <?php
    }
    
    // Sync hidden billing fields (Wordpress edit user pages)
    add_action( 'personal_options_update', 'sync_user_data_wp_and_billing_wc', 100, 1 );
    add_action( 'edit_user_profile_update', 'sync_user_data_wp_and_billing_wc', 100, 1 );
    function sync_user_data_wp_and_billing_wc( $user_id )
    {
        if( ! empty($_POST['first_name']) ) {
            update_user_meta( $user_id, 'billing_first_name', sanitize_text_field( $_POST['first_name'] ) );
        }
    
        if( ! empty($_POST['last_name']) ) {
            update_user_meta( $user_id, 'billing_last_name', sanitize_text_field( $_POST['last_name'] ) );
        }
    
        if( ! empty($_POST['email']) ) {
            update_user_meta( $user_id, 'billing_email', sanitize_text_field( $_POST['email'] ), sanitize_text_field( $_POST['billing_email'] ) );
        }
    }
    

    Code goes in function.php file of your active child theme (or theme) or also in any plugin file.

    Tested and works…

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥50 如何用脚本实现输入法的热键设置
  • ¥20 我想使用一些网络协议或者部分协议也行,主要想实现类似于traceroute的一定步长内的路由拓扑功能
  • ¥30 深度学习,前后端连接
  • ¥15 孟德尔随机化结果不一致
  • ¥15 apm2.8飞控罗盘bad health,加速度计校准失败
  • ¥15 求解O-S方程的特征值问题给出边界层布拉休斯平行流的中性曲线
  • ¥15 谁有desed数据集呀
  • ¥20 手写数字识别运行c仿真时,程序报错错误代码sim211-100
  • ¥15 关于#hadoop#的问题
  • ¥15 (标签-Python|关键词-socket)