Forum Replies Created
- AuthorPosts
-
phong-tran
ParticipantI’m newbie and my English is not good so the answer may be a little confusing.
Thank vlad274 for the advice.
My approach:
Same with Daniel Salcedo, I also try to change the metadata by editing woocommerce_sessions, but there is a problem. When adding an item to the cart, the woocommerce will create a unique cart_item_key for it by md5 (product_id + … + metadata), then look for this cart_item_key already exists, if available, this item will be updated in quantity, otherwise will create a new item.
This means that if you change the meta value of the hat product from blue to red, then add the hat product with blue, instead of creating a new item blue hat, it will only increase the quantity of red hat, you need to change the cart_item_key if you want the cart to be updated correctly.
Changing cart_item_key is quite risky, instead we can simply remove and re-add the product. Like this
// get cart_item_key of item you want to change $cart_item_key_old = $_POST['cart_item_key']; // retrieve its information $cart_item_old = WC()->cart->cart_contents[ $cart_item_key_old ]; $product_id_old = $cart_item_old['product_id']; $quantity_old = $cart_item_old['quantity']; $variation_id_old = $cart_item_old['variation_id']; $variation_old = $cart_item_old['variation']; // creating a cart_item_key with the same information except metadata $cart_item_key_new = WC()->cart->generate_cart_id( $product_id_old, $variation_id_old, $variation_old, ['color'=>'red'] ); // check new cart_item_key already exists $found = WC()->cart->find_product_in_cart( $cart_item_key_new ); // if true, update its quantity if ($found != '') { $new_quantity = $cart_item_old['quantity'] + WC()->cart->cart_contents[ $cart_item_key_new ]['quantity']; WC()->cart->set_quantity( $cart_item_key_new, $new_quantity ); } // else, re-add with new metadata else { WC()->cart->add_to_cart($product_id_old, $quantity_old, $variation_id_old, $variation_old, ['color'=>'red'] ); } // finally delete the old item WC()->cart->remove_cart_item($cart_item_key_old); wp_die();
Note: If you want to submit cart form instead of page refreshes after running the above ajax, the quantity of item is likely to be overridden by the set_quantity method when woocommerce update_cart. In this case you just need to return new_quantity and change the input value by js before submitting the form.
Full code:
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) { ... ?> <!-- place it anywhere within the foreach --> <div class="box-type-field"> <select class="box-type" name="box-type" cart_item_key="<?php echo $cart_item_key ?>"> <option <?php echo $cart_item['box-type']=='boxes'?"selected":""; ?> value="boxes"><?php _e( 'Boxes', 'woocommerce' ); ?></option> <option <?php echo $cart_item['box-type']=='bags'?"selected":""; ?> value="bags"><?php _e( 'Bags', 'woocommerce' ); ?></option> </select> </div> <?php ... }
AJAX:
$('.box-type-field .box-type').live('change', function () { var cartItemKey = $(this).attr("cart_item_key"); var boxType = $(this).val(); $.ajax({ type : "post", url : '<?php echo admin_url('admin-ajax.php');?>', datatype: 'json', data : { action : "update_cart_boxtype", cart_item_key : cartItemKey, box_type : boxType, }, success: function(cartItem) { cartItemKey = cartItem[0]; cartItemQty = cartItem[1]; if (cartItem) $('input[name="cart['+cartItemKey+'][qty]"]').val(cartItemQty); // update quantity $('.woocommerce-cart-form button[type="submit"]').click(); // submit form } }) })
PHP:
add_action( 'wp_ajax_update_cart_boxtype', 'update_cart_boxtype_init' ); add_action( 'wp_ajax_nopriv_update_cart_boxtype', 'update_cart_boxtype_init' ); function update_cart_boxtype_init() { if ( ! WC()->cart->is_empty() ) { $cart_item_key = (isset($_POST['cart_item_key']))?$_POST['cart_item_key'] : ''; $cart_item = WC()->cart->cart_contents[ $cart_item_key ]; $box_type = (isset($_POST['box_type']))?$_POST['box_type'] : ''; $cart_updated = false; $cart_item_key_new = WC()->cart->generate_cart_id( $cart_item['product_id'], $cart_item['variation_id'], $cart_item['variation'], ['box-type'=>$box_type] ); $found = WC()->cart->find_product_in_cart( $cart_item_key_new ); if ($found != '') { $new_qty = $cart_item['quantity'] + WC()->cart->cart_contents[ $cart_item_key_new ]['quantity']; WC()->cart->remove_cart_item($cart_item_key); wp_send_json_success([$cart_item_key_new, $new_qty]); } else { WC()->cart->add_to_cart($cart_item['product_id'], $cart_item['quantity'], $cart_item['variation_id'], $cart_item['variation'], ['box-type' => $box_type]); $cart_updated = true; WC()->cart->remove_cart_item($cart_item_key); wp_send_json_success(false); } } wp_die(); }
- AuthorPosts