woocommerce_before_calculate_totals в woocommerce 3.0

Вопрос или проблема

Я недавно перешел с woocommerce 2.7 на 3.1. У меня возникли проблемы с хуком woocommerce_before_calculate_totals в функции ниже.

function calculate_embossing_fee( $cart_object ) {
    if( !WC()->session->__isset( "reload_checkout" )) {
        /* Цена упаковки */
        $additionalPrice = 5;
        foreach ( $cart_object->cart_contents as $key => $value ) {
            if( isset( $value["embossing_fee"] ) ) {
                $orgPrice = floatval( $value['data']->price );
                $discPrice = $orgPrice + $additionalPrice;
                $value['data']->set_price($discPrice);
            }
        }
    }
}
add_action( 'woocommerce_before_calculate_totals', 'calculate_embossing_fee', 99 );

Кто-нибудь знает, почему это вызывает ошибку и как я могу это исправить?

Ошибка, которую я получаю:

Notice: price was called incorrectly. Product properties should not be accessed directly. Backtrace: require('wp-blog-header.php'), require_once('wp-includes/template-loader.php'), include('/themes/bdop/page.php'), the_content, apply_filters('the_content'), WP_Hook->apply_filters, call_user_func_array, do_shortcode, preg_replace_callback, do_shortcode_tag, call_user_func, WC_Shortcodes::cart, WC_Shortcodes::shortcode_wrapper, call_user_func, WC_Shortcode_Cart::output, WC_Cart->calculate_totals, do_action('woocommerce_before_calculate_totals'), WP_Hook->do_action, WP_Hook->apply_filters, call_user_func_array, calculate_embossing_fee, WC_Abstract_Legacy_Product->__get, wc_doing_it_wrong Please see Debugging in WordPress for more information. (This message was added in version 3.0.) in /Applications/MAMP/htdocs/bdop/wp-includes/functions.php on line 4139

Проблема в том, что вы вызываете price напрямую в $value['data']->price. Измените его на $value['data']->get_price(), и я думаю, ваша проблема будет решена. Таким образом, весь блок кода будет выглядеть так:

function calculate_embossing_fee( $cart_object ) {
    if( !WC()->session->__isset( "reload_checkout" )) {
        /* Цена упаковки */
        $additionalPrice = 5;
        foreach ( $cart_object->cart_contents as $key => $value ) {
            if( isset( $value["embossing_fee"] ) ) {
                // Замените $value['data']->price на $value['data']->get_price()
                $orgPrice = floatval( $value['data']->get_price() );
                $discPrice = $orgPrice + $additionalPrice;
                $value['data']->set_price($discPrice);
            }
        }
    }
}
add_action( 'woocommerce_before_calculate_totals', 'calculate_embossing_fee', 99 );

Надеюсь, это поможет.

function action_woocommerce_before_calculate_totals( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
        return;

    // Получить способ оплаты
    $chosen_payment_method = WC()->session->get( 'chosen_payment_method' );
    $chosen_default_deposit = WC()->session->get('deposit_enabled');
    // Сравнить
    if(empty($chosen_default_deposit))
    {
            if ( $chosen_payment_method == 'bacs' ) {

                // Перебор элементов корзины
                foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {     
                    // Получить цену
                    //echo "<pre>";
                    //print_r($cart_item);
                    //$price = 7000;
                    $custom_bank_transfer_price_text_field = get_post_meta($cart_item['product_id'], '_custom_bank_transfer_price_text_field', true);
                    if(!empty($custom_bank_transfer_price_text_field))
                    {
                        $cart_item['data']->set_price( $custom_bank_transfer_price_text_field );
                    }

                }

            }
    }
}

add_action( 'woocommerce_before_calculate_totals', 'action_woocommerce_before_calculate_totals', 10, 1 );

Ответ или решение

В новой версии WooCommerce (3.0 и выше) произошли значительные изменения в способах обращения к свойствам продуктов. Это вызвало определенные изменения в методах доступа к данным о цене товара, что могло стать причиной возникновения ошибок в вашем коде, таких как "price was called incorrectly". Вот полное объяснение проблемы и ее решения.

Проблема

Ваш код использует метод обращения к свойству price напрямую с помощью $value['data']->price, что вызывает предупреждение о неправильном использовании. В WooCommerce версии 3.0 и выше, рекомендуется использовать метод get_price(), который является частью интерфейса для работы с объектами продукта. Это изменение было введено для обеспечения более консистентного и безопасного доступа к данным продуктов.

Решение

Измените строку обращения к цене с прямого доступа к свойству на использование функции get_price(). Вот обновленный код:

function calculate_embossing_fee( $cart_object ) {
    if( !WC()->session->__isset( "reload_checkout" )) {
        /* Дополнительная плата за упаковку */
        $additionalPrice = 5;
        foreach ( $cart_object->cart_contents as $key => $value ) {
            if( isset( $value["embossing_fee"] ) ) {
                // Используем get_price() вместо доступа к свойству price
                $orgPrice = floatval( $value['data']->get_price() );
                $discPrice = $orgPrice + $additionalPrice;
                $value['data']->set_price($discPrice);
            }
        }
    }
}
add_action( 'woocommerce_before_calculate_totals', 'calculate_embossing_fee', 99 );

Что еще стоит учитывать

  1. Проверка на админ-панели: Если функция выполняется на админ-страницах и не в процессе AJAX-запроса, стоит вернуть выполнение, чтобы не возникали лишние вычисления в админке.

  2. Дополнительные условия: Убедитесь, что ваши условия для изменения цены соответствуют вашей бизнес-логике. Например, если пользователь выбрал способ оплаты, который требует изменения цены, необходимо это учитывать при расчетах.

  3. Оптимизация кода: Не забывайте чистить код от лишнего и оставлять только те части, которые строго необходимы для выполнения вашей задачи.

  4. Тестирование: Перед переводом изменений на продуктивную версию, проведите тестирование на локальной среде или staging-сайте, чтобы гарантировать отсутствие проблем с функциональностью.

Заключительные рекомендации

Следует всегда придерживаться документации WooCommerce и обращать внимание на обновления и изменения в API. Правильное использование методов, таких как get_price() и set_price(), не только улучшает совместимость кода с будущими версиями, но и обеспечивает безопасность и предсказуемость вашего функционала.

Оцените материал
Добавить комментарий

Капча загружается...