#php #wordpress #if-statement #woocommerce #shipping-method
#php #wordpress #if-оператор #woocommerce #способ доставки
Вопрос:
Не могли бы вы, пожалуйста, помочь мне оптимизировать мой небольшой фрагмент, который я написал, чтобы применить скидку после добавления товаров в корзину с tech
назначенным классом доставки и других товаров, класс которых не указан для веб-сайта WordPress (Woocommerce). Как я могу оптимизировать if .. elseif
и в целом улучшить его. Кроме того, является ли добавление break
хорошей практикой? Я новичок в PHP, но в настоящее время я учусь и хотел бы улучшить свой код. Возможно, я могу использовать что-то подобное switch
? Любая помощь и примеры приветствуются!
add_filter( 'woocommerce_package_rates', 'adjustment_in_rates_of_product_with_shipping_class', 12, 2 );
function adjustment_in_rates_of_product_with_shipping_class( $available_shipping_methods, $package ) {
// Shipping class slug to be eligible for a discount when combined with no class products
$shipping_class = array(
'tech',
);
// Discount
$discounteuro = 3.50;
$discountgbp = 3.20;
$discountusd = 4;
$discountglobalusd = 5;
// Enter the shipping method value
$shipping_services = array(
'flat_rate:5',
);
$shipping_class_exists = false;
foreach(WC()->cart->get_cart_contents() as $key => $values) {
if ( in_array($values['data']->get_shipping_class() , $shipping_class) ) {
$shipping_class_exists = true;
break;
}
}
$shipping_class_no_exists = false;
foreach(WC()->cart->get_cart_contents() as $key => $values) {
if ( strlen($values['data']->get_shipping_class()) == 0 ) {
$shipping_class_no_exists = true;
break;
}
}
if ($shipping_class_exists amp;amp; $shipping_class_no_exists) {
foreach ($available_shipping_methods as $key => $value) {
if ( in_array($value->get_id() , $shipping_services) amp;amp; get_woocommerce_currency() == 'EUR' ) {
$available_shipping_methods[$key]->cost -= $discounteuro;
break;
}
elseif ( in_array($value->get_id() , $shipping_services) amp;amp; get_woocommerce_currency() == 'GBP' ) {
$available_shipping_methods[$key]->cost -= $discountgbp;
break;
}
elseif ( in_array($value->get_id() , $shipping_services) amp;amp; get_woocommerce_currency() == 'USD' ) {
$available_shipping_methods[$key]->cost -= $discountusd;
break;
}
else {
$available_shipping_methods[$key]->cost -= $discountglobalusd;
break;
}
}
}
return $available_shipping_methods;
}
Комментарии:
1. @GrumpyCrouton — Понятно, так что я просто оставлю
break
$shipping_class_exists
и$shipping_class_no_exists
, верно?2. @GrumpyCrouton — Большое вам спасибо. В дополнение к вашему замечательному подходу, который вы опубликовали ниже, с реализацией всех
elseif
s только в одномif
, видите ли вы способ улучшить оба$shipping_class_exists
и$shipping_class_no_exists
тоже? В целом, хорош ли остальной код? Еще раз большое вам спасибо за то, что нашли время, чтобы помочь мне. Очень признателен!
Ответ №1:
Я бы объединил ваши первые два цикла в один цикл, потому что нет причин перебирать данные дважды. Что-то вроде этого
$shipping_class_exists = false;
$shipping_class_no_exists = false;
foreach(WC()->cart->get_cart_contents() as $key => $values) {
if(in_array($values['data']->get_shipping_class() , $shipping_class)) {
$shipping_class_exists = true;
}
if(strlen($values['data']->get_shipping_class()) == 0) {
$shipping_class_no_exists = true;
}
}
Я бы также преобразовал ваши скидки в массив, чтобы упростить вызов из вашего цикла.
$discounts = [
'EUR' => 3.5,
'GBP' => 3.2,
'USD' => 4,
'globalusd' => 5
];
Тогда ваш цикл станет
if ($shipping_class_exists amp;amp; $shipping_class_no_exists) {
foreach ($available_shipping_methods as $key => $value) {
//store currency type in an easier to access variable
$currency = get_woocommerce_currency();
//create variable `$discount` defaulting to `$discounts['globalusd']`
$discount = $discounts['globalusd'];
if(in_array($value->get_id(), $shipping_services) amp;amp; array_key_exists($currency, $discounts)) {
//if $value->get_id()` is in `$shipping_services` and `$currency` key exists in $discounts
//then alter $discount to the correct value
$discount = $discounts[$currency];
}
//subtract discount from cost
$available_shipping_methods[$key]->cost -= $discount;
}
}
Комментарии:
1. Большое вам спасибо, однако он не делает то, что делает мой код. Если служба доставки
flat_rate:5
и валюта магазинаUSD
,EUR
,GBP
она должна делать скидку, но если служба доставки отличается от того, что она должна делатьglobaldiscount
. Я немного запутался в том, что я должен отредактировать в вашем коде, чтобы он вел себя точно так же, как мой. Спасибо2. @Korla немного изменил его для второй части, потому что троичный код стал слишком длинным на мой личный вкус. Это выглядит чище. Ваша проблема из вашего комментария также должна быть решена.
Ответ №2:
Обновлено 2 , Удалены некоторые ошибки
Следующий оптимизированный код должен сделать свое дело (код прокомментирован):
add_filter( 'woocommerce_package_rates', 'adjustment_in_rates_of_product_with_shipping_class', 12, 2 );
function adjustment_in_rates_of_product_with_shipping_class( $rates, $package ) {
// Shipping class slug to be eligible for a discount when combined with no class products
$target_shipping_classes = array('tech');
// Enter the shipping method value
$shipping_rate_ids = array('flat_rate:5');
// Discount based on currency
$currency_discounts = array(
'' => 5,
'EUR' => 3.50,
'GBP' => 3.20,
'USD' => 4,
);
$shipping_class_found = $other_shipping_classes = $currency_found = false;
$woocommerce_currency = get_woocommerce_currency();
// Loop through cart items for the current package
foreach( $package['contents'] as $item ) {
$shipping_class = $item['data']->get_shipping_class(); // Get item shipping class
if ( in_array( $shipping_class, $target_shipping_classes ) ) {
$shipping_class_found = true;
}
elseif ( ! empty($shipping_class) ) {
$other_shipping_classes = true;
}
}
// When there is only items from the defined shipping classes
if ( $shipping_class_found amp;amp; ! $other_shipping_class ) {
// Loop through available shipping rates in the current shipping package
foreach ( $rates as $rate_key => $rate ) {
if ( in_array($rate_key, $shipping_rate_ids) ) {
// Loop through defined currency discounts
foreach ( $currency_discounts as $currency => $discount ) {
if ( $woocommerce_currency === $currency ) {
$rates[$rate_key]->cost -= $discount;
$currency_found = true;
break;
}
}
// If no currency match, we get the default value (the first one)
if ( ! $currency_found ) {
$rates[$shipping_rate_id]->cost -= reset($currency_discounts);
}
}
}
}
return $rates;
}
Код вводится functions.php файл активной дочерней темы (или активной темы). Протестировано и работает.
Примечание: вы должны очистить свой после сохранения этого кода.
Комментарии:
1. Спасибо, что нашли время, чтобы помочь мне, но после тестирования вашего кода он вообще не работает. Не уверен, почему это так, но скидки вообще нет, и он ведет себя не так, как мой код в исходном сообщении.