Woocommerce - can't add to cart as a guest usi

2019-07-20 07:17发布

Using the plugin @ http://products.solvercircle.com/woocommerce-one-page-quick-shop/quick-shop/

It seems like if I'm logged in as a regular user in the admin, I can add items to the cart fine. If I add to cart as a guest however it does the ajax request and returns a '1' but the item is never added to the cart.

Does anyone know why it might be so? The other 2 plugins I have on the site I deactivated and can still reproduce this, so I believe this is a bug in this plugin.

EDIT: I confirmed that 'guests can checkout' settings box is applied, so that doesn't seem to be it.

EDIT #2: Here's the add to cart fn:

  function wqo_add_prod(pid,vid){
    var qty= jQuery('#product_qty_'+vid).val();
    if(qty==0){
      jQuery('#wqo_alert_info').text('Out of Stock');
      jQuery('#wqo_alert_info').show()
      setTimeout(function(){jQuery('#wqo_alert_info').hide()}, 1500);      
      return false;
    }
    if(vid==0){
      qty= jQuery('#product_qty_'+pid).val();
    }

    var ajax_url = 'http://DOMAIN.com/wp-admin/admin-ajax.php';
        jQuery.ajax({
          type: "POST",
          url:ajax_url,
              data : {
                  'action':          'wqo_addtocart',
                  'wqo_prod_id':     pid,
                  'wqo_prod_var_id': vid,
                  'wqo_prod_qty':    qty
          },
          success: function(response){            
            if(response==1){
              jQuery('#wqo_alert_info').text('Added to your cart');
            }else{
              jQuery('#wqo_alert_info').text(response);
            }

            jQuery.ajax({
              type: "POST",
              url:ajax_url,
              data : {'action': 'wqo_cart_amount'},
              success: function(data){             
                jQuery('#wqo_cart_price').html(data);
              }
            });

             jQuery('#wqo_alert_info').show()
             setTimeout(function(){jQuery('#wqo_alert_info').hide()}, 2000);          
          }
        });
  }

EDIT #3: Source for the php callback

function wqo_addtocart() {
  global $woocommerce;
  $vid=$_POST['wqo_prod_var_id'];
  $pid=$_POST['wqo_prod_id'];
  $vid=$_POST['wqo_prod_var_id'];
  $pqty=$_POST['wqo_prod_qty'];

  if($vid==0){
    $product = WC_Product_Factory::get_product($pid);    
  }else{
    $product = WC_Product_Factory::get_product($vid);    
  }
  $stock=$product->get_stock_quantity();
  $availability = $product->get_availability();

  if($availability['class']=='out-of-stock'){
    echo 'Out of stock';
    exit;
  }

  if($stock!=''){
        foreach($woocommerce->cart->cart_contents as $cart_item_key => $values ) {
        $c_item_id='';
        $c_stock='';
        if($values['variation_id']!=''){
          $c_item_id=$values['variation_id'];
        }else{
          $c_item_id=$values['product_id'];
        }
        $c_stock=$values['quantity']+$pqty;

        if($vid==0 && $pid==$c_item_id && $c_stock>$stock){
          $product = WC_Product_Factory::get_product($pid);
          echo 'You have cross the stock limit';
          exit;
        }else if($vid==$c_item_id && $c_stock>$stock){
          $product = WC_Product_Factory::get_product($vid);
          echo 'You have cross the stock limit';
          exit;
        }        
       }    
  }

  if($vid==0){
    $z=$woocommerce->cart->add_to_cart($pid,$pqty,null, null, null );
  }else{    
    $z=$woocommerce->cart->add_to_cart($pid, $pqty, $vid, $product->get_variation_attributes(),null);
  }
  echo '1';

  exit;
}

Registers at the bottom of woo-quick-order/includes/wqo-view.php ( also where the above fns are stolen from )

675 add_action( 'wp_ajax_nopriv_wqo_addtocart','wqo_addtocart' );
676 add_action( 'wp_ajax_wqo_addtocart', 'wqo_addtocart' );

EDIT #4: I think it's a session issue. In the first ajax call which calls wqo_addtocart if I do:

var_dump($woocommerce->cart->cart_contents);

It returns the array and the main key is the hash that $z returns.

On the second ajax request however, this is lost:

 59 function wqo_cart_amount(){
 60   global $woocommerce;
 61   var_dump($woocommerce->cart->cart_contents);
 62   echo $woocommerce->cart->get_cart_total();
 63   exit;
 64 }

This returns an empty array. So in between the first and second ajax requests it gets lost.

1条回答
▲ chillily
2楼-- · 2019-07-20 07:47

There is the answer :),

// Hook after add to cart
add_action( 'woocommerce_add_to_cart' , 'repair_woocommerce_2_2_8_session_add_to_cart');

function repair_woocommerce_2_2_8_session_add_to_cart( ){
    if ( defined( 'DOING_AJAX' ) ) {
        wc_setcookie( 'woocommerce_items_in_cart', 1 );
        wc_setcookie( 'woocommerce_cart_hash', md5( json_encode( WC()->cart->get_cart() ) ) );
        do_action( 'woocommerce_set_cart_cookies', true );
    }
}

WooCommerce have made some change on the add_to_cart function The problem is here : https://github.com/woothemes/woocommerce/blob/master/includes/class-wc-cart.php#L978

the right code should be :

if ( did_action( 'wp' ) || defined( 'DOING_AJAX' ) ) {
    $this->set_cart_cookies( sizeof( $this->cart_contents ) > 0 );
}
查看更多
登录 后发表回答