Добавить вариант в корзину с помощью AJAX-WooCommerce API?

у меня есть элемент со следующими данными:

var item = {
  id : "124",
  name : "xxx",
  price : "13.13",
  quantity : 1,
  options : {
    "size" : "xl",
    "color": "pink"
  }
};

когда пользователь нажимает "добавить в корзину", я хотел бы сделать запрос Ajax с помощью WC API и добавить вышеуказанный элемент в корзину.

jQuery.ajax({
   url: "some/woocommerce/api/add/to/cart/request/path",
   data: item,
   type: "POST"
});

затем на странице корзины я хотел бы сделать еще один запрос Ajax с помощью WC API и получить содержимое корзины.

Я не нашел никакой документации (официальной или неофициальной) о том, как это сделать от клиента с помощью Javascript.

тут кто-нибудь знает и может дать мне пример, пожалуйста?

кроме того, кто-нибудь знает, почему документация Api WooCommerce настолько ужасна (не хватает какой-либо информации относительно очевидных/стандартных вопросов, таких как выше). Я серьезно думаю о том, чтобы наша компания переключилась на Shopify.

2 ответов


вы можете исследовать, как WooCommerce добавляет элементы в корзину через ajax непосредственно в коде.... обратный вызов находится в includes/class-wc-ajax.php. WooCommerce уже делает это на "циклах" продукта (архивах продуктов), поэтому я не думаю, что вам нужно изобретать колесо, и если их существующий код не работает для того, что вы пытаетесь сделать, то вы должны иметь возможность заимствовать у него.

начало этого файла имеет цикл со всеми действиями WooCommerce Ajax, но мы можем отслеживать вниз, что добавить в корзину в основном это:

add_action( 'wp_ajax_nopriv_woocommerce_add_to_cart', array( 'WC_AJAX', 'add_to_cart' ) );

и это обратный вызов немного дальше по файлу:

/**
 * AJAX add to cart
 */
public static function add_to_cart() {
    ob_start();

    $product_id        = apply_filters( 'woocommerce_add_to_cart_product_id', absint( $_POST['product_id'] ) );
    $quantity          = empty( $_POST['quantity'] ) ? 1 : wc_stock_amount( $_POST['quantity'] );
    $passed_validation = apply_filters( 'woocommerce_add_to_cart_validation', true, $product_id, $quantity, $variation_id, $variations, $cart_item_data );

    if ( $passed_validation && WC()->cart->add_to_cart( $product_id, $quantity ) ) {

        do_action( 'woocommerce_ajax_added_to_cart', $product_id );

        if ( get_option( 'woocommerce_cart_redirect_after_add' ) == 'yes' ) {
            wc_add_to_cart_message( $product_id );
        }

        // Return fragments
        self::get_refreshed_fragments();

    } else {

        // If there was an error adding to the cart, redirect to the product page to show any errors
        $data = array(
            'error' => true,
            'product_url' => apply_filters( 'woocommerce_cart_redirect_after_error', get_permalink( $product_id ), $product_id )
        );

        wp_send_json( $data );

    }

    die();
}

если вы хотите просмотреть их добавить в корзину ajax, JS для этого находится в assest/js/frontend/add-to-cart.js.

редактировать

теперь, когда я знаю, что вы хотите добавить вариацию,может быть мы можем настроить выше.

во-первых, я думаю, вам нужно будет передать url AJAX вашему сценарий:

wp_enqueue_script( 'wc-variation-add-to-cart', 'source-to-script/your-script.js' );

$vars = array( 'ajax_url' => admin_url( 'admin-ajax.php' ) );
wp_localize_script( 'wc-variation-add-to-cart', 'WC_VARIATION_ADD_TO_CART', $vars );

тогда ваш вызов AJAX будет выглядеть примерно так:

jQuery.ajax({
    url: WC_VARIATION_ADD_TO_CART.ajax_url,
    data: {
        "action" : "woocommerce_add_variation_to_cart",
        "product_id" : "124",
        "variation_id" : "125",
        "quantity" : 1,
        "variation" : {
            "size" : "xl",
            "color": "pink"
        },
    },
    type: "POST"
});

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

и, наконец, новый обратный вызов для woocommerce_add_variation_to_cart действие ajax будет выглядеть следующим образом:

add_action( 'wp_ajax_nopriv_woocommerce_add_variation_to_cart', 'so_27270880_add_variation_to_cart' );

function so_27270880_add_variation_to_cart() {

    ob_start();

    $product_id        = apply_filters( 'woocommerce_add_to_cart_product_id', absint( $_POST['product_id'] ) );
    $quantity          = empty( $_POST['quantity'] ) ? 1 : wc_stock_amount( $_POST['quantity'] );

    $variation_id      = isset( $_POST['variation_id'] ) ? absint( $_POST['variation_id'] ) : '';
    $variations         = ! empty( $_POST['variation'] ) ? (array) $_POST['variation'] : '';

    $passed_validation = apply_filters( 'woocommerce_add_to_cart_validation', true, $product_id, $quantity, $variation_id, $variations, $cart_item_data );

    if ( $passed_validation && WC()->cart->add_to_cart( $product_id, $quantity, $variation_id, $variations ) ) {

        do_action( 'woocommerce_ajax_added_to_cart', $product_id );

        if ( get_option( 'woocommerce_cart_redirect_after_add' ) == 'yes' ) {
            wc_add_to_cart_message( $product_id );
        }

        // Return fragments
        WC_AJAX::get_refreshed_fragments();

    } else {

        // If there was an error adding to the cart, redirect to the product page to show any errors
        $data = array(
            'error' => true,
            'product_url' => apply_filters( 'woocommerce_cart_redirect_after_error', get_permalink( $product_id ), $product_id )
        );

        wp_send_json( $data );

    }

    die();
}

в основном, я просто копирую подход WooCommerce и добавляю 2 переменные, необходимые для добавления вариаций. Совершенно непроверенный, но я надеюсь, это поможет.


Если кто-то заинтересован, я также написал функцию "Удалить из корзины", чтобы противостоять добавлению в корзину. Мой проект вызвал переключатели на кассе, поэтому мне нужно было добавить продукт и удалить альтернативу, она уже была там:

вот php:

function remove_from_cart( $product_id ) {
    $cart_contents  = WC()->cart->get_cart();

    if (empty($product_id)) { $product_id = $_POST['product_id']; }

    foreach ($cart_contents as $product_key => $product){
        if ($product['variation_id'] == $product_id){
            WC()->cart->remove_cart_item($product_key);
        }
    }
}

add_action( 'wp_ajax_nopriv_remove_from_cart', 'remove_from_cart' );

и тогда вот jQuery:

function remove_item_from_cart(product){

    var data = {
                "action" : "remove_from_cart",
                "product_id" : product,
    };

    jQuery.post(WC_VARIATION_ADD_TO_CART.ajax_url, data, function(response) {
        $(document.body).trigger("update_checkout");
    });

}

if (пустой)... в php было так, что я мог бы вызвать функцию со стороны сервера, если мне нужно.