Как вызвать действие хуком в функции обратного вызова wp_ajax?

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

Мне нужно вызвать AJAX-запрос на основе изменений пользовательского поля в форме оформления заказа, чтобы добавить скидку. Но если я вызываю хуки для добавления скидки в подсчет итоговой суммы корзины, то это ничего не делает. Обратите внимание, что AJAX-запрос работает нормально. Даже если я использую хук woocommerce_cart_calculate_fees вне функции обратного вызова AJAX, это сработает.

add_action('wp_ajax_test', 'test');
add_action('wp_ajax_nopriv_test', 'test');

function test(){
  add_action('woocommerce_cart_calculate_fees' , 'add_custom_fees');
}

function add_custom_fees( WC_Cart $cart ){

    // Рассчитаем сумму скидки
    $discount = $cart->subtotal * 0.2;
    $cart->add_fee( 'У вас более 3-х предметов в корзине, скидка 10% добавлена.', -$discount);
}

Проблема, с которой вы столкнулись, заключается в том, что функция add_action будет влиять только на текущий запрос, который в данном случае является вашим AJAX-запросом. После этого, когда вы отправляете форму, это уже другой запрос, и действие больше не присутствует.

Чтобы достичь желаемого, вам нужно каким-то образом изменить форму, чтобы скидка была учтена при ее отправке.

Вы можете использовать AJAX, возможно, чтобы проверить, разрешена ли скидка, и вернуть текст для пользователя и/или правильный элемент для добавления в форму, чтобы сделать ее с учетом скидки позднее.

Вот примерно что я имею в виду:

add_action('wp_ajax_discount', 'maybe_discount');
function maybe_discount() { 
    /* определите, уместна ли скидка, затем */
    if ($discount) {
        echo json_encode('status'=>'discount', 'text'=>'....');
    } else {
        echo json_encode('status'=>'nodiscount');
    die();
}

/* На стороне клиента вы будете использовать возвращенную информацию для
 * отображения чего-то пользователю или, возможно, изменения самой формы
 * (я не знаю, что поддерживает WooCommerce).
 * Затем, когда вы *отправите* форму, вам может понадобиться хук вроде этого:
 */

add_action('some_woocomerce_hook_here','add_my_discount');
function add_my_discount( WC_Cart $cart ) {
    $discount = $cart->subtotal * 0.2;
    $cart->add_fee( 'У вас есть скидка...', -$discount);
}

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

Чтобы правильно вызвать действие в callback-функции wp_ajax для добавления скидки в WooCommerce, нужно учитывать несколько ключевых аспектов работы с AJAX и хуками в WordPress. Ниже приведен подробный ответ на поставленный вопрос, который поможет решить вашу задачу.

Введение в проблему

Вы столкнулись с задачей, которая требует выполнения AJAX-вызова на основе изменений пользовательского поля в форме оформления заказа для добавления скидки. Ваша текущая реализация не дает ожидаемого результата, потому что вызов хука add_action в вашем AJAX callback не сохраняется для других запросов, которые проходит форма после AJAX-вызова.

Почему ваш код не работает?

Ваша функция test() добавляет хук woocommerce_cart_calculate_fees, но этот хук срабатывает только в текущем запросе AJAX. При последующей обработке формы (например, при отправке ее финансами) хук больше не активен, так как был добавлен только в рамках AJAX-реквеста.

Решение проблемы

Для того чтобы скидка применялась при каждом запросе, вам нужно применить логику определения скидки глобально, а не только внутри вашей AJAX-функции. Вот предложенная структура кода, которая сделает это:

// Хуки для AJAX запросов
add_action('wp_ajax_discount', 'maybe_discount');
add_action('wp_ajax_nopriv_discount', 'maybe_discount');

function maybe_discount() {
    // Определяем, требуется ли скидка
    // В вашем коде это будет зависеть от логики
    $should_discount = true; // Это условие должно зависеть от ваших требований

    if ($should_discount) {
        // Пример того, как вернуть ответ на AJAX-запрос
        echo json_encode(array('status' => 'discount', 'message' => 'Скидка применена.'));
    } else {
        echo json_encode(array('status' => 'nodiscount'));
    }
    wp_die(); // Завершение AJAX вызова
}

// Выполнение скидки при расчете стоимости корзины
add_action('woocommerce_cart_calculate_fees', 'add_my_discount');

function add_my_discount(WC_Cart $cart) {
    // Проверяем, предопределена ли скидка (можно создать глобальную переменную или опцию для этого)
    $discount_allowed = true; // Это нужно поменять на ваше условие

    if ($discount_allowed) {
        // Рассчитываем и добавляем скидку
        $discount = $cart->subtotal * 0.2; // Пример: 20% скидка
        $cart->add_fee('Скидка за более чем 3 товара: -' . wc_price($discount), -$discount);
    }
}

Объяснение решения

  1. AJAX Вызов: Функция maybe_discount() обрабатывает AJAX-запросы и возвращает информацию о том, применяется ли скидка. Не забудьте проверить условия для применения скидки в соответствии с вашими нуждами.

  2. Добавление скидки: Использование хука woocommerce_cart_calculate_fees, который обрабатывается при каждом расчете корзины, позволяет применять скидку, даже если она была инициирована через AJAX.

  3. Глобальные параметры скидки: Убедитесь, что вы определили условие для применения скидки в вашем приложении (например, проверка количества товаров в корзине). Это можно сделать через глобальные переменные, опции или с помощью сессий.

Заключение

Следуя данной инструкции, вы сможете успешно интегрировать логику применения скидок в WooCommerce и учесть изменения пользовательских форм в реальном времени через AJAX. При этом убедитесь, что вся логика правильно обрабатывает условия для скидки и корректно реагирует на запросы клиента, тем самым обеспечивая безупречный пользовательский опыт.

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

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