Javascript 使用 AJAX - WooCommerce API 向购物车添加变体?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27270880/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-22 23:57:35  来源:igfitidea点击:

Add a Variation to Cart using AJAX - WooCommerce API?

javascriptajaxwoocommerce

提问by Sprout Coder

I have an item with the following data :

我有一个包含以下数据的项目:

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

When the user clicks on "Add to Cart" I'd like to make an Ajax Request using the WC API and add the above item to the Cart.

当用户单击“添加到购物车”时,我想使用 WC API 发出 Ajax 请求并将上述项目添加到购物车。

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

Then on the Cart Page I'd like to make another Ajax Request using the WC API and retrieve the contents of the cart.

然后在购物车页面上,我想使用 WC API 发出另一个 Ajax 请求并检索购物车的内容。

I haven't found any documentation (official or unofficial) on how to do that from the client using Javascript.

我还没有找到任何关于如何使用 Javascript 从客户端执行此操作的文档(官方或非官方)。

Does anyone know and can provide me with an example please?

有谁知道并且可以给我提供一个例子吗?

Also, does anyone know why the WooCommerce Api Documentation is so horrible (lacking any kind of information regarding obvious/standard questions like the above). I'm seriously thinking of having our company switch to Shopify.

另外,有谁知道为什么 WooCommerce Api 文档如此糟糕(缺乏关于上述明显/标准问题的任何类型的信息)。我正在认真考虑让我们公司改用 Shopify。

回答by helgatheviking

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.

您可以直接在代码中调查 WooCommerce 如何通过 ajax 将商品添加到购物车中……回调位于includes/class-wc-ajax.php. WooCommerce 已经在产品“循环”(产品档案)上做到了这一点,所以我认为你不需要重新发明轮子,如果他们现有的代码对你想要做的事情不起作用,那么你应该能够借用严重从它。

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:

该文件的开头有一个包含所有 WooCommerce Ajax 操作的循环,但我们可以追踪到添加到购物车的内容基本上是这样的:

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.

如果您想查看他们添加到购物车的 ajax 调用,则其 JS 位于assest/js/frontend/add-to-cart.js.

EDIT

编辑

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

既然我知道你想添加一个变体,也许我们可以调整上面的内容。

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

首先,我认为您需要将 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 );

Then your AJAX call would look something like this:

那么您的 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"
});

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

基本上要添加特定变体,除了所有特定选项之外,您还需要变体的 ID。

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

最后,woocommerce_add_variation_to_cartajax 操作的新回调将遵循以下内容:

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.

大多数情况下,我只是复制 WooCommerce 的方法并添加添加变体所需的 2 个变量。完全未经测试,但我希望它有所帮助。

回答by RestlessWeb

If anyone is interested I've also written a "remove from cart" function to counter the add to cart. My project called for radio buttons on checkout so I needed to add a product and remove the alternative it was already there:

如果有人感兴趣,我还编写了一个“从购物车中删除”功能来对抗添加到购物车。我的项目要求在结账时使用单选按钮,所以我需要添加一个产品并删除它已经存在的替代品:

Here's the php:

这是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' );

And then here's the jQuery:

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

}

The if(empty)... in the php was so I could call the function from the server side as well if I needed to.

php 中的 if(empty)... 这样我也可以在需要时从服务器端调用该函数。