Add a Variation to Cart using AJAX - WooCommerce API?

后端 未结 2 669
广开言路
广开言路 2020-11-27 17:28

I have an item with the following data :

var item = {
  id : \"124\",
  name : \"xxx\",
  price : \"13.13\",
  quantity : 1,
  options : {
    \"size\" : \"x         


        
2条回答
  •  再見小時候
    2020-11-27 18:27

    You can investigate how WooCommerce is adding items to the cart via ajax directly in the code.... the callback is located in includes/class-wc-ajax.php. WooCommerce already does this on product "loops" (product archives), so I don't think you need to reinvent the wheel and if their existing code doesn't work for what you are trying to do, then you should be able to borrow heavily from it.

    The beginning of that file has a loop with all the WooCommerce Ajax actions, but we can track down that the add to cart is basically this:

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

    And it's callback is a little further down the file:

    /**
     * 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();
    }
    

    If you want to view their add to cart ajax call, the JS for that is located in assest/js/frontend/add-to-cart.js.

    EDIT

    Now that I know you are looking to add a variation, maybe we can tweak the above.

    First, I think you'll need to pass the AJAX url to your script:

    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 );
    

    Then your AJAX call would look something like this:

    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"
    });
    

    Basically to add a specific variation you need the variation's ID in addition to all its specific options.

    And finally the new callback for the woocommerce_add_variation_to_cart ajax action would be along the lines of the following:

    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();
    }
    

    Mostly, I'm just copying WooCommerce's approach and adding in the 2 variables needed for adding variations. Totally untested, but I hope it helps.

提交回复
热议问题