将其他帐单注册字段与 WooCommerce 中的默认 Wordpress 字段同步

Posted

技术标签:

【中文标题】将其他帐单注册字段与 WooCommerce 中的默认 Wordpress 字段同步【英文标题】:Sync additional Billing registration fields with default Wordpress fields in WooCommerce 【发布时间】:2018-04-26 16:52:18 【问题描述】:

我已将以下代码添加到 Woocommerce 用户注册表单中,以在注册页面上获取帐单详细信息。

现在当新用户注册时会发生什么,名字和姓氏将被注册到帐单详细信息数据库以及默认的 wordpress 用户帐户中。如果用户在他的帐户(wordpress 用户帐户)上更新他的名字和姓氏,也应该更新帐单详细信息。

Woocommerce 设置:

访客结帐已禁用。 结帐页面用户注册已启用。 登录页面注册已启用。 只有注册用户才能购买。

    这是我从结帐流程中提取这些额外帐单详细信息的用户注册表单。

    在“帐户详细信息”上,我更新了“名字”,它在这里工作,但我在“帐单详细信息”上没有得到相同的更新。如果用户在“帐户详细信息”中更新这 2 个字段和他的电子邮件地址,我希望在“帐单详细信息”上更新相同的“名字”和“姓氏”。

    现在更新“帐户详细信息”上的“名字”和“姓氏”后,我回到了“帐单详细信息”,但它仍然显示旧的“名字”和“姓氏”,它们在注册过程。另外,我想从帐单详细信息中隐藏这 3 个字段,“名字”、“姓氏”和“电子邮件地址”——以免混淆注册用户。我只需要数据库中“账单明细”的这些更新,因为这些信息将打印在发票和电子邮件中

只有当管理员或商店经理进入用户配置文件(从后端)并手动按下“更新”按钮时,数据才会同步/更新,然后才会生效。当注册用户从他的帐户(前端)进行任何更改时,我希望数据自动同步/更新。

我们将不胜感激。

请检查以下代码:

// 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】:

我重新审视了你的代码,例如最后的 4 个函数可以合并为一个,还有其他的……

数据更新和同步

现在,当客户在我的帐户页面上更新他的数据时,所有数据都由 woocommerce 同步,除了他现有的过去订单...

如果客户更改结帐字段并处理结帐,数据也会随处更新……

所以您无需担心客户同步数据。

注意: woocommerce_billing_fields 中挂钩的功能将在您的附加注册字段和结帐字段中启用,因为您正在使用结帐对象生成附加注册字段... 您可以使用条件 ! is_checkout() 仅定位我的帐户注册字段。

这是您重新访问的代码:

// 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;

客户无法(从不)访问 WordPress 后端用户编辑页面。只有店长和管理员才能做到…… 要在后端同步 Wordpress 用户数据,您需要选择哪些字段具有优先级:

Wordpress 默认字段(或) 账单字段(来自 WooCommerce)。

最好优先考虑 WordPress 默认字段并隐藏必要的计费字段...

此代码将隐藏 3 个结算字段(名字、姓氏和电子邮件)并将它们与默认字段更新值同步:

// 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'] ) );
    

代码进入您的活动子主题(或主题)的 function.php 文件或任何插件文件中。

经过测试并且可以工作……

【讨论】:

我试了你的代码,效果很好。我需要你的更多帮助。我已经编辑了这个问题。你能再检查一下并给出解决方案吗?谢谢 我在上面更新了我的问题。你能帮我看看吗?谢谢 @AdnanAli 这变得太复杂和模糊了......这意味着你正在混淆并且你对用户数据过于担心...... WooCommerce 是一个强大而稳定的系统,其中“客户数据是同步的。重要的是woocommerce 中的东西,是 woocommerce 始终使用的计费和运输信息。客户从不访问后端,也看不到 WP 用户编辑页面...... WooCommerce 很好地同步数据本身......所以你应该重新考虑你在这方面的位置... 通常开发人员不会在我的帐户客户页面中使用结帐表格。... / ... @AdnanAli (2) ...因此,您最好回到最初的问题...并提出一个新问题,完全重新考虑您的立场,因为您不会得到任何真正完整的答案,您的实际位置。正如众所周知的那样“思考不同”…… 该代码对我有用!但是...如果没有与国家/地区相关的州/省,如何根据国家/地区选择更新选择的州或将字段更改为文本框?

以上是关于将其他帐单注册字段与 WooCommerce 中的默认 Wordpress 字段同步的主要内容,如果未能解决你的问题,请参考以下文章

当用户选择贝宝付款方式时,在结帐表单中禁用 WooCommerce 中的帐单地址

在 WooCommerce 结帐时格式化帐单电话号码

Woocommerce 结帐页面先显示送货地址,然后显示帐单地址?

如何将自定义字段添加到 WooCommerce 注册表单

Woocommerce 和 PayPal 账单地址

当他们使用 WooCommerce 进行购买时,如何将客户帐单信息添加到 MailChimp 组