wordpress — ошибка PHP в хуке фильтра woocommerce_get_availability

В WooCommerce почему-то я получаю эту ошибку:

Предупреждение: неверный аргумент указан для foreach () в /home//wp-content/themes/flat/functions.php в строке 32

Ошибка появляется только для простых продуктов, а не для переменных продуктов с несколькими вариантами. Эта ошибка, кажется, в этой строке:

foreach($available as $i) {

Любая помощь будет потрясающей!

Вот мой код:

/**
* Backorder Hook
**/

function backorder_text($available) {

foreach($available as $i) {

$available = str_replace('Available on backorder', 'This size is on backorder : Dont Miss out!<BR><span style="font-weight: normal;">Buy it now and we will dispatch as soon as they arrive</span>', $available);

}

return $available;
}
add_filter('woocommerce_get_availability', 'backorder_text');add_filter( 'woocommerce_get_availability' , 'revised_woocommerce_get_availability' , 10, 2 );

function revised_woocommerce_get_availability( $available_array , $product) {

if ( $product->managing_stock() ) {

if ( !($product->is_in_stock() && $product->get_stock_quantity() > get_option( 'woocommerce_notify_no_stock_amount' ))  && ($product->backorders_allowed() && $product->backorders_require_notification())  ) {

$custom_meta_value = get_post_meta( $product->id, 'Out_of_stock_message', true );
$available_array["availability"] = $custom_meta_value;

}

}
return $available_array;
}

2

Решение

Вы можете использовать 2 разных крючка для этого. И поскольку вы используете одни и те же перехватчики для 2 функций, вы можете объединить их в одну функцию.

woocommerce_get_availability фильтр-крюк: используется в get_availability() метод:

public function get_availability() {
return apply_filters( 'woocommerce_get_availability', array(
'availability' => $this->get_availability_text(),
'class'        => $this->get_availability_class(),
), $this );
}

Таким образом, вы также можете видеть, что это массив с 2 ключами 'availability' а также 'class'. Ключ 'availability' это то, что вам нужно и использует get_availability_text() метод и что вы можете использовать напрямую woocommerce_get_availability_text фильтр-хук в конце кода метода.

1) Использование woocommerce_get_availability_text фильтр-крюк (лучший выбор):

add_filter( 'woocommerce_get_availability_text', 'customizing_availability_text', 10, 2);
function customizing_availability_text( $availability, $product ) {

if ( $_product->is_in_stock() )
$availability = str_replace('Available on backorder', 'This size is on backorder : Dont Miss out!<BR><span style="font-weight: normal;">Buy it now and we will dispatch as soon as they arrive</span>', $availability);

if ( $product->managing_stock() && !($product->is_in_stock() && $product->get_stock_quantity() > get_option( 'woocommerce_notify_no_stock_amount' ))  && ($product->backorders_allowed() && $product->backorders_require_notification())  ) {
$availability = get_post_meta( $product->id, 'Out_of_stock_message', true );

return $availability;
}

2) Использование woocommerce_get_availability фильтр-крючок.

Здесь вам нужно нацелиться на 'availability' в массиве, таким образом:

add_filter( 'woocommerce_get_availability', 'customizing_availability_text', 10, 2);
function customizing_availability_text( $availability, $product ) {

if ( $_product->is_in_stock() )
$availability['availability'] = str_replace('Available on backorder', 'This size is on backorder : Dont Miss out!<BR><span style="font-weight: normal;">Buy it now and we will dispatch as soon as they arrive</span>', $availability['availability']);

if ( $product->managing_stock() && !($product->is_in_stock() && $product->get_stock_quantity() > get_option( 'woocommerce_notify_no_stock_amount' ))  && ($product->backorders_allowed() && $product->backorders_require_notification())  ) {
$availability['availability'] = get_post_meta( $product->id, 'Out_of_stock_message', true );

return $availability;
}

Код помещается в файл function.php вашей активной дочерней темы (или темы) или также в любой файл плагина.

Я не проверял ваш код, поскольку он очень специфический, но он должен работать.


Ссылка: Справочник по действиям и фильтрам

1

Другие решения

использование is_array функция для проверки, если это массив

function backorder_text($available) {
is_array($available){
foreach($available as $i) {

$available = str_replace('Available on backorder', 'This size is on backorder : Dont Miss out!<BR><span style="font-weight: normal;">Buy it now and we will dispatch as soon as they arrive</span>', $available);

}
} else{

$available = str_replace('Available on backorder', 'This size is on backorder : Dont Miss out!<BR><span style="font-weight: normal;">Buy it now and we will dispatch as soon as they arrive</span>', $available);

}

return $available;
}
0

Поскольку ошибка находится в строке foreach, вы, вероятно, пытаетесь перебрать переменную, которая не является массивом. Добавление условной проверки, является ли переменная $ Availability массивом, должно решить проблему. Как это:

function backorder_text($available) {
if (is_array($available)) {
foreach($available as $i) {
$available = str_replace('Available on backorder', 'This size is on backorder : Dont Miss out!<BR><span style="font-weight: normal;">Buy it now and we will dispatch as soon as they arrive</span>', $available );
}
} else {
$available = str_replace('Available on backorder', 'This size is on backorder : Dont Miss out!<BR><span style="font-weight: normal;">Buy it now and we will dispatch as soon as they arrive</span>', $available);
}
return $available;
}

Тем не менее, есть еще лучший способ. Поскольку str_replace может принимать массивы или строки в качестве параметров, это также будет работать во всех ситуациях. Это на самом деле то, что делает ваш код, когда он работает. В вашем коде цикл foreach не нужен, так как вы вызываете str_replace для переменной $ Availability, а не для элемента в этом массиве ($ i). Следующее проще и будет работать независимо от того, является ли $ Availability массивом или строкой.

function backorder_text($available) {
return str_replace('Available on backorder', 'This size is on backorder : Dont Miss out!<BR><span style="font-weight: normal;">Buy it now and we will dispatch as soon as they arrive</span>', $available);
}
0