Woocommerce, скрыть способ доставки в зависимости от класса доставки
Я пытаюсь скрыть все, кроме одного метода доставки, основанного на классе доставки, по сути, принудительно применяя метод FedEx overnight, когда выбран продукт, принадлежащий к определенному классу.
Я начинаю с этого кода и модифицирую его, как указано ниже:
add_filter( 'woocommerce_available_shipping_methods', 'hide_shipping_based_on_class' , 10, 1 );
function check_cart_for_share() {
// load the contents of the cart into an array.
global $woocommerce;
$cart = $woocommerce->cart->cart_contents;
$found = false;
// loop through the array looking for the tag you set. Switch to true if the tag is found.
foreach ($cart as $array_item) {
$term_list = wp_get_post_terms( $array_item['product_id'], 'product_shipping_class', array( "fields" => "names" ) );
if (in_array("Frozen",$term_list)) {
$found = true;
break;
}
}
return $found;
}
function hide_shipping_based_on_class( $available_methods ) {
// use the function above to check the cart for the tag.
if ( check_cart_for_share() ) {
// remove the rate you want
unset( $available_methods['canada_post,purolator,fedex:FEDEX_GROUND,fedex:GOUND_HOME_DELIVERY'] );
}
// return the available methods without the one you unset.
return $available_methods;
}
Похоже, что он не скрывает никаких способов доставки. Не уверен, что мне не хватает...
Это многосайтовая установка, я тестирую ее на канадской стороне по адресу http://stjeans.harbourcitydevelopment.com/
Я использую модуль доставки Table Rate, а также модули FedEx, Purolator и Canada Post.
3 ответа
У меня была та же проблема, и помогла модификация вашего кода. Одной из проблем является то, что фильтр " woocommerce_available_shipping_methods " не поддерживается в WooCommerce 2.1. Поэтому вы должны использовать новый: " woocommerce_package_rates ". Для аналогичной задачи также есть учебник по WooCommerce.
Итак, я изменил фильтр-ловушку, и когда условие выполнено, я перебираю все методы / тарифы доставки, нахожу тот, который хочу показать клиенту, создаю из него новый массив и возвращаю этот массив (только с одним элементом).
Я думаю, что ваша проблема была (кроме устаревшей ловушки) в основном в неправильной строке unset($available_methods[...]). Это не могло так работать.
Итак, вот мой код:
add_filter( 'woocommerce_package_rates', 'hide_shipping_based_on_class' , 10, 2 );
function hide_shipping_based_on_class( $available_methods ) {
if ( check_cart_for_share() ) {
foreach($available_methods as $key=>$method) {
if( strpos($key,'YOUR_METHOD_KEY') !== FALSE ) {
$new_rates = array();
$new_rates[$key] = $method;
return $new_rates;
}
}
}
return $available_methods;
}
Предупреждение! I found out that woocommerce_package_rates hook is not fired everytime, but only when you change items or quantity of items in your cart. Or it looks like that for me. Maybe those available rates are cached somehow for cart content.
Если кто-то спотыкается здесь, интересно, почему не работает. Вы можете очистить кеш, используя следующий фрагмент:
/**
* This implementation will disable the shipping rate cache.
* To conditionally disable the cache, replace `wp_rand()` with a conditional value.
* Changing the conditional value will invalidate the cache.
* Example: A hidden form field or a query string parameter.
*/
function wc_shipping_rate_cache_invalidation( $packages ) {
foreach ( $packages as &$package ) {
$package['rate_cache'] = wp_rand();
}
unset($package);
return $packages;
}
add_filter( 'woocommerce_cart_shipping_packages', 'wc_shipping_rate_cache_invalidation', 100 );
Был комментарий по поводуwoocommerce_package_rates
крючок, который указывал на суть github для этого фрагмента кода.
Приведенный ниже фрагмент кода позволяет скрыть методы доставки в зависимости от класса доставки. Подробное описание доступно здесь
add_filter('woocommerce_package_rates', 'wf_hide_shipping_method_based_on_shipping_class', 10, 2);
function wf_hide_shipping_method_based_on_shipping_class($available_shipping_methods, $package)
{
$hide_when_shipping_class_exist = array(
42 => array(
'free_shipping'
)
);
$hide_when_shipping_class_not_exist = array(
42 => array(
'wf_shipping_ups:03',
'wf_shipping_ups:02',
'wf_shipping_ups:01'
),
43 => array(
'free_shipping'
)
);
$shipping_class_in_cart = array();
foreach(WC()->cart->cart_contents as $key => $values) {
$shipping_class_in_cart[] = $values['data']->get_shipping_class_id();
}
foreach($hide_when_shipping_class_exist as $class_id => $methods) {
if(in_array($class_id, $shipping_class_in_cart)){
foreach($methods as & $current_method) {
unset($available_shipping_methods[$current_method]);
}
}
}
foreach($hide_when_shipping_class_not_exist as $class_id => $methods) {
if(!in_array($class_id, $shipping_class_in_cart)){
foreach($methods as & $current_method) {
unset($available_shipping_methods[$current_method]);
}
}
}
return $available_shipping_methods;
}