根据WooCommerce中的运输类别自定义计算的运费

问题描述 投票:1回答:1

在昨晚将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;
}

有什么想法吗?

php wordpress object woocommerce checkout
1个回答
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文件中。经过测试和工作。

刷新运输缓存:(必填)

  1. 此代码已保存在活动主题的function.php文件中。
  2. 购物车是空的
  3. 在送货区设置中,禁用/保存任何送货方式,然后启用返回/保存。

初步答复。

由于$methodstdClass实例对象而不是WC_Shipping_Rate实例对象,因此没有为它定义get_label()方法(不存在)。相反,你可以使用属性label

所以你只需要在模板中替换:

$label = $method->get_label();

通过

$label = $method->label; 

这应该可以阻止此错误并解决您的问题。

© www.soinside.com 2019 - 2024. All rights reserved.