根据 WooCommerce 中的运输类别自定义计算的运输成本
Posted
技术标签:
【中文标题】根据 WooCommerce 中的运输类别自定义计算的运输成本【英文标题】:Custom calculated shipping costs based on shipping class in WooCommerce 【发布时间】:2019-04-01 16:08:58 【问题描述】:昨晚将 Woocommerce 更新到最新版本 3.5.7 后,如果在结帐页面上将国家/地区从美国切换到加拿大,则结帐会冻结。如果我们返回购物车页面,则会显示错误。错误详细信息在此问题的末尾。这可能是什么原因造成的?我还复制了下面导致此错误的代码。具体来说,$label = $method->get_label();
行,但我认为这没有任何问题。
我已经测试过的内容: 1- 我最初认为在运输标签上使用大括号会损坏,但这不是问题,已经在演示网站上进行了测试。 2- 仅当购物车中存在特定的运输方式时才会发生这种情况,其他运输方式不会发生,如下面的截屏视频突出显示的那样。
编辑#1:
我与 Woocommerce 支持人员进行了交谈,他们说我们使用的是旧模板版本,因此我们必须对其进行更新。我现在正在更新模板,但也怀疑这不会解决问题。有什么想法吗?
录屏:https://screencast-o-matic.com/watch/cqfVoTZckd
cart-shipping.php
中导致问题的代码:
foreach ( $available_methods as $method ) : ?>
<li>
<?php
$a = (int)$method->cost;
$b = $method->id;
$label = $method->get_label(); /* this line is causing the error but I don't see any issue with it */
if ($a === 0 && $b != "legacy_local_pickup"):
printf( '<input type="radio" name="shipping_method[%1$d]" data-index="%1$d" id="shipping_method_%1$d_%2$s" value="%3$s" class="shipping_method" %4$s />
<label for="shipping_method_%1$d_%2$s">Standard (Ships in 10-12 work days): <span class="woocommerce-Price-amount amount">Free</span></label>',
$index, sanitize_title( $method->id ), esc_attr( $method->id ), checked( $method->id, $chosen_method, false ) );
elseif ($b == "legacy_local_pickup"):
printf( '<input type="radio" name="shipping_method[%1$d]" data-index="%1$d" id="shipping_method_%1$d_%2$s" value="%3$s" class="shipping_method" %4$s />
<label for="shipping_method_%1$d_%2$s">%5$s</label>',
$index, sanitize_title( $method->id ), esc_attr( $method->id ), checked( $method->id, $chosen_method, false ), $label );
else:
printf( '<input type="radio" name="shipping_method[%1$d]" data-index="%1$d" id="shipping_method_%1$d_%2$s" value="%3$s" class="shipping_method" %4$s />
<label for="shipping_method_%1$d_%2$s">%5$s</label>',
$index, sanitize_title( $method->id ), esc_attr( $method->id ), checked( $method->id, $chosen_method, false ), wc_cart_totals_shipping_method_label( $method ) );
endif;
do_action( 'woocommerce_after_shipping_rate', $method, $index );
?>
</li>
<?php endforeach;
错误:
Fatal error: Uncaught Error: Call to undefined method stdClass::get_label() in .../themes/genesis-sample/woocommerce/cart/cart-shipping.php:35 Stack trace: #0 .../plugins/woocommerce/includes/wc-core-functions.php(211): include() #1 .../plugins/woocommerce/includes/wc-cart-functions.php(233): wc_get_template('cart/cart-shipp...', Array) #2 .../plugins/woocommerce/templates/cart/cart-totals.php(48): wc_cart_totals_shipping_html() #3 .../plugins/woocommerce/includes/wc-core-functions.php(211): include('...') #4 .../plugins/woocommerce/includes/wc-template-functions.php(1922): wc_get_template('cart/cart-total...') #5 .../wp-includes/class-wp-hook.php(286): woocommerce_cart_totals('') in .../themes/genesis-sample/woocommerce/cart/cart-shipping.php on line 35
编辑#2:
在临时站点上进行测试后,我找到了真正的原因。这是造成问题的一段代码。问题是,$method_id5
仅适用于美国而不适用于加拿大,因此当客户切换到加拿大时,这段代码会出错。对于加拿大,可用的送货方式是$method_id6 = 'flat_rate:6';
:
add_filter( 'woocommerce_package_rates', 'change_shipping_method_rate_based_on_shipping_class_2', 11, 2 );
function change_shipping_method_rate_based_on_shipping_class_2( $rates, $package )
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
// HERE define your shipping class to find
$class = array(206);
// HERE define the shipping method to change rates for
$method_id5 = 'flat_rate:5';
// Checking in cart items
$found = false;
$item_price = $item_qty = $rush_fee = 0;
foreach( WC()->cart->get_cart() as $cart_item )
$item_shipping_class_id = $cart_item['data']->get_shipping_class_id();
if( in_array( $item_shipping_class_id, $class ) )
$found = true; // Target shipping class found
$item_price += $cart_item['data']->get_price(); // Sum line item prices that have target shipping class
$item_qty += $cart_item['quantity']; // Sum line item prices that have target shipping class
$item_total = $item_price * $item_qty;
$rush_fee = $item_total * 0.2;
if( $found )
if( $item_total > 0 && $item_total < 200 )
if($rush_fee < 25)
$rates[$method_id5]->cost = 25 + 18.99;
else
$rates[$method_id5]->cost = $rush_fee + 18.99;
elseif ( $item_total > 200 )
if($rush_fee < 25)
$rates[$method_id5]->cost = 25;
else
$rates[$method_id5]->cost = $rush_fee;
return $rates;
对此有什么想法吗?
【问题讨论】:
【参考方案1】:更新 #1: (基于您的第二次编辑)
请尝试以下方法:
add_filter( 'woocommerce_package_rates', 'custom_shipping_rates_based_on_shipping_class', 11, 2 );
function custom_shipping_rates_based_on_shipping_class( $rates, $package )
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
// HERE define your shipping class to find
$class = array(206);
// HERE define the shipping method to change rates for
$shipping_rate_ids = array('flat_rate:5', 'flat_rate:6')
// Initialising
$found = false;
$item_price = $item_qty = $rush_fee = $item_total = 0;
// Loop through cart items
foreach( $package['contents'] as $cart_item_key => $cart_item )
$item_shipping_class_id = $cart_item['data']->get_shipping_class_id();
if( in_array( $item_shipping_class_id, $class ) )
$item_price += $cart_item['data']->get_price(); // Sum line item prices that have target shipping class
$item_qty += $cart_item['quantity']; // Sum line item prices that have target shipping class
$item_total = $item_price * $item_qty;
$rush_fee = $item_total * 0.2;
$found = true; // Target shipping class found
if( $found )
// Loop through shipping rates
foreach( $rates as $rate_key => $rate )
if( in_array($rate_key, $shipping_rate_ids) )
if( $item_total > 0 && $item_total < 200 )
if($rush_fee < 25)
$rates[$rate_key]->cost = 25 + 18.99;
else
$rates[$rate_key]->cost = $rush_fee + 18.99;
elseif ( $item_total > 200 )
if($rush_fee < 25)
$rates[$rate_key]->cost = 25;
else
$rates[$rate_key]->cost = $rush_fee;
return $rates;
代码在您的活动子主题(或主题)的 function.php 文件中。经过测试并且可以工作。
刷新运输缓存: (必需)
此代码已保存在活动主题的 function.php 文件中。 购物车是空的 在配送区域设置中,禁用/保存任何配送方式,然后启用返回/保存。
初步回答。
由于$method
是stdClass
实例对象而不是WC_Shipping_Rate
实例对象,因此没有为它定义get_label()
方法(不存在)。 您可以使用属性label
。
所以你只需要在模板中替换:
$label = $method->get_label();
由
$label = $method->label;
这应该会停止此错误并解决您的问题。
【讨论】:
它仍然给出错误...但是现在文件已更改〜致命错误:未捕获的错误:调用 .../plugins/woocommerce/includes/ 中的未定义方法 stdClass::get_label() wc-cart-functions.php:345~ @DanishMuneer 这是另一个问题,其他问题正在制造麻烦:现在这发生在 Woocommerce 核心文件中。您应该尝试取回 woocommerce 默认模板(将您的模板保存在重命名的文件夹中),看看会发生什么。然后您将逐步对这些模板进行必要的更改,始终测试您的代码。 你需要把错误读到最后……罪魁祸首似乎是 cart-shipping.php 模板…… 看起来是其他原因造成的...我在运输方式标题中使用了大括号 () 和破折号。这会以某种方式破坏功能吗?我目前正在创建一个临时站点,它将帮助我开始测试和更新模板。 @DanishMuneer 更新了…以上是关于根据 WooCommerce 中的运输类别自定义计算的运输成本的主要内容,如果未能解决你的问题,请参考以下文章
Woocommerce 3中的自定义结帐字段和运输方式ajax交互