首页 > 解决方案 > WooCommerce:在帐单中设置默认国家/地区(使用地理位置),但不在结帐页面的运输中

问题描述

我目前使用下面的代码来设置默认国家(基于用户当前的地理位置)。

function custom_update_allowed_countries( $countries ) {

    // Only on frontend
    if( is_admin() ) return $countries;

    if( class_exists( 'WC_Geolocation' ) ) {
        $location = WC_Geolocation::geolocate_ip();

        if ( isset( $location['country'] ) ) {
            $countryCode = $location['country'];
        } else {
            // If there is no country, then return allowed countries
            return $countries;
        }
    } else {
        // If you can't geolocate user country by IP, then return allowed countries
        return $countries;
    }

    // If everything went ok then I filter user country in the allowed countries array
    $user_country_code_array = array( $countryCode );

    $intersect_countries = array_intersect_key( $countries, array_flip( $user_country_code_array ) );

    return $intersect_countries;
}
add_filter( 'woocommerce_countries_allowed_countries', 'custom_update_allowed_countries', 30, 1 );

上述代码不仅影响计费部分,还影响运输部分。在这种情况下,美国用户只能运送到美国;来自加拿大的用户只能运送到加拿大等等。

如果有一种方式,它仍然会在账单上默认为 Goelocated 国家,但用户可以运送到其他国家?

标签: phpajaxwordpresswoocommerce

解决方案


我检查了每个钩子/过滤器,没有发现任何有用的东西。所以我想出了这个解决方案。将此代码添加到您的子主题functions.php文件中:

add_action( 'wp_enqueue_scripts', 'wp_enqueue_scripts_action' );
function wp_enqueue_scripts_action() {
    wp_register_script( 'test-script', get_stylesheet_directory_uri() . '/test.js', [ 'jquery', ] );
    wp_enqueue_script( 'test-script' );

    wp_localize_script( 'test-script', 'test_script', [
            'customer_country' => get_customer_geo_location_country()
        ]
    );
}

/**
 * Returns the customer country
 *
 * @return string|null
 */
function get_customer_geo_location_country(): ?string {
    if ( class_exists( 'WC_Geolocation' ) ) {
        $location = WC_Geolocation::geolocate_ip();

        if ( isset( $location['country'] ) ) {
            return $location['country'];
        }
    }

    return null;
}

add_action( 'woocommerce_after_checkout_validation', 'woocommerce_after_checkout_validation_action', 10, 2 );
function woocommerce_after_checkout_validation_action( $fields, $errors ) {
    $billing_country = $fields['billing_country'];

    if ( ! empty( $billing_country ) && $billing_country !== get_customer_geo_location_country() ) {
        $errors->add( 'validation', 'You are not allowed to select this billing country!' );
    }
}

首先我们添加一个新脚本。如果您已经有一个脚本,您可以复制该wp_localize_script函数并更改处理程序和对象名称。

使用此函数,我们可以将客户的当前国家/地区传递给我们的 JavaScript 文件。在这个文件中,我们做了这些事情:

(function ( $ ) {
    $( document ).ready( function () {
        if (test_script.customer_country) {
            $( '#billing_country option' ).each( function () {
                if ($( this ).val() !== test_script.customer_country) {
                    $( this ).remove();
                }
            } );
        }
    } );
})( jQuery );

这个小功能会从我们的账单选择中删除与客户国家不匹配的每个国家。如果您愿意,您可以删除else声明中的所有国家/地区,以确保客户在没有可用国家/地区的情况下无法订购。

客户现在应该只能在帐单国家/地区下拉列表中看到他的本国。

为确保他不会入侵我们,我们在结帐时添加了一些验证,我们再次验证所选国家/地区。

如果您在 localhost 上进行测试,则没有可用的国家/地区,因此请确保它位于网络中的实时网站上(甚至是登台)。

这是一个基本的想法。您需要对其进行测试,并可能根据需要对其进行调整。


推荐阅读