wordpress - WooCommerce - 为非注册用户获取发货国家
问题描述
大家早上好。如果运输目的地包含在特定的值数组中,我需要实施一种方法从总成本中减去运输成本。 这不是免费送货的情况,因为稍后会出于其他原因添加此费用。
我不能根据用户所在国家/地区做出决定,原因有两个:
- 用户不能注册
- 用户国和发货国可以不同。
我看到 WooCommerce 在我更改帐单/发货国家/地区时重新加载订单总数。我相信我需要拦截这种更改并触发插入新购物车费用的操作(当然是负费用)。
好吧,我该怎么做?
这是我的代码的一部分
function delayShippingCosts(){
global $woocommerce;
$EUcountries = ['IT','AT','BE','BG','CY','HR','DK','EE','FI','FR','DE','GR','IE','LV','LT','LU','MT','NE','PL','PT','CZ','RO','SK','SI','ES','SE','HU'];
return in_array( $woocommerce->customer->get_country() , $EUcountries);
}
add_action( 'woocommerce_cart_calculate_fees', 'scc_detract_shipping_costs' );
function scc_detract_shipping_costs(){
global $woocommerce;
if(delayShippingCosts()){
$shippingCosts = WC()->cart->get_shipping_total() * -1;
if(current_user_can('administrator')) {
$woocommerce->cart->add_fee( 'Delayed shipping costs', $shippingCosts, true, 'standard' );
}
}
}
问题是现在我正在查看我的客户数据,这些数据不是动态的(对于未注册/未登录的用户无效)。
有什么建议么?谢谢!!
编辑
几乎可以
我设法从“woocommerce_checkout_update_order_review”钩子中检索了发货国家,如下所示:
function action_woocommerce_checkout_update_order_review($posted_data) {
global $shipTo;
$data = array();
$vars = explode('&', $posted_data);
foreach ($vars as $k => $value){
$v = explode('=', urldecode($value));
$data[$v[0]] = $v[1];
}
WC()->cart->calculate_shipping();
$shipTo = $data['shipping_country'] ? $data['shipping_country'] : $data['billing_country'];
// REMOVE ALL NOTICES, IF PRESENTS...
wc_clear_notices();
}
add_action('woocommerce_checkout_update_order_review', 'action_woocommerce_checkout_update_order_review', 10, 1);
add_action( 'woocommerce_cart_calculate_fees', 'scc_detract_shipping_costs' );
function scc_detract_shipping_costs(){
global $woocommerce;
... something ...
if(condition) {
wc_add_notice("info message", "error");
}
}
我的问题是,当“条件”为假时,通知不会被删除。我尝试在 woocommerce_cart_calculate_fees 和 woocommerce_checkout_update_order_review 中调用 wc_remove_notices()。差别不大!:(
有什么提示吗?
解决方案
delayShippingCosts()
不需要该功能。您可以通过类的get_european_union_countries
方法获取欧洲国家的列表(除非您想自定义列表)。WC_Countries
此外,您还通过课程的get_country()
方法获得了国家WC_Customer
。
WC_Customer::get_country 函数自 3.0 版起已弃用。
你可以像这样得到国家:
WC()->customer->get_shipping_country()
收货地址所在的国家WC()->customer->get_billing_country()
账单地址所在的国家
最后,请注意,要为费用应用标准税级,您必须将第 4 个参数设置为空字符串,而不是'standard'
. 请参阅此处了解更多信息。
从未使用Hook登录的用户那里获取国家/地区字段woocommerce_cart_calculate_fees
当结帐中的相应字段发生变化时,您可以发送 AJAX 调用以发送帐单和发货国家/地区值。
为了确保 AJAX 函数在woocommerce_cart_calculate_fees
钩子之前执行,有必要update_totals_on_change
从帐单和运输国家字段中删除类(以避免进行 AJAX 调用以更新结帐)并仅在调用 AJAX 后更新结帐完全的。
此方法可能需要几毫秒/秒的额外时间来更新结帐,因为您必须等待 AJAX 调用才能完成创建选项。
有关如何在 Wordpress 中提交 AJAX 调用的更多详细信息,请参阅此答案。
在活动主题的 functions.php 中添加以下代码:
// enqueue the script for the AJAX call
add_action('wp_enqueue_scripts', 'add_js_scripts');
function add_js_scripts(){
wp_enqueue_script( 'ajax-script', get_stylesheet_directory_uri().'/js/script.js', array('jquery'), '1.0', true );
wp_localize_script( 'ajax-script', 'ajax_object', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );
}
// update options with checkout country values
add_action( 'wp_ajax_nopriv_set_option_country', 'set_option_country' );
add_action( 'wp_ajax_set_option_country', 'set_option_country' );
function set_option_country() {
if ( isset( $_POST ) ) {
// get the countries valued in the checkout by the user (guest or logged in)
$countries = $_POST['countries'];
$billing_country = $countries['billing_country'];
$shipping_country = $countries['shipping_country'];
// update options
update_option( 'guest_billing_country', $billing_country );
update_option( 'guest_shipping_country', $shipping_country );
// returns the output as a response to the AJAX call
echo 'success';
}
// always die in functions echoing AJAX content
die();
}
创建一个script.js
文件并将其添加到目录中的子主题中(因为我使用get_stylesheet_directory_uri()
而不是get_template_directory_uri()
)/child-theme/js/script.js
::
jQuery(function($){
// disable AJAX update
$('#billing_country_field').removeClass('update_totals_on_change');
$('#shipping_country_field').removeClass('update_totals_on_change');
// when the country fields change
$('#billing_country, #shipping_country').change(function(){
var countries = {
'billing_country': $('#billing_country').val(),
'shipping_country': $('#shipping_country').val(),
};
$.ajax({
url: ajax_object.ajaxurl,
type : 'post',
data: {
'action': 'set_option_country',
'countries': countries
},
complete: function(){
// update checkout via AJAX
$(document.body).trigger('update_checkout');
},
success:function(data) {
console.log(data);
},
error: function(errorThrown){
console.log(errorThrown);
}
});
});
});
该代码已经过测试并且可以工作。
因此,正确的scc_detract_shipping_costs
功能将是:
add_action( 'woocommerce_cart_calculate_fees', 'scc_detract_shipping_costs' );
function scc_detract_shipping_costs(){
$countries = new WC_Countries();
// get the list of countries of the european union
$eu_countries = $countries->get_european_union_countries();
// get countries from checkout
$billing_country = get_option( 'guest_billing_country' );
$shipping_country = get_option( 'guest_shipping_country' );
// if the shipping country is part of the European Union
if ( in_array( $shipping_country, $eu_countries ) ) {
$shippingCosts = WC()->cart->get_shipping_total() * -1;
if ( current_user_can('administrator') ) {
WC()->cart->add_fee( 'Delayed shipping costs', $shippingCosts, true, '' );
}
}
}
该代码已经过测试并且可以工作。将它添加到您的活动主题的functions.php。
从未使用Hook登录的用户那里获取国家/地区字段woocommerce_calculate_totals
add_action( 'woocommerce_calculate_totals', 'get_post_checkout_data' );
function get_post_checkout_data( $cart ) {
// get post data
if ( isset( $_POST['post_data'] ) ) {
parse_str( $_POST['post_data'], $post_data );
} else {
$post_data = $_POST;
}
if ( ! empty( $post_data ) ) {
$billing_country = $post_data['billing_country'];
$shipping_country = $post_data['shipping_country'];
// ...
}
}
在活动主题的functions.php 中添加代码。
推荐阅读
- python - 如何在 Python 代码中使用记录器级别状态
- java - 无法使用 setIconImage() 方法为 Java 应用程序设置图标
- php - 部分变量保存到另一个变量
- javascript - Vue.js 将事件绑定到 SVG 图像元素
- javascript - 更改最外面的 svg 大小,但保留该 svg 内所有内容的大小
- python - 删除熊猫中的列的最佳方法是什么
- linux - 在 linux compile 中错过 asm/types.h
- date - CakePHP 3 日期格式问题
- javascript - 如何在Javascript中旋转图像?
- amazon-web-services - AWS lambda Step Functions 活动和 RDS