D
D
DeniSidorenko2020-11-05 15:02:14
WordPress
DeniSidorenko, 2020-11-05 15:02:14

Woocommerce one function instead of several?

Good afternoon, I made adding products via ajax. The fact is that adding a product and changing the quantity became a problem when there are a lot of them, and we decided to do it as follows. Just on js, a person will add , and when you click on the button at once, everything will go to the server. Sounds cool, and fast enough BUT!
an ajax request can only be sent once, and the second one will be executed when the response complete is necessary
And why the ajax function looks like this

var dataActions = [];
    for(var i = 0; i<$allProducts.length; i++){

      var item = $allProducts[i]
      var id = parseFloat($(item).attr('data-id'))
      var quantity = parseFloat($(item).find('.item-quantity').attr('value'))
      var data = {
        action: 'woocommerce_ajax_add_to_cart',
        product_id: id,
        product_sku: '',
        quantity: quantity,
      }
      dataActions.push(data)
    }

    postProducts(dataActions, 0);
    function postProducts(products, index){
      $.ajax({
        type: 'post',
        url: wc_add_to_cart_params.ajax_url,
        data: products[index],
        beforeSend: function (response) {

        },
        complete: function (response) {
          index++;
          if (products.length - 1 >= index) {
            postProducts(products, index);
          }
          else{
            if(window.location.hostname == "site.ru"){
              window.location.href = window.location.href + "?opencheck";
           }
          }
          
        },
      
      });
    }


And this code in php

add_action('wp_ajax_woocommerce_ajax_add_to_cart', 'woocommerce_ajax_add_to_cart');
add_action('wp_ajax_nopriv_woocommerce_ajax_add_to_cart', 'woocommerce_ajax_add_to_cart');
        
function woocommerce_ajax_add_to_cart() {

  $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 = absint($_POST['variation_id']);
  $passed_validation = apply_filters('woocommerce_add_to_cart_validation', true, $product_id, $quantity);
  $product_status = get_post_status($product_id);

  if ($passed_validation && WC()->cart->add_to_cart($product_id, $quantity, $variation_id) && 'publish' === $product_status) {

      do_action('woocommerce_ajax_added_to_cart', $product_id);

      if ('yes' === get_option('woocommerce_cart_redirect_after_add')) {
          wc_add_to_cart_message(array($product_id => $quantity), true);
      }

      WC_AJAX :: get_refreshed_fragments();
  } else {

      $data = array(
          'error' => true,
          'product_url' => apply_filters('woocommerce_cart_redirect_after_error', get_permalink($product_id), $product_id));

      echo wp_send_json($data);
  }

  wp_die();
}


And the code works, it really works, but the problem is that this is a cyclic function for adding goods, if there are about 8 of them, it works for 8-10 seconds. Tell me if it is possible to make the products added in one request, and not 8 (depending on the number of products)

Answer the question

In order to leave comments, you need to log in

1 answer(s)
P
Pychev Anatoly, 2020-11-05
@DeniSidorenko

Everything is quite simple.
You need to change the data that you send and send all the items selected by the user and their number. And on the server, process the incoming data and add everything to the basket.

Example of processing a multiple add to cart request
/**
   * Множественное добавление в корзину
   * Вызывается по Ajax
   *
   * @hook-handle qop_add_to_cart
   */
  public function ajax_add_to_cart() {

    $product_items = isset( $_POST['products'] ) && is_array( $_POST['products'] ) ? $_POST['products'] : false;

    $errors               = array();
    $added_products_count = 0;

    foreach ( $product_items as $item ) {
      $product_id   = $item['product_id'];
      $quantity     = $item['quantity'];
      $variation_id = $item['variation_id'];
      $title        = $item['product_title'];
      $sku          = $item['sku']; // для простого товара здесь тоже его sku


      $passed_validation = apply_filters( 'woocommerce_add_to_cart_validation', true, $product_id, $quantity );
      $product_status    = get_post_status( $product_id );

      if ( $passed_validation && WC()->cart->add_to_cart( $product_id, $quantity, $variation_id ) && 'publish' === $product_status ) {

        do_action( 'woocommerce_ajax_added_to_cart', $product_id );
        $added_products_count ++;

      } else {
        $notices = WC()->session->get( 'wc_notices', array() );
        if ( isset( $notices['error'] ) ) {
          $error   = array_pop( $notices['error'] );
          $err_msg = preg_replace( '/<a.*?href.*?=(.*)>(.*?)<\/a>/', '', $error );

          $errors[] = array(
            'variationId' => $variation_id,
            'title'       => $title,
            'sku'         => $sku,
            'msg'         => $err_msg,
          );
        }
        wc_clear_notices();
      }
    }

    $response = array(
      'added'  => $added_products_count,
      'errors' => $errors,
      'popup'  => $this->template_errors_formating( $errors ),  // Формирование собственного popup-a для пользователя
      'cart'   => $this->get_refreshed_fragments(),  // необходимо для обновления миникорзины в шапке.
    );

    wp_send_json( $response );
  }

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question