Проблема с функцией добавления в корзину пользовательского WooCommerce Ajax

Я пытаюсь добавлять товары (у меня только простые товары) в корзину с помощью JavaScript и PHP. Я отправляю идентификаторы продуктов, а затем вызываю метод WC_Cartadd_to_cart() в funcions.php.

Это код HTML (и JavaScript), который я использую:

<button onclick = "f1()" style = "margin-block:100px;margin-inline:auto;">✅</button>
<script>
    function f1(){
        // const cartItems=[9660, 9568, 8625]
        const cartItems=9568
        const data = {
            action: 'AddtocartF',
            ProductsToPay: JSON.stringify(cartItems)
        };
        fetch('https://9effa.ma/wp-admin/admin-ajax.php', {
            method: 'POST',
            body: new URLSearchParams(data),
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded',
            }
        })
            .then(response => response.json())
            .then(data => {
                console.info(data)
            })
            .catch(error => {
                console.error('Error:', error);
            });
    }
</script>

PHP-код:

add_action('wp_ajax_AddtocartF', 'AddtocartFunction');
add_action('wp_ajax_nopriv_AddtocartF', 'AddtocartFunction');

function AddtocartFunction(){
    if (!isset($_POST['ProductsToPay'])) {
        wp_send_json_error(['message' => "Veuillez ajouter les produits au panier avant de passer au paiement."]);
    }
    $product_id = $_POST['ProductsToPay'];
    $quantity = 1;
    $WC_Cart = new WC_Cart();
    $result = $WC_Cart->add_to_cart($product_id, $quantity);
    if (is_wp_error($result)) {
        // Handle the error case
        wp_send_json_error(['message' => $result->get_error_message()]);
    } else {
        // Product added successfully
        $response = ['success' => true, 'message' => 'Product added to cart', 'id' => $product_id, 'result value: ' => $result];
        wp_send_json_success($response);
    }
    wp_die();
}

У меня проблема в том, что он возвращает true (товар добавлен в корзину), но на самом деле это не так: корзина пуста, и при оформлении заказа я тоже не вижу товаров.

Это сообщение, которое я получаю в консоли:

{
    "success": true,
    "data": {
        "success": true,
        "message": "Product added to cart",
        "id": "9568",
        "result value: ": "621d187a8e1a345cc07422a61c669654"
    }
}

У меня есть последние версии WooCommerce и Elementor, и я использую тему Hello Elementor. На вкладке статуса WooCommerce все выглядит нормально, проблем нет, и я могу добавить товар в корзину обычным способом, то есть если я перейду на страницу магазина или страницу продукта и нажму кнопку «Добавить в корзину».

Я попытался отключить все плагины, кроме Elementor и WooCommerce. Я протестировал много разных идентификаторов продуктов.

Это проблема PHP или проблема AJAX?

Nico Haase 21.06.2024 14:40

Сначала я думал, что это проблема PHP, но оказалось, что это проблема AJAX. Теперь это решено.

Stuff lahza 25.06.2024 11:13
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать 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 и хотите разрабатывать...
1
2
57
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Похоже, вы действительно пытаетесь добавить несколько товаров одновременно:

// const cartItems=[9660, 9568, 8625]

Следующее, основанное на Добавить в корзину несколько вариантов с помощью JQuery и Ajax в WooCommerce ветке ответов, будет обрабатывать добавление в корзину одного или нескольких продуктов с помощью вашей пользовательской кнопки через Ajax.

Он также обрабатывает разные количества каждого продукта (опционально).

Я встроил HTML-код вашей пользовательской кнопки в виде короткого кода (см. использование в конце).

Код:

add_shortcode( 'multi_atc', 'multi_add_to_cart_button_html');
function multi_add_to_cart_button_html( $atts ) {
    extract( shortcode_atts( array(
        'data'  => '',
        'text'  => '✅',
        'class' => 'multi-atc-btn'
    ), $atts, 'multi_atc' ) );

    if ( $data ):

    ob_start();

    wc_enqueue_js("const products = \"{$data}\";
    $(document.body).on('click', '.{$class}', function(e) {
        e.preventDefault();
        
        $.ajax({
            type: 'POST',
            url: '" . admin_url('/admin-ajax.php') . "',
            data: {
                'action': 'multi_add_to_cart',
                'nonce': '" . wp_create_nonce('multi_atc') . "',
                'products': products
            },
            success: function(response) {
                $(document.body).trigger('wc_fragment_refresh');
                console.info(response);
            },
            error: function (error) {
                console.info(error);
            }
        });
    });");

    echo "<style>.{$class}{margin-block:100px; margin-inline:auto;}</style>
    <button class=\"{$class}\">{$text}</button>";

    return ob_get_clean();
    endif;
}

add_action('wp_ajax_multi_add_to_cart', 'multi_add_to_cart');
add_action('wp_ajax_nopriv_multi_add_to_cart', 'multi_add_to_cart');
function multi_add_to_cart() {
    if ( isset($_POST['nonce']) 
    && wp_verify_nonce($_POST['nonce'], 'multi_atc')
    && isset($_POST['products']) && !empty($_POST['products']) ) {
        $response  = array();

        foreach( explode(',',esc_attr($_POST['products'])) as $values ) {
            $values = (array) explode(':',$values);
            if ( is_array($values) ) {
                $product_id = absint(current($values));
                $quantity   = count($values) == 2 ? end($values) : 1;
                $product    = wc_get_product( $product_id );

                $not_added  = array( 
                    'key'   => null,
                    'added' => 0,
                    'id'    => $product_id,
                );

                if ( ! is_a($product, 'WC_Product') ) {
                    $response[] = $not_added;
                    continue;
                }

                $quantity     = wc_stock_amount( wp_unslash( $quantity ) );
                $variation_id = 0;
                $variation    = array();

                if ( $product && 'variation' === $product->get_type() ) {
                    $variation_id = $product_id;
                    $product_id   = $product->get_parent_id();
                    $variation    = $product->get_variation_attributes(); 
                }
                
                if ( 'publish' !== get_post_status( $product_id ) ) {
                    $response[] = $not_added;
                    continue;
                }
                
                if ( $variation_id && 'publish' !== $product->get_status() ) {
                    $response[] = $not_added;
                    continue;
                }

                $cart_item_key = WC()->cart->add_to_cart( $product_id, $quantity, $variation_id, $variation );
                
                $response[] = array( 
                    'key'   => $cart_item_key,
                    'added' => $cart_item_key ? $quantity : '0',
                    'id'    => $variation_id ?: $product_id,
                );
            }
        }

        if ( ! empty($response) ) {
            wp_send_json($response);
        }
    }
    wp_die('Something went wrong.');
}

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


Примеры ИСПОЛЬЗОВАНИЯ (идентификаторы продуктов разделены запятыми):

Вы можете использовать шорткод в текстовом редакторе WordPress, в некоторых блоках, в некоторых виджетах, в Elementor…

  • Количества не определены (по умолчанию 1 для каждого продукта):
    [multi_atc data='9660,9568,8625']
    
  • При разных количествах (2 первых продукта и 4 последних продукта):
    [multi_atc data='9660:2,9568,8625:4']
    

Чтобы использовать шорткод внутри PHP-кода, используйте функцию do_shortcode(), например:

echo do_shortcode("[multi_atc data='9660:2,9568,8625:4']");

Я использую кнопку «Добавить в корзину» в продукте React, поэтому короткий код мне не подойдет. Однако основная проблема заключалась не в WooCommerce, WordPress или бэкэнде в целом; это было в моем коде JavaScript, где я неправильно получал данные из-за неправильных параметров заголовка. Как только я это исправил, все стало работать как положено. Благодарю за ваш ответ. Кроме того, я скорректировал код PHP в соответствии с вашими предложениями, что решило проблему. Еще раз спасибо!

Stuff lahza 25.06.2024 11:10

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