Обновить цену продукта WooCommerce на основе настраиваемого поля ввода

Я добавил настраиваемое поле ввода номера на страницы отдельных продуктов. Обычная цена умножается на введенное целое значение. Например, если базовая цена составляет 10 долларов США, а пользователь вводит значение 2 в поле настраиваемого ввода, новая цена станет 20 долларов США.

Обновление цены работает нормально, но когда пользователь попадает в корзину и обновляет количество товара в корзине, цена пересчитывается. например Новая рассчитанная цена составила 20 долларов (пример выше), и пользователь меняет количество в корзине с 1 на 5, цена снова пересчитывается с помощью пользовательского целочисленного поля, поэтому 20 долларов снова умножаются на 2 и теперь составляют 40 долларов. .

Но я не понимаю, почему это происходит...

Это мой текущий код:

add_action( 'woocommerce_after_add_to_cart_quantity', 'add_custom_input_number_field', 0 );
function add_custom_input_number_field() {
    echo '<div class = "custom-input-number-field">';
    echo '<label>' . __( 'Custom Input Number', 'woocommerce' ) . '</label>';
    echo '<input type = "number" required = "true" placeholder = "max. 30.500" class = "custom-input-number" name = "custom_input_number" min = "1" step = "0.001" />';
    echo '</div>';
}

add_filter( 'woocommerce_get_price_html', 'update_product_price_based_on_custom_input_on_product_page', 9999, 2 );
function update_product_price_based_on_custom_input_on_product_page( $price, $product ) {
    if ( is_product() && isset( $_POST['custom_input_number'] ) ) {
        $custom_input_value = (float) $_POST['custom_input_number'];
        $product_price = $product->get_price();
        $new_price = $product_price * $custom_input_value;
        $price = wc_price( $new_price ) . $product->get_price_suffix();
    }
    return $price;
}

add_filter( 'woocommerce_add_cart_item_data', 'save_custom_input_number_field_data', 10, 2 );
function save_custom_input_number_field_data( $cart_item_data, $product_id ) {
    if ( isset( $_POST['custom_input_number'] ) ) {
        $cart_item_data['custom_input_number'] = wc_clean( $_POST['custom_input_number'] );
        $cart_item_data['custom_input_number'] = (float) $cart_item_data['custom_input_number'];
    }
    return $cart_item_data;
}

add_action( 'woocommerce_before_calculate_totals', 'update_product_price_based_on_custom_input_in_cart', 10, 1 );
function update_product_price_based_on_custom_input_in_cart( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) ) {
        return;
    }
 
    foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
        if ( isset( $cart_item['custom_input_number'] ) ) {
            $custom_input_value = $cart_item['custom_input_number'];
            $product = $cart_item['data'];
            $product_price = $product->get_price();
            $new_price = $product_price * $custom_input_value;
            $product->set_price( $new_price );
        }
    }
}

Я пробовал разные подходы. Лучшим вариантом было просто заблокировать Woo от повторного обновления цены после того, как она была добавлена ​​один раз, но я также хочу работать с многоуровневым ценообразованием для некоторых продуктов, поэтому это не вариант.

Я также пробовал разные хуки (add_to_cart, woocommerce_before_calculate_totals и т. д.).

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
2
0
75
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В вашем коде есть некоторые ошибки и неправильное использование хуков.

Вместо этого попробуйте следующее, это решит проблему, с которой вы столкнулись:

// Additional custom input field in single product
add_action( 'woocommerce_after_add_to_cart_quantity', 'add_custom_input_number_field', 0 );
function add_custom_input_number_field() {
    echo '<div class = "custom-input-number-field">
    <label>' . __( 'Custom Input Number', 'woocommerce' ) . '</label>
    <input type = "number" required = "true" placeholder = "max. 30.500" class = "custom-input-number" name = "custom_number" min = "1" step = "0.001" />
    </div>';
}

// Save custom input field value as custom cart item data
add_filter( 'woocommerce_add_cart_item_data', 'save_custom_input_number_field_data', 10, 2 );
function save_custom_input_number_field_data( $item_data, $product_id ) {
    if (isset( $_POST['custom_number']) ) {
        $item_data['custom_number'] = floatval($_POST['custom_number']);
    }
    return $item_data;
}

// Change and set cart item custom calculated price
add_action( 'woocommerce_before_calculate_totals', 'update_product_price_based_on_custom_input_in_cart', 10, 1 );
function update_product_price_based_on_custom_input_in_cart( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;
    
    foreach ( $cart->get_cart() as $item ) {
        if ( isset($item['custom_number']) && $item['custom_number'] ) {
            $item['data']->set_price( $item['data']->get_price() * $item['custom_number'] );
        }
    }
}

// Cart and mini cart displayed calculated price
add_filter( 'woocommerce_cart_item_price', 'filter_cart_item_price', 10, 2 );
function filter_cart_item_price( $price_html, $cart_item ) {

    if ( isset($cart_item['custom_number']) && $cart_item['custom_number'] ) {
        $product = wc_get_product( $cart_item['variation_id'] > 0 ? $cart_item['variation_id'] : $cart_item['product_id'] );
        $args    = array('price' => ($product->get_price() * $cart_item['custom_number']));

        if ( WC()->cart->display_prices_including_tax() ) {
            $product_price = wc_get_price_including_tax( $cart_item['data'], $args );
        } else {
            $product_price = wc_get_price_excluding_tax( $cart_item['data'], $args );
        }
        return wc_price( $product_price );
    }
    return $price_html;
}

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

Спасибо, это сработало (по крайней мере частично). Он работает с традиционными Woo Cart и Checkout, но с новыми блоками Cart и Checkout проблема остается (действительно интересно). У вас есть идеи, почему это так?

n1k1dk 03.05.2024 07:38

Причина в том, что блоки корзины и оформления заказа на самом деле не допускают настройки за пределами доступных настроек блока.

LoicTheAztec 03.05.2024 07:57

Хорошо, тогда я буду использовать традиционную корзину и оформление заказа, спасибо :)

n1k1dk 03.05.2024 08:20

Другие вопросы по теме

Пользовательский блок Wordpress Gutenberg, viewScript не загружается во внешнем интерфейсе, когда мой блок вставлен
Отключить кнопку размещения заказа WooCommerce Checkout на основе идентификатора пользователя
Проблема с обновлением CSS в WordPress с помощью хостинга
Горячая перезагрузка не работает полностью при использовании плагина Vite/Laravel Vite внутри Wordpress
Создайте собственный фильтр в списке заказов администратора WooCommerce (HPOS)
Изменение цвета фона в списке заказов администратора WooCommerce в зависимости от роли пользователя
Обновление метаданных пользовательского заказа администратора для высокопроизводительного хранилища заказов WooCommerce (HPOS)
Как сделать URL-ссылку для более чем одной ячейки в wptables?
Update_user_meta(), содержащий URL-адрес, запускает правило Modsecurity
Динамически добавляйте адреса электронной почты CC или BCC при отправке формы Elementor через файл WordPress function.php