Ошибка 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;
}

person Loz Glen    schedule 24.02.2017    source источник


Ответы (3)


Для этого можно использовать 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 );
}

Вы также можете видеть, что это массив с двумя ключами: '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 вашей активной дочерней темы (или темы) или также в любом файле плагина.

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


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

person LoicTheAztec    schedule 24.02.2017

используйте функцию 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;
}
person Rafiqul Islam    schedule 24.02.2017

Поскольку ошибка находится в строке 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);
}
person DeezPineapples    schedule 24.02.2017